On 17.11.2014 02:46, Lukasz Marek wrote:
ffmenc will store recommended encoder configuration if present.
This will allow the user to base on local defaults and
apply only explicitly set options.

If recommended encoder configuration is not present, then
non-default context's options are stored.

Signed-off-by: Lukasz Marek <lukasz.m.lu...@gmail.com>
---
  libavformat/ffmenc.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++---
  1 file changed, 70 insertions(+), 4 deletions(-)

diff --git a/libavformat/ffmenc.c b/libavformat/ffmenc.c
index b717813..2f3f90d 100644
--- a/libavformat/ffmenc.c
+++ b/libavformat/ffmenc.c
@@ -162,6 +162,60 @@ static int ffm_write_header_codec_ctx(AVIOContext *pb, 
AVCodecContext *ctx, unsi
  #undef ENC
  }


Updated patch, av_dict_serialize -> av_dict_get string

>From dd19271a6724b31fe1da3a32db5d355832c0ad07 Mon Sep 17 00:00:00 2001
From: Lukasz Marek <lukasz.m.lu...@gmail.com>
Date: Sun, 16 Nov 2014 21:55:14 +0100
Subject: [PATCH 8/9] lavf/ffmenc: store recommended encoder configuration

ffmenc will store recommended encoder configuration if present.
This will allow the user to base on local defaults and
apply only explicitly set options.

If recommended encoder configuration is not present, then
non-default context's options are stored.

Signed-off-by: Lukasz Marek <lukasz.m.lu...@gmail.com>
---
 libavformat/ffmenc.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 70 insertions(+), 4 deletions(-)

diff --git a/libavformat/ffmenc.c b/libavformat/ffmenc.c
index c64c26b..e6d1a31 100644
--- a/libavformat/ffmenc.c
+++ b/libavformat/ffmenc.c
@@ -162,6 +162,60 @@ static int ffm_write_header_codec_ctx(AVIOContext *pb, AVCodecContext *ctx, unsi
 #undef ENC
 }
 
+static int ffm_write_recommended_config(AVIOContext *pb, AVCodecContext *ctx, unsigned tag,
+                                        const char *configuration)
+{
+    int ret;
+    const AVCodec *enc = ctx->codec ? ctx->codec : avcodec_find_encoder(ctx->codec_id);
+    AVIOContext *tmp;
+    AVDictionaryEntry *t = NULL;
+    AVDictionary *all = NULL, *comm = NULL, *prv = NULL;
+    char *buf = NULL;
+
+    if (!enc || !enc->priv_class || !enc->priv_data_size) {
+        /* codec is not known/has no private options, so save everything as common options */
+        if (avio_open_dyn_buf(&tmp) < 0)
+            return AVERROR(ENOMEM);
+        avio_put_str(tmp, configuration);
+        write_header_chunk(pb, tmp, tag);
+        return 0;
+    }
+
+    if ((ret = av_dict_parse_string(&all, configuration, "=", ",", 0)) < 0)
+        return ret;
+
+    while ((t = av_dict_get(all, "", t, AV_DICT_IGNORE_SUFFIX))) {
+        if (av_opt_find((void *)&enc->priv_class, t->key, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ)) {
+            if ((ret = av_dict_set(&prv, t->key, t->value, 0)) < 0)
+                goto fail;
+        } else if ((ret = av_dict_set(&comm, t->key, t->value, 0)) < 0)
+            goto fail;
+    }
+
+    if (comm) {
+        if ((ret = av_dict_get_string(comm, &buf, '=', ',')) < 0 ||
+            (ret = avio_open_dyn_buf(&tmp)) < 0)
+            goto fail;
+        avio_put_str(tmp, buf);
+        av_freep(&buf);
+        write_header_chunk(pb, tmp, tag);
+    }
+    if (prv) {
+        if ((ret = av_dict_get_string(prv, &buf, '=', ',')) < 0 ||
+            (ret = avio_open_dyn_buf(&tmp)) < 0)
+            goto fail;
+        avio_put_str(tmp, buf);
+        write_header_chunk(pb, tmp, MKBETAG('C', 'P', 'R', 'V'));
+    }
+
+  fail:
+    av_free(buf);
+    av_dict_free(&all);
+    av_dict_free(&comm);
+    av_dict_free(&prv);
+    return ret;
+}
+
 static int ffm_write_header(AVFormatContext *s)
 {
     FFMContext *ffm = s->priv_data;
@@ -220,13 +274,25 @@ static int ffm_write_header(AVFormatContext *s)
         /* specific info */
         switch(codec->codec_type) {
         case AVMEDIA_TYPE_VIDEO:
-            if ((ret = ffm_write_header_codec_ctx(s->pb, codec, MKBETAG('S', '2', 'V', 'I'), AV_OPT_FLAG_VIDEO_PARAM)) < 0 ||
-                (ret = ffm_write_header_codec_private_ctx(s->pb, codec, AV_OPT_FLAG_VIDEO_PARAM)) < 0)
+            if (st->recommended_encoder_configuration) {
+                av_log(NULL, AV_LOG_DEBUG, "writing recommended configuration: %s\n",
+                       st->recommended_encoder_configuration);
+                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 ||
+                       (ret = ffm_write_header_codec_private_ctx(s->pb, codec, AV_OPT_FLAG_VIDEO_PARAM)) < 0)
                 return ret;
             break;
         case AVMEDIA_TYPE_AUDIO:
-            if ((ret = ffm_write_header_codec_ctx(s->pb, codec, MKBETAG('S', '2', 'A', 'U'), AV_OPT_FLAG_AUDIO_PARAM)) < 0 ||
-                (ret = ffm_write_header_codec_private_ctx(s->pb, codec, AV_OPT_FLAG_AUDIO_PARAM)) < 0)
+            if (st->recommended_encoder_configuration) {
+                av_log(NULL, AV_LOG_DEBUG, "writing recommended configuration: %s\n",
+                       st->recommended_encoder_configuration);
+                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 ||
+                     (ret = ffm_write_header_codec_private_ctx(s->pb, codec, AV_OPT_FLAG_AUDIO_PARAM)) < 0)
                 return ret;
             break;
         default:
-- 
1.9.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to