From 78519a0029734d1d11e735d568fc402709bb6427 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 1 Dec 2016 16:17:41 +0100 Subject: [PATCH] avformat/ffmenc: Make ffm_write_header_codec_ctx() use codecpar This would be simpler if codecpar supported AVOptions modern ffserver should be unaffected by this, older ffserver which required the muxer to directly access the encoder could have issues with this, but this direct access is just wrong and unsafe Signed-off-by: Michael Niedermayer --- libavformat/ffmenc.c | 19 ++++++++++++++++--- tests/ref/lavf/ffm | 2 +- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/libavformat/ffmenc.c b/libavformat/ffmenc.c index 7ed4320fed..caf278fff2 100644 --- a/libavformat/ffmenc.c +++ b/libavformat/ffmenc.c @@ -95,11 +95,12 @@ static void write_header_chunk(AVIOContext *pb, AVIOContext *dpb, unsigned id) av_free(dyn_buf); } -static int ffm_write_header_codec_ctx(AVIOContext *pb, AVCodecContext *ctx, unsigned tag, int type) +static int ffm_write_header_codec_ctx(AVIOContext *pb, AVCodecParameters *ctxpar, unsigned tag, int type) { AVIOContext *tmp; char *buf = NULL; int ret, need_coma = 0; + AVCodecContext *ctx = NULL; #define SKIP_DEFAULTS AV_OPT_SERIALIZE_SKIP_DEFAULTS #define OPT_FLAGS_EXACT AV_OPT_SERIALIZE_OPT_FLAGS_EXACT @@ -107,6 +108,16 @@ static int ffm_write_header_codec_ctx(AVIOContext *pb, AVCodecContext *ctx, unsi if (avio_open_dyn_buf(&tmp) < 0) return AVERROR(ENOMEM); + + // AVCodecParameters does not suport AVOptions, we thus must copy it over to a context that does + // otherwise it could be used directly and this would be much simpler + ctx = avcodec_alloc_context3(NULL); + if (!ctx) { + ret = AVERROR(ENOMEM); + goto fail; + } + avcodec_parameters_to_context(ctx, ctxpar); + if ((ret = av_opt_serialize(ctx, ENC | type, SKIP_DEFAULTS, &buf, '=', ',')) < 0) goto fail; if (buf && strlen(buf)) { @@ -124,10 +135,12 @@ static int ffm_write_header_codec_ctx(AVIOContext *pb, AVCodecContext *ctx, unsi av_freep(&buf); avio_w8(tmp, 0); write_header_chunk(pb, tmp, tag); + avcodec_free_context(&ctx); return 0; fail: av_free(buf); ffio_free_dyn_buf(&tmp); + avcodec_free_context(&ctx); return ret; #undef SKIP_DEFAULTS @@ -261,7 +274,7 @@ static int ffm_write_header(AVFormatContext *s) if ((ret = ffm_write_recommended_config(s->pb, codec, MKBETAG('S', '2', 'V', 'I'), st->recommended_encoder_configuration)) < 0) return ret; - } else if ((ret = ffm_write_header_codec_ctx(s->pb, codec, MKBETAG('S', '2', 'V', 'I'), AV_OPT_FLAG_VIDEO_PARAM)) < 0) + } else if ((ret = ffm_write_header_codec_ctx(s->pb, codecpar, MKBETAG('S', '2', 'V', 'I'), AV_OPT_FLAG_VIDEO_PARAM)) < 0) return ret; break; case AVMEDIA_TYPE_AUDIO: @@ -271,7 +284,7 @@ static int ffm_write_header(AVFormatContext *s) if ((ret = ffm_write_recommended_config(s->pb, codec, MKBETAG('S', '2', 'A', 'U'), st->recommended_encoder_configuration)) < 0) return ret; - } else if ((ret = ffm_write_header_codec_ctx(s->pb, codec, MKBETAG('S', '2', 'A', 'U'), AV_OPT_FLAG_AUDIO_PARAM)) < 0) + } else if ((ret = ffm_write_header_codec_ctx(s->pb, codecpar, MKBETAG('S', '2', 'A', 'U'), AV_OPT_FLAG_AUDIO_PARAM)) < 0) return ret; break; default: diff --git a/tests/ref/lavf/ffm b/tests/ref/lavf/ffm index 7a51d9b586..54c56034aa 100644 --- a/tests/ref/lavf/ffm +++ b/tests/ref/lavf/ffm @@ -1,3 +1,3 @@ -03f2673a39a9494157eb4be9af537f84 *./tests/data/lavf/lavf.ffm +a0e9616f0d9a8c1029f3220b1b9175f4 *./tests/data/lavf/lavf.ffm 376832 ./tests/data/lavf/lavf.ffm ./tests/data/lavf/lavf.ffm CRC=0x000e23ae