/* $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-codec/ffmpeg_codecs.h>
#include <pjmedia-codec/h263_packetizer.h>
#include <pjmedia-codec/h264_packetizer.h>
#include <pjmedia/errno.h>
#include <pjmedia/vid_codec_util.h>
#include <pj/assert.h>
#include <pj/list.h>
#include <pj/log.h>
#include <pj/math.h>
#include <pj/pool.h>
#include <pj/string.h>
#include <pj/os.h>


/*
 * Only build this file if PJMEDIA_HAS_FFMPEG_CODEC != 0 and 
 * PJMEDIA_HAS_VIDEO != 0
 */
#if defined(PJMEDIA_HAS_FFMPEG_CODEC) && PJMEDIA_HAS_FFMPEG_CODEC != 0 && \
    defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)

#define THIS_FILE   "ffmpeg_codecs.c"

#include "../pjmedia/ffmpeg_util.h"
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>

#define ENABLE_H264	0

/* Prototypes for FFMPEG codecs factory */
static pj_status_t ffmpeg_test_alloc( pjmedia_vid_codec_factory *factory, 
				      const pjmedia_vid_codec_info *id );
static pj_status_t ffmpeg_default_attr( pjmedia_vid_codec_factory *factory, 
				        const pjmedia_vid_codec_info *info, 
				        pjmedia_vid_codec_param *attr );
static pj_status_t ffmpeg_enum_codecs( pjmedia_vid_codec_factory *factory, 
				       unsigned *count, 
				       pjmedia_vid_codec_info codecs[]);
static pj_status_t ffmpeg_alloc_codec( pjmedia_vid_codec_factory *factory, 
				       const pjmedia_vid_codec_info *info, 
				       pjmedia_vid_codec **p_codec);
static pj_status_t ffmpeg_dealloc_codec( pjmedia_vid_codec_factory *factory, 
				         pjmedia_vid_codec *codec );

/* Prototypes for FFMPEG codecs implementation. */
static pj_status_t  ffmpeg_codec_init( pjmedia_vid_codec *codec, 
				       pj_pool_t *pool );
static pj_status_t  ffmpeg_codec_open( pjmedia_vid_codec *codec, 
				       pjmedia_vid_codec_param *attr );
static pj_status_t  ffmpeg_codec_close( pjmedia_vid_codec *codec );
static pj_status_t  ffmpeg_codec_modify(pjmedia_vid_codec *codec, 
				        const pjmedia_vid_codec_param *attr );
static pj_status_t  ffmpeg_codec_get_param(pjmedia_vid_codec *codec,
					   pjmedia_vid_codec_param *param);
static pj_status_t ffmpeg_codec_encode_begin( pjmedia_vid_codec *codec,
                                              const pjmedia_frame *input,
					      unsigned out_size,
					      pjmedia_frame *output,
					      pj_bool_t *has_more);
static pj_status_t ffmpeg_codec_encode_more(pjmedia_vid_codec *codec,
					    unsigned out_size,
					    pjmedia_frame *output,
					    pj_bool_t *has_more);
static pj_status_t ffmpeg_codec_decode( pjmedia_vid_codec *codec,
					pj_size_t pkt_count,
					pjmedia_frame packets[],
					unsigned out_size,
					pjmedia_frame *output);

/* Definition for FFMPEG codecs operations. */
static pjmedia_vid_codec_op ffmpeg_op = 
{
    &ffmpeg_codec_init,
    &ffmpeg_codec_open,
    &ffmpeg_codec_close,
    &ffmpeg_codec_modify,
    &ffmpeg_codec_get_param,
    &ffmpeg_codec_encode_begin,
    &ffmpeg_codec_encode_more,
    &ffmpeg_codec_decode,
    NULL
};

/* Definition for FFMPEG codecs factory operations. */
static pjmedia_vid_codec_factory_op ffmpeg_factory_op =
{
    &ffmpeg_test_alloc,
    &ffmpeg_default_attr,
    &ffmpeg_enum_codecs,
    &ffmpeg_alloc_codec,
    &ffmpeg_dealloc_codec
};


/* FFMPEG codecs factory */
static struct ffmpeg_factory {
    pjmedia_vid_codec_factory    base;
    pjmedia_vid_codec_mgr	*mgr;
    pj_pool_factory             *pf;
    pj_pool_t		        *pool;
    pj_mutex_t		        *mutex;
} ffmpeg_factory;


typedef struct ffmpeg_codec_desc ffmpeg_codec_desc;


/* FFMPEG codecs private data. */
typedef struct ffmpeg_private
{
    const ffmpeg_codec_desc	    *desc;
    pjmedia_vid_codec_param	     param;	/**< Codec param	    */
    pj_pool_t			    *pool;	/**< Pool for each instance */
    pj_timestamp		     last_tx;   /**< Timestamp of last 
						     transmit		    */

    /* Format info and apply format param */
    const pjmedia_video_format_info *enc_vfi;
    pjmedia_video_apply_fmt_param    enc_vafp;
    const pjmedia_video_format_info *dec_vfi;
    pjmedia_video_apply_fmt_param    dec_vafp;

    /* Buffers, only needed for multi-packets */
    pj_bool_t			     whole;
    void			    *enc_buf;
    unsigned			     enc_buf_size;
    unsigned			     enc_frame_len;
    unsigned     		     enc_processed;
    void			    *dec_buf;
    unsigned			     dec_buf_size;

    /* The ffmpeg codec states. */
    AVCodec			    *enc;
    AVCodec			    *dec;
    AVCodecContext		    *enc_ctx;
    AVCodecContext		    *dec_ctx;

    /* The ffmpeg decoder cannot set the output format, so format conversion
     * may be needed for post-decoding.
     */
    enum PixelFormat		     expected_dec_fmt;
						/**< Expected output format of 
						     ffmpeg decoder	    */

    void			    *data;	/**< Codec specific data    */		    
} ffmpeg_private;


/* Shortcuts for packetize & unpacketize function declaration,
 * as it has long params and is reused many times!
 */
#define FUNC_PACKETIZE(name) \
    pj_status_t(name)(ffmpeg_private *ff, pj_uint8_t *bits, \
		      pj_size_t bits_len, unsigned *bits_pos, \
		      const pj_uint8_t **payload, pj_size_t *payload_len)

#define FUNC_UNPACKETIZE(name) \
    pj_status_t(name)(ffmpeg_private *ff, const pj_uint8_t *payload, \
		      pj_size_t payload_len, pj_uint8_t *bits, \
		      pj_size_t bits_len, unsigned *bits_pos)

#define FUNC_FMT_MATCH(name) \
    pj_status_t(name)(pj_pool_t *pool, \
		      pjmedia_sdp_media *offer, unsigned o_fmt_idx, \
		      pjmedia_sdp_media *answer, unsigned a_fmt_idx, \
		      unsigned option)


/* Type definition of codec specific functions */
typedef FUNC_PACKETIZE(*func_packetize);
typedef FUNC_UNPACKETIZE(*func_unpacketize);
typedef pj_status_t (*func_preopen)	(ffmpeg_private *ff);
typedef pj_status_t (*func_postopen)	(ffmpeg_private *ff);
typedef FUNC_FMT_MATCH(*func_sdp_fmt_match);


