diff options
Diffstat (limited to 'ext/ffmpeg/gstffmpegdec.c')
-rw-r--r-- | ext/ffmpeg/gstffmpegdec.c | 198 |
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); |