* [FFmpeg-devel] [PATCH 1/2] avutil/test/opt: test the AV_OPT_SERIALIZE_SKIP_DEFAULTS flag
@ 2024-04-12 23:16 James Almer
2024-04-12 23:16 ` [FFmpeg-devel] [PATCH 2/2] avutil/opt: add support for children objects in av_opt_serialize James Almer
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: James Almer @ 2024-04-12 23:16 UTC (permalink / raw)
To: ffmpeg-devel
Signed-off-by: James Almer <jamrial@gmail.com>
---
The floats are set to "1.0 / 3" and the serialization prints a value that's not
exact, hence them not being skipped.
array_int is weird, though. Although it's the only array that doesn't set
AVOption.arr
libavutil/tests/opt.c | 5 +++++
tests/ref/fate/opt | 1 +
2 files changed, 6 insertions(+)
diff --git a/libavutil/tests/opt.c b/libavutil/tests/opt.c
index ccf3a54f96..32301ba842 100644
--- a/libavutil/tests/opt.c
+++ b/libavutil/tests/opt.c
@@ -279,6 +279,11 @@ int main(void)
if (av_opt_serialize(&test_ctx, 0, 0, &buf, '=', ',') >= 0) {
printf("%s\n", buf);
av_free(buf);
+ if (av_opt_serialize(&test_ctx, 0, AV_OPT_SERIALIZE_SKIP_DEFAULTS, &buf, '=', ',') >= 0) {
+ if (strlen(buf))
+ printf("%s\n", buf);
+ av_free(buf);
+ }
}
}
av_opt_free(&test_ctx);
diff --git a/tests/ref/fate/opt b/tests/ref/fate/opt
index f4fce1bd49..43bf0929a3 100644
--- a/tests/ref/fate/opt
+++ b/tests/ref/fate/opt
@@ -179,6 +179,7 @@ Setting entry with key 'array_int' to value ''
Setting entry with key 'array_str' to value 'str0|str\|1|str\\2'
Setting entry with key 'array_dict' to value 'k00=v\\\\00:k01=v\,01,k10=v\\=1\\:0'
num=0,toggle=1,rational=1/1,string=default,escape=\\\=\,,flags=0x00000001,size=200x300,pix_fmt=0bgr,sample_fmt=s16,video_rate=25/1,duration=0.001,color=0xffc0cbff,cl=hexagonal,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333,bool1=auto,bool2=true,bool3=false,dict1=,dict2=happy\=\\:-),array_int=,array_str=str0|str\\|1|str\\\\2,array_dict=k00\=v\\\\\\\\00:k01\=v\\\,01\,k10\=v\\\\\=1\\\\:0
+flt=0.333333,dbl=0.333333,array_int=
Testing av_set_options_string()
Setting options string ''
--
2.44.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 6+ messages in thread
* [FFmpeg-devel] [PATCH 2/2] avutil/opt: add support for children objects in av_opt_serialize
2024-04-12 23:16 [FFmpeg-devel] [PATCH 1/2] avutil/test/opt: test the AV_OPT_SERIALIZE_SKIP_DEFAULTS flag James Almer
@ 2024-04-12 23:16 ` James Almer
2024-04-15 12:51 ` James Almer
2024-04-13 14:21 ` [FFmpeg-devel] [PATCH 3/3] avutil/tests/opt: test av_opt_find2() James Almer
2024-04-15 15:09 ` [FFmpeg-devel] [PATCH 4/4] fftools/ffmpeg_mux_init: allow mapping a stream group from one of the inputs James Almer
2 siblings, 1 reply; 6+ messages in thread
From: James Almer @ 2024-04-12 23:16 UTC (permalink / raw)
To: ffmpeg-devel
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavutil/opt.c | 65 +++++++++++++++++++++++++++++--------------
libavutil/opt.h | 1 +
libavutil/tests/opt.c | 47 +++++++++++++++++++++++++++++--
tests/ref/fate/opt | 2 +-
4 files changed, 90 insertions(+), 25 deletions(-)
diff --git a/libavutil/opt.c b/libavutil/opt.c
index d11e9d2ac5..ecbf7efe5f 100644
--- a/libavutil/opt.c
+++ b/libavutil/opt.c
@@ -2386,26 +2386,22 @@ int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_fla
return av_opt_is_set_to_default(target, o);
}
-int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer,
- const char key_val_sep, const char pairs_sep)
+static int opt_serialize(void *obj, int opt_flags, int flags, int *cnt,
+ AVBPrint *bprint, const char key_val_sep, const char pairs_sep)
{
const AVOption *o = NULL;
+ void *child = NULL;
uint8_t *buf;
- AVBPrint bprint;
- int ret, cnt = 0;
+ int ret;
const char special_chars[] = {pairs_sep, key_val_sep, '\0'};
- if (pairs_sep == '\0' || key_val_sep == '\0' || pairs_sep == key_val_sep ||
- pairs_sep == '\\' || key_val_sep == '\\') {
- av_log(obj, AV_LOG_ERROR, "Invalid separator(s) found.");
- return AVERROR(EINVAL);
- }
-
- if (!obj || !buffer)
- return AVERROR(EINVAL);
-
- *buffer = NULL;
- av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED);
+ if (flags & AV_OPT_SERIALIZE_SEARCH_CHILDREN)
+ while (child = av_opt_child_next(obj, child)) {
+ ret = opt_serialize(child, opt_flags, flags, cnt, bprint,
+ key_val_sep, pairs_sep);
+ if (ret < 0)
+ return ret;
+ }
while (o = av_opt_next(obj, o)) {
if (o->type == AV_OPT_TYPE_CONST)
@@ -2417,18 +2413,45 @@ int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer,
if (flags & AV_OPT_SERIALIZE_SKIP_DEFAULTS && av_opt_is_set_to_default(obj, o) > 0)
continue;
if ((ret = av_opt_get(obj, o->name, 0, &buf)) < 0) {
- av_bprint_finalize(&bprint, NULL);
+ av_bprint_finalize(bprint, NULL);
return ret;
}
if (buf) {
- if (cnt++)
- av_bprint_append_data(&bprint, &pairs_sep, 1);
- av_bprint_escape(&bprint, o->name, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
- av_bprint_append_data(&bprint, &key_val_sep, 1);
- av_bprint_escape(&bprint, buf, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
+ if ((*cnt)++)
+ av_bprint_append_data(bprint, &pairs_sep, 1);
+ av_bprint_escape(bprint, o->name, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
+ av_bprint_append_data(bprint, &key_val_sep, 1);
+ av_bprint_escape(bprint, buf, special_chars, AV_ESCAPE_MODE_BACKSLASH, 0);
av_freep(&buf);
}
}
+
+ return 0;
+}
+
+int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer,
+ const char key_val_sep, const char pairs_sep)
+{
+ AVBPrint bprint;
+ int ret, cnt = 0;
+
+ if (pairs_sep == '\0' || key_val_sep == '\0' || pairs_sep == key_val_sep ||
+ pairs_sep == '\\' || key_val_sep == '\\') {
+ av_log(obj, AV_LOG_ERROR, "Invalid separator(s) found.");
+ return AVERROR(EINVAL);
+ }
+
+ if (!obj || !buffer)
+ return AVERROR(EINVAL);
+
+ *buffer = NULL;
+ av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED);
+
+ ret = opt_serialize(obj, opt_flags, flags, &cnt, &bprint,
+ key_val_sep, pairs_sep);
+ if (ret < 0)
+ return ret;
+
ret = av_bprint_finalize(&bprint, buffer);
if (ret < 0)
return ret;
diff --git a/libavutil/opt.h b/libavutil/opt.h
index e6013662f6..855e363091 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -929,6 +929,7 @@ int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name)
#define AV_OPT_SERIALIZE_SKIP_DEFAULTS 0x00000001 ///< Serialize options that are not set to default values only.
#define AV_OPT_SERIALIZE_OPT_FLAGS_EXACT 0x00000002 ///< Serialize options that exactly match opt_flags only.
+#define AV_OPT_SERIALIZE_SEARCH_CHILDREN 0x00000004 ///< Serialize options in possible children of the given object.
/**
* Serialize object's options.
diff --git a/libavutil/tests/opt.c b/libavutil/tests/opt.c
index 32301ba842..53d8951bcf 100644
--- a/libavutil/tests/opt.c
+++ b/libavutil/tests/opt.c
@@ -30,6 +30,7 @@
typedef struct TestContext {
const AVClass *class;
+ struct ChildContext *child;
int num;
int toggle;
char *string;
@@ -123,10 +124,46 @@ static const char *test_get_name(void *ctx)
return "test";
}
+typedef struct ChildContext {
+ const AVClass *class;
+ int64_t child_num64;
+ int child_num;
+} ChildContext;
+
+#undef OFFSET
+#define OFFSET(x) offsetof(ChildContext, x)
+
+static const AVOption child_options[]= {
+ {"child_num64", "set num 64bit", OFFSET(child_num64), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, 100, 1 },
+ {"child_num", "set child_num", OFFSET(child_num), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 100, 1 },
+ { NULL },
+};
+
+static const char *child_get_name(void *ctx)
+{
+ return "child";
+}
+
+static const AVClass child_class = {
+ .class_name = "ChildContext",
+ .item_name = child_get_name,
+ .option = child_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static void *test_child_next(void *obj, void *prev)
+{
+ TestContext *test_ctx = obj;
+ if (!prev)
+ return test_ctx->child;
+ return NULL;
+}
+
static const AVClass test_class = {
.class_name = "TestContext",
.item_name = test_get_name,
.option = test_options,
+ .child_next = test_child_next,
.version = LIBAVUTIL_VERSION_INT,
};
@@ -277,11 +314,15 @@ int main(void)
av_set_options_string(&test_ctx, buf, "=", ",");
av_free(buf);
if (av_opt_serialize(&test_ctx, 0, 0, &buf, '=', ',') >= 0) {
+ ChildContext child_ctx = { 0 };
printf("%s\n", buf);
av_free(buf);
- if (av_opt_serialize(&test_ctx, 0, AV_OPT_SERIALIZE_SKIP_DEFAULTS, &buf, '=', ',') >= 0) {
- if (strlen(buf))
- printf("%s\n", buf);
+ test_ctx.child = &child_ctx;
+ child_ctx.class = &child_class;
+ if (av_opt_serialize(&test_ctx, 0,
+ AV_OPT_SERIALIZE_SKIP_DEFAULTS|AV_OPT_SERIALIZE_SEARCH_CHILDREN,
+ &buf, '=', ',') >= 0) {
+ printf("%s\n", buf);
av_free(buf);
}
}
diff --git a/tests/ref/fate/opt b/tests/ref/fate/opt
index 43bf0929a3..05d57066a1 100644
--- a/tests/ref/fate/opt
+++ b/tests/ref/fate/opt
@@ -179,7 +179,7 @@ Setting entry with key 'array_int' to value ''
Setting entry with key 'array_str' to value 'str0|str\|1|str\\2'
Setting entry with key 'array_dict' to value 'k00=v\\\\00:k01=v\,01,k10=v\\=1\\:0'
num=0,toggle=1,rational=1/1,string=default,escape=\\\=\,,flags=0x00000001,size=200x300,pix_fmt=0bgr,sample_fmt=s16,video_rate=25/1,duration=0.001,color=0xffc0cbff,cl=hexagonal,bin=62696E00,bin1=,bin2=,num64=1,flt=0.333333,dbl=0.333333,bool1=auto,bool2=true,bool3=false,dict1=,dict2=happy\=\\:-),array_int=,array_str=str0|str\\|1|str\\\\2,array_dict=k00\=v\\\\\\\\00:k01\=v\\\,01\,k10\=v\\\\\=1\\\\:0
-flt=0.333333,dbl=0.333333,array_int=
+child_num=0,flt=0.333333,dbl=0.333333,array_int=
Testing av_set_options_string()
Setting options string ''
--
2.44.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 6+ messages in thread
* [FFmpeg-devel] [PATCH 3/3] avutil/tests/opt: test av_opt_find2()
2024-04-12 23:16 [FFmpeg-devel] [PATCH 1/2] avutil/test/opt: test the AV_OPT_SERIALIZE_SKIP_DEFAULTS flag James Almer
2024-04-12 23:16 ` [FFmpeg-devel] [PATCH 2/2] avutil/opt: add support for children objects in av_opt_serialize James Almer
@ 2024-04-13 14:21 ` James Almer
2024-04-15 15:09 ` [FFmpeg-devel] [PATCH 4/4] fftools/ffmpeg_mux_init: allow mapping a stream group from one of the inputs James Almer
2 siblings, 0 replies; 6+ messages in thread
From: James Almer @ 2024-04-13 14:21 UTC (permalink / raw)
To: ffmpeg-devel
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavutil/tests/opt.c | 29 +++++++++++++++++++++++++++++
tests/ref/fate/opt | 4 ++++
2 files changed, 33 insertions(+)
diff --git a/libavutil/tests/opt.c b/libavutil/tests/opt.c
index bac0e80bd5..dc968567eb 100644
--- a/libavutil/tests/opt.c
+++ b/libavutil/tests/opt.c
@@ -452,5 +452,34 @@ int main(void)
av_opt_free(&test_ctx);
}
+ printf("\nTesting av_opt_find2()\n");
+ {
+ TestContext test_ctx = { 0 };
+ ChildContext child_ctx = { 0 };
+ void *target;
+ const AVOption *opt;
+
+ test_ctx.class = &test_class;
+ test_ctx.child = &child_ctx;
+ child_ctx.class = &child_class;
+ av_opt_set_defaults(&test_ctx);
+ av_opt_set_defaults(&child_ctx);
+
+ av_log_set_level(AV_LOG_QUIET);
+
+ opt = av_opt_find2(&test_ctx, "num", NULL, 0, 0, &target);
+ if (opt && target == &test_ctx)
+ printf("OK '%s'\n", opt->name);
+ else
+ printf("Error '%s'\n", "num");
+
+ opt = av_opt_find2(&test_ctx, "child_num", NULL, 0, AV_OPT_SEARCH_CHILDREN, &target);
+ if (opt && target == &child_ctx)
+ printf("OK '%s'\n", opt->name);
+ else
+ printf("Error '%s'\n", "child_num");
+ av_opt_free(&test_ctx);
+ }
+
return 0;
}
diff --git a/tests/ref/fate/opt b/tests/ref/fate/opt
index 05d57066a1..39659b2248 100644
--- a/tests/ref/fate/opt
+++ b/tests/ref/fate/opt
@@ -449,3 +449,7 @@ Setting options string 'a_very_long_option_name_that_will_need_to_be_ellipsized_
Setting 'a_very_long_option_name_that_will_need_to_be_ellipsized_around_here' to value '42'
Option 'a_very_long_option_name_that_will_need_to_be_ellipsized_around_here' not found
Error 'a_very_long_option_name_that_will_need_to_be_ellipsized_around_here=42'
+
+Testing av_opt_find2()
+OK 'num'
+OK 'child_num'
--
2.44.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [FFmpeg-devel] [PATCH 2/2] avutil/opt: add support for children objects in av_opt_serialize
2024-04-12 23:16 ` [FFmpeg-devel] [PATCH 2/2] avutil/opt: add support for children objects in av_opt_serialize James Almer
@ 2024-04-15 12:51 ` James Almer
2024-04-23 19:09 ` James Almer
0 siblings, 1 reply; 6+ messages in thread
From: James Almer @ 2024-04-15 12:51 UTC (permalink / raw)
To: ffmpeg-devel
On 4/12/2024 8:16 PM, James Almer wrote:
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
> libavutil/opt.c | 65 +++++++++++++++++++++++++++++--------------
> libavutil/opt.h | 1 +
> libavutil/tests/opt.c | 47 +++++++++++++++++++++++++++++--
> tests/ref/fate/opt | 2 +-
> 4 files changed, 90 insertions(+), 25 deletions(-)
Ping.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 6+ messages in thread
* [FFmpeg-devel] [PATCH 4/4] fftools/ffmpeg_mux_init: allow mapping a stream group from one of the inputs
2024-04-12 23:16 [FFmpeg-devel] [PATCH 1/2] avutil/test/opt: test the AV_OPT_SERIALIZE_SKIP_DEFAULTS flag James Almer
2024-04-12 23:16 ` [FFmpeg-devel] [PATCH 2/2] avutil/opt: add support for children objects in av_opt_serialize James Almer
2024-04-13 14:21 ` [FFmpeg-devel] [PATCH 3/3] avutil/tests/opt: test av_opt_find2() James Almer
@ 2024-04-15 15:09 ` James Almer
2 siblings, 0 replies; 6+ messages in thread
From: James Almer @ 2024-04-15 15:09 UTC (permalink / raw)
To: ffmpeg-devel
Do this by extending the -stream_group option to accept a map key where the
value selects the input file and stream group.
The can and should set the streams in the output that the copied group will
reference, same as they'd do if they created a group from scratch.
Example command line:
ffmpeg -i input.iamf -map 0 -c:a copy -f null -stream_group \
map=0=0:st=0:st=1:st=2:st=3 -stream_group map=0=1:st=0:st=1:st=2:st=3
Signed-off-by: James Almer <jamrial@gmail.com>
---
fftools/ffmpeg_mux_init.c | 154 +++++++++++++++++++++++++++++++++++++-
1 file changed, 152 insertions(+), 2 deletions(-)
diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c
index 6d8bd5bcdf..a46b0628d8 100644
--- a/fftools/ffmpeg_mux_init.c
+++ b/fftools/ffmpeg_mux_init.c
@@ -2232,11 +2232,137 @@ fail:
return ret;
}
+static int of_serialize_options(Muxer *mux, void *obj, AVBPrint *bp)
+{
+ char *ptr;
+ int ret;
+
+ ret = av_opt_serialize(obj, 0, AV_OPT_SERIALIZE_SKIP_DEFAULTS | AV_OPT_SERIALIZE_SEARCH_CHILDREN,
+ &ptr, '=', ':');
+ if (ret < 0) {
+ av_log(mux, AV_LOG_ERROR, "Failed to serialize group\n");
+ return ret;
+ }
+
+ av_bprintf(bp, "%s", ptr);
+ ret = strlen(ptr);
+ av_free(ptr);
+
+ return ret;
+}
+
+#define SERIALIZE(parent, child) do { \
+ ret = of_serialize_options(mux, parent->child, bp); \
+ if (ret < 0) \
+ return ret; \
+} while (0)
+
+#define SERIALIZE_LOOP(parent, child, suffix, separator) do { \
+ for (int j = 0; j < parent->nb_## child ## suffix; j++) { \
+ av_bprintf(bp, separator#child "="); \
+ SERIALIZE(parent, child ## suffix[j]); \
+ } \
+} while (0)
+
+static int64_t get_stream_group_index_from_id(Muxer *mux, int64_t id)
+{
+ AVFormatContext *oc = mux->fc;
+
+ for (unsigned i = 0; i < oc->nb_stream_groups; i++)
+ if (oc->stream_groups[i]->id == id)
+ return oc->stream_groups[i]->index;
+
+ return AVERROR(EINVAL);
+}
+
+static int of_map_group(Muxer *mux, AVDictionary **dict, AVBPrint *bp, const char *map)
+{
+ AVStreamGroup *stg;
+ int ret, file_idx, stream_idx;
+ char *ptr;
+
+ file_idx = strtol(map, &ptr, 0);
+ if (file_idx >= nb_input_files || file_idx < 0 || map == ptr) {
+ av_log(mux, AV_LOG_ERROR, "Invalid input file index: %d.\n", file_idx);
+ return AVERROR(EINVAL);
+ }
+
+ stream_idx = strtol(*ptr == '=' ? ptr + 1 : ptr, &ptr, 0);
+ if (*ptr || stream_idx >= input_files[file_idx]->ctx->nb_stream_groups || stream_idx < 0) {
+ av_log(mux, AV_LOG_ERROR, "Invalid input stream group index: %d.\n", stream_idx);
+ return AVERROR(EINVAL);
+ }
+
+ stg = input_files[file_idx]->ctx->stream_groups[stream_idx];
+ ret = of_serialize_options(mux, stg, bp);
+ if (ret < 0)
+ return ret;
+
+ ret = av_dict_parse_string(dict, bp->str, "=", ":", 0);
+ if (ret < 0)
+ av_log(mux, AV_LOG_ERROR, "Error parsing mapped group specification %s\n", ptr);
+ av_dict_set_int(dict, "type", stg->type, 0);
+
+ av_log(mux, AV_LOG_VERBOSE, "stg %s\n", bp->str);
+ av_bprint_clear(bp);
+ switch(stg->type) {
+ case AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT: {
+ AVIAMFAudioElement *audio_element = stg->params.iamf_audio_element;
+
+ if (audio_element->demixing_info) {
+ av_bprintf(bp, ",demixing=");
+ SERIALIZE(audio_element, demixing_info);
+ }
+ if (audio_element->recon_gain_info) {
+ av_bprintf(bp, ",recon_gain=");
+ SERIALIZE(audio_element, recon_gain_info);
+ }
+ SERIALIZE_LOOP(audio_element, layer, s, ",");
+ break;
+ }
+ case AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION: {
+ AVIAMFMixPresentation *mix = stg->params.iamf_mix_presentation;
+
+ for (int i = 0; i < mix->nb_submixes; i++) {
+ AVIAMFSubmix *submix = mix->submixes[i];
+
+ av_bprintf(bp, ",submix=");
+ SERIALIZE(mix, submixes[i]);
+ for (int j = 0; j < submix->nb_elements; j++) {
+ AVIAMFSubmixElement *element = submix->elements[j];
+ int64_t id = get_stream_group_index_from_id(mux, element->audio_element_id);
+
+ if (id < 0) {
+ av_log(mux, AV_LOG_ERROR, "Invalid or missing stream group index in"
+ "submix element");
+ return id;
+ }
+
+ av_bprintf(bp, "|element=");
+ SERIALIZE(submix, elements[j]);
+ if (ret)
+ av_bprintf(bp, ":");
+ av_bprintf(bp, "stg=%"PRId64, id);
+ }
+ SERIALIZE_LOOP(submix, layout, s, "|");
+ }
+ break;
+ }
+ default:
+ av_log(mux, AV_LOG_ERROR, "Unsupported mapped group type %d.\n", stg->type);
+ ret = AVERROR(EINVAL);
+ break;
+ }
+ av_log(mux, AV_LOG_VERBOSE, "extra %s\n", bp->str);
+ return 0;
+}
+
static int of_parse_group_token(Muxer *mux, const char *token, char *ptr)
{
AVFormatContext *oc = mux->fc;
AVStreamGroup *stg;
AVDictionary *dict = NULL, *tmp = NULL;
+ char *mapped_string = NULL;
const AVDictionaryEntry *e;
const AVOption opts[] = {
{ "type", "Set group type", offsetof(AVStreamGroup, type), AV_OPT_TYPE_INT,
@@ -2262,8 +2388,31 @@ static int of_parse_group_token(Muxer *mux, const char *token, char *ptr)
return ret;
}
+ av_dict_copy(&tmp, dict, 0);
+ e = av_dict_get(dict, "map", NULL, 0);
+ if (e) {
+ AVBPrint bp;
+
+ if (ptr) {
+ av_log(mux, AV_LOG_ERROR, "Unexpected extra parameters when mapping a"
+ " stream group\n");
+ ret = AVERROR(EINVAL);
+ goto end;
+ }
+
+ av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC);
+ ret = of_map_group(mux, &tmp, &bp, e->value);
+ if (ret < 0) {
+ av_bprint_finalize(&bp, NULL);
+ goto end;
+ }
+
+ av_bprint_finalize(&bp, &mapped_string);
+ ptr = mapped_string;
+ }
+
// "type" is not a user settable AVOption in AVStreamGroup, so handle it here
- e = av_dict_get(dict, "type", NULL, 0);
+ e = av_dict_get(tmp, "type", NULL, 0);
if (!e) {
av_log(mux, AV_LOG_ERROR, "No type specified for Stream Group in \"%s\"\n", token);
ret = AVERROR(EINVAL);
@@ -2278,7 +2427,6 @@ static int of_parse_group_token(Muxer *mux, const char *token, char *ptr)
goto end;
}
- av_dict_copy(&tmp, dict, 0);
stg = avformat_stream_group_create(oc, type, &tmp);
if (!stg) {
ret = AVERROR(ENOMEM);
@@ -2331,6 +2479,7 @@ static int of_parse_group_token(Muxer *mux, const char *token, char *ptr)
// make sure that nothing but "st" and "stg" entries are left in the dict
e = NULL;
+ av_dict_set(&tmp, "map", NULL, 0);
av_dict_set(&tmp, "type", NULL, 0);
while (e = av_dict_iterate(tmp, e)) {
if (!strcmp(e->key, "st") || !strcmp(e->key, "stg"))
@@ -2343,6 +2492,7 @@ static int of_parse_group_token(Muxer *mux, const char *token, char *ptr)
ret = 0;
end:
+ av_free(mapped_string);
av_dict_free(&dict);
av_dict_free(&tmp);
--
2.44.0
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [FFmpeg-devel] [PATCH 2/2] avutil/opt: add support for children objects in av_opt_serialize
2024-04-15 12:51 ` James Almer
@ 2024-04-23 19:09 ` James Almer
0 siblings, 0 replies; 6+ messages in thread
From: James Almer @ 2024-04-23 19:09 UTC (permalink / raw)
To: ffmpeg-devel
On 4/15/2024 9:51 AM, James Almer wrote:
> On 4/12/2024 8:16 PM, James Almer wrote:
>> Signed-off-by: James Almer <jamrial@gmail.com>
>> ---
>> libavutil/opt.c | 65 +++++++++++++++++++++++++++++--------------
>> libavutil/opt.h | 1 +
>> libavutil/tests/opt.c | 47 +++++++++++++++++++++++++++++--
>> tests/ref/fate/opt | 2 +-
>> 4 files changed, 90 insertions(+), 25 deletions(-)
>
> Ping.
Will apply the set (four patches).
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-04-23 19:09 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-12 23:16 [FFmpeg-devel] [PATCH 1/2] avutil/test/opt: test the AV_OPT_SERIALIZE_SKIP_DEFAULTS flag James Almer
2024-04-12 23:16 ` [FFmpeg-devel] [PATCH 2/2] avutil/opt: add support for children objects in av_opt_serialize James Almer
2024-04-15 12:51 ` James Almer
2024-04-23 19:09 ` James Almer
2024-04-13 14:21 ` [FFmpeg-devel] [PATCH 3/3] avutil/tests/opt: test av_opt_find2() James Almer
2024-04-15 15:09 ` [FFmpeg-devel] [PATCH 4/4] fftools/ffmpeg_mux_init: allow mapping a stream group from one of the inputs James Almer
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git