/* FFMPEG codec info */
struct ffmpeg_codec_desc
{
    /* Predefined info */
    pjmedia_vid_codec_info       info;
    pjmedia_format_id		 base_fmt_id;	/**< Some codecs may be exactly
						     same or compatible with
						     another codec, base format
						     will tell the initializer
						     to copy this codec desc
						     from its base format   */
    pj_uint32_t			 avg_bps;
    pj_uint32_t			 max_bps;
    func_packetize		 packetize;
    func_unpacketize		 unpacketize;
    func_preopen		 preopen;
    func_preopen		 postopen;
    func_sdp_fmt_match		 sdp_fmt_match;
    pjmedia_codec_fmtp		 dec_fmtp;

    /* Init time defined info */
    pj_bool_t			 enabled;
    AVCodec                     *enc;
    AVCodec                     *dec;
};


#if ENABLE_H264
/* H264 constants */
#define PROFILE_H264_BASELINE		66
#define PROFILE_H264_MAIN		77

/* Codec specific functions */
static pj_status_t h264_preopen(ffmpeg_private *ff);
static pj_status_t h264_postopen(ffmpeg_private *ff);
static FUNC_PACKETIZE(h264_packetize);
static FUNC_UNPACKETIZE(h264_unpacketize);
#endif	/* ENABLE_H264 */

static pj_status_t h263_preopen(ffmpeg_private *ff);
static FUNC_PACKETIZE(h263_packetize);
static FUNC_UNPACKETIZE(h263_unpacketize);


/* Internal codec info */
static ffmpeg_codec_desc codec_desc[] =
{
#if ENABLE_H264
    {
	{PJMEDIA_FORMAT_H264, PJMEDIA_RTP_PT_H264, {"H264",4},
	 {"Constrained Baseline (level=30, pack=1)", 39}},
	0,	128000,    1000000,
	&h264_packetize, &h264_unpacketize, &h264_preopen, &h264_postopen,
	&pjmedia_vid_codec_h264_match_sdp,
	/* Leading space for better compatibility (strange indeed!) */
	{2, { {{"profile-level-id",16},    {"42e01e",6}}, 
	      {{" packetization-mode",19},  {"1",1}}, } },
    },
    {
	{PJMEDIA_FORMAT_H264, PJMEDIA_RTP_PT_H264_RSV1, {"H264",4},
	 {"Baseline (level=30, pack=1)", 27}},
	PJMEDIA_FORMAT_H264,	128000,    1000000,
	&h264_packetize, &h264_unpacketize, &h264_preopen, &h264_postopen,
	&pjmedia_vid_codec_h264_match_sdp,
	{2, { {{"profile-level-id",16},    {"42001e",6}}, 
	      {{" packetization-mode",19},  {"1",1}}, } },
    },
#endif
    {
	{PJMEDIA_FORMAT_H263P, PJMEDIA_RTP_PT_H263P, {"H263-1998",9}},
	PJMEDIA_FORMAT_H263,	1000000,    2000000,
	&h263_packetize, &h263_unpacketize, &h263_preopen, NULL, NULL,
	{2, { {{"CIF",3},   {"1",1}}, 
	      {{"QCIF",4},  {"1",1}}, } },
    },
    {
	{PJMEDIA_FORMAT_H263, PJMEDIA_RTP_PT_H263, {"H263",4}},
	PJMEDIA_FORMAT_H263,	1000000,    2000000,
	&h263_packetize, &h263_unpacketize, &h263_preopen, NULL, NULL,
	{2, { {{"CIF",3},   {"1",1}}, 
	      {{"QCIF",4},  {"1",1}}, } },
    },
    {
	{PJMEDIA_FORMAT_H263,	PJMEDIA_RTP_PT_H263,	{"H263",4}},
    },
    {
	{PJMEDIA_FORMAT_H261,	PJMEDIA_RTP_PT_H261,	{"H261",4}},
    },
    {
	{PJMEDIA_FORMAT_MJPEG,	PJMEDIA_RTP_PT_JPEG,	{"JPEG",4}},
    },
    {
	{PJMEDIA_FORMAT_MPEG4,	0,			{"MP4V",4}},
    },
    {
	{PJMEDIA_FORMAT_XVID,	0,			{"XVID",4}},
	PJMEDIA_FORMAT_MPEG4,
    },
};

#if ENABLE_H264
typedef struct h264_data
{
    pjmedia_vid_codec_h264_fmtp	 fmtp;
    pjmedia_h264_packetizer	*pktz;
} h264_data;


static pj_status_t h264_preopen(ffmpeg_private *ff)
{
    h264_data *data;
    pjmedia_h264_packetizer_cfg pktz_cfg;
    pj_status_t status;

    data = PJ_POOL_ZALLOC_T(ff->pool, h264_data);
    ff->data = data;

    /* Parse remote fmtp */
    status = pjmedia_vid_codec_h264_parse_fmtp(&ff->param.enc_fmtp,
					       &data->fmtp);
    if (status != PJ_SUCCESS)
	return status;

    /* Create packetizer */
    pktz_cfg.mtu = ff->param.enc_mtu;
#if 0
    if (data->fmtp.packetization_mode == 0)
	pktz_cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL;
    else if (data->fmtp.packetization_mode == 1)
	pktz_cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED;
    else
	return PJ_ENOTSUP;
#else
    if (data->fmtp.packetization_mode!=
				PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL &&
	data->fmtp.packetization_mode!=
				PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED)
    {
	return PJ_ENOTSUP;
    }
    /* Better always send in single NAL mode for better compatibility */
    pktz_cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL;
#endif

    status = pjmedia_h264_packetizer_create(ff->pool, &pktz_cfg, &data->pktz);
    if (status != PJ_SUCCESS)
	return status;

    /* Apply SDP fmtp to format in codec param */
    status = pjmedia_vid_codec_h264_apply_fmtp(&ff->param);
    if (status != PJ_SUCCESS)
	return status;

    if (ff->param.dir & PJMEDIA_DIR_ENCODING) {
	AVCodecContext *ctx = ff->enc_ctx;

	/* Apply profile. Note that, for x264 backend, ffmpeg doesn't seem to
	 * use this profile param field, so let's try to apply it "manually".
	 */
	ctx->profile  = data->fmtp.profile_idc;
	if (ctx->profile == PROFILE_H264_BASELINE) {
	    /* Baseline profile settings (the most used profile in
	     * conversational/real-time communications).
	     */
	    ctx->coder_type = FF_CODER_TYPE_VLC;
	    ctx->max_b_frames = 0;
	    ctx->flags2 &= ~(CODEC_FLAG2_WPRED | CODEC_FLAG2_8X8DCT);
	    ctx->weighted_p_pred = 0;
	} else if (ctx->profile == PROFILE_H264_MAIN) {
	    ctx->flags2 &= ~CODEC_FLAG2_8X8DCT;
	}

	/* Apply profile constraint bits. */
	// The x264 doesn't seem to support non-constrained (baseline) profile
	// so this shouldn't be a problem (for now).
	//PJ_TODO(set_h264_constraint_bits_properly_in_ffmpeg);
	if (data->fmtp.profile_iop) {
#if defined(FF_PROFILE_H264_CONSTRAINED)
	    ctx->profile |= FF_PROFILE_H264_CONSTRAINED;
#endif
	}

	/* Apply profile level. */
	ctx->level    = data->fmtp.level;

	/* Libx264 rejects the "broken" ffmpeg defaults, so just change some */
	ctx->me_range = 16;
	ctx->max_qdiff = 4;
	ctx->qmin = 20;
	ctx->qmax = 32;
	ctx->qcompress = 0.6f;

	ctx->rtp_payload_size = ff->param.enc_mtu;
    }

    if (ff->param.dir & PJMEDIA_DIR_DECODING) {
	AVCodecContext *ctx = ff->dec_ctx;

	/* Apply the "sprop-parameter-sets" fmtp from remote SDP to
	 * extradata of ffmpeg codec context.
	 */
	if (data->fmtp.sprop_param_sets_len) {
	    ctx->extradata_size = data->fmtp.sprop_param_sets_len;
	    ctx->extradata = data->fmtp.sprop_param_sets;
	}
    }

    return PJ_SUCCESS;
}

static pj_status_t h264_postopen(ffmpeg_private *ff)
{
    h264_data *data = (h264_data*)ff->data;
    PJ_UNUSED_ARG(data);
    return PJ_SUCCESS;
}


static FUNC_PACKETIZE(h264_packetize)
{
    h264_data *data = (h264_data*)ff->data;
    return pjmedia_h264_packetize(data->pktz, bits, bits_len, bits_pos,
				  payload, payload_len);
}

static FUNC_UNPACKETIZE(h264_unpacketize)
{
    h264_data *data = (h264_data*)ff->data;
    return pjmedia_h264_unpacketize(data->pktz, payload, payload_len,
				    bits, bits_len, bits_pos);
}
#endif	/* ENABLE_H264 */

typedef struct h263_data
{
    pjmedia_h263_packetizer	*pktz;
} h263_data;

/* H263 pre-open */
static pj_status_t h263_preopen(ffmpeg_private *ff)
{
    h263_data *data;
    pjmedia_h263_packetizer_cfg pktz_cfg;
    pj_status_t status;

    data = PJ_POOL_ZALLOC_T(ff->pool, h263_data);
    ff->data = data;

    /* Create packetizer */
    pktz_cfg.mtu = ff->param.enc_mtu;
    pktz_cfg.mode = PJMEDIA_H263_PACKETIZER_MODE_RFC4629;
    status = pjmedia_h263_packetizer_create(ff->pool, &pktz_cfg, &data->pktz);
    if (status != PJ_SUCCESS)
	return status;

    /* Apply fmtp settings to codec param */
    status = pjmedia_vid_codec_h263_apply_fmtp(&ff->param);

    return status;
}

static FUNC_PACKETIZE(h263_packetize)
{
    h263_data *data = (h263_data*)ff->data;
    return pjmedia_h263_packetize(data->pktz, bits, bits_len, bits_pos,
				  payload, payload_len);
}

static FUNC_UNPACKETIZE(h263_unpacketize)
{
    h263_data *data = (h263_data*)ff->data;
    return pjmedia_h263_unpacketize(data->pktz, payload, payload_len,
				    bits, bits_len, bits_pos);
}


static const ffmpeg_codec_desc* find_codec_desc_by_info(
			const pjmedia_vid_codec_info *info)
{
    int i;

    for (i=0; i<PJ_ARRAY_SIZE(codec_desc); ++i) {
	ffmpeg_codec_desc *desc = &codec_desc[i];

	if (desc->enabled &&
	    (desc->info.fmt_id == info->fmt_id) &&
            ((desc->info.dir & info->dir) == info->dir) &&
	    (desc->info.pt == info->pt) &&
	    (desc->info.packings & info->packings))
        {
            return desc;
        }
    }

    return NULL;
}


static int find_codec_idx_by_fmt_id(pjmedia_format_id fmt_id)
{
    int i;
    for (i=0; i<PJ_ARRAY_SIZE(codec_desc); ++i) {
	if (codec_desc[i].info.fmt_id == fmt_id)
	    return i;
    }

    return -1;
}


/*
 * Initialize and register FFMPEG codec factory to pjmedia endpoint.
 */
PJ_DEF(pj_status_t) pjmedia_codec_ffmpeg_init(pjmedia_vid_codec_mgr *mgr,
                                              pj_pool_factory *pf)
{
    pj_pool_t *pool;
    AVCodec *c;
    pj_status_t status;
    unsigned i;

    if (ffmpeg_factory.pool != NULL) {
	/* Already initialized. */
	return PJ_SUCCESS;
    }

    if (!mgr) mgr = pjmedia_vid_codec_mgr_instance();
    PJ_ASSERT_RETURN(mgr, PJ_EINVAL);

    /* Create FFMPEG codec factory. */
    ffmpeg_factory.base.op = &ffmpeg_factory_op;
    ffmpeg_factory.base.factory_data = NULL;
    ffmpeg_factory.mgr = mgr;
    ffmpeg_factory.pf = pf;

    pool = pj_pool_create(pf, "ffmpeg codec factory", 256, 256, NULL);
    if (!pool)
	return PJ_ENOMEM;

    /* Create mutex. */
    status = pj_mutex_create_simple(pool, "ffmpeg codec factory", 
				    &ffmpeg_factory.mutex);
    if (status != PJ_SUCCESS)
	goto on_error;

    avcodec_init();
    avcodec_register_all();
    av_log_set_level(AV_LOG_ERROR);

    /* Enum FFMPEG codecs */
    for (c=av_codec_next(NULL); c; c=av_codec_next(c)) {
        ffmpeg_codec_desc *desc;
	pjmedia_format_id fmt_id;
	int codec_info_idx;
        
#if LIBAVCODEC_VERSION_MAJOR <= 52
#   define AVMEDIA_TYPE_VIDEO	CODEC_TYPE_VIDEO
#endif
        if (c->type != AVMEDIA_TYPE_VIDEO)
            continue;

        /* Video encoder and decoder are usually implemented in separate
         * AVCodec instances. While the codec attributes (e.g: raw formats,
	 * supported fps) are in the encoder.
         */

	//PJ_LOG(3, (THIS_FILE, "%s", c->name));
	status = CodecID_to_pjmedia_format_id(c->id, &fmt_id);
	/* Skip if format ID is unknown */
	if (status != PJ_SUCCESS)
	    continue;

	codec_info_idx = find_codec_idx_by_fmt_id(fmt_id);
	/* Skip if codec is unwanted by this wrapper (not listed in 
	 * the codec info array)
	 */
	if (codec_info_idx < 0)
	    continue;

	desc = &codec_desc[codec_info_idx];

	/* Skip duplicated codec implementation */
	if ((c->encode && (desc->info.dir & PJMEDIA_DIR_ENCODING)) ||
	    (c->decode && (desc->info.dir & PJMEDIA_DIR_DECODING)))
	{
	    continue;
	}

	/* Get raw/decoded format ids in the encoder */
	if (c->pix_fmts && c->encode) {
	    pjmedia_format_id raw_fmt[PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT];
	    unsigned raw_fmt_cnt = 0;
	    unsigned raw_fmt_cnt_should_be = 0;
	    const enum PixelFormat *p = c->pix_fmts;

	    for(;(p && *p != -1) &&
		 (raw_fmt_cnt < PJMEDIA_VID_CODEC_MAX_DEC_FMT_CNT);
		 ++p)
	    {
		pjmedia_format_id fmt_id;

		raw_fmt_cnt_should_be++;
		status = PixelFormat_to_pjmedia_format_id(*p, &fmt_id);
		if (status != PJ_SUCCESS) {
		    PJ_LOG(6, (THIS_FILE, "Unrecognized ffmpeg pixel "
			       "format %d", *p));
		    continue;
		}
		raw_fmt[raw_fmt_cnt++] = fmt_id;
	    }

	    if (raw_fmt_cnt == 0) {
		PJ_LOG(5, (THIS_FILE, "No recognized raw format "
				      "for codec [%s/%s], codec ignored",
				      c->name, c->long_name));
		/* Skip this encoder */
		continue;
	    }

	    if (raw_fmt_cnt < raw_fmt_cnt_should_be) {
		PJ_LOG(6, (THIS_FILE, "Codec [%s/%s] have %d raw formats, "
				      "recognized only %d raw formats",
				      c->name, c->long_name,
				      raw_fmt_cnt_should_be, raw_fmt_cnt));
	    }

	    desc->info.dec_fmt_id_cnt = raw_fmt_cnt;
	    pj_memcpy(desc->info.dec_fmt_id, raw_fmt, 
		      sizeof(raw_fmt[0])*raw_fmt_cnt);
	}

	/* Get supported framerates */
	if (c->supported_framerates) {
	    const AVRational *fr = c->supported_framerates;
	    while ((fr->num != 0 || fr->den != 0) && 
		   desc->info.fps_cnt < PJMEDIA_VID_CODEC_MAX_FPS_CNT)
	    {
		desc->info.fps[desc->info.fps_cnt].num = fr->num;
		desc->info.fps[desc->info.fps_cnt].denum = fr->den;
		++desc->info.fps_cnt;
		++fr;
	    }
	}

	/* Get ffmpeg encoder instance */
        if (c->encode && !desc->enc) {
            desc->info.dir |= PJMEDIA_DIR_ENCODING;
            desc->enc = c;
        }
	
	/* Get ffmpeg decoder instance */
        if (c->decode && !desc->dec) {
            desc->info.dir |= PJMEDIA_DIR_DECODING;
            desc->dec = c;
        }

	/* Enable this codec when any ffmpeg codec instance are recognized
	 * and the supported raw formats info has been collected.
	 */
	if ((desc->dec || desc->enc) && desc->info.dec_fmt_id_cnt)
	{
	    desc->enabled = PJ_TRUE;
	}

	/* Normalize default value of clock rate */
	if (desc->info.clock_rate == 0)
	    desc->info.clock_rate = 90000;

	/* Set supported packings */
	desc->info.packings |= PJMEDIA_VID_PACKING_WHOLE;
	if (desc->packetize && desc->unpacketize)
	    desc->info.packings |= PJMEDIA_VID_PACKING_PACKETS;

    }

    /* Review all codecs for applying base format, registering format match for
     * SDP negotiation, etc.
     */
    for (i = 0; i < PJ_ARRAY_SIZE(codec_desc); ++i) {
	ffmpeg_codec_desc *desc = &codec_desc[i];

	/* Init encoder/decoder description from base format */
	if (desc->base_fmt_id && (!desc->dec || !desc->enc)) {
	    ffmpeg_codec_desc *base_desc = NULL;
	    int base_desc_idx;
	    pjmedia_dir copied_dir = PJMEDIA_DIR_NONE;

	    base_desc_idx = find_codec_idx_by_fmt_id(desc->base_fmt_id);
	    if (base_desc_idx != -1)
		base_desc = &codec_desc[base_desc_idx];
	    if (!base_desc || !base_desc->enabled)
		continue;

	    /* Copy description from base codec */
	    if (!desc->info.dec_fmt_id_cnt) {
		desc->info.dec_fmt_id_cnt = base_desc->info.dec_fmt_id_cnt;
		pj_memcpy(desc->info.dec_fmt_id, base_desc->info.dec_fmt_id, 
			  sizeof(pjmedia_format_id)*desc->info.dec_fmt_id_cnt);
	    }
	    if (!desc->info.fps_cnt) {
		desc->info.fps_cnt = base_desc->info.fps_cnt;
		pj_memcpy(desc->info.fps, base_desc->info.fps, 
			  sizeof(desc->info.fps[0])*desc->info.fps_cnt);
	    }
	    if (!desc->info.clock_rate) {
		desc->info.clock_rate = base_desc->info.clock_rate;
	    }
	    if (!desc->dec && base_desc->dec) {
		copied_dir |= PJMEDIA_DIR_DECODING;
		desc->dec = base_desc->dec;
	    }
	    if (!desc->enc && base_desc->enc) {
		copied_dir |= PJMEDIA_DIR_ENCODING;
		desc->enc = base_desc->enc;
	    }

	    desc->info.dir |= copied_dir;
	    desc->enabled = (desc->info.dir != PJMEDIA_DIR_NONE);

	    /* Set supported packings */
	    desc->info.packings |= PJMEDIA_VID_PACKING_WHOLE;
	    if (desc->packetize && desc->unpacketize)
		desc->info.packings |= PJMEDIA_VID_PACKING_PACKETS;

	    if (copied_dir != PJMEDIA_DIR_NONE) {
		const char *dir_name[] = {NULL, "encoder", "decoder", "codec"};
		PJ_LOG(5, (THIS_FILE, "The %.*s %s is using base codec (%.*s)",
			   desc->info.encoding_name.slen,
			   desc->info.encoding_name.ptr,
			   dir_name[copied_dir],
			   base_desc->info.encoding_name.slen,
			   base_desc->info.encoding_name.ptr));
	    }
        }

	/* Registering format match for SDP negotiation */
	if (desc->sdp_fmt_match) {
	    status = pjmedia_sdp_neg_register_fmt_match_cb(
						&desc->info.encoding_name,
						desc->sdp_fmt_match);
	    pj_assert(status == PJ_SUCCESS);
	}
    }

    /* Register codec factory to codec manager. */
    status = pjmedia_vid_codec_mgr_register_factory(mgr, 
						    &ffmpeg_factory.base);
    if (status != PJ_SUCCESS)
	goto on_error;

    ffmpeg_factory.pool = pool;

    /* Done. */
    return PJ_SUCCESS;

on_error:
    pj_pool_release(pool);
    return status;
}

/*
 * Unregister FFMPEG codecs factory from pjmedia endpoint.
 */
PJ_DEF(pj_status_t) pjmedia_codec_ffmpeg_deinit(void)
{
    pj_status_t status = PJ_SUCCESS;

    if (ffmpeg_factory.pool == NULL) {
	/* Already deinitialized */
	return PJ_SUCCESS;
    }

    pj_mutex_lock(ffmpeg_factory.mutex);

    /* Unregister FFMPEG codecs factory. */
    status = pjmedia_vid_codec_mgr_unregister_factory(ffmpeg_factory.mgr,
						      &ffmpeg_factory.base);

    /* Destroy mutex. */
    pj_mutex_destroy(ffmpeg_factory.mutex);

    /* Destroy pool. */
    pj_pool_release(ffmpeg_factory.pool);
    ffmpeg_factory.pool = NULL;

    return status;
}


/* 
 * Check if factory can allocate the specified codec. 
 */
static pj_status_t ffmpeg_test_alloc( pjmedia_vid_codec_factory *factory, 
				      const pjmedia_vid_codec_info *info )
{
    const ffmpeg_codec_desc *desc;

    PJ_ASSERT_RETURN(factory==&ffmpeg_factory.base, PJ_EINVAL);
    PJ_ASSERT_RETURN(info, PJ_EINVAL);

    desc = find_codec_desc_by_info(info);
    if (!desc) {
        return PJMEDIA_CODEC_EUNSUP;
    }

    return PJ_SUCCESS;
}

/*
 * Generate default attribute.
 */
static pj_status_t ffmpeg_default_attr( pjmedia_vid_codec_factory *factory, 
				        const pjmedia_vid_codec_info *info, 
				        pjmedia_vid_codec_param *attr )
{
    const ffmpeg_codec_desc *desc;
    unsigned i;

    PJ_ASSERT_RETURN(factory==&ffmpeg_factory.base, PJ_EINVAL);
    PJ_ASSERT_RETURN(info && attr, PJ_EINVAL);

    desc = find_codec_desc_by_info(info);
    if (!desc) {
        return PJMEDIA_CODEC_EUNSUP;
    }

    pj_bzero(attr, sizeof(pjmedia_vid_codec_param));

    /* Scan the requested packings and use the lowest number */
    attr->packing = 0;
    for (i=0; i<15; ++i) {
	unsigned packing = (1 << i);
	if ((desc->info.packings & info->packings) & packing) {
	    attr->packing = (pjmedia_vid_packing)packing;
	    break;
	}
    }
    if (attr->packing == 0) {
	/* No supported packing in info */
	return PJMEDIA_CODEC_EUNSUP;
    }

    /* Direction */
    attr->dir = desc->info.dir;

    /* Encoded format */
    pjmedia_format_init_video(&attr->enc_fmt, desc->info.fmt_id,
                              352, 288, 30000, 1001);

    /* Decoded format */
    pjmedia_format_init_video(&attr->dec_fmt, desc->info.dec_fmt_id[0],
                              //352, 288, 30000, 1001);
                              720, 576, 30000, 1001);

    /* Decoding fmtp */
    attr->dec_fmtp = desc->dec_fmtp;

    /* Bitrate */
    attr->enc_fmt.det.vid.avg_bps = desc->avg_bps;
    attr->enc_fmt.det.vid.max_bps = desc->max_bps;

    /* MTU */
    attr->enc_mtu = PJMEDIA_MAX_MTU;

    return PJ_SUCCESS;
}

/*
 * Enum codecs supported by this factory.
 */
static pj_status_t ffmpeg_enum_codecs( pjmedia_vid_codec_factory *factory,
				       unsigned *count, 
				       pjmedia_vid_codec_info codecs[])
{
    unsigned i, max_cnt;

    PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL);
    PJ_ASSERT_RETURN(factory == &ffmpeg_factory.base, PJ_EINVAL);

    max_cnt = PJ_MIN(*count, PJ_ARRAY_SIZE(codec_desc));
    *count = 0;

    for (i=0; i<max_cnt; ++i) {
	if (codec_desc[i].enabled) {
	    pj_memcpy(&codecs[*count], &codec_desc[i].info, 
		      sizeof(pjmedia_vid_codec_info));
	    (*count)++;
	}
    }

    return PJ_SUCCESS;
}

/*
 * Allocate a new codec instance.
 */
static pj_status_t ffmpeg_alloc_codec( pjmedia_vid_codec_factory *factory, 
				       const pjmedia_vid_codec_info *info,
				       pjmedia_vid_codec **p_codec)
{
    ffmpeg_private *ff;
    const ffmpeg_codec_desc *desc;
    pjmedia_vid_codec *codec;
    pj_pool_t *pool = NULL;
    pj_status_t status = PJ_SUCCESS;

    PJ_ASSERT_RETURN(factory && info && p_codec, PJ_EINVAL);
    PJ_ASSERT_RETURN(factory == &ffmpeg_factory.base, PJ_EINVAL);

    desc = find_codec_desc_by_info(info);
    if (!desc) {
        return PJMEDIA_CODEC_EUNSUP;
    }

    /* Create pool for codec instance */
    pool = pj_pool_create(ffmpeg_factory.pf, "ffmpeg codec", 512, 512, NULL);
    codec = PJ_POOL_ALLOC_T(pool, pjmedia_vid_codec);
    if (!codec) {
        status = PJ_ENOMEM;
        goto on_error;
    }
    pjmedia_vid_codec_reset(codec, PJMEDIA_SIG_VID_CODEC_FFMPEG);
    codec->op = &ffmpeg_op;
    codec->factory = factory;
    ff = PJ_POOL_ZALLOC_T(pool, ffmpeg_private);
    if (!ff) {
        status = PJ_ENOMEM;
        goto on_error;
    }
    codec->codec_data = ff;
    ff->pool = pool;
    ff->enc = desc->enc;
    ff->dec = desc->dec;
    ff->desc = desc;

    *p_codec = codec;
    return PJ_SUCCESS;

on_error:
    if (pool)
        pj_pool_release(pool);
    return status;
}

/*
 * Free codec.
 */
static pj_status_t ffmpeg_dealloc_codec( pjmedia_vid_codec_factory *factory, 
				         pjmedia_vid_codec *codec )
{
    ffmpeg_private *ff;
    pj_pool_t *pool;

    PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL);
    PJ_ASSERT_RETURN(factory == &ffmpeg_factory.base, PJ_EINVAL);

    /* Close codec, if it's not closed. */
    ff = (ffmpeg_private*) codec->codec_data;
    pool = ff->pool;
    codec->codec_data = NULL;
    pj_pool_release(pool);

    return PJ_SUCCESS;
}

/*
 * Init codec.
 */
static pj_status_t ffmpeg_codec_init( pjmedia_vid_codec *codec, 
				      pj_pool_t *pool )
{
    PJ_UNUSED_ARG(codec);
    PJ_UNUSED_ARG(pool);
    return PJ_SUCCESS;
}

static void print_ffmpeg_err(int err)
{
#if LIBAVCODEC_VERSION_MAJOR > 52 || \
    (LIBAVCODEC_VERSION_MAJOR >= 52 && LIBAVCODEC_VERSION_MINOR >= 72)
    char errbuf[512];
    if (av_strerror(err, errbuf, sizeof(errbuf)) >= 0)
        PJ_LOG(5, (THIS_FILE, "ffmpeg err %d: %s", err, errbuf));
#else
    PJ_LOG(5, (THIS_FILE, "ffmpeg err %d", err));
#endif

}

static enum PixelFormat dec_get_format(struct AVCodecContext *s, 
                                       const enum PixelFormat * fmt)
{
    ffmpeg_private *ff = (ffmpeg_private*)s->opaque;
    enum PixelFormat def_fmt = *fmt;

    while (*fmt != -1) {
	if (*fmt == ff->expected_dec_fmt)
	    return *fmt;
	++fmt;
    }

    pj_assert(!"Inconsistency in supported formats");
    return def_fmt;
}


