They are probably not valid for the resulting file. They look like this: BPS : 40665 BPS-eng : 40665 DURATION : 00:00:20.000000000 DURATION-eng : 00:00:20.000000000 NUMBER_OF_FRAMES: 10 NUMBER_OF_FRAMES-eng: 10 NUMBER_OF_BYTES : 101664 NUMBER_OF_BYTES-eng: 101664 _STATISTICS_WRITING_APP: mkvmerge v9.8.0 ('Kuglblids') 64bit _STATISTICS_WRITING_APP-eng: mkvmerge v9.8.0 ('Kuglblids') 64bit _STATISTICS_WRITING_DATE_UTC: 2017-04-06 08:22:08 _STATISTICS_WRITING_DATE_UTC-eng: 2017-04-06 08:22:08 _STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
Signed-off-by: Nicolas George <geo...@nsup.org> --- ffmpeg_opt.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) Note: as written in a comment, this code ignores the return value of av_dict_set(), because the surrounding code ignores the return value of av_dict_copy(). A lot of unchecked errors happen in this function, but I am not reworking a 2700-lines function today. diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c index d1fe8742ff..f72f38796a 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -497,6 +497,53 @@ static void parse_meta_type(char *arg, char *type, int *index, const char **stre *type = 'g'; } +/** + * Copy a dictionary except the stats metadata added by mkvmerge. + * They are probably not valid for the resulting file. + * + * FIXME Return values are ignored by the surrounding code and here. + */ +static void dict_copy_nostats(AVDictionary **dst, const AVDictionary *src) +{ + AVDictionaryEntry *t; + const char *tags = NULL, *p, *q; + size_t len; + + t = av_dict_get(src, "_STATISTICS_TAGS", NULL, AV_DICT_MATCH_CASE); + if (t) + tags = t->value; + t = NULL; + while ((t = av_dict_get(src, "", t, AV_DICT_IGNORE_SUFFIX))) { + if (av_strstart(t->key, "_STATISTICS_", NULL)) + continue; + if (tags) { + /* tags is a space-separated list of stats tags */ + p = tags; + while (*p) { + q = strchr(p, ' '); + len = q ? q - p : strlen(p); + if (!q) + q = p + strlen(p); +#define ff_islower(c) ((unsigned)((c) - 'a') < 26) + if (!memcmp(t->key, p, len) && + (!t->key[len] || + /* also remove TAG-lng */ + (t->key[len] == '-' && + ff_islower(t->key[len + 1]) && + ff_islower(t->key[len + 2]) && + ff_islower(t->key[len + 3]) && + !t->key[len + 4]))) + break; +#undef ff_islower + for (p += len; *p == ' '; p++); + } + if (*p) /* match found => do not copy */ + continue; + } + av_dict_set(dst, t->key, t->value, AV_DICT_DONT_OVERWRITE); + } +} + static int copy_metadata(char *outspec, char *inspec, AVFormatContext *oc, AVFormatContext *ic, OptionsContext *o) { AVDictionary **meta_in = NULL; @@ -2546,7 +2593,7 @@ loop_end: if (output_streams[i]->source_index < 0) /* this is true e.g. for attached files */ continue; ist = input_streams[output_streams[i]->source_index]; - av_dict_copy(&output_streams[i]->st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE); + dict_copy_nostats(&output_streams[i]->st->metadata, ist->st->metadata); if (!output_streams[i]->stream_copy) { av_dict_set(&output_streams[i]->st->metadata, "encoder", NULL, 0); } -- 2.11.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel