summaryrefslogtreecommitdiff
path: root/ext/ffmpeg/gstffmpegdec.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/ffmpeg/gstffmpegdec.c')
-rw-r--r--ext/ffmpeg/gstffmpegdec.c198
1 files changed, 68 insertions, 130 deletions
diff --git a/ext/ffmpeg/gstffmpegdec.c b/ext/ffmpeg/gstffmpegdec.c
index b9a0406..c00a674 100644
--- a/ext/ffmpeg/gstffmpegdec.c
+++ b/ext/ffmpeg/gstffmpegdec.c
@@ -1,4 +1,4 @@
- /* GStreamer
+/* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* This library is free software; you can redistribute it and/or
@@ -164,6 +164,9 @@ struct _GstFFMpegDec
/* Can downstream allocate 16bytes aligned data. */
gboolean can_allocate_aligned;
+
+ /* Extra info which can determine codec Context on the Host side(QEMU)*/
+ CodecExtraInfo codecInfo;
};
typedef struct _GstFFMpegDecClass GstFFMpegDecClass;
@@ -426,10 +429,14 @@ gst_ffmpegdec_init (GstFFMpegDec * ffmpegdec)
ffmpegdec->picture = avcodec_alloc_frame ();
GST_CODEC_LOG("allocate context and frame for emul\n")
- if (oclass->in_plugin->type == AVMEDIA_TYPE_VIDEO) {
- emul_avcodec_alloc_context();
- emul_avcodec_alloc_frame();
- }
+ emul_avcodec_alloc_context(&ffmpegdec->codecInfo);
+ GST_CODEC_LOG("Context Index:%d ffmpegdec:%p\n",
+ ffmpegdec->codecInfo.contextIndex, ffmpegdec)
+ if (ffmpegdec->codecInfo.contextIndex < 0) {
+ fprintf(stderr, "[%s] The index of codec context is %d\n", __func__,
+ ffmpegdec->codecInfo.contextIndex);
+ }
+ emul_avcodec_alloc_frame(&ffmpegdec->codecInfo);
ffmpegdec->pctx = NULL;
ffmpegdec->pcache = NULL;
ffmpegdec->par = NULL;
@@ -458,25 +465,18 @@ gst_ffmpegdec_finalize (GObject * object)
{
GstFFMpegDec *ffmpegdec = (GstFFMpegDec *) object;
- enum AVMediaType codec_type = -1;
-
if (ffmpegdec->context != NULL) {
- codec_type = ffmpegdec->context->codec_type;
- if (codec_type == AVMEDIA_TYPE_VIDEO) {
- GST_CODEC_LOG("video codec context\n");
- emul_av_free_context();
- }
- av_free(ffmpegdec->context);
+ GST_CODEC_LOG("free AVCodecContext\n");
+ emul_av_free_context (&ffmpegdec->codecInfo);
+ av_free (ffmpegdec->context);
ffmpegdec->context = NULL;
}
if (ffmpegdec->picture != NULL) {
- if (codec_type == AVMEDIA_TYPE_VIDEO) {
- GST_CODEC_LOG("Free video type frame\n");
- emul_av_free_picture();
- emul_close_codecdev();
- }
- av_free(ffmpegdec->picture);
+ GST_CODEC_LOG("Free AVFrame\n");
+ emul_av_free_picture(&ffmpegdec->codecInfo);
+ emul_close_codecdev(&ffmpegdec->codecInfo);
+ av_free (ffmpegdec->picture);
ffmpegdec->picture = NULL;
}
@@ -598,25 +598,21 @@ gst_ffmpegdec_close (GstFFMpegDec * ffmpegdec)
}
if (ffmpegdec->context->priv_data)
- gst_ffmpeg_avcodec_close (ffmpegdec->context);
+ gst_ffmpeg_avcodec_close (ffmpegdec->context, &ffmpegdec->codecInfo);
ffmpegdec->opened = FALSE;
if (ffmpegdec->context->palctrl) {
- if (ffmpegdec->context->codec_type == AVMEDIA_TYPE_VIDEO) {
- GST_CODEC_LOG("Free palctrl of video codec context\n");
- emul_av_free_palctrl();
- }
- av_free (ffmpegdec->context->palctrl);
+ GST_CODEC_LOG("Free palctrl of codec context\n");
+ emul_av_free_palctrl(&ffmpegdec->codecInfo);
+ av_free (ffmpegdec->context->palctrl);
ffmpegdec->context->palctrl = NULL;
}
if (ffmpegdec->context->extradata) {
- if (ffmpegdec->context->codec_type == AVMEDIA_TYPE_VIDEO) {
- GST_CODEC_LOG("Free extradata of video codec context\n");
- emul_av_free_extradata();
- }
- av_free (ffmpegdec->context->extradata);
+ GST_CODEC_LOG("Free extradata of codec context\n");
+ emul_av_free_extradata(&ffmpegdec->codecInfo);
+ av_free (ffmpegdec->context->extradata);
ffmpegdec->context->extradata = NULL;
}
@@ -625,16 +621,10 @@ gst_ffmpegdec_close (GstFFMpegDec * ffmpegdec)
gst_buffer_unref (ffmpegdec->pcache);
ffmpegdec->pcache = NULL;
}
+ GST_CODEC_LOG("before emul_av_parser_close\n")
+ emul_av_parser_close (&ffmpegdec->codecInfo);
GST_CODEC_LOG("before av_parser_close\n")
- if (ffmpegdec->context->codec_type == AVMEDIA_TYPE_VIDEO) {
- GST_CODEC_LOG("before emul_av_parser_close\n")
- emul_av_parser_close ();
- GST_CODEC_LOG("before av_parser_close\n")
- av_parser_close (ffmpegdec->pctx);
- } else {
- GST_CODEC_LOG("\n")
- av_parser_close (ffmpegdec->pctx);
- }
+ av_parser_close (ffmpegdec->pctx);
ffmpegdec->pctx = NULL;
}
@@ -652,7 +642,7 @@ gst_ffmpegdec_open (GstFFMpegDec * ffmpegdec)
oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
- if (gst_ffmpeg_avcodec_open (ffmpegdec->context, oclass->in_plugin) < 0)
+ if (gst_ffmpeg_avcodec_open (ffmpegdec->context, oclass->in_plugin, &ffmpegdec->codecInfo) < 0)
goto could_not_open;
ffmpegdec->opened = TRUE;
@@ -674,15 +664,9 @@ gst_ffmpegdec_open (GstFFMpegDec * ffmpegdec)
* we're talking AVC */
if (ffmpegdec->context->extradata_size == 0) {
GST_LOG_OBJECT (ffmpegdec, "H264 with no extradata, creating parser");
- if (ffmpegdec->context->codec_type == AVMEDIA_TYPE_VIDEO) {
- GST_CODEC_LOG("before emul_av_parser_init\n")
- ffmpegdec->pctx = av_parser_init(oclass->in_plugin->id);
- emul_av_parser_init ();
- } else {
- GST_CODEC_LOG("before av_parser_init\n")
- GST_CODEC_LOG("codec_id:%d\n", oclass->in_plugin->id)
- ffmpegdec->pctx = av_parser_init (oclass->in_plugin->id);
- }
+ GST_CODEC_LOG("before emul_av_parser_init\n")
+ ffmpegdec->pctx = av_parser_init(oclass->in_plugin->id);
+ emul_av_parser_init (&ffmpegdec->codecInfo);
} else {
GST_LOG_OBJECT (ffmpegdec,
"H264 with extradata implies framed data - not using parser");
@@ -697,15 +681,9 @@ gst_ffmpegdec_open (GstFFMpegDec * ffmpegdec)
break;
default:
if (!ffmpegdec->turnoff_parser) {
- if (ffmpegdec->context->codec_type == AVMEDIA_TYPE_VIDEO) {
- GST_CODEC_LOG("before av_parser_init, codec_id:%d\n", oclass->in_plugin->id)
- ffmpegdec->pctx = av_parser_init (oclass->in_plugin->id);
- GST_CODEC_LOG("before emul_av_parser_init\n")
- emul_av_parser_init ();
- } else {
- GST_CODEC_LOG("before av_parser_init, codec:id:%d\n", oclass->in_plugin->id)
- ffmpegdec->pctx = av_parser_init (oclass->in_plugin->id);
- }
+ emul_av_parser_init (&ffmpegdec->codecInfo);
+ GST_CODEC_LOG("before av_parser_init, codec:id:%d\n", oclass->in_plugin->id)
+ ffmpegdec->pctx = av_parser_init (oclass->in_plugin->id);
if (ffmpegdec->pctx)
GST_LOG_OBJECT (ffmpegdec, "Using parser %p", ffmpegdec->pctx);
else
@@ -782,8 +760,7 @@ gst_ffmpegdec_setcaps (GstPad * pad, GstCaps * caps)
gst_ffmpegdec_close (ffmpegdec);
/* and reset the defaults that were set when a context is created */
- GST_CODEC_LOG("before avcodec_get_context_defaults\n")
- avcodec_get_context_defaults (ffmpegdec->context);
+ avcodec_get_context_defaults (ffmpegdec->context);
}
/* set buffer functions */
@@ -1041,9 +1018,7 @@ gst_ffmpegdec_get_buffer (AVCodecContext * context, AVFrame * picture)
coded_width, coded_height);
if (!ffmpegdec->current_dr) {
GST_LOG_OBJECT (ffmpegdec, "direct rendering disabled, fallback alloc");
-
- GST_CODEC_LOG("before avcodec_default_get_buffer\n")
- res = avcodec_default_get_buffer (context, picture);
+ res = avcodec_default_get_buffer (context, picture);
GST_LOG_OBJECT (ffmpegdec, "linsize %d %d %d", picture->linesize[0],
picture->linesize[1], picture->linesize[2]);
@@ -1078,9 +1053,7 @@ gst_ffmpegdec_get_buffer (AVCodecContext * context, AVFrame * picture)
if (width != clip_width || height != clip_height) {
/* We can't alloc if we need to clip the output buffer later */
GST_LOG_OBJECT (ffmpegdec, "we need clipping, fallback alloc");
-
- GST_CODEC_LOG("before avcodec_default_get_buffer\n")
- return avcodec_default_get_buffer (context, picture);
+ return avcodec_default_get_buffer (context, picture);
}
/* alloc with aligned dimensions for ffmpeg */
@@ -1139,8 +1112,7 @@ gst_ffmpegdec_release_buffer (AVCodecContext * context, AVFrame * picture)
/* check if it was our buffer */
if (picture->opaque == NULL) {
GST_DEBUG_OBJECT (ffmpegdec, "default release buffer");
- GST_CODEC_LOG("before avcodec_default_release_buffer\n")
- avcodec_default_release_buffer (context, picture);
+ avcodec_default_release_buffer (context, picture);
return;
}
@@ -1307,7 +1279,7 @@ gst_ffmpegdec_negotiate (GstFFMpegDec * ffmpegdec, gboolean force)
break;
}
- GST_CODEC_LOG("codec_type:%d, codec_id:%d\n", oclass->in_plugin->type, oclass->in_plugin->id)
+ GST_CODEC_LOG("codec_type:%d, codec_id:%x\n", oclass->in_plugin->type, oclass->in_plugin->id)
caps = gst_ffmpeg_codectype_to_caps (oclass->in_plugin->type,
ffmpegdec->context, oclass->in_plugin->id, FALSE);
@@ -1636,13 +1608,10 @@ get_output_buffer (GstFFMpegDec * ffmpegdec, GstBuffer ** outbuf)
(guint) (outpic->data[1] - outpic->data[0]),
(guint) (outpic->data[2] - outpic->data[0]));
- GST_CODEC_LOG("before av_picture_copy, codec_type:%d\n", ffmpegdec->context->codec_type)
- if (ffmpegdec->context->codec_type == AVMEDIA_TYPE_VIDEO) {
- GST_CODEC_LOG("before emul_av_picture_copy\n")
- emul_av_picture_copy (&pic, outpic, ffmpegdec->context->pix_fmt, width, height);
- } else {
- av_picture_copy (&pic, outpic, ffmpegdec->context->pix_fmt, width, height);
- }
+ GST_CODEC_LOG("before av_picture_copy, codec_type:%d\n", ffmpegdec->context->codec_type)
+ GST_CODEC_LOG("before emul_av_picture_copy\n")
+ emul_av_picture_copy (&pic, outpic, ffmpegdec->context->pix_fmt,
+ width, height, &ffmpegdec->codecInfo);
GST_CODEC_LOG("After av_picture_copy\n")
}
ffmpegdec->picture->pts = -1;
@@ -1830,15 +1799,10 @@ gst_ffmpegdec_video_frame (GstFFMpegDec * ffmpegdec,
out_offset));
/* now decode the frame */
- if (ffmpegdec->context->codec_type == AVMEDIA_TYPE_VIDEO) {
- GST_CODEC_LOG("before emul_avcodec_decode_video, codec_id:%d\n", ffmpegdec->context->codec_id)
- len = emul_avcodec_decode_video (ffmpegdec->context,
- ffmpegdec->picture, &have_data, data, size);
- } else {
- GST_CODEC_LOG("before avcodec_decode_video, codec_id:%d\n", ffmpegdec->context->codec_id)
- len = avcodec_decode_video (ffmpegdec->context,
- ffmpegdec->picture, &have_data, data, size);
- }
+ GST_CODEC_LOG("before emul_avcodec_decode_video, codec_type:%d codec_id:%d\n",
+ ffmpegdec->context->codec_type, ffmpegdec->context->codec_id)
+ len = emul_avcodec_decode_video (ffmpegdec->context,
+ ffmpegdec->picture, &have_data, data, size, &ffmpegdec->codecInfo);
GST_CODEC_LOG("after decode len : %d, have_data:%d\n", len, have_data)
gst_ts_handler_consume (ffmpegdec, len);
@@ -2195,8 +2159,9 @@ gst_ffmpegdec_audio_frame (GstFFMpegDec * ffmpegdec,
new_aligned_buffer (AVCODEC_MAX_AUDIO_FRAME_SIZE,
GST_PAD_CAPS (ffmpegdec->srcpad));
- len = avcodec_decode_audio2 (ffmpegdec->context,
- (int16_t *) GST_BUFFER_DATA (*outbuf), &have_data, data, size);
+ GST_CODEC_LOG("before emul_avcodec_decode_audio\n")
+ len = emul_avcodec_decode_audio (ffmpegdec->context,
+ (int16_t *) GST_BUFFER_DATA (*outbuf), &have_data, data, size, &ffmpegdec->codecInfo);
GST_DEBUG_OBJECT (ffmpegdec,
"Decode audio: len=%d, have_data=%d", len, have_data);
@@ -2440,17 +2405,11 @@ gst_ffmpegdec_flush_pcache (GstFFMpegDec * ffmpegdec)
GstFFMpegDecClass *oclass;
oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec));
-
- if (ffmpegdec->context->codec_type == AVMEDIA_TYPE_VIDEO) {
- av_parser_close (ffmpegdec->pctx);
- ffmpegdec->pctx = av_parser_init (oclass->in_plugin->id);
- GST_CODEC_LOG("emul_av_parser_close and init\n")
- emul_av_parser_close ();
- emul_av_parser_init ();
- } else {
- av_parser_close (ffmpegdec->pctx);
- ffmpegdec->pctx = av_parser_init (oclass->in_plugin->id);
- }
+ GST_CODEC_LOG("emul_av_parser_close and init\n")
+ emul_av_parser_close (&ffmpegdec->codecInfo);
+ emul_av_parser_init (&ffmpegdec->codecInfo);
+ av_parser_close (ffmpegdec->pctx);
+ ffmpegdec->pctx = av_parser_init (oclass->in_plugin->id);
}
}
@@ -2476,13 +2435,8 @@ gst_ffmpegdec_sink_event (GstPad * pad, GstEvent * event)
case GST_EVENT_FLUSH_STOP:
{
if (ffmpegdec->opened) {
- if (ffmpegdec->context->codec_type == AVMEDIA_TYPE_VIDEO) {
- GST_CODEC_LOG("before emul_avcodec_flush_buffers\n")
- emul_avcodec_flush_buffers(ffmpegdec->context);
- } else {
- GST_CODEC_LOG("\n")
- avcodec_flush_buffers (ffmpegdec->context);
- }
+ GST_CODEC_LOG("before emul_avcodec_flush_buffers\n")
+ emul_avcodec_flush_buffers(ffmpegdec->context, &ffmpegdec->codecInfo);
GST_CODEC_LOG("after flushing buffers\n")
}
ffmpegdec->last_out = GST_CLOCK_TIME_NONE;
@@ -2616,23 +2570,16 @@ gst_ffmpegdec_chain (GstPad * pad, GstBuffer * inbuf)
if (G_UNLIKELY (discont)) {
GST_DEBUG_OBJECT (ffmpegdec, "received DISCONT");
/* drain what we have queued */
- GST_CODEC_LOG("before drain codec_type:%d codec_id:%x\n",
+ GST_CODEC_LOG("before drain codec_type:%d codec_id:%x\n",
ffmpegdec->context->codec_type, ffmpegdec->context->codec_id)
gst_ffmpegdec_drain (ffmpegdec);
- GST_CODEC_LOG("after drain codec_type:%d codec_id:%x\n",
+ GST_CODEC_LOG("after drain codec_type:%d codec_id:%x\n",
ffmpegdec->context->codec_type, ffmpegdec->context->codec_id)
gst_ffmpegdec_flush_pcache (ffmpegdec);
- if (ffmpegdec->context->codec_type == AVMEDIA_TYPE_VIDEO) {
- GST_CODEC_LOG("flush codec buffer:codec_type:%d, codec_id:%d\n",
- ffmpegdec->context->codec_type, ffmpegdec->context->codec_id)
- emul_avcodec_flush_buffers(ffmpegdec->context);
- } else {
- GST_CODEC_LOG("flush codec buffer:codec_type:%d, codec_id:%d\n",
- ffmpegdec->context->codec_type, ffmpegdec->context->codec_id)
- avcodec_flush_buffers(ffmpegdec->context);
- }
-
+ GST_CODEC_LOG("flush codec buffer:codec_type:%d, codec_id:%x\n",
+ ffmpegdec->context->codec_type, ffmpegdec->context->codec_id)
+ emul_avcodec_flush_buffers(ffmpegdec->context, &ffmpegdec->codecInfo);
ffmpegdec->discont = TRUE;
ffmpegdec->last_out = GST_CLOCK_TIME_NONE;
ffmpegdec->next_ts = GST_CLOCK_TIME_NONE;
@@ -2711,19 +2658,10 @@ gst_ffmpegdec_chain (GstPad * pad, GstBuffer * inbuf)
/* feed the parser. We store the raw gstreamer timestamp because
* converting it to ffmpeg timestamps can corrupt it if the framerate is
* wrong. */
- if (ffmpegdec->context->codec_type == AVMEDIA_TYPE_VIDEO) {
- GST_CODEC_LOG("before emul_av_parser_parse\n")
- res = emul_av_parser_parse (ffmpegdec->pctx, ffmpegdec->context,
- &data, &size, bdata, bsize, in_timestamp, in_timestamp);
- GST_CODEC_LOG("after emul_av_parser_parse outbuf_size:%d, insize:%d, res:%d\n",
- size, bsize, res)
- } else {
- GST_CODEC_LOG("before av_parser_parse\n")
- res = av_parser_parse (ffmpegdec->pctx, ffmpegdec->context,
- &data, &size, bdata, bsize, in_timestamp, in_timestamp);
- GST_CODEC_LOG("after av_parser_parse, outbuf_size:%d, res:%d\n", size, res)
- }
-
+ GST_CODEC_LOG("before emul_av_parser_parse, input size:%d\n", bsize)
+ res = emul_av_parser_parse (ffmpegdec->pctx, ffmpegdec->context,
+ &data, &size, bdata, bsize, in_timestamp, in_timestamp, &ffmpegdec->codecInfo);
+ GST_CODEC_LOG("after emul_av_parser_parse outbuf_size:%d, insize:%d, res:%d\n", size, bsize, res)
GST_LOG_OBJECT (ffmpegdec,
"parser returned res %d and size %d", res, size);