static pj_status_t open_ffmpeg_codec(ffmpeg_private *ff,
                                     pj_mutex_t *ff_mutex)
{
    enum PixelFormat pix_fmt;
    pjmedia_video_format_detail *vfd;
    pj_bool_t enc_opened = PJ_FALSE, dec_opened = PJ_FALSE;
    pj_status_t status;

    /* Get decoded pixel format */
    status = pjmedia_format_id_to_PixelFormat(ff->param.dec_fmt.id,
                                              &pix_fmt);
    if (status != PJ_SUCCESS)
        return status;
    ff->expected_dec_fmt = pix_fmt;

    /* Get video format detail for shortcut access to encoded format */
    vfd = pjmedia_format_get_video_format_detail(&ff->param.enc_fmt, 
						 PJ_TRUE);

    /* Allocate ffmpeg codec context */
    if (ff->param.dir & PJMEDIA_DIR_ENCODING) {
	ff->enc_ctx = avcodec_alloc_context();
	if (ff->enc_ctx == NULL)
	    goto on_error;
    }
    if (ff->param.dir & PJMEDIA_DIR_DECODING) {
	ff->dec_ctx = avcodec_alloc_context();
	if (ff->dec_ctx == NULL)
	    goto on_error;
    }

    /* Let the codec apply specific settings before the codec opened */
    if (ff->desc->preopen) {
	status = (*ff->desc->preopen)(ff);
	if (status != PJ_SUCCESS)
	    goto on_error;
    }

    if (ff->param.dir & PJMEDIA_DIR_ENCODING) {
        AVCodecContext *ctx = ff->enc_ctx;
        int err;

	/* Init common settings */
        ctx->pix_fmt = pix_fmt;
	ctx->width = vfd->size.w;
	ctx->height = vfd->size.h;
	ctx->time_base.num = vfd->fps.denum;
	ctx->time_base.den = vfd->fps.num;
	if (vfd->avg_bps) {
	    ctx->bit_rate = vfd->avg_bps;
	    if (vfd->max_bps > vfd->avg_bps)
		ctx->bit_rate_tolerance = vfd->max_bps - vfd->avg_bps;
	}
	ctx->strict_std_compliance = FF_COMPLIANCE_STRICT;
        ctx->workaround_bugs = FF_BUG_AUTODETECT;
        ctx->opaque = ff;

	/* Set no delay, note that this may cause some codec functionals
	 * not working (e.g: rate control).
	 */
#if LIBAVCODEC_VERSION_MAJOR > 52 || \
    (LIBAVCODEC_VERSION_MAJOR >= 52 && LIBAVCODEC_VERSION_MINOR >= 113)
	ctx->rc_lookahead = 0;
#endif

	/* Open ffmpeg codec */
        pj_mutex_lock(ff_mutex);
        err = avcodec_open(ctx, ff->enc);
        pj_mutex_unlock(ff_mutex);
        if (err < 0) {
            print_ffmpeg_err(err);
            status = PJMEDIA_CODEC_EFAILED;
	    goto on_error;
        }
	enc_opened = PJ_TRUE;
    }

    if (ff->param.dir & PJMEDIA_DIR_DECODING) {
	AVCodecContext *ctx = ff->dec_ctx;
	int err;

	/* Init common settings */
	/* Width/height may be overriden by ffmpeg after first decoding. */
	ctx->width  = ctx->coded_width  = ff->param.dec_fmt.det.vid.size.w;
	ctx->height = ctx->coded_height = ff->param.dec_fmt.det.vid.size.h;
	ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
        ctx->workaround_bugs = FF_BUG_AUTODETECT;
        ctx->opaque = ff;
	ctx->get_format = &dec_get_format;

	/* Open ffmpeg codec */
        pj_mutex_lock(ff_mutex);
        err = avcodec_open(ctx, ff->dec);
        pj_mutex_unlock(ff_mutex);
        if (err < 0) {
            print_ffmpeg_err(err);
            status = PJMEDIA_CODEC_EFAILED;
	    goto on_error;
        }
	dec_opened = PJ_TRUE;
    }

    /* Let the codec apply specific settings after the codec opened */
    if (ff->desc->postopen) {
	status = (*ff->desc->postopen)(ff);
	if (status != PJ_SUCCESS)
	    goto on_error;
    }

    return PJ_SUCCESS;

on_error:
    if (ff->enc_ctx) {
	if (enc_opened)
	    avcodec_close(ff->enc_ctx);
	av_free(ff->enc_ctx);
	ff->enc_ctx = NULL;
    }
    if (ff->dec_ctx) {
	if (dec_opened)
	    avcodec_close(ff->dec_ctx);
	av_free(ff->dec_ctx);
	ff->dec_ctx = NULL;
    }
    return status;
}

/*
 * Open codec.
 */
static pj_status_t ffmpeg_codec_open( pjmedia_vid_codec *codec, 
				      pjmedia_vid_codec_param *attr )
{
    ffmpeg_private *ff;
    pj_status_t status;
    pj_mutex_t *ff_mutex;

    PJ_ASSERT_RETURN(codec && attr, PJ_EINVAL);
    ff = (ffmpeg_private*)codec->codec_data;

    pj_memcpy(&ff->param, attr, sizeof(*attr));

    /* Open the codec */
    ff_mutex = ((struct ffmpeg_factory*)codec->factory)->mutex;
    status = open_ffmpeg_codec(ff, ff_mutex);
    if (status != PJ_SUCCESS)
        goto on_error;

    /* Init format info and apply-param of decoder */
    ff->dec_vfi = pjmedia_get_video_format_info(NULL, ff->param.dec_fmt.id);
    if (!ff->dec_vfi) {
        status = PJ_EINVAL;
        goto on_error;
    }
    pj_bzero(&ff->dec_vafp, sizeof(ff->dec_vafp));
    ff->dec_vafp.size = ff->param.dec_fmt.det.vid.size;
    ff->dec_vafp.buffer = NULL;
    status = (*ff->dec_vfi->apply_fmt)(ff->dec_vfi, &ff->dec_vafp);
    if (status != PJ_SUCCESS) {
        goto on_error;
    }

    /* Init format info and apply-param of encoder */
    ff->enc_vfi = pjmedia_get_video_format_info(NULL, ff->param.dec_fmt.id);
    if (!ff->enc_vfi) {
        status = PJ_EINVAL;
        goto on_error;
    }
    pj_bzero(&ff->enc_vafp, sizeof(ff->enc_vafp));
    ff->enc_vafp.size = ff->param.enc_fmt.det.vid.size;
    ff->enc_vafp.buffer = NULL;
    status = (*ff->enc_vfi->apply_fmt)(ff->enc_vfi, &ff->enc_vafp);
    if (status != PJ_SUCCESS) {
        goto on_error;
    }

    /* Alloc buffers if needed */
    ff->whole = (ff->param.packing == PJMEDIA_VID_PACKING_WHOLE);
    if (!ff->whole) {
	ff->enc_buf_size = ff->enc_vafp.framebytes;
	ff->enc_buf = pj_pool_alloc(ff->pool, ff->enc_buf_size);

	ff->dec_buf_size = ff->dec_vafp.framebytes;
	ff->dec_buf = pj_pool_alloc(ff->pool, ff->dec_buf_size);
    }

    /* Update codec attributes, e.g: encoding format may be changed by
     * SDP fmtp negotiation.
     */
    pj_memcpy(attr, &ff->param, sizeof(*attr));

    return PJ_SUCCESS;

on_error:
    ffmpeg_codec_close(codec);
    return status;
}

/*
 * Close codec.
 */
static pj_status_t ffmpeg_codec_close( pjmedia_vid_codec *codec )
{
    ffmpeg_private *ff;
    pj_mutex_t *ff_mutex;

    PJ_ASSERT_RETURN(codec, PJ_EINVAL);
    ff = (ffmpeg_private*)codec->codec_data;
    ff_mutex = ((struct ffmpeg_factory*)codec->factory)->mutex;

    pj_mutex_lock(ff_mutex);
    if (ff->enc_ctx) {
        avcodec_close(ff->enc_ctx);
        av_free(ff->enc_ctx);
    }
    if (ff->dec_ctx && ff->dec_ctx!=ff->enc_ctx) {
        avcodec_close(ff->dec_ctx);
        av_free(ff->dec_ctx);
    }
    ff->enc_ctx = NULL;
    ff->dec_ctx = NULL;
    pj_mutex_unlock(ff_mutex);

    return PJ_SUCCESS;
}


/*
 * Modify codec settings.
 */
static pj_status_t  ffmpeg_codec_modify( pjmedia_vid_codec *codec, 
				         const pjmedia_vid_codec_param *attr)
{
    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data;

    PJ_UNUSED_ARG(attr);
    PJ_UNUSED_ARG(ff);

    return PJ_ENOTSUP;
}

