diff options
Diffstat (limited to 'ext/ffmpeg')
-rw-r--r-- | ext/ffmpeg/gstffmpeg.c | 43 | ||||
-rw-r--r-- | ext/ffmpeg/gstffmpeg.h | 6 | ||||
-rw-r--r-- | ext/ffmpeg/gstffmpegdec.c | 198 | ||||
-rw-r--r-- | ext/ffmpeg/gstffmpegdef.c | 950 | ||||
-rw-r--r-- | ext/ffmpeg/gstffmpegdef.h | 85 | ||||
-rw-r--r-- | ext/ffmpeg/gstffmpegenc.c | 60 | ||||
-rw-r--r-- | ext/ffmpeg/gstffmpegenc.h | 3 |
7 files changed, 846 insertions, 499 deletions
diff --git a/ext/ffmpeg/gstffmpeg.c b/ext/ffmpeg/gstffmpeg.c index 71e2b8a..5536f95 100644 --- a/ext/ffmpeg/gstffmpeg.c +++ b/ext/ffmpeg/gstffmpeg.c @@ -44,22 +44,20 @@ static GStaticMutex gst_avcodec_mutex = G_STATIC_MUTEX_INIT; int -gst_ffmpeg_avcodec_open (AVCodecContext * avctx, AVCodec * codec) +gst_ffmpeg_avcodec_open (AVCodecContext * avctx, AVCodec * codec, CodecExtraInfo *pInfo) { int ret = -1; g_static_mutex_lock (&gst_avcodec_mutex); - GST_CODEC_LOG("before avcodec_open!!\n"); - if (codec->type == AVMEDIA_TYPE_VIDEO) { - ret = emul_avcodec_open(avctx, codec); - GST_CODEC_LOG("[video] after emul_avcodec_open type:%d id:%d\n", - avctx->codec_type, avctx->codec_id) - } else { - ret = avcodec_open (avctx, codec); - GST_CODEC_LOG("[audio] after avcodec_open type:%d id:%d\n", - avctx->codec_type, avctx->codec_id) - } + GST_CODEC_LOG("before avcodec_open.\n") + GST_CODEC_LOG("extradata_size:%d\n", avctx->extradata_size) + + ret = emul_avcodec_open(avctx, codec, pInfo); + + GST_CODEC_LOG("after emul_avcodec_open type:%d id:%x\n", + avctx->codec_type, avctx->codec_id) + GST_CODEC_LOG("after avcodec_open!!, context index:%x\n", pInfo->contextIndex); if (ret < 0) { printf("[%s] Failed to open %d(ret:%d)\n", __func__, codec->id, ret); @@ -71,23 +69,19 @@ gst_ffmpeg_avcodec_open (AVCodecContext * avctx, AVCodec * codec) } int -gst_ffmpeg_avcodec_close (AVCodecContext * avctx) +gst_ffmpeg_avcodec_close (AVCodecContext * avctx, CodecExtraInfo *pInfo) { int ret; g_static_mutex_lock (&gst_avcodec_mutex); - if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { - GST_CODEC_LOG("video codec close\n"); - ret = emul_avcodec_close (avctx); - } else { - GST_CODEC_LOG("\n"); - ret = avcodec_close(avctx); - } + GST_CODEC_LOG("codec close, codec_type:%d, context index:%d\n", + avctx->codec_type, pInfo->contextIndex) + ret = emul_avcodec_close (avctx, pInfo); if (ret < 0) { - printf("[%]s Failed to close. %d(ret:%d)\n", - avctx->codec_id, ret); + printf("[%s] Failed to close. codec_id:%d ret:%d\n", + __func__, avctx->codec_id, ret); } g_static_mutex_unlock (&gst_avcodec_mutex); @@ -166,21 +160,22 @@ plugin_init (GstPlugin * plugin) av_register_all (); - emul_open_codecdev(); - emul_av_register_all(); - gst_ffmpegenc_register (plugin); gst_ffmpegdec_register (plugin); gst_ffmpegdemux_register (plugin); gst_ffmpegmux_register (plugin); +#if 0 gst_ffmpegdeinterlace_register (plugin); +#endif #if 0 gst_ffmpegscale_register (plugin); #endif #if 0 gst_ffmpegcsp_register (plugin); #endif +#if 0 gst_ffmpegaudioresample_register (plugin); +#endif register_protocol (&gstreamer_protocol); register_protocol (&gstpipe_protocol); diff --git a/ext/ffmpeg/gstffmpeg.h b/ext/ffmpeg/gstffmpeg.h index 0a36f8e..be05e72 100644 --- a/ext/ffmpeg/gstffmpeg.h +++ b/ext/ffmpeg/gstffmpeg.h @@ -52,11 +52,13 @@ extern gboolean gst_ffmpegcsp_register (GstPlugin * plugin); #if 0 extern gboolean gst_ffmpegscale_register (GstPlugin * plugin); #endif +#if 0 extern gboolean gst_ffmpegaudioresample_register (GstPlugin * plugin); extern gboolean gst_ffmpegdeinterlace_register (GstPlugin * plugin); +#endif -int gst_ffmpeg_avcodec_open (AVCodecContext *avctx, AVCodec *codec); -int gst_ffmpeg_avcodec_close (AVCodecContext *avctx); +int gst_ffmpeg_avcodec_open (AVCodecContext *avctx, AVCodec *codec, CodecExtraInfo *pInfo); +int gst_ffmpeg_avcodec_close (AVCodecContext *avctx, CodecExtraInfo *pInfo); int gst_ffmpeg_av_find_stream_info(AVFormatContext *ic); G_END_DECLS 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); diff --git a/ext/ffmpeg/gstffmpegdef.c b/ext/ffmpeg/gstffmpegdef.c index 05c3143..b80fe37 100644 --- a/ext/ffmpeg/gstffmpegdef.c +++ b/ext/ffmpeg/gstffmpegdef.c @@ -36,59 +36,19 @@ */ #include "gstffmpegdef.h" +#include <semaphore.h> #define CODEC_DEV "/dev/codec" -#define CODEC_MMAP_SIZE 512 * 4096 +#define CODEC_MMAP_SIZE (16 * 1024 * 1024) CodecParam _param; ParserBuf _parserBuf; -static int codecfd; -static void *pMapBuf; +static int bRegister = 0; +static sem_t hCodecSem; -int emul_open_codecdev (void) -{ - int fd = -1; - - GST_CODEC_LOG("Enter\n"); - if ((fd = open(CODEC_DEV, O_RDWR)) < 0) { - perror("Failed to open codec device"); - GST_CODEC_LOG("Failed to open %s, ret:%d\n", CODEC_DEV, fd) - } else { - GST_CODEC_LOG("Succeeded to open %s, ret:%d\n", CODEC_DEV, fd) - } - codecfd = fd; - - GST_CODEC_LOG("AVCodecContext : %d\n", sizeof(AVCodecContext)); - GST_CODEC_LOG("AVFrame : %d\n", sizeof(AVFrame)); - GST_CODEC_LOG("AVCodecParserContext : %d\n", sizeof(AVCodecParserContext)); - - GST_CODEC_LOG("Leave, fd:%d\n", fd); - - return fd; -} - -void emul_close_codecdev (void) -{ -#ifndef CODEC_HOST - void *pBuf; - int ret; - - pBuf = pMapBuf; - if (!pBuf) { - printf("mapping address is null\n"); - return; - } - - ret = munmap(pBuf, CODEC_MMAP_SIZE); - printf("release mapping address :%d\n", ret); -#endif - GST_CODEC_LOG("Enter\n") - if (codecfd > 0) { - close(codecfd); - codecfd = -1; - } - GST_CODEC_LOG("Leave, close %s device and fd:%d\n", CODEC_DEV, codecfd) -} +/* + * Helper APIs + */ void restore_codec_context(AVCodecContext *dstctx, AVCodecContext *srcctx) { @@ -138,26 +98,230 @@ int get_picture_size (int pix_fmt, int width, int height) return size; } -void emul_av_register_all (void) +/* + * Open Codec Device + */ + +int emul_open_codecdev (CodecExtraInfo *pInfo) +{ + int fd = -1; + + GST_CODEC_LOG("Enter\n"); + if ((fd = open(CODEC_DEV, O_RDWR)) < 0) { + perror("Failed to open codec device"); + GST_CODEC_LOG("Failed to open %s, ret:%d\n", CODEC_DEV, fd) + GST_CODEC_LOG("%d\n", errno) + } else { + GST_CODEC_LOG("Succeeded to open %s, ret:%d\n", CODEC_DEV, fd) + } + + pInfo->codecfd = fd; +#if 0 + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_INIT_MMAP_INDEX; + CODEC_WRITE(fd, &_param, 1); +#endif + + if (!bRegister) { + GST_CODEC_LOG("Initialize codec semaphore\n") + if (sem_init(&hCodecSem, 0, 1) < 0) { + printf("[%s] Semaphore Initialization Error\n", __func__); + return -1; + } + GST_CODEC_LOG("Register all codecs\n") + emul_av_register_all(pInfo); + bRegister++; + } + + GST_CODEC_LOG("Leave\n"); + + return fd; +} + +/* + * Release mmaping memory space with Codec Device Memory. + * And then, close Codec Device. + */ + +void emul_close_codecdev (CodecExtraInfo *pInfo) +{ +#ifndef CODEC_HOST + void *pBuf; + int fd; + int result; + + GST_CODEC_LOG("Enter\n") + pBuf = pInfo->pMmapBuf; + if (!pBuf) { + printf("mapping address is null\n"); + return; + } + + result = munmap(pBuf, CODEC_MMAP_SIZE); + printf("release mapping address :%d\n", result); + + fd = pInfo->codecfd; + if (fd < 0) { + printf("[%s] Codec device has not been opened yet.\n", __func__); + return; + } + +#if 0 + GST_CODEC_LOG("beore reset mmap index :%d, %d\n", pInfo->mmapIndex, EMUL_RESET_MMAP_INDEX); + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_RESET_MMAP_INDEX; + _param.mmapOffset = pInfo->mmapIndex; + CODEC_WRITE(fd, &_param, 1); + GST_CODEC_LOG("after reset mmap index\n"); +#endif + +#endif + close(fd); + pInfo->codecfd = -1; + bRegister--; + + if (!bRegister) { + GST_CODEC_LOG("destroy codec semaphore, %d\n", bRegister) + sem_destroy(&hCodecSem); + } + + GST_CODEC_LOG("Leave, close %s device and fd:%d\n", CODEC_DEV, fd) +} + +void emul_av_register_all (CodecExtraInfo *pInfo) { int fd; GST_CODEC_LOG("Enter\n") + fd = pInfo->codecfd; + if (fd < 0) { + printf("[%s] Codec device has not been opened yet.\n", __func__); + return; + } + + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_AV_REGISTER_ALL; + CODEC_WRITE(fd, &_param, 1); + + GST_CODEC_LOG("Leave\n") +} + +#ifdef CODEC_HOST +int emul_avcodec_alloc_context (CodecExtraInfo *pInfo) +{ + int fd; + int result = -1; + fd = codecfd; if (fd < 0) { + fd = emul_open_codecdev(); + if (fd < 0) { + printf("[%s] Codec device has not been opened yet.\n", __func__); + return -1; + } + } + + GST_CODEC_LOG("Enter\n") + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_AVCODEC_ALLOC_CONTEXT; + CODEC_WRITE(fd, &_param, 1); + GST_CODEC_LOG("Leave, ret:%d\n", result) + + return result; +} +#else +void emul_avcodec_alloc_context (CodecExtraInfo *pInfo) +{ + int fd; + int _ctxIndex = -1; + int mmapIndex = -1; + void *pBuf; + off_t offset = 0; + + GST_CODEC_LOG("Enter\n") + + GST_CODEC_LOG("before emul_open_codecdev:%d\n", fd) + PARAM_INIT(pInfo, CodecExtraInfo); + fd = emul_open_codecdev(pInfo); + if (fd < 0) { printf("[%s] Codec device has not been opened yet.\n", __func__); return; } - PARAM_INIT(_param, CodecParam); - _param.func_num = EMUL_AV_REGISTER_ALL; - write(fd, &_param, 1); + sem_wait(&hCodecSem); + + PARAM_INIT(&_param, CodecParam); + + while (1) { + _param.apiIndex = EMUL_GET_MMAP_INDEX; + _param.ret_args = (uint32_t)&mmapIndex; + CODEC_WRITE(fd, &_param, 1); + if (mmapIndex != -1) { + printf("[%s] Success to get mmap index:%d\n", __func__, mmapIndex); + break; + } + sleep(1); + printf("[%s] Failure to get mmap index:%d\n", __func__, mmapIndex); + } + + pInfo->mmapIndex = mmapIndex; + + offset = mmapIndex * CODEC_MMAP_SIZE; + GST_CODEC_LOG("mmap index:%d, offset:%d\n", mmapIndex, offset) + + pBuf = mmap(NULL, CODEC_MMAP_SIZE, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, offset); + if (pBuf) { + GST_CODEC_LOG("success mmap : %x\n", pBuf); + printf("success mmap : %x\n", pBuf); + pInfo->pMmapBuf = pBuf; + } else { + GST_CODEC_LOG("failure mmap\n"); + pInfo->pMmapBuf = NULL; + return; + } + + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_AVCODEC_ALLOC_CONTEXT; + _param.mmapOffset = mmapIndex; + CODEC_WRITE(fd, &_param, 1); + + memcpy(&_ctxIndex, pBuf, sizeof(int)); + pInfo->contextIndex = _ctxIndex; + + GST_CODEC_LOG("context index : %d, mmap:%p\n", _ctxIndex, pInfo->pMmapBuf) + + sem_post(&hCodecSem); + + GST_CODEC_LOG("Leave\n") +} +#endif + +void emul_avcodec_alloc_frame (CodecExtraInfo *pInfo) +{ + int fd; + + GST_CODEC_LOG("Enter\n") + + sem_wait(&hCodecSem); + + fd = pInfo->codecfd; + if (fd < 0) { + printf("[%s] Codec device has not been opened yet.\n", __func__); + return; + } + + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_AVCODEC_ALLOC_FRAME; + CODEC_WRITE(fd, &_param, 1); + + sem_post(&hCodecSem); GST_CODEC_LOG("Leave\n") } #ifdef CODEC_HOST -int emul_avcodec_open (AVCodecContext *avctx, AVCodec *codec) +int emul_avcodec_open (AVCodecContext *avctx, AVCodec *codec, CodecExtraInfo *pInfo) { int fd; int result = -1; @@ -168,22 +332,20 @@ int emul_avcodec_open (AVCodecContext *avctx, AVCodec *codec) fd = codecfd; if (fd < 0) { printf("[%s] Codec device has not been opened yet.\n", __func__); - fd = emul_open_codecdev(); - if (fd < 0) { - return -1; - } + return -1; } priv_data_size = codec->priv_data_size; avctx->priv_data = (void*)av_mallocz(priv_data_size); - PARAM_INIT(_param, CodecParam); - _param.func_num = EMUL_AVCODEC_OPEN; + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_AVCODEC_OPEN; + _param.ctxIndex = pInfo->contextIndex; _param.in_args_num = 2; _param.in_args[0] = (uint32_t)avctx; _param.in_args[1] = (uint32_t)codec; _param.ret_args = (uint32_t)&result; - write(fd, &_param, 1); + CODEC_WRITE(fd, &_param, 1); GST_CODEC_LOG("after codec type:%d, id:%d\n", avctx->codec_type, avctx->codec_id) GST_CODEC_LOG("Leave, ret : %d\n", result) @@ -191,18 +353,21 @@ int emul_avcodec_open (AVCodecContext *avctx, AVCodec *codec) return result; } #else -int emul_avcodec_open (AVCodecContext *avctx, AVCodec *codec) +int emul_avcodec_open (AVCodecContext *avctx, AVCodec *codec, CodecExtraInfo *pInfo) { int fd; int result = -1; int priv_data_size; int size; - void *buf; + int bEncode = 0; + void *pBuf; AVCodecContext tmpCtx; GST_CODEC_LOG("Enter\n") - fd = codecfd; + sem_wait(&hCodecSem); + + fd = pInfo->codecfd; if (fd < 0) { printf("[%s] Codec device has not been opened yet.\n", __func__); return -1; @@ -211,44 +376,130 @@ int emul_avcodec_open (AVCodecContext *avctx, AVCodec *codec) priv_data_size = codec->priv_data_size; avctx->priv_data = (void*)av_mallocz(priv_data_size); - buf = mmap(NULL, CODEC_MMAP_SIZE, PROT_READ | PROT_WRITE, - MAP_SHARED, codecfd, 0); - if (buf) { - GST_CODEC_LOG("success mmap : %x\n", pMapBuf); - pMapBuf = buf; - } else { - GST_CODEC_LOG("failure mmap\n"); - pMapBuf = NULL; - } + pBuf = pInfo->pMmapBuf; + if (!pBuf) { + printf("mapping address is null\n"); + return result; + } + GST_CODEC_LOG("codec type:%d, codec id:%x\n", avctx->codec_type, avctx->codec_id) + +#ifndef CODEC_DUMMY + memcpy(&tmpCtx, avctx, sizeof(AVCodecContext)); + memcpy(pBuf, avctx, sizeof(AVCodecContext)); size = sizeof(AVCodecContext); - memcpy(&tmpCtx, avctx, size); - memcpy(buf, avctx, size); - memcpy((uint8_t*)buf + size, codec, sizeof(AVCodec)); + memcpy((uint8_t*)pBuf + size, codec, sizeof(AVCodec)); size += sizeof(AVCodec); - memcpy((uint8_t*)buf + size, avctx->extradata, avctx->extradata_size); + memcpy((uint8_t*)pBuf + size, avctx->extradata, avctx->extradata_size); +#else + GST_CODEC_LOG("\n") + + memcpy((uint8_t*)pBuf, &avctx->bit_rate, sizeof(int)); + size = sizeof(int); + memcpy((uint8_t*)pBuf + size, &avctx->bit_rate_tolerance, sizeof(int)); + size += sizeof(int); + memcpy((uint8_t*)pBuf + size, &avctx->flags, sizeof(int)); + size += sizeof(int); + memcpy((uint8_t*)pBuf + size, &avctx->time_base, sizeof(AVRational)); + size += sizeof(AVRational); + memcpy((uint8_t*)pBuf + size, &avctx->width, sizeof(int)); + size += sizeof(int); + memcpy((uint8_t*)pBuf + size, &avctx->height, sizeof(int)); + size += sizeof(int); + memcpy((uint8_t*)pBuf + size, &avctx->gop_size, sizeof(int)); + size += sizeof(int); + memcpy((uint8_t*)pBuf + size, &avctx->pix_fmt, sizeof(int)); + size += sizeof(int); + memcpy((uint8_t*)pBuf + size, &avctx->sample_rate, sizeof(int)); + size += sizeof(int); + memcpy((uint8_t*)pBuf + size, &avctx->channels, sizeof(int)); + size += sizeof(int); + memcpy((uint8_t*)pBuf + size, &avctx->codec_tag, sizeof(int)); + size += sizeof(int); + memcpy((uint8_t*)pBuf + size, &avctx->rc_strategy, sizeof(int)); + size += sizeof(int); + memcpy((uint8_t*)pBuf + size, &avctx->strict_std_compliance, sizeof(int)); + size += sizeof(int); + memcpy((uint8_t*)pBuf + size, &avctx->rc_qsquish, sizeof(float)); + size += sizeof(float); + memcpy((uint8_t*)pBuf + size, &avctx->sample_aspect_ratio, sizeof(AVRational)); + size += sizeof(AVRational); + memcpy((uint8_t*)pBuf + size, &avctx->mb_qmin, sizeof(int)); + size += sizeof(int); + memcpy((uint8_t*)pBuf + size, &avctx->mb_qmax, sizeof(int)); + size += sizeof(int); + memcpy((uint8_t*)pBuf + size, &avctx->pre_me, sizeof(int)); + size += sizeof(int); + memcpy((uint8_t*)pBuf + size, &avctx->trellis, sizeof(int)); + size += sizeof(int); + GST_CODEC_LOG("extradata size :%d\n", avctx->extradata_size) + memcpy((uint8_t*)pBuf + size, &avctx->extradata_size, sizeof(int)); + size += sizeof(int); + memcpy((uint8_t*)pBuf + size, &codec->id, sizeof(int)); + size += sizeof(int); + if (codec->encode) { + bEncode = 1; + } + memcpy((uint8_t*)pBuf + size, &bEncode, sizeof(int)); + memcpy((uint8_t*)pBuf + size, &codec->encode, sizeof(int)); + size += sizeof(int); + if (avctx->extradata_size > 0) { + memcpy((uint8_t*)pBuf + size, avctx->extradata, avctx->extradata_size); + } +#endif - PARAM_INIT(_param, CodecParam); - _param.func_num = EMUL_AVCODEC_OPEN; - write(fd, &_param, 1); + GST_CODEC_LOG("ctxIndex:%d, mmapIndex:%d\n", pInfo->contextIndex, pInfo->mmapIndex) - GST_CODEC_LOG("after write system call\n") + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_AVCODEC_OPEN; + _param.ctxIndex = pInfo->contextIndex; + _param.mmapOffset = pInfo->mmapIndex; + CODEC_WRITE(fd, &_param, 1); + GST_CODEC_LOG("after CODEC_WRITE system call\n") + +#ifndef CODEC_DUMMY size = sizeof(AVCodecContext); - memcpy(avctx, buf, size); + memcpy(avctx, pBuf, size); restore_codec_context(avctx, &tmpCtx); avctx->codec = codec; - memcpy(&result, (uint8_t*)buf + size, sizeof(int)); + memcpy(&result, (uint8_t*)pBuf + size, sizeof(int)); +#else + memcpy(&avctx->pix_fmt, (uint8_t*)pBuf, sizeof(int)); + size = sizeof(int); + memcpy(&avctx->time_base, (uint8_t*)pBuf + size, sizeof(AVRational)); + size += sizeof(AVRational); + memcpy(&avctx->sample_fmt, (uint8_t*)pBuf + size, sizeof(int)); + size += sizeof(int); + memcpy(&avctx->codec_type, (uint8_t*)pBuf + size, sizeof(int)); + size += sizeof(int); + memcpy(&avctx->codec_id, (uint8_t*)pBuf + size, sizeof(int)); + size += sizeof(int); + memcpy(&avctx->coded_width, (uint8_t*)pBuf + size, sizeof(int)); + size += sizeof(int); + memcpy(&avctx->coded_height, (uint8_t*)pBuf + size, sizeof(int)); + size += sizeof(int); + memcpy(&avctx->ticks_per_frame, (uint8_t*)pBuf + size, sizeof(int)); + size += sizeof(int); + memcpy(&avctx->chroma_sample_location, (uint8_t*)pBuf + size, sizeof(int)); + size += sizeof(int); + memcpy(avctx->priv_data, (uint8_t*)pBuf + size, codec->priv_data_size); + size += codec->priv_data_size; + memcpy(&result, (uint8_t*)pBuf + size, sizeof(int)); + avctx->codec = codec; +#endif GST_CODEC_LOG("after codec type:%d, id:%d\n", avctx->codec_type, avctx->codec_id) GST_CODEC_LOG("Leave, ret : %d\n", result) + sem_post(&hCodecSem); + return result; } #endif #ifdef CODEC_HOST -int emul_avcodec_close(AVCodecContext *avctx) +int emul_avcodec_close(AVCodecContext *avctx, CodecExtraInfo *pInfo) { int fd; int result; @@ -261,212 +512,182 @@ int emul_avcodec_close(AVCodecContext *avctx) return -1; } - PARAM_INIT(_param, CodecParam); - _param.func_num = EMUL_AVCODEC_CLOSE; + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_AVCODEC_CLOSE; + _param.ctxIndex = pInfo->contextIndex; _param.in_args_num = 1; _param.in_args[0] = (uint32_t)avctx; _param.ret_args = (uint32_t)&result; - write(fd, &_param, 1); + CODEC_WRITE(fd, &_param, 1); GST_CODEC_LOG("Leave, ret : %d\n", result) return result; } #else -int emul_avcodec_close(AVCodecContext *avctx) +int emul_avcodec_close(AVCodecContext *avctx, CodecExtraInfo *pInfo) { int fd; int result; - int size; void *pBuf; GST_CODEC_LOG("Enter\n") - fd = codecfd; + sem_wait(&hCodecSem); + + fd = pInfo->codecfd; if (fd < 0) { printf("[%s] Codec device has not been opened yet.\n", __func__); return -1; } - pBuf = pMapBuf; + pBuf = pInfo->pMmapBuf; if (!pBuf) { printf("mapping address is null\n"); return -1; } - PARAM_INIT(_param, CodecParam); - _param.func_num = EMUL_AVCODEC_CLOSE; - write(fd, &_param, 1); + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_AVCODEC_CLOSE; + _param.ctxIndex = pInfo->contextIndex; + _param.mmapOffset = pInfo->mmapIndex; + CODEC_WRITE(fd, &_param, 1); memcpy(&result, pBuf, sizeof(int)); + sem_post(&hCodecSem); GST_CODEC_LOG("Leave, ret : %d\n", result) - return result; } #endif -void emul_avcodec_alloc_context (void) +void emul_av_free_context (CodecExtraInfo *pInfo) { int fd; - fd = codecfd; - if (fd < 0) { - printf("[%s] Codec device has not been opened yet.\n", __func__); - fd = emul_open_codecdev(); - if (fd < 0) { - return; - } - } - GST_CODEC_LOG("Enter\n") - PARAM_INIT(_param, CodecParam); - _param.func_num = EMUL_AVCODEC_ALLOC_CONTEXT; - write(fd, &_param, 1); - GST_CODEC_LOG("Leave\n") -} -void emul_avcodec_alloc_frame (void) -{ - int fd; + sem_wait(&hCodecSem); - GST_CODEC_LOG("Enter\n") - fd = codecfd; + fd = pInfo->codecfd; if (fd < 0) { printf("[%s] Codec device has not been opened yet.\n", __func__); return; } - PARAM_INIT(_param, CodecParam); - _param.func_num = EMUL_AVCODEC_ALLOC_FRAME; - write(fd, &_param, 1); - GST_CODEC_LOG("Leave\n") -} - -void emul_av_free_context (void) -{ - int fd; + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_AV_FREE_CONTEXT; + _param.ctxIndex = pInfo->contextIndex; + _param.mmapOffset = pInfo->mmapIndex; + CODEC_WRITE(fd, &_param, 1); - GST_CODEC_LOG("Enter\n") - fd = codecfd; - if (fd < 0) { - printf("[%s] Codec device has not been opened yet.\n", __func__); - return; - } + sem_post(&hCodecSem); - PARAM_INIT(_param, CodecParam); - _param.func_num = EMUL_AV_FREE_CONTEXT; - write(fd, &_param, 1); GST_CODEC_LOG("Leave\n") } -void emul_av_free_picture (void) +void emul_av_free_picture (CodecExtraInfo *pInfo) { int fd; GST_CODEC_LOG("Enter\n") - fd = codecfd; - if (fd < 0) { - printf("[%s] Codec device has not been opened yet.\n", __func__); - return; - } - PARAM_INIT(_param, CodecParam); - _param.func_num = EMUL_AV_FREE_PICTURE; - write(fd, &_param, 1); - GST_CODEC_LOG("Leave\n") -} + sem_wait(&hCodecSem); -void emul_av_free_palctrl (void) -{ - int fd; - - GST_CODEC_LOG("Enter\n") - fd = codecfd; + fd = pInfo->codecfd; if (fd < 0) { printf("[%s] Codec device has not been opened yet.\n", __func__); return; } - PARAM_INIT(_param, CodecParam); - _param.func_num = EMUL_AV_FREE_PALCTRL; - write(fd, &_param, 1); + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_AV_FREE_PICTURE; + _param.ctxIndex = pInfo->contextIndex; + _param.mmapOffset = pInfo->mmapIndex; + CODEC_WRITE(fd, &_param, 1); + + sem_post(&hCodecSem); + GST_CODEC_LOG("Leave\n") } -void emul_av_free_extradata (void) +void emul_av_free_palctrl (CodecExtraInfo *pInfo) { int fd; GST_CODEC_LOG("Enter\n") - fd = codecfd; + + sem_wait(&hCodecSem); + + fd = pInfo->codecfd; if (fd < 0) { printf("[%s] Codec device has not been opened yet.\n", __func__); return; } - PARAM_INIT(_param, CodecParam); - _param.func_num = EMUL_AV_FREE_EXTRADATA; - write(fd, &_param, 1); + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_AV_FREE_PALCTRL; + _param.ctxIndex = pInfo->contextIndex; + _param.mmapOffset = pInfo->mmapIndex; + CODEC_WRITE(fd, &_param, 1); + + sem_post(&hCodecSem); + GST_CODEC_LOG("Leave\n") } -#ifdef CODEC_HOST -void emul_avcodec_flush_buffers(AVCodecContext *avctx) +void emul_av_free_extradata (CodecExtraInfo *pInfo) { int fd; GST_CODEC_LOG("Enter\n") - fd = codecfd; + + sem_wait(&hCodecSem); + fd = pInfo->codecfd; if (fd < 0) { printf("[%s] Codec device has not been opened yet.\n", __func__); return; } - PARAM_INIT(_param, CodecParam); - _param.func_num = EMUL_AVCODEC_FLUSH_BUFFERS; - _param.in_args_num = 1; - _param.in_args[0] = (uint32_t)avctx; - write(fd, &_param, 1); + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_AV_FREE_EXTRADATA; + _param.ctxIndex = pInfo->contextIndex; + _param.mmapOffset = pInfo->mmapIndex; + CODEC_WRITE(fd, &_param, 1); + + sem_post(&hCodecSem); + GST_CODEC_LOG("Leave\n") } -#else -void emul_avcodec_flush_buffers(AVCodecContext *avctx) + +void emul_avcodec_flush_buffers(AVCodecContext *avctx, CodecExtraInfo *pInfo) { int fd; - void *pBuf; -// AVCodecContext tmpCtx; GST_CODEC_LOG("Enter\n") - fd = codecfd; + sem_wait(&hCodecSem); + + fd = pInfo->codecfd; if (fd < 0) { printf("[%s] Codec device has not been opened yet.\n", __func__); return; } -/* pBuf = pMapBuf; - if (!pBuf) { - printf("mapping address is null\n"); - return -1; - } */ - -// memcpy(&tmpCtx, avctx, sizeof(AVCodecContext); -// memcpy(pBuf, avctx, sizeof(AVCodecContext)); - - PARAM_INIT(_param, CodecParam); - _param.func_num = EMUL_AVCODEC_FLUSH_BUFFERS; - write(fd, &_param, 1); + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_AVCODEC_FLUSH_BUFFERS; + _param.ctxIndex = pInfo->contextIndex; + _param.mmapOffset = pInfo->mmapIndex; + CODEC_WRITE(fd, &_param, 1); -// memcpy(avctx, pBuf, sizeof(AVCodecContext)); -// restore_codec_context(avctx, &tmpCtx); + sem_post(&hCodecSem); GST_CODEC_LOG("Leave\n") } -#endif #ifdef CODEC_HOST int emul_avcodec_decode_video(AVCodecContext *ctx, AVFrame *frame, - int *got_picture_ptr, uint8_t *buf, int buf_size) + int *got_picture_ptr, uint8_t *buf, + int buf_size, CodecExtraInfo *pInfo) { int fd; int result; @@ -478,8 +699,9 @@ int emul_avcodec_decode_video(AVCodecContext *ctx, AVFrame *frame, return -1; } - PARAM_INIT(_param, CodecParam); - _param.func_num = EMUL_AVCODEC_DECODE_VIDEO; + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_AVCODEC_DECODE_VIDEO; + _param.ctxIndex = pInfo->contextIndex; _param.in_args_num = 5; _param.in_args[0] = (uint32_t)ctx; _param.in_args[1] = (uint32_t)frame; @@ -487,7 +709,7 @@ int emul_avcodec_decode_video(AVCodecContext *ctx, AVFrame *frame, _param.in_args[3] = (uint32_t)buf; _param.in_args[4] = (uint32_t)&buf_size; _param.ret_args = (uint32_t)&result; - write(fd, &_param, 1); + CODEC_WRITE(fd, &_param, 1); GST_CODEC_LOG("Leave, ret:%d\n", result) @@ -495,7 +717,8 @@ int emul_avcodec_decode_video(AVCodecContext *ctx, AVFrame *frame, } #else int emul_avcodec_decode_video(AVCodecContext *ctx, AVFrame *frame, - int *got_picture_ptr, uint8_t *buf, int buf_size) + int *got_picture_ptr, uint8_t *buf, + int buf_size, CodecExtraInfo *pInfo) { int fd; int result; @@ -504,13 +727,15 @@ int emul_avcodec_decode_video(AVCodecContext *ctx, AVFrame *frame, AVCodecContext tmpCtx; GST_CODEC_LOG("Enter\n") - fd = codecfd; + sem_wait(&hCodecSem); + + fd = pInfo->codecfd; if (fd < 0) { printf("[%s] Codec device has not been opened yet.\n", __func__); return -1; } - pBuf = pMapBuf; + pBuf = pInfo->pMmapBuf; if (!pBuf) { printf("mapping address is null\n"); return -1; @@ -523,14 +748,39 @@ int emul_avcodec_decode_video(AVCodecContext *ctx, AVFrame *frame, memcpy((uint8_t*)pBuf + size, buf, buf_size); } - PARAM_INIT(_param, CodecParam); - _param.func_num = EMUL_AVCODEC_DECODE_VIDEO; - write(fd, &_param, 1); + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_AVCODEC_DECODE_VIDEO; + _param.ctxIndex = pInfo->contextIndex; + _param.mmapOffset = pInfo->mmapIndex; + CODEC_WRITE(fd, &_param, 1); +#ifndef CODEC_DUMMY size = sizeof(AVCodecContext); memcpy(&tmpCtx, ctx, size); memcpy(ctx, pBuf, size); restore_codec_context(ctx, &tmpCtx); +#else + memcpy(&ctx->pix_fmt, (uint8_t*)pBuf, sizeof(int)); + size = sizeof(int); + memcpy(&ctx->time_base, (uint8_t*)pBuf + size, sizeof(AVRational)); + size += sizeof(AVRational); + memcpy(&ctx->width, (uint8_t*)pBuf + size, sizeof(int)); + size += sizeof(int); + memcpy(&ctx->height, (uint8_t*)pBuf + size, sizeof(int)); + size += sizeof(int); + memcpy(&ctx->has_b_frames, (uint8_t*)pBuf + size, sizeof(int)); + size += sizeof(int); + memcpy(&ctx->frame_number, (uint8_t*)pBuf + size, sizeof(int)); + size += sizeof(int); + memcpy(&ctx->sample_aspect_ratio, (uint8_t*)pBuf + size, sizeof(AVRational)); + size += sizeof(AVRational); + memcpy(&ctx->internal_buffer_count, (uint8_t*)pBuf + size, sizeof(int)); + size += sizeof(int); + memcpy(&ctx->profile, (uint8_t*)pBuf + size, sizeof(int)); + size += sizeof(int); + memcpy(&ctx->level, (uint8_t*)pBuf + size, sizeof(int)); + size += sizeof(int); +#endif ctx->coded_frame = frame; memcpy(frame, (uint8_t*)pBuf + size, sizeof(AVFrame)); @@ -540,8 +790,11 @@ int emul_avcodec_decode_video(AVCodecContext *ctx, AVFrame *frame, size += sizeof(int); memcpy(&result, (uint8_t*)pBuf + size, sizeof(int)); + GST_CODEC_LOG("have_data:%d\n", *got_picture_ptr) GST_CODEC_LOG("Leave, ret:%d\n", result) + sem_post(&hCodecSem); + return result; } #endif @@ -550,7 +803,7 @@ int emul_avcodec_decode_video(AVCodecContext *ctx, AVFrame *frame, #ifdef CODEC_HOST int emul_avcodec_encode_video (AVCodecContext *ctx, uint8_t *buf, int buf_size, const AVFrame *pict, - uint8_t *pict_buf) + uint8_t *pict_buf, CodecExtraInfo *pInfo) { int fd; int result = -1; @@ -564,8 +817,9 @@ int emul_avcodec_encode_video (AVCodecContext *ctx, uint8_t *buf, ctx->coded_frame = avcodec_alloc_frame(); - PARAM_INIT(_param, CodecParam); - _param.func_num = EMUL_AVCODEC_ENCODE_VIDEO; + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_AVCODEC_ENCODE_VIDEO; + _param.ctxIndex = pInfo->contextIndex; _param.in_args_num = 5; _param.in_args[0] = (uint32_t)ctx; _param.in_args[1] = (uint32_t)buf; @@ -573,7 +827,7 @@ int emul_avcodec_encode_video (AVCodecContext *ctx, uint8_t *buf, _param.in_args[3] = (uint32_t)pict; _param.in_args[4] = (uint32_t)pict_buf; _param.ret_args = (uint32_t)&result; - write(fd, &_param, 1); + CODEC_WRITE(fd, &_param, 1); GST_CODEC_LOG("after encoding video, ret :%d\n", result) return result; @@ -581,7 +835,7 @@ int emul_avcodec_encode_video (AVCodecContext *ctx, uint8_t *buf, #else int emul_avcodec_encode_video (AVCodecContext *ctx, uint8_t *buf, int buf_size, const AVFrame *pict, - uint8_t *pict_buf) + uint8_t *pict_buf, CodecExtraInfo *pInfo) { void *pBuf; int fd; @@ -591,7 +845,9 @@ int emul_avcodec_encode_video (AVCodecContext *ctx, uint8_t *buf, int result = -1; GST_CODEC_LOG("Enter\n") - fd = codecfd; + sem_wait(&hCodecSem); + + fd = pInfo->codecfd; if (fd < 0) { printf("[%s] Codec device has not been opened yet.\n", __func__); return -1; @@ -599,32 +855,35 @@ int emul_avcodec_encode_video (AVCodecContext *ctx, uint8_t *buf, ctx->coded_frame = avcodec_alloc_frame(); - pBuf = pMapBuf; + pBuf = pInfo->pMmapBuf; if (!pBuf) { printf("mapping address is null\n"); return -1; } GST_CODEC_LOG("output buffer size :%d\n", buf_size); inputSize = get_picture_size(ctx->pix_fmt, ctx->height, ctx->width); + size = 0; if (pict && pict_buf) { flush_buf = 0; - size = sizeof(int); - memcpy(pBuf, &flush_buf, size); - memcpy((uint8_t*)pBuf + size, &buf_size, size); + memcpy((uint8_t*)pBuf + size, &flush_buf, sizeof(int)); + size += sizeof(int); + memcpy((uint8_t*)pBuf + size, &buf_size, sizeof(int)); size += sizeof(int); memcpy((uint8_t*)pBuf + size, pict, sizeof(AVFrame)); size += sizeof(AVFrame); memcpy((uint8_t*)pBuf + size, pict_buf, inputSize); } else { flush_buf = 1; - memcpy(pBuf, &flush_buf, sizeof(int)); + memcpy((uint8_t*)pBuf + size, &flush_buf, sizeof(int)); } - PARAM_INIT(_param, CodecParam); - _param.func_num = EMUL_AVCODEC_ENCODE_VIDEO; - write(fd, &_param, 1); + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_AVCODEC_ENCODE_VIDEO; + _param.ctxIndex = pInfo->contextIndex; + _param.mmapOffset = pInfo->mmapIndex; + CODEC_WRITE(fd, &_param, 1); - GST_CODEC_LOG("after write system call\n") + GST_CODEC_LOG("after CODEC_WRITE system call\n") if (pict && pict_buf) { memcpy(buf, (uint8_t*)pBuf, buf_size); @@ -633,14 +892,114 @@ int emul_avcodec_encode_video (AVCodecContext *ctx, uint8_t *buf, memcpy(&result, pBuf, sizeof(int)); } + sem_post(&hCodecSem); + GST_CODEC_LOG("after encoding video, ret :%d\n", result) return result; } #endif #ifdef CODEC_HOST +int emul_avcodec_decode_audio (AVCodecContext *avctx, int16_t *samples, + int *frame_size_ptr, const uint8_t *buf, + int buf_size, CodecExtraInfo *pInfo) +{ + int result = -1; + + GST_CODEC_LOG("buf_size :%d(0x%x)\n", buf_size, (uint32_t)&buf_size) + + PARAM_INIT(_param, CodecParam); + _param.apiIndex = 22; + _param.ctxIndex = ctxIndex; + _param.in_args_num = 5; + _param.in_args[0] = (uint32_t)avctx; + _param.in_args[1] = (uint32_t)samples; + _param.in_args[2] = (uint32_t)frame_size_ptr; + _param.in_args[3] = (uint32_t)buf; + _param.in_args[4] = (uint32_t)&buf_size; + _param.ret_args = (uint32_t)&result; + CODEC_WRITE(gst_codec_fd, &_param, 1); + + GST_CODEC_LOG("[audio]frame_number:%d, result:%d\n", avctx->frame_number, result) + return result; +} +#else +int emul_avcodec_decode_audio (AVCodecContext *avctx, int16_t *samples, + int *frame_size_ptr, const uint8_t *buf, + int buf_size, CodecExtraInfo *pInfo) +{ + int fd; + int result; + int size; + void *pBuf; + AVCodecContext tmpCtx; + + GST_CODEC_LOG("Enter\n") + sem_wait(&hCodecSem); + + fd = pInfo->codecfd; + if (fd < 0) { + printf("[%s] Codec device has not been opened yet.\n", __func__); + return -1; + } + + pBuf = pInfo->pMmapBuf; + if (!pBuf) { + printf("mapping address is null\n"); + return -1; + } + + memcpy((uint8_t*)pBuf, &buf_size, sizeof(int)); + size = sizeof(int); + GST_CODEC_LOG("input buffer size :%d\n", buf_size); + if (buf_size > 0) { + memcpy((uint8_t*)pBuf + size, buf, buf_size); + } + + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_AVCODEC_DECODE_AUDIO; + _param.ctxIndex = pInfo->contextIndex; + _param.mmapOffset = pInfo->mmapIndex; + CODEC_WRITE(fd, &_param, 1); + +#ifndef CODEC_DUMMY + memcpy(&tmpCtx, avctx, sizeof(AVCodecContext)); + memcpy(avctx, (uint8_t*)pBuf, sizeof(AVCodecContext)); + size = sizeof(AVCodecContext); + restore_codec_context(avctx, &tmpCtx); +#else + memcpy(&avctx->bit_rate, (uint8_t*)pBuf, sizeof(int)); + size = sizeof(int); + memcpy(&avctx->sub_id, (uint8_t*)pBuf + size, sizeof(int)); + size += sizeof(int); + memcpy(&avctx->frame_size, (uint8_t*)pBuf + size, sizeof(int)); + size += sizeof(int); + memcpy(&avctx->frame_number, (uint8_t*)pBuf + size, sizeof(int)); + size += sizeof(int); +#endif + + memcpy(samples, (uint8_t*)pBuf + size, AVCODEC_MAX_AUDIO_FRAME_SIZE); + size += AVCODEC_MAX_AUDIO_FRAME_SIZE; + memcpy(frame_size_ptr, (uint8_t*)pBuf + size, sizeof(int)); + size += sizeof(int); + memcpy(&result, (uint8_t*)pBuf + size, sizeof(int)); + + GST_CODEC_LOG("frame_size_ptr:%d\n", *frame_size_ptr) + GST_CODEC_LOG("after decoding audio:%d\n", result) + + sem_post(&hCodecSem); + + GST_CODEC_LOG("Leave, ret:%d\n", result) + + return result; +} +#endif + + +#ifdef CODEC_HOST void emul_av_picture_copy(AVPicture *dst, const AVPicture *src, - enum PixelFormat pix_fmt, int width, int height) + enum PixelFormat pix_fmt, int width, + int height, CodecExtraInfo *pInfo) { int fd; @@ -651,34 +1010,38 @@ void emul_av_picture_copy(AVPicture *dst, const AVPicture *src, return; } - PARAM_INIT(_param, CodecParam); - _param.func_num = EMUL_AV_PICTURE_COPY; + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_AV_PICTURE_COPY; + _param.ctxIndex = pInfo->contextIndex; _param.in_args_num = 5; _param.in_args[0] = (uint32_t)dst; _param.in_args[1] = (uint32_t)&pix_fmt; _param.in_args[2] = (uint32_t)&width; _param.in_args[3] = (uint32_t)&height; _param.in_args[4] = (uint32_t)dst->data[0]; - write(fd, &_param, 1); + CODEC_WRITE(fd, &_param, 1); GST_CODEC_LOG("Leave\n") } #else void emul_av_picture_copy(AVPicture *dst, const AVPicture *src, - enum PixelFormat pix_fmt, int width, int height) + enum PixelFormat pix_fmt, int width, + int height, CodecExtraInfo *pInfo) { void *pBuf; int imgSize; int fd; GST_CODEC_LOG("Enter\n") - fd = codecfd; + sem_wait(&hCodecSem); + + fd = pInfo->codecfd; if (fd < 0) { printf("[%s] Codec device has not been opened yet.\n", __func__); return; } - pBuf = pMapBuf; + pBuf = pInfo->pMmapBuf; if (!pBuf) { printf("mapping address is null\n"); return ; @@ -686,40 +1049,52 @@ void emul_av_picture_copy(AVPicture *dst, const AVPicture *src, imgSize = get_picture_size(pix_fmt, width, height); - PARAM_INIT(_param, CodecParam); - _param.func_num = EMUL_AV_PICTURE_COPY; - write(fd, &_param, 1); + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_AV_PICTURE_COPY; + _param.ctxIndex = pInfo->contextIndex; + _param.mmapOffset = pInfo->mmapIndex; + CODEC_WRITE(fd, &_param, 1); + + GST_CODEC_LOG("after CODEC_WRITE system call\n") memcpy(dst->data[0], pBuf, imgSize); + sem_post(&hCodecSem); + GST_CODEC_LOG("Leave\n") } #endif -void emul_av_parser_init (void) +void emul_av_parser_init (CodecExtraInfo *pInfo) { int fd; GST_CODEC_LOG("Enter\n") - fd = codecfd; + sem_wait(&hCodecSem); + + fd = pInfo->codecfd; if (fd < 0) { printf("[%s] Codec device has not been opened yet.\n", __func__); return; } - PARAM_INIT(_param, CodecParam); - PARAM_INIT(_parserBuf, ParserBuf); - _param.func_num = EMUL_AV_PARSER_INIT; - write(fd, &_param, 1); + PARAM_INIT(&_param, CodecParam); + PARAM_INIT(&_parserBuf, ParserBuf); + _param.apiIndex = EMUL_AV_PARSER_INIT; + _param.ctxIndex = pInfo->contextIndex; + _param.mmapOffset = pInfo->mmapIndex; + CODEC_WRITE(fd, &_param, 1); + + sem_post(&hCodecSem); GST_CODEC_LOG("Leave\n") } #ifdef CODEC_HOST int emul_av_parser_parse (AVCodecParserContext *s, AVCodecContext *ctx, - uint8_t **outbuf, int *outbuf_size, - const uint8_t *buf, int buf_size, - int64_t pts, int64_t dts) + uint8_t **outbuf, int *outbuf_size, + const uint8_t *buf, int buf_size, + int64_t pts, int64_t dts, CodecExtraInfo *pInfo) { int result = -1; int fd; @@ -744,8 +1119,9 @@ int emul_av_parser_parse (AVCodecParserContext *s, AVCodecContext *ctx, _parserBuf.buf = NULL; } - PARAM_INIT(_param, CodecParam); - _param.func_num = EMUL_AV_PARSER_PARSE ; + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_AV_PARSER_PARSE; + _param.ctxIndex = pInfo->contextIndex; _param.in_args_num = 8; _param.in_args[0] = (uint32_t)s; _param.in_args[1] = (uint32_t)ctx; @@ -756,7 +1132,7 @@ int emul_av_parser_parse (AVCodecParserContext *s, AVCodecContext *ctx, _param.in_args[6] = (uint32_t)&pts; _param.in_args[7] = (uint32_t)&dts; _param.ret_args = (uint32_t)&result; - write(fd, &_param, 1); + CODEC_WRITE(fd, &_param, 1); if (*outbuf_size == 0) { *outbuf = NULL; @@ -769,11 +1145,10 @@ int emul_av_parser_parse (AVCodecParserContext *s, AVCodecContext *ctx, } #else int emul_av_parser_parse (AVCodecParserContext *s, AVCodecContext *ctx, - uint8_t **outbuf, int *outbuf_size, - const uint8_t *buf, int buf_size, - int64_t pts, int64_t dts) + uint8_t **outbuf, int *outbuf_size, + const uint8_t *buf, int buf_size, + int64_t pts, int64_t dts, CodecExtraInfo *pInfo) { - AVCodecContext tmpCtx; void *pBuf; int fd; int size; @@ -781,58 +1156,63 @@ int emul_av_parser_parse (AVCodecParserContext *s, AVCodecContext *ctx, *outbuf = NULL; GST_CODEC_LOG("Enter\n") - fd = codecfd; + sem_wait(&hCodecSem); + + fd = pInfo->codecfd; if (fd < 0) { printf("[%s] Codec device has not been opened yet.\n", __func__); return -1; } - pBuf = pMapBuf; + pBuf = pInfo->pMmapBuf; if (!pBuf) { printf("mapping address is null\n"); return -1; } - GST_CODEC_LOG("input buffer size :%d\n", buf_size); - GST_CODEC_LOG("previous result:%d\n", _parserBuf.size); - if (_parserBuf.size > 0 && !_parserBuf.buf) { - GST_CODEC_LOG("allocate buffer bufsize:%d\n", _parserBuf.size); - *outbuf = av_malloc (_parserBuf.size); - _parserBuf.buf = *outbuf; - } else if (_parserBuf.size == -1) { - GST_CODEC_LOG("release previous buffer\n"); - av_free(_parserBuf.buf); - _parserBuf.buf = NULL; + GST_CODEC_LOG("input buffer size :%d\n", buf_size) + GST_CODEC_LOG("previous result:%d\n", _parserBuf.size) + if (ctx->codec_type == AVMEDIA_TYPE_VIDEO) { + if (_parserBuf.size > 0 && !_parserBuf.buf) { + GST_CODEC_LOG("allocate buffer bufsize:%d\n", _parserBuf.size) + *outbuf = av_malloc (_parserBuf.size); + _parserBuf.buf = *outbuf; + } else if (_parserBuf.size == -1) { + GST_CODEC_LOG("release previous buffer\n"); + av_free(_parserBuf.buf); + _parserBuf.buf = NULL; + } + } else if (ctx->codec_type == AVMEDIA_TYPE_AUDIO) { + if (!_parserBuf.buf) { + GST_CODEC_LOG("allocate buffer for audio\n") + *outbuf = av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE); + _parserBuf.buf = *outbuf; + } else { + *outbuf = _parserBuf.buf; + } + } else { + printf("Codec type is wrong!!\n"); + return -1; } - memcpy(&tmpCtx, ctx, sizeof(AVCodecContext)); - - size = sizeof(AVCodecContext); - memcpy(pBuf, ctx, size); - memcpy((uint8_t*)pBuf + size, &pts, sizeof(int64_t)); - size += sizeof(int64_t); + memcpy((uint8_t*)pBuf, &pts, sizeof(int64_t)); + size = sizeof(int64_t); memcpy((uint8_t*)pBuf + size, &dts, sizeof(int64_t)); size += sizeof(int64_t); memcpy((uint8_t*)pBuf + size, &buf_size, sizeof(int)); size += sizeof(int); memcpy((uint8_t*)pBuf + size, buf, buf_size); - PARAM_INIT(_param, CodecParam); - _param.func_num = EMUL_AV_PARSER_PARSE; - write(fd, &_param, 1); - - GST_CODEC_LOG("After write system call\n") - - memcpy(ctx, pBuf, sizeof(AVCodecContext)); - restore_codec_context(ctx, &tmpCtx); - size = sizeof(AVCodecContext); + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_AV_PARSER_PARSE; + _param.ctxIndex = pInfo->contextIndex; + _param.mmapOffset = pInfo->mmapIndex; + CODEC_WRITE(fd, &_param, 1); - GST_CODEC_LOG("after copying AVCodecContext :%d\n", size); + GST_CODEC_LOG("After CODEC_WRITE system call\n") - memcpy(outbuf_size, (uint8_t*)pBuf + size, sizeof(int)); - size += sizeof(int); - - GST_CODEC_LOG("after copying output buffer size :%d\n", size); + memcpy(outbuf_size, (uint8_t*)pBuf, sizeof(int)); + size = sizeof(int); GST_CODEC_LOG("Output Buffer Size :%d\n", *outbuf_size); if (*outbuf_size > 0) { @@ -844,32 +1224,46 @@ int emul_av_parser_parse (AVCodecParserContext *s, AVCodecContext *ctx, GST_CODEC_LOG("Result :%d\n", result); - if (*outbuf_size == 0) { - *outbuf = NULL; - _parserBuf.size = result; - } else { - _parserBuf.size = -1; + if (ctx->codec_type == AVMEDIA_TYPE_VIDEO) { + GST_CODEC_LOG("for Video type\n") + if (*outbuf_size == 0) { + *outbuf = NULL; + _parserBuf.size = result; + GST_CODEC_LOG("parser outbuf size :%d\n", _parserBuf.size); + } else { + _parserBuf.size = -1; + GST_CODEC_LOG("parser outbuf size :%d\n", _parserBuf.size); + } } + sem_post(&hCodecSem); + GST_CODEC_LOG("Leave\n") return result; } #endif -void emul_av_parser_close (void) +void emul_av_parser_close (CodecExtraInfo *pInfo) { int fd; GST_CODEC_LOG("Enter\n") - fd = codecfd; + sem_wait(&hCodecSem); + + fd = pInfo->codecfd; if (fd < 0) { printf("[%s] Codec device has not been opened yet.\n", __func__); - return -1; + return; } - PARAM_INIT(_param, CodecParam); - _param.func_num = EMUL_AV_PARSER_CLOSE; - write(fd, &_param, 1); + PARAM_INIT(&_param, CodecParam); + _param.apiIndex = EMUL_AV_PARSER_CLOSE; + _param.ctxIndex = pInfo->contextIndex; + _param.mmapOffset = pInfo->mmapIndex; + CODEC_WRITE(fd, &_param, 1); + + sem_post(&hCodecSem); + GST_CODEC_LOG("Leave\n") } diff --git a/ext/ffmpeg/gstffmpegdef.h b/ext/ffmpeg/gstffmpegdef.h index 7d86e55..01fe91c 100644 --- a/ext/ffmpeg/gstffmpegdef.h +++ b/ext/ffmpeg/gstffmpegdef.h @@ -42,14 +42,12 @@ #include <unistd.h> #include <string.h> #include <sys/mman.h> +#include <sys/stat.h> /* FFMPEG API */ #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> -// #define EMULCODEC_DEBUG -// #define CODEC_HOST - #ifdef EMULCODEC_DEBUG #define GST_CODEC_LOG(fmt, ...) \ fprintf(stdout, "[%s][%d]" fmt, __func__, __LINE__, ##__VA_ARGS__); @@ -57,8 +55,23 @@ #define GST_CODEC_LOG(fmt, ...) ((void)0); #endif +#define CODEC_WRITE(fd, _codec, size) \ + if (write(fd, _codec, size) < 0) { \ + printf("[%s] Failed to call FFmpeg API using write call\n", __func__); \ + printf("codecfd : %d\n", fd); \ + } + +typedef struct _CodecExtraInfo { + int contextIndex; + int mmapIndex; + void *pMmapBuf; + int codecfd; +} CodecExtraInfo; + typedef struct _CodecParam { - uint32_t func_num; + uint32_t apiIndex; + uint32_t ctxIndex; + uint32_t mmapOffset; uint32_t in_args_num; uint32_t in_args[20]; uint32_t ret_args; @@ -70,14 +83,14 @@ typedef struct _ParserBuf { } ParserBuf; #define PARAM_INIT(varCodec, defCodec) \ - memset(&varCodec, 0x00, sizeof(defCodec)) + memset(varCodec, 0x00, sizeof(defCodec)) enum { EMUL_AV_REGISTER_ALL = 1, - EMUL_AVCODEC_OPEN, - EMUL_AVCODEC_CLOSE, EMUL_AVCODEC_ALLOC_CONTEXT, EMUL_AVCODEC_ALLOC_FRAME, + EMUL_AVCODEC_OPEN, + EMUL_AVCODEC_CLOSE, EMUL_AV_FREE_CONTEXT, EMUL_AV_FREE_PICTURE, EMUL_AV_FREE_PALCTRL, @@ -85,51 +98,71 @@ enum { EMUL_AVCODEC_FLUSH_BUFFERS, EMUL_AVCODEC_DECODE_VIDEO, EMUL_AVCODEC_ENCODE_VIDEO, + EMUL_AVCODEC_DECODE_AUDIO, + EMUL_AVCODEC_ENCODE_AUDIO, EMUL_AV_PICTURE_COPY, EMUL_AV_PARSER_INIT, EMUL_AV_PARSER_PARSE, EMUL_AV_PARSER_CLOSE, + EMUL_INIT_MMAP_INDEX, + EMUL_GET_MMAP_INDEX, + EMUL_RESET_MMAP_INDEX, }; -int emul_open_codecdev (void); -void emul_close_codecdev (void); +void restore_codec_context(AVCodecContext *dstctx, + AVCodecContext *srcctx); + +int get_picture_size(int pix_fmt, int width, int height); + +int emul_open_codecdev (CodecExtraInfo *pInfo); + +void emul_close_codecdev (CodecExtraInfo *pInfo); /* FFMPEG API */ -void emul_av_register_all (void); +void emul_av_register_all (CodecExtraInfo *pInfo); -int emul_avcodec_open (AVCodecContext *avctx, AVCodec *codec); +int emul_avcodec_open (AVCodecContext *avctx, + AVCodec *codec, + CodecExtraInfo *pInfo); -int emul_avcodec_close (AVCodecContext *avctx); +int emul_avcodec_close (AVCodecContext *avctx, CodecExtraInfo *pInfo); -void emul_avcodec_alloc_frame (void); +void emul_avcodec_alloc_frame (CodecExtraInfo *pInfo); -void emul_avcodec_alloc_context (void); +void emul_avcodec_alloc_context (CodecExtraInfo *pInfo); -void emul_av_free_context (void); +void emul_av_free_context (CodecExtraInfo *pInfo); -void emul_av_free_picture (void); +void emul_av_free_picture (CodecExtraInfo *pInfo); -void emul_av_free_palctrl (void); +void emul_av_free_palctrl (CodecExtraInfo *pInfo); -void emul_av_free_extradata (void); +void emul_av_free_extradata (CodecExtraInfo *pInfo); -void emul_avcodec_flush_buffers (AVCodecContext *ctx); +void emul_avcodec_flush_buffers (AVCodecContext *ctx, CodecExtraInfo *pInfo); int emul_avcodec_decode_video (AVCodecContext *ctx, AVFrame *frame, - int *got_picture_ptr, uint8_t *buf, int buf_size); + int *got_picture_ptr, uint8_t *buf, + int buf_size, CodecExtraInfo *pInfo); int emul_avcodec_encode_video (AVCodecContext *ctx, uint8_t *buf, - int buf_size, const AVFrame *pict, uint8_t *pict_buf); + int buf_size, const AVFrame *pict, + uint8_t *pict_buf, CodecExtraInfo *pInfo); + +int emul_avcodec_decode_audio (AVCodecContext *avctx, int16_t *samples, + int *frame_size_ptr, const uint8_t *buf, + int buf_size, CodecExtraInfo *pInfo); -void emul_av_picture_copy(AVPicture *dst, const AVPicture *src, - enum PixelFormat pix_fmt, int width, int height); +void emul_av_picture_copy (AVPicture *dst, const AVPicture *src, + enum PixelFormat pix_fmt, int width, + int height, CodecExtraInfo *pInfo); -void emul_av_parser_init (void); +void emul_av_parser_init (CodecExtraInfo *pInfo); int emul_av_parser_parse (AVCodecParserContext *s, AVCodecContext *ctx, uint8_t **outbuf, int *outbuf_size, const uint8_t *buf, int buf_size, - int64_t pts, int64_t dts); + int64_t pts, int64_t dts, CodecExtraInfo *pInfo); -void emul_av_parser_close (void); +void emul_av_parser_close (CodecExtraInfo *pInfo); diff --git a/ext/ffmpeg/gstffmpegenc.c b/ext/ffmpeg/gstffmpegenc.c index b827c93..0cf2a1d 100644 --- a/ext/ffmpeg/gstffmpegenc.c +++ b/ext/ffmpeg/gstffmpegenc.c @@ -248,10 +248,8 @@ gst_ffmpegenc_init (GstFFMpegEnc * ffmpegenc) GST_CODEC_LOG("\n") ffmpegenc->context = avcodec_alloc_context (); ffmpegenc->picture = avcodec_alloc_frame (); - if (oclass->in_plugin->type == CODEC_TYPE_VIDEO) { - emul_avcodec_alloc_context(); - emul_avcodec_alloc_frame(); - } + emul_avcodec_alloc_context(&ffmpegenc->codecInfo); + emul_avcodec_alloc_frame(&ffmpegenc->codecInfo); ffmpegenc->opened = FALSE; ffmpegenc->file = NULL; @@ -290,23 +288,20 @@ static void gst_ffmpegenc_finalize (GObject * object) { GstFFMpegEnc *ffmpegenc = (GstFFMpegEnc *) object; - enum AVMediaType codec_type; gst_ffmpeg_cfg_finalize (ffmpegenc); /* close old session */ if (ffmpegenc->opened) { - gst_ffmpeg_avcodec_close (ffmpegenc->context); + gst_ffmpeg_avcodec_close (ffmpegenc->context, &ffmpegenc->codecInfo); ffmpegenc->opened = FALSE; } /* clean up remaining allocated data */ GST_CODEC_LOG("before free AVCodecContext and AVFrame\n") - codec_type = ffmpegenc->context->codec_type; - if (codec_type == AVMEDIA_TYPE_VIDEO) { - emul_av_free_context(); - emul_av_free_picture(); - } + emul_av_free_context(&ffmpegenc->codecInfo); + emul_av_free_picture(&ffmpegenc->codecInfo); + emul_close_codecdev(&ffmpegenc->codecInfo); av_free(ffmpegenc->context); av_free(ffmpegenc->picture); @@ -477,7 +472,7 @@ gst_ffmpegenc_getcaps (GstPad * pad) GST_DEBUG ("Attempting to open codec"); GST_CODEC_LOG("before gst_ffmpeg_avcodec_open, codec_id:%d\n", oclass->in_plugin->id) - if (gst_ffmpeg_avcodec_open (ctx, oclass->in_plugin) >= 0 && + if (gst_ffmpeg_avcodec_open (ctx, oclass->in_plugin, &ffmpegenc->codecInfo) >= 0 && ctx->pix_fmt == pixfmt) { ctx->width = -1; if (!caps) @@ -490,13 +485,13 @@ gst_ffmpegenc_getcaps (GstPad * pad) GST_LOG_OBJECT (ffmpegenc, "Couldn't get caps for oclass->in_plugin->name:%s", oclass->in_plugin->name); - gst_ffmpeg_avcodec_close (ctx); + gst_ffmpeg_avcodec_close (ctx, &ffmpegenc->codecInfo); } else { GST_DEBUG_OBJECT (ffmpegenc, "Opening codec failed with pixfmt : %d", pixfmt); } if (ctx->priv_data) - gst_ffmpeg_avcodec_close (ctx); + gst_ffmpeg_avcodec_close (ctx, &ffmpegenc->codecInfo); av_free (ctx); } #ifndef GST_DISABLE_GST_DEBUG @@ -534,7 +529,7 @@ gst_ffmpegenc_setcaps (GstPad * pad, GstCaps * caps) /* close old session */ if (ffmpegenc->opened) { - gst_ffmpeg_avcodec_close (ffmpegenc->context); + gst_ffmpeg_avcodec_close (ffmpegenc->context, &ffmpegenc->codecInfo); ffmpegenc->opened = FALSE; } @@ -658,9 +653,9 @@ gst_ffmpegenc_setcaps (GstPad * pad, GstCaps * caps) /* open codec */ GST_CODEC_LOG("before gst_ffmpeg_avcodec_open\n") - if (gst_ffmpeg_avcodec_open (ffmpegenc->context, oclass->in_plugin) < 0) { + if (gst_ffmpeg_avcodec_open (ffmpegenc->context, oclass->in_plugin, &ffmpegenc->codecInfo) < 0) { if (ffmpegenc->context->priv_data) - gst_ffmpeg_avcodec_close (ffmpegenc->context); + gst_ffmpeg_avcodec_close (ffmpegenc->context, &ffmpegenc->codecInfo); if (ffmpegenc->context->stats_in) g_free (ffmpegenc->context->stats_in); GST_DEBUG_OBJECT (ffmpegenc, "ffenc_%s: Failed to open FFMPEG codec", @@ -674,7 +669,7 @@ gst_ffmpegenc_setcaps (GstPad * pad, GstCaps * caps) /* is the colourspace correct? */ if (pix_fmt != ffmpegenc->context->pix_fmt) { - gst_ffmpeg_avcodec_close (ffmpegenc->context); + gst_ffmpeg_avcodec_close (ffmpegenc->context, &ffmpegenc->codecInfo); GST_DEBUG_OBJECT (ffmpegenc, "ffenc_%s: AV wants different colourspace (%d given, %d wanted)", oclass->in_plugin->name, pix_fmt, ffmpegenc->context->pix_fmt); @@ -708,7 +703,7 @@ gst_ffmpegenc_setcaps (GstPad * pad, GstCaps * caps) ffmpegenc->context, TRUE); if (!other_caps) { - gst_ffmpeg_avcodec_close (ffmpegenc->context); + gst_ffmpeg_avcodec_close (ffmpegenc->context, &ffmpegenc->codecInfo); GST_DEBUG ("Unsupported codec - no caps found"); return FALSE; } @@ -732,7 +727,7 @@ gst_ffmpegenc_setcaps (GstPad * pad, GstCaps * caps) } if (!gst_pad_set_caps (ffmpegenc->srcpad, icaps)) { - gst_ffmpeg_avcodec_close (ffmpegenc->context); + gst_ffmpeg_avcodec_close (ffmpegenc->context, &ffmpegenc->codecInfo); gst_caps_unref (icaps); return FALSE; } @@ -795,21 +790,13 @@ gst_ffmpegenc_chain_video (GstPad * pad, GstBuffer * inbuf) gst_ffmpeg_time_gst_to_ff (GST_BUFFER_TIMESTAMP (inbuf) / ffmpegenc->context->ticks_per_frame, ffmpegenc->context->time_base); - GST_CODEC_LOG("picture->pts:%d\n", ffmpegenc->picture->pts) - ffmpegenc_setup_working_buf (ffmpegenc); GST_CODEC_LOG("before avcodec_encode_video, codec_id:%d\n", ffmpegenc->context->codec_id) - if (ffmpegenc->context->codec_type == AVMEDIA_TYPE_VIDEO) { - GST_CODEC_LOG("\n") - ret_size = emul_avcodec_encode_video (ffmpegenc->context, ffmpegenc->working_buf, - ffmpegenc->working_buf_size, ffmpegenc->picture, GST_BUFFER_DATA(inbuf)); - } else { - GST_CODEC_LOG("\n") - ret_size = avcodec_encode_video (ffmpegenc->context, - ffmpegenc->working_buf, ffmpegenc->working_buf_size, ffmpegenc->picture); - } + GST_CODEC_LOG("\n") + ret_size = emul_avcodec_encode_video (ffmpegenc->context, ffmpegenc->working_buf, + ffmpegenc->working_buf_size, ffmpegenc->picture, GST_BUFFER_DATA(inbuf), &ffmpegenc->codecInfo); GST_CODEC_LOG("after encode video, ret:%d\n", ret_size) if (ret_size < 0) { @@ -1101,13 +1088,8 @@ gst_ffmpegenc_flush_buffers (GstFFMpegEnc * ffmpegenc, gboolean send) GST_CODEC_LOG("before avcodec_encode_video, codec_id:%d\n", ffmpegenc->context->codec_id) - if (ffmpegenc->context->codec_type == AVMEDIA_TYPE_VIDEO) { - ret_size = emul_avcodec_encode_video (ffmpegenc->context, - ffmpegenc->working_buf, ffmpegenc->working_buf_size, NULL, NULL); - } else { - ret_size = avcodec_encode_video (ffmpegenc->context, - ffmpegenc->working_buf, ffmpegenc->working_buf_size, NULL); - } + ret_size = emul_avcodec_encode_video (ffmpegenc->context, + ffmpegenc->working_buf, ffmpegenc->working_buf_size, NULL, NULL, &ffmpegenc->codecInfo); GST_CODEC_LOG("after encode vidoe : ret(%d)\n", ret_size) if (ret_size < 0) { /* there should be something, notify and give up */ #ifndef GST_DISABLE_GST_DEBUG @@ -1299,7 +1281,7 @@ gst_ffmpegenc_change_state (GstElement * element, GstStateChange transition) case GST_STATE_CHANGE_PAUSED_TO_READY: gst_ffmpegenc_flush_buffers (ffmpegenc, FALSE); if (ffmpegenc->opened) { - gst_ffmpeg_avcodec_close (ffmpegenc->context); + gst_ffmpeg_avcodec_close (ffmpegenc->context, &ffmpegenc->codecInfo); ffmpegenc->opened = FALSE; } gst_adapter_clear (ffmpegenc->adapter); diff --git a/ext/ffmpeg/gstffmpegenc.h b/ext/ffmpeg/gstffmpegenc.h index c13a0d3..a6dd88f 100644 --- a/ext/ffmpeg/gstffmpegenc.h +++ b/ext/ffmpeg/gstffmpegenc.h @@ -76,6 +76,9 @@ struct _GstFFMpegEnc AVCodecContext config; gboolean force_keyframe; + + /* Extra info which can determine codec Context on the Host side(QEMU)*/ + CodecExtraInfo codecInfo; }; typedef struct _GstFFMpegEncClass GstFFMpegEncClass; |