[FFmpeg-cvslog] fftools/ffmpeg_mux_init: improve of_add_programs()
Anton Khirnov
git at videolan.org
Sat Jul 15 12:03:00 EEST 2023
ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Wed Jul 12 17:58:53 2023 +0200| [dd44871eb9c696db8d95a89918cfa2a3a556d4db] | committer: Anton Khirnov
fftools/ffmpeg_mux_init: improve of_add_programs()
Replace duplicated(!) and broken* custom string parsing with
av_dict_parse_string(). Return error codes instead of aborting.
* e.g. it treats NULL returned from av_get_token() as "separator not
found", when in fact av_get_token() only returns NULL on memory
allocation failure
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=dd44871eb9c696db8d95a89918cfa2a3a556d4db
---
fftools/ffmpeg_mux_init.c | 105 ++++++++++++++++++++++------------------------
1 file changed, 49 insertions(+), 56 deletions(-)
diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c
index 3a327048bb..b0befb8924 100644
--- a/fftools/ffmpeg_mux_init.c
+++ b/fftools/ffmpeg_mux_init.c
@@ -1782,76 +1782,66 @@ static int setup_sync_queues(Muxer *mux, AVFormatContext *oc, int64_t buf_size_u
return 0;
}
-static void of_add_programs(Muxer *mux, const OptionsContext *o)
+static int of_add_programs(Muxer *mux, const OptionsContext *o)
{
AVFormatContext *oc = mux->fc;
/* process manually set programs */
for (int i = 0; i < o->nb_program; i++) {
- const char *p = o->program[i].u.str;
- int progid = i+1;
+ AVDictionary *dict = NULL;
+ const AVDictionaryEntry *e;
AVProgram *program;
+ int ret, progid = i + 1;
- while(*p) {
- const char *p2 = av_get_token(&p, ":");
- const char *to_dealloc = p2;
- char *key;
- if (!p2)
- break;
+ ret = av_dict_parse_string(&dict, o->program[i].u.str, "=", ":",
+ AV_DICT_MULTIKEY);
+ if (ret < 0) {
+ av_log(mux, AV_LOG_ERROR, "Error parsing program specification %s\n",
+ o->program[i].u.str);
+ return ret;
+ }
- if(*p) p++;
+ e = av_dict_get(dict, "program_num", NULL, 0);
+ if (e) {
+ progid = strtol(e->value, NULL, 0);
+ av_dict_set(&dict, e->key, NULL, 0);
+ }
- key = av_get_token(&p2, "=");
- if (!key || !*p2) {
- av_freep(&to_dealloc);
- av_freep(&key);
- break;
- }
- p2++;
+ program = av_new_program(oc, progid);
+ if (!program) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
- if (!strcmp(key, "program_num"))
- progid = strtol(p2, NULL, 0);
- av_freep(&to_dealloc);
- av_freep(&key);
+ e = av_dict_get(dict, "title", NULL, 0);
+ if (e) {
+ av_dict_set(&program->metadata, e->key, e->value, 0);
+ av_dict_set(&dict, e->key, NULL, 0);
}
- program = av_new_program(oc, progid);
- if (!program)
- report_and_exit(AVERROR(ENOMEM));
+ e = NULL;
+ while (e = av_dict_get(dict, "st", e, 0)) {
+ int st_num = strtol(e->value, NULL, 0);
+ av_program_add_stream_index(oc, progid, st_num);
+ }
- p = o->program[i].u.str;
- while(*p) {
- const char *p2 = av_get_token(&p, ":");
- const char *to_dealloc = p2;
- char *key;
- if (!p2)
- break;
- if(*p) p++;
+ // make sure that nothing but "st" entries are left in the dict
+ e = NULL;
+ while (e = av_dict_iterate(dict, e)) {
+ if (!strcmp(e->key, "st"))
+ continue;
- key = av_get_token(&p2, "=");
- if (!key) {
- av_log(mux, AV_LOG_FATAL,
- "No '=' character in program string %s.\n",
- p2);
- exit_program(1);
- }
- if (!*p2)
- exit_program(1);
- p2++;
-
- if (!strcmp(key, "title")) {
- av_dict_set(&program->metadata, "title", p2, 0);
- } else if (!strcmp(key, "program_num")) {
- } else if (!strcmp(key, "st")) {
- int st_num = strtol(p2, NULL, 0);
- av_program_add_stream_index(oc, progid, st_num);
- } else {
- av_log(mux, AV_LOG_FATAL, "Unknown program key %s.\n", key);
- exit_program(1);
- }
- av_freep(&to_dealloc);
- av_freep(&key);
+ av_log(mux, AV_LOG_FATAL, "Unknown program key %s.\n", e->key);
+ ret = AVERROR(EINVAL);
+ goto fail;
}
+
+fail:
+ av_dict_free(&dict);
+ if (ret < 0)
+ return ret;
}
+
+ return 0;
}
/**
@@ -2547,7 +2537,10 @@ int of_open(const OptionsContext *o, const char *filename)
if (err < 0)
return err;
- of_add_programs(mux, o);
+ err = of_add_programs(mux, o);
+ if (err < 0)
+ return err;
+
of_add_metadata(of, oc, o);
err = set_dispositions(mux, o);
More information about the ffmpeg-cvslog
mailing list