static pj_status_t  ffmpeg_codec_get_param(pjmedia_vid_codec *codec,
					   pjmedia_vid_codec_param *param)
{
    ffmpeg_private *ff;

    PJ_ASSERT_RETURN(codec && param, PJ_EINVAL);

    ff = (ffmpeg_private*)codec->codec_data;
    pj_memcpy(param, &ff->param, sizeof(*param));

    return PJ_SUCCESS;
}


static pj_status_t  ffmpeg_packetize ( pjmedia_vid_codec *codec,
                                       pj_uint8_t *bits,
                                       pj_size_t bits_len,
                                       unsigned *bits_pos,
                                       const pj_uint8_t **payload,
                                       pj_size_t *payload_len)
{
    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data;

    if (ff->desc->packetize) {
	return (*ff->desc->packetize)(ff, bits, bits_len, bits_pos,
                                      payload, payload_len);
    }

    return PJ_ENOTSUP;
}

static pj_status_t  ffmpeg_unpacketize(pjmedia_vid_codec *codec,
                                       const pj_uint8_t *payload,
                                       pj_size_t   payload_len,
                                       pj_uint8_t *bits,
                                       pj_size_t   bits_len,
				       unsigned   *bits_pos)
{
    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data;

    if (ff->desc->unpacketize) {
        return (*ff->desc->unpacketize)(ff, payload, payload_len,
                                        bits, bits_len, bits_pos);
    }
    
    return PJ_ENOTSUP;
}


/*
 * Encode frames.
 */
static pj_status_t ffmpeg_codec_encode_whole(pjmedia_vid_codec *codec,
					     const pjmedia_frame *input,
					     unsigned output_buf_len,
					     pjmedia_frame *output)
{
    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data;
    pj_uint8_t *p = (pj_uint8_t*)input->buf;
    AVFrame avframe;
    pj_uint8_t *out_buf = (pj_uint8_t*)output->buf;
    int out_buf_len = output_buf_len;
    int err;
    //AVRational src_timebase;
    /* For some reasons (e.g: SSE/MMX usage), the avcodec_encode_video() must
     * have stack aligned to 16 bytes. Let's try to be safe by preparing the
     * 16-bytes aligned stack here, in case it's not managed by the ffmpeg.
     */
    PJ_ALIGN_DATA(pj_uint32_t i[4], 16);

    if ((long)i & 0xF) {
	PJ_LOG(2,(THIS_FILE, "Stack alignment fails"));
    }

    /* Check if encoder has been opened */
    PJ_ASSERT_RETURN(ff->enc_ctx, PJ_EINVALIDOP);

    avcodec_get_frame_defaults(&avframe);

    // Let ffmpeg manage the timestamps
    /*
    src_timebase.num = 1;
    src_timebase.den = ff->desc->info.clock_rate;
    avframe.pts = av_rescale_q(input->timestamp.u64, src_timebase,
			       ff->enc_ctx->time_base);
    */
    
    for (i[0] = 0; i[0] < ff->enc_vfi->plane_cnt; ++i[0]) {
        avframe.data[i[0]] = p;
        avframe.linesize[i[0]] = ff->enc_vafp.strides[i[0]];
        p += ff->enc_vafp.plane_bytes[i[0]];
    }

    err = avcodec_encode_video(ff->enc_ctx, out_buf, out_buf_len, &avframe);
    if (err < 0) {
        print_ffmpeg_err(err);
        return PJMEDIA_CODEC_EFAILED;
    } else {
        output->size = err;
    }

    return PJ_SUCCESS;
}

static pj_status_t ffmpeg_codec_encode_begin( pjmedia_vid_codec *codec,
                                              const pjmedia_frame *input,
					      unsigned out_size,
					      pjmedia_frame *output,
					      pj_bool_t *has_more)
{
    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data;
    pj_status_t status;

    *has_more = PJ_FALSE;

    if (ff->whole) {
	status = ffmpeg_codec_encode_whole(codec, input, out_size, output);
    } else {
	pjmedia_frame whole_frm;
        const pj_uint8_t *payload;
        pj_size_t payload_len;

	pj_bzero(&whole_frm, sizeof(whole_frm));
	whole_frm.buf = ff->enc_buf;
	whole_frm.size = ff->enc_buf_size;
	status = ffmpeg_codec_encode_whole(codec, input,
	                                   whole_frm.size, &whole_frm);
	if (status != PJ_SUCCESS)
	    return status;

	ff->enc_frame_len = (unsigned)whole_frm.size;
	ff->enc_processed = 0;
        status = ffmpeg_packetize(codec, (pj_uint8_t*)whole_frm.buf,
                                  whole_frm.size, &ff->enc_processed,
				  &payload, &payload_len);
        if (status != PJ_SUCCESS)
            return status;

        if (out_size < payload_len)
            return PJMEDIA_CODEC_EFRMTOOSHORT;

        output->type = PJMEDIA_FRAME_TYPE_VIDEO;
        pj_memcpy(output->buf, payload, payload_len);
        output->size = payload_len;

        *has_more = (ff->enc_processed < ff->enc_frame_len);
    }

    return status;
}

static pj_status_t ffmpeg_codec_encode_more(pjmedia_vid_codec *codec,
					    unsigned out_size,
					    pjmedia_frame *output,
					    pj_bool_t *has_more)
{
    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data;
    const pj_uint8_t *payload;
    pj_size_t payload_len;
    pj_status_t status;

    *has_more = PJ_FALSE;

    if (ff->enc_processed >= ff->enc_frame_len) {
	/* No more frame */
	return PJ_EEOF;
    }

    status = ffmpeg_packetize(codec, (pj_uint8_t*)ff->enc_buf,
                              ff->enc_frame_len, &ff->enc_processed,
                              &payload, &payload_len);
    if (status != PJ_SUCCESS)
        return status;

    if (out_size < payload_len)
        return PJMEDIA_CODEC_EFRMTOOSHORT;

    output->type = PJMEDIA_FRAME_TYPE_VIDEO;
    pj_memcpy(output->buf, payload, payload_len);
    output->size = payload_len;

    *has_more = (ff->enc_processed < ff->enc_frame_len);

    return PJ_SUCCESS;
}


/*
 * Decode frame.
 */
