diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c index 35f786dba5..e906d4506d 100644 --- a/fftools/cmdutils.c +++ b/fftools/cmdutils.c @@ -1613,3 +1613,28 @@ int check_avoptions(AVDictionary *m) return 0; } + +void dump_dictionary(void *ctx, const AVDictionary *m, + const char *name, const char *indent, + int log_level) +{ + const AVDictionaryEntry *tag = NULL; + + if (!m) + return; + + av_log(ctx, log_level, "%s%s:\n", indent, name); + while ((tag = av_dict_iterate(m, tag))) { + const char *p = tag->value; + av_log(ctx, log_level, "%s %-16s: ", indent, tag->key); + while (*p) { + size_t len = strcspn(p, "\x8\xa\xb\xc\xd"); + av_log(ctx, log_level, "%.*s", (int)(FFMIN(255, len)), p); + p += len; + if (*p == 0xd) av_log(ctx, log_level, " "); + if (*p == 0xa) av_log(ctx, log_level, "\n%s %-16s: ", indent, ""); + if (*p) p++; + } + av_log(ctx, log_level, "\n"); + } +} diff --git a/fftools/cmdutils.h b/fftools/cmdutils.h index 93e05c7130..85b468f2af 100644 --- a/fftools/cmdutils.h +++ b/fftools/cmdutils.h @@ -549,4 +549,12 @@ int check_avoptions(AVDictionary *m); int cmdutils_isalnum(char c); +/** + * This does the same as libavformat/dump.c corresponding function + * and should probably be kept in sync when the other one changes. + */ +void dump_dictionary(void *ctx, const AVDictionary *m, + const char *name, const char *indent, + int log_level); + #endif /* FFTOOLS_CMDUTILS_H */ diff --git a/fftools/ffplay.c b/fftools/ffplay.c index dc2627521e..dcd20e70bc 100644 --- a/fftools/ffplay.c +++ b/fftools/ffplay.c @@ -2843,6 +2843,7 @@ static int read_thread(void *arg) int st_index[AVMEDIA_TYPE_NB]; AVPacket *pkt = NULL; int64_t stream_start_time; + char metadata_description[96]; int pkt_in_play_range = 0; const AVDictionaryEntry *t; SDL_mutex *wait_mutex = SDL_CreateMutex(); @@ -2950,8 +2951,10 @@ static int read_thread(void *arg) is->realtime = is_realtime(ic); - if (show_status) + if (show_status) { + fprintf(stderr, "\x1b[2K\r"); av_dump_format(ic, 0, is->filename, 0); + } for (i = 0; i < ic->nb_streams; i++) { AVStream *st = ic->streams[i]; @@ -2960,6 +2963,9 @@ static int read_thread(void *arg) if (type >= 0 && wanted_stream_spec[type] && st_index[type] == -1) if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0) st_index[type] = i; + // Clear all pre-existing metadata update flags to avoid printing + // initial metadata as update. + st->event_flags &= ~AVSTREAM_EVENT_FLAG_METADATA_UPDATED; } for (i = 0; i < AVMEDIA_TYPE_NB; i++) { if (wanted_stream_spec[i] && st_index[i] == -1) { @@ -3128,6 +3134,19 @@ static int read_thread(void *arg) } else { is->eof = 0; } + + if (show_status && ic->streams[pkt->stream_index]->event_flags & + AVSTREAM_EVENT_FLAG_METADATA_UPDATED) { + fprintf(stderr, "\x1b[2K\r"); + snprintf(metadata_description, + sizeof(metadata_description), + "\r New metadata for stream %d", + pkt->stream_index); + dump_dictionary(NULL, ic->streams[pkt->stream_index]->metadata, + metadata_description, " ", AV_LOG_INFO); + } + ic->streams[pkt->stream_index]->event_flags &= ~AVSTREAM_EVENT_FLAG_METADATA_UPDATED; + /* check if packet is in play range specified by user, then queue, otherwise discard */ stream_start_time = ic->streams[pkt->stream_index]->start_time; pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;