[FFmpeg-devel] [PATCH] ffprobe: add "-show sections" option.
Stefano Sabatini
stefasab at gmail.com
Sun Jan 12 10:59:19 CET 2014
On date Saturday 2014-01-11 12:50:58 +0100, Nicolas George encoded:
> This syntax is more concise than the various -show_* options
> and furthermore allows to control the order of the sections.
>
> Signed-off-by: Nicolas George <george at nsup.org>
> ---
> doc/ffprobe.texi | 23 +++++++++
> ffprobe.c | 154 ++++++++++++++++++++++++++++++++++++++++++-------------
> 2 files changed, 141 insertions(+), 36 deletions(-)
>
>
> I have to reasons for proposing this patch:
>
> * There is a project I have that that needs the format and streams sections
> before the packets, and -show format,streams,packets instead of -show
> packets,streams,format seems like a convenient enough way of allowing it.
>
> * As a user, I have found the interaction between the various -show_*
> options and the -show_entries option rather confusing. Merging everything
> into a single option with a short name and a logical syntax looks like a
> good idea. But this is nit yet done.
-show_entries enables to specify which branches to show, or which
entries to show in a given section. -show_XXX is the equivalent of
-enable_entries=XXX, but can only be used for first level sections.
In short, -enable_entries could be used instead of -show_XXX but was
retained for backward compatibility and convenience.
> diff --git a/doc/ffprobe.texi b/doc/ffprobe.texi
> index 8de8956..7cdec46 100644
> --- a/doc/ffprobe.texi
> +++ b/doc/ffprobe.texi
> @@ -124,6 +124,29 @@ Show information about the error found when trying to probe the input.
>
> The error information is printed within a section with name "ERROR".
>
> + at item -show @var{sections}
> +Enable showing various informational sections about the file;
> + at var{sections} is a comma-separated list of section names chosen in the
> +following list:
> + at code{format},
> + at code{programs},
> + at code{streams},
> + at code{chapters},
> + at code{packets},
> + at code{frames},
> + at code{packets_and_frames}.
> +Section names can be abbreviated provided the prefix is unambiguous; since
> +new sections can be added later, the prefixes are not guaranteed to stay
> +unambiguous.
> +
> +The sections are printed in the given order. It can make a difference for
> +files with streams reconfiguration: printing the format and streams sections
> +before reading the packets or frame will show information about the
> +beginning of the file while printing them after will show information about
> +the end of the file. Sections can be printed several times, but will not
> +cause the file to be re-read, so printing frames or packets twice will
> +result mostly in empty output.
How is that different from -show_entries format:programs:frames? Did
you consider to extend the -show_entries option? This would avoid two
different options with slightly different semantics.
> +
> @item -show_format
> Show information about the container format of the input multimedia
> stream.
> diff --git a/ffprobe.c b/ffprobe.c
> index ef3bcc6..193c411 100644
> --- a/ffprobe.c
> +++ b/ffprobe.c
> @@ -78,6 +78,8 @@ static int use_byte_value_binary_prefix = 0;
> static int use_value_sexagesimal_format = 0;
> static int show_private_data = 1;
>
> +static char *opt_show;
> +
> static char *print_format;
> static char *stream_specifier;
>
> @@ -195,6 +197,9 @@ static uint64_t *nb_streams_packets;
> static uint64_t *nb_streams_frames;
> static int *selected_streams;
>
> +static SectionID do_show[SECTION_MAX_NB_CHILDREN * 5];
> +static unsigned do_show_nb = 0;
> +
> static void ffprobe_cleanup(int ret)
> {
> int i;
> @@ -2351,14 +2356,34 @@ static void close_input_file(AVFormatContext **ctx_ptr)
> avformat_close_input(ctx_ptr);
> }
>
> +static inline int check_section_show_entries(int section_id);
> +static inline void mark_section_show_entries(SectionID section_id,
> + int show_all_entries, AVDictionary *entries);
> +
> +static int show_packets_and_frames(WriterContext *wctx, AVFormatContext *fmt_ctx,
> + SectionID section_id)
> +{
> + int ret;
> +
> + do_show_packets = section_id == SECTION_ID_PACKETS_AND_FRAMES || section_id == SECTION_ID_PACKETS;
> + do_show_frames = section_id == SECTION_ID_PACKETS_AND_FRAMES || section_id == SECTION_ID_FRAMES;
> + do_read_frames = do_show_frames || do_count_frames;
> + do_read_packets = do_show_packets || do_count_packets;
> +
> + if (do_show_frames || do_show_packets)
> + writer_print_section_header(wctx, section_id);
> + ret = read_packets(wctx, fmt_ctx);
> + if (do_show_frames || do_show_packets)
> + writer_print_section_footer(wctx);
> + return ret;
> +}
> +
> static int probe_file(WriterContext *wctx, const char *filename)
> {
> AVFormatContext *fmt_ctx;
> int ret, i;
> int section_id;
> -
> - do_read_frames = do_show_frames || do_count_frames;
> - do_read_packets = do_show_packets || do_count_packets;
> + struct section *sec;
>
> ret = open_input_file(&fmt_ctx, filename);
> if (ret < 0)
> @@ -2384,38 +2409,38 @@ static int probe_file(WriterContext *wctx, const char *filename)
> }
> }
>
> - if (do_read_frames || do_read_packets) {
> - if (do_show_frames && do_show_packets &&
> - wctx->writer->flags & WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER)
> - section_id = SECTION_ID_PACKETS_AND_FRAMES;
> - else if (do_show_packets && !do_show_frames)
> - section_id = SECTION_ID_PACKETS;
> - else // (!do_show_packets && do_show_frames)
> - section_id = SECTION_ID_FRAMES;
> - if (do_show_frames || do_show_packets)
> - writer_print_section_header(wctx, section_id);
> - ret = read_packets(wctx, fmt_ctx);
> - if (do_show_frames || do_show_packets)
> - writer_print_section_footer(wctx);
> - CHECK_END;
> - }
> -
> - if (do_show_programs) {
> - ret = show_programs(wctx, fmt_ctx);
> - CHECK_END;
> - }
> -
> - if (do_show_streams) {
> - ret = show_streams(wctx, fmt_ctx);
> - CHECK_END;
> - }
> - if (do_show_chapters) {
> - ret = show_chapters(wctx, fmt_ctx);
> - CHECK_END;
> - }
> - if (do_show_format) {
> - ret = show_format(wctx, fmt_ctx);
> - CHECK_END;
> + for (i = 0; i < do_show_nb; i++) {
> + section_id = do_show[i];
> + sec = §ions[section_id];
> + if (!check_section_show_entries(section_id))
> + mark_section_show_entries(section_id, 1, NULL);
> + switch (section_id) {
> + case SECTION_ID_FORMAT:
> + ret = show_format(wctx, fmt_ctx);
> + break;
> + case SECTION_ID_PROGRAMS:
> + ret = show_programs(wctx, fmt_ctx);
> + break;
> + case SECTION_ID_STREAMS:
> + ret = show_streams(wctx, fmt_ctx);
> + break;
> + case SECTION_ID_CHAPTERS:
> + ret = show_chapters(wctx, fmt_ctx);
> + break;
> + case SECTION_ID_PACKETS:
> + case SECTION_ID_FRAMES:
> + case SECTION_ID_PACKETS_AND_FRAMES:
> + case -SECTION_ID_PACKETS_AND_FRAMES:
> + ret = show_packets_and_frames(wctx, fmt_ctx, section_id);
> + break;
> + default:
> + av_log(NULL, AV_LOG_ERROR, "Unknown section to show: %s\n",
> + sec->name);
> + ret = AVERROR(EINVAL);
> + break;
> + }
Possibly more general: we set the function with signature
int show_section(wctx, fmt_ctx, section_id) in the section definition,
and call the function if it is defined. This will work only for first
level sections.
[...]
--
FFmpeg = Fostering and Freak Majestic Peaceful EniGma
More information about the ffmpeg-devel
mailing list