/* $Id$ */
/*
 * Copyright (C) 2010-2011 Teluu Inc. (http://www.teluu.com)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#include <pjmedia/types.h>
#include <pj/errno.h>
#include <pj/log.h>
#include <pj/string.h>

#if PJMEDIA_HAS_LIBAVFORMAT && PJMEDIA_HAS_LIBAVUTIL

#include "ffmpeg_util.h"
#include <libavformat/avformat.h>

#define MAKE_VER(mj,mn,mi)	((mj << 16) | (mn << 8) | (mi << 0))
#define VER_AT_LEAST(mj,mn,mi)	(MAKE_VER(LIBAVUTIL_VERSION_MAJOR, \
                              	          LIBAVUTIL_VERSION_MINOR, \
                              	          LIBAVUTIL_VERSION_MICRO) >= \
                              	 MAKE_VER(mj,mn,mi))



/* Conversion table between pjmedia_format_id and PixelFormat */
static const struct ffmpeg_fmt_table_t
{
    pjmedia_format_id	id;
    enum PixelFormat	pf;
} ffmpeg_fmt_table[] =
{
    { PJMEDIA_FORMAT_RGBA, PIX_FMT_RGBA},
    { PJMEDIA_FORMAT_RGB24,PIX_FMT_BGR24},
    { PJMEDIA_FORMAT_BGRA, PIX_FMT_BGRA},
#if VER_AT_LEAST(51,20,1)
    { PJMEDIA_FORMAT_GBRP, PIX_FMT_GBR24P},
#endif

    { PJMEDIA_FORMAT_AYUV, PIX_FMT_NONE},
    { PJMEDIA_FORMAT_YUY2, PIX_FMT_YUYV422},
    { PJMEDIA_FORMAT_UYVY, PIX_FMT_UYVY422},
    { PJMEDIA_FORMAT_I420, PIX_FMT_YUV420P},
    //{ PJMEDIA_FORMAT_YV12, PIX_FMT_YUV420P},
    { PJMEDIA_FORMAT_I422, PIX_FMT_YUV422P},
    { PJMEDIA_FORMAT_I420JPEG, PIX_FMT_YUVJ420P},
    { PJMEDIA_FORMAT_I422JPEG, PIX_FMT_YUVJ422P},
};

/* Conversion table between pjmedia_format_id and CodecID */
static const struct ffmpeg_codec_table_t
{
    pjmedia_format_id	id;
    enum CodecID	codec_id;
} ffmpeg_codec_table[] =
{
    {PJMEDIA_FORMAT_H261,	CODEC_ID_H261},
    {PJMEDIA_FORMAT_H263,	CODEC_ID_H263},
    {PJMEDIA_FORMAT_H263P,	CODEC_ID_H263P},
    {PJMEDIA_FORMAT_H264,	CODEC_ID_H264},
    {PJMEDIA_FORMAT_MPEG1VIDEO,	CODEC_ID_MPEG1VIDEO},
    {PJMEDIA_FORMAT_MPEG2VIDEO, CODEC_ID_MPEG2VIDEO},
    {PJMEDIA_FORMAT_MPEG4,	CODEC_ID_MPEG4},
    {PJMEDIA_FORMAT_MJPEG,	CODEC_ID_MJPEG}
};

static int pjmedia_ffmpeg_ref_cnt;

static void ffmpeg_log_cb(void* ptr, int level, const char* fmt, va_list vl);

void pjmedia_ffmpeg_add_ref()
{
    if (pjmedia_ffmpeg_ref_cnt++ == 0) {
	av_log_set_level(AV_LOG_ERROR);
	av_log_set_callback(&ffmpeg_log_cb);
	av_register_all();
    }
}

void pjmedia_ffmpeg_dec_ref()
{
    if (pjmedia_ffmpeg_ref_cnt-- == 1) {
	/* How to shutdown ffmpeg? */
    }

    if (pjmedia_ffmpeg_ref_cnt < 0) pjmedia_ffmpeg_ref_cnt = 0;
}