static pj_status_t ffmpeg_codec_decode_whole(pjmedia_vid_codec *codec,
					     const pjmedia_frame *input,
					     unsigned output_buf_len,
					     pjmedia_frame *output)
{
    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data;
    AVFrame avframe;
    AVPacket avpacket;
    int err, got_picture;

    /* Check if decoder has been opened */
    PJ_ASSERT_RETURN(ff->dec_ctx, PJ_EINVALIDOP);

    /* Reset output frame bit info */
    output->bit_info = 0;

    /* Validate output buffer size */
    // Do this validation later after getting decoding result, where the real
    // decoded size will be assured.
    //if (ff->dec_vafp.framebytes > output_buf_len)
	//return PJ_ETOOSMALL;

    /* Init frame to receive the decoded data, the ffmpeg codec context will
     * automatically provide the decoded buffer (single buffer used for the
     * whole decoding session, and seems to be freed when the codec context
     * closed).
     */
    avcodec_get_frame_defaults(&avframe);

    /* Init packet, the container of the encoded data */
    av_init_packet(&avpacket);
    avpacket.data = (pj_uint8_t*)input->buf;
    avpacket.size = input->size;

    /* ffmpeg warns:
     * - input buffer padding, at least FF_INPUT_BUFFER_PADDING_SIZE
     * - null terminated
     * Normally, encoded buffer is allocated more than needed, so lets just
     * bzero the input buffer end/pad, hope it will be just fine.
     */
    pj_bzero(avpacket.data+avpacket.size, FF_INPUT_BUFFER_PADDING_SIZE);

    output->bit_info = 0;
    output->timestamp = input->timestamp;

#if LIBAVCODEC_VERSION_MAJOR > 52 || \
    (LIBAVCODEC_VERSION_MAJOR >= 52 && LIBAVCODEC_VERSION_MINOR >= 72)
    //avpacket.flags = AV_PKT_FLAG_KEY;
#else
    avpacket.flags = 0;
#endif

#if LIBAVCODEC_VERSION_MAJOR > 52 || \
    (LIBAVCODEC_VERSION_MAJOR >= 52 && LIBAVCODEC_VERSION_MINOR >= 72)
    err = avcodec_decode_video2(ff->dec_ctx, &avframe, 
                                &got_picture, &avpacket);
#else
    err = avcodec_decode_video(ff->dec_ctx, &avframe,
                               &got_picture, avpacket.data, avpacket.size);
#endif
    if (err < 0) {
	output->type = PJMEDIA_FRAME_TYPE_NONE;
	output->size = 0;
        print_ffmpeg_err(err);
        return PJMEDIA_CODEC_EFAILED;
    } else if (got_picture) {
        pjmedia_video_apply_fmt_param *vafp = &ff->dec_vafp;
        pj_uint8_t *q = (pj_uint8_t*)output->buf;
	unsigned i;

	/* Decoder output format is set by libavcodec, in case it is different
	 * to the configured param.
	 */
	if (ff->dec_ctx->pix_fmt != ff->expected_dec_fmt ||
	    ff->dec_ctx->width != (int)vafp->size.w ||
	    ff->dec_ctx->height != (int)vafp->size.h)
	{
	    pjmedia_format_id new_fmt_id;
	    pj_status_t status;

	    /* Get current raw format id from ffmpeg decoder context */
	    status = PixelFormat_to_pjmedia_format_id(ff->dec_ctx->pix_fmt, 
						      &new_fmt_id);
	    if (status != PJ_SUCCESS)
		return status;

	    /* Update decoder format in param */
    	    ff->param.dec_fmt.id = new_fmt_id;
	    ff->param.dec_fmt.det.vid.size.w = ff->dec_ctx->width;
	    ff->param.dec_fmt.det.vid.size.h = ff->dec_ctx->height;

	    /* Re-init format info and apply-param of decoder */
	    ff->dec_vfi = pjmedia_get_video_format_info(NULL, ff->param.dec_fmt.id);
	    if (!ff->dec_vfi)
		return PJ_ENOTSUP;
	    pj_bzero(&ff->dec_vafp, sizeof(ff->dec_vafp));
	    ff->dec_vafp.size = ff->param.dec_fmt.det.vid.size;
	    ff->dec_vafp.buffer = NULL;
	    status = (*ff->dec_vfi->apply_fmt)(ff->dec_vfi, &ff->dec_vafp);
	    if (status != PJ_SUCCESS)
		return status;

	    /* Realloc buffer if necessary */
	    if (ff->dec_vafp.framebytes > ff->dec_buf_size) {
		PJ_LOG(5,(THIS_FILE, "Reallocating decoding buffer %u --> %u",
			   (unsigned)ff->dec_buf_size,
			   (unsigned)ff->dec_vafp.framebytes));
		ff->dec_buf_size = ff->dec_vafp.framebytes;
		ff->dec_buf = pj_pool_alloc(ff->pool, ff->dec_buf_size);
	    }

	    /* Broadcast event */
	    if (pjmedia_event_publisher_has_sub(&codec->epub)) {
		pjmedia_event event;

		pjmedia_event_init(&event, PJMEDIA_EVENT_FMT_CHANGED,
				   &input->timestamp, &codec->epub);
		event.data.fmt_changed.dir = PJMEDIA_DIR_DECODING;
		pj_memcpy(&event.data.fmt_changed.new_fmt, &ff->param.dec_fmt,
			  sizeof(ff->param.dec_fmt));
		pjmedia_event_publish(&codec->epub, &event);
	    }
	}

	/* Check provided buffer size */
	if (vafp->framebytes > output_buf_len)
	    return PJ_ETOOSMALL;

	/* Get the decoded data */
	for (i = 0; i < ff->dec_vfi->plane_cnt; ++i) {
	    pj_uint8_t *p = avframe.data[i];

	    /* The decoded data may contain padding */
	    if (avframe.linesize[i]!=vafp->strides[i]) {
		/* Padding exists, copy line by line */
		pj_uint8_t *q_end;
                    
		q_end = q+vafp->plane_bytes[i];
		while(q < q_end) {
		    pj_memcpy(q, p, vafp->strides[i]);
		    q += vafp->strides[i];
		    p += avframe.linesize[i];
		}
	    } else {
		/* No padding, copy the whole plane */
		pj_memcpy(q, p, vafp->plane_bytes[i]);
		q += vafp->plane_bytes[i];
	    }
	}

	output->type = PJMEDIA_FRAME_TYPE_VIDEO;
        output->size = vafp->framebytes;

        /* Check if we got key frame */
        if (avframe.key_frame && pjmedia_event_publisher_has_sub(&codec->epub))
        {
            pjmedia_event event;

            pjmedia_event_init(&event, PJMEDIA_EVENT_KEY_FRAME_FOUND,
                               &output->timestamp, &codec->epub);
            pjmedia_event_publish(&codec->epub, &event);
        }
    } else {
	output->type = PJMEDIA_FRAME_TYPE_NONE;
	output->size = 0;
    }
    
    return PJ_SUCCESS;
}

static pj_status_t ffmpeg_codec_decode( pjmedia_vid_codec *codec,
					pj_size_t pkt_count,
					pjmedia_frame packets[],
					unsigned out_size,
					pjmedia_frame *output)
{
    ffmpeg_private *ff = (ffmpeg_private*)codec->codec_data;
    pj_status_t status;

    PJ_ASSERT_RETURN(codec && pkt_count > 0 && packets && output,
                     PJ_EINVAL);

    if (ff->whole) {
	pj_assert(pkt_count==1);
	return ffmpeg_codec_decode_whole(codec, &packets[0], out_size, output);
    } else {
	pjmedia_frame whole_frm;
	unsigned whole_len = 0;
	unsigned i;

	for (i=0; i<pkt_count; ++i) {
	    if (whole_len + packets[i].size > ff->dec_buf_size) {
		PJ_LOG(5,(THIS_FILE, "Decoding buffer overflow"));
		break;
	    }

	    status = ffmpeg_unpacketize(codec, packets[i].buf, packets[i].size,
	                                ff->dec_buf, ff->dec_buf_size,
	                                &whole_len);
	    if (status != PJ_SUCCESS) {
		PJ_PERROR(5,(THIS_FILE, status, "Unpacketize error"));
		continue;
	    }
	}

	whole_frm.buf = ff->dec_buf;
	whole_frm.size = whole_len;
	whole_frm.timestamp = output->timestamp = packets[i].timestamp;
	whole_frm.bit_info = 0;

	return ffmpeg_codec_decode_whole(codec, &whole_frm, out_size, output);
    }
}


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

#endif	/* PJMEDIA_HAS_FFMPEG_CODEC */

