[FFmpeg-devel] [PATCH 5/9] ffmpeg_opt: use codec private context in ffserver streams

Lukasz Marek lukasz.m.luki2 at gmail.com
Tue Nov 11 08:31:27 CET 2014


Signed-off-by: Lukasz Marek <lukasz.m.luki2 at gmail.com>
---
 ffmpeg_opt.c | 48 ++++++++++++++++++++++++++++++++----------------
 1 file changed, 32 insertions(+), 16 deletions(-)

diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c
index 1b3f73a..fdbab58 100644
--- a/ffmpeg_opt.c
+++ b/ffmpeg_opt.c
@@ -1618,6 +1618,35 @@ static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata)
     return 0;
 }
 
+static int ffserver_streams_copy_context(AVCodecContext *dest, const AVCodecContext *src)
+{
+    int ret;
+    if ((ret = avcodec_copy_context(dest, src)) < 0)
+        return ret;
+    if (src->priv_data) {
+        if (dest->priv_data && *(const AVClass**)src->priv_data != *(const AVClass**)dest->priv_data) {
+            av_opt_free(dest->priv_data);
+            av_freep(&dest->priv_data);
+        }
+        if (!dest->priv_data) {
+            if (!src->codec) {
+                av_log(NULL, AV_LOG_WARNING, "Cannot copy codec private options. They won't get applied.\n");
+                return 0;
+            }
+            dest->priv_data = av_mallocz(src->codec->priv_data_size);
+            if (!dest->priv_data)
+                return AVERROR(ENOMEM);
+            *(const AVClass**)dest->priv_data = src->codec->priv_class;
+        }
+        av_opt_copy(dest->priv_data, src->priv_data);
+    } else if (dest->priv_data) {
+        av_opt_free(dest->priv_data);
+        av_freep(&dest->priv_data);
+    }
+
+    return 0;
+}
+
 static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const char *filename)
 {
     int i, err;
@@ -1632,35 +1661,22 @@ static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const ch
         AVStream *st;
         OutputStream *ost;
         AVCodec *codec;
-        AVCodecContext *avctx;
 
         codec = avcodec_find_encoder(ic->streams[i]->codec->codec_id);
         if (!codec) {
             av_log(s, AV_LOG_ERROR, "no encoder found for codec id %i\n", ic->streams[i]->codec->codec_id);
             return AVERROR(EINVAL);
         }
-        ost   = new_output_stream(o, s, codec->type, -1, NULL);
+        ost   = new_output_stream(o, s, codec->type, -1, codec);
         st    = ost->st;
-        avctx = st->codec;
-        ost->enc = codec;
 
-        // FIXME: a more elegant solution is needed
-        memcpy(st, ic->streams[i], sizeof(AVStream));
-        st->cur_dts = 0;
-        st->info = av_malloc(sizeof(*st->info));
-        memcpy(st->info, ic->streams[i]->info, sizeof(*st->info));
-        st->codec= avctx;
-        avcodec_copy_context(st->codec, ic->streams[i]->codec);
+        ffserver_streams_copy_context(st->codec, ic->streams[i]->codec);
 
         if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && !ost->stream_copy)
             choose_sample_fmt(st, codec);
         else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && !ost->stream_copy)
             choose_pixel_fmt(st, st->codec, codec, st->codec->pix_fmt);
-        avcodec_copy_context(ost->enc_ctx, st->codec);
-        if (ost->enc_ctx->priv_data) {
-            av_opt_free(ost->enc_ctx->priv_data);
-            av_freep(&ost->enc_ctx->priv_data);
-        }
+        ffserver_streams_copy_context(ost->enc_ctx, st->codec);
     }
 
     avformat_close_input(&ic);
-- 
1.9.1



More information about the ffmpeg-devel mailing list