static void ffmpeg_log_cb(void* ptr, int level, const char* fmt, va_list vl)
{
    const char *LOG_SENDER = "ffmpeg";
    enum { LOG_LEVEL = 5 };
    char buf[100];
    pj_size_t bufsize = sizeof(buf), len;
    pj_str_t fmt_st;

    /* Custom callback needs to filter log level by itself */
    if (level > av_log_get_level())
	return;
    
    /* Add original ffmpeg sender to log format */
    if (ptr) {
	AVClass* avc = *(AVClass**)ptr;
	len = pj_ansi_snprintf(buf, bufsize, "%s: ", avc->item_name(ptr));
	if (len < 1 || len >= bufsize)
	    len = bufsize - 1;
	bufsize -= len;
    }

    /* Copy original log format */
    len = pj_ansi_strlen(fmt);
    if (len > bufsize-1)
	len = bufsize-1;
    pj_memcpy(buf+sizeof(buf)-bufsize, fmt, len);
    bufsize -= len;

    /* Trim log format */
    pj_strset(&fmt_st, buf, sizeof(buf)-bufsize);
    pj_strrtrim(&fmt_st);
    buf[fmt_st.slen] = '\0';

    pj_log(LOG_SENDER, LOG_LEVEL, buf, vl);
}


pj_status_t pjmedia_format_id_to_PixelFormat(pjmedia_format_id fmt_id,
					     enum PixelFormat *pixel_format)
{
    unsigned i;
    for (i=0; i<PJ_ARRAY_SIZE(ffmpeg_fmt_table); ++i) {
	const struct ffmpeg_fmt_table_t *t = &ffmpeg_fmt_table[i];
	if (t->id==fmt_id && t->pf != PIX_FMT_NONE) {
	    *pixel_format = t->pf;
	    return PJ_SUCCESS;
	}
    }

    *pixel_format = PIX_FMT_NONE;
    return PJ_ENOTFOUND;
}

pj_status_t PixelFormat_to_pjmedia_format_id(enum PixelFormat pf,
					     pjmedia_format_id *fmt_id)
{
    unsigned i;
    for (i=0; i<PJ_ARRAY_SIZE(ffmpeg_fmt_table); ++i) {
	const struct ffmpeg_fmt_table_t *t = &ffmpeg_fmt_table[i];
	if (t->pf == pf) {
	    if (fmt_id) *fmt_id = t->id;
	    return PJ_SUCCESS;
	}
    }

    return PJ_ENOTFOUND;
}

pj_status_t pjmedia_format_id_to_CodecID(pjmedia_format_id fmt_id,
					 enum CodecID *codec_id)
{
    unsigned i;
    for (i=0; i<PJ_ARRAY_SIZE(ffmpeg_codec_table); ++i) {
	const struct ffmpeg_codec_table_t *t = &ffmpeg_codec_table[i];
	if (t->id==fmt_id && t->codec_id != PIX_FMT_NONE) {
	    *codec_id = t->codec_id;
	    return PJ_SUCCESS;
	}
    }

    *codec_id = PIX_FMT_NONE;
    return PJ_ENOTFOUND;
}

pj_status_t CodecID_to_pjmedia_format_id(enum CodecID codec_id,
					 pjmedia_format_id *fmt_id)
{
    unsigned i;
    for (i=0; i<PJ_ARRAY_SIZE(ffmpeg_codec_table); ++i) {
	const struct ffmpeg_codec_table_t *t = &ffmpeg_codec_table[i];
	if (t->codec_id == codec_id) {
	    if (fmt_id) *fmt_id = t->id;
	    return PJ_SUCCESS;
	}
    }

    return PJ_ENOTFOUND;
}


#ifdef _MSC_VER
#   pragma comment( lib, "avformat.lib")
#   pragma comment( lib, "avutil.lib")
#endif

#endif	/* #if PJMEDIA_HAS_LIBAVFORMAT && PJMEDIA_HAS_LIBAVUTIL */
