[FFmpeg-devel] [PATCH] Add programs to ffprobe
Stefano Sabatini
stefasab at gmail.com
Fri Jul 12 09:08:25 CEST 2013
On date Thursday 2013-07-11 11:29:01 +0200, Florent Tribouilloy encoded:
> Option -show_programs for ffprobe will sort the output by programs
>
> Signed-off-by: Florent Tribouilloy <florent.tribouilloy at smartjog.com>
> ---
> ffprobe.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 58 insertions(+), 5 deletions(-)
Missing doc/ffprobe.texi and ffprobe.xsd updates.
> diff --git a/ffprobe.c b/ffprobe.c
> index d4adde0..59daacc 100644
> --- a/ffprobe.c
> +++ b/ffprobe.c
> @@ -57,12 +57,16 @@ static int do_show_error = 0;
> static int do_show_format = 0;
> static int do_show_frames = 0;
> static int do_show_packets = 0;
> +static int do_show_programs = 0;
> static int do_show_streams = 0;
> static int do_show_stream_disposition = 0;
> static int do_show_data = 0;
> static int do_show_program_version = 0;
> static int do_show_library_versions = 0;
>
> +static int have_show_programs = 0;
> +static int have_show_streams = 0;
> +
> static int show_value_unit = 0;
> static int use_value_prefix = 0;
> static int use_byte_value_binary_prefix = 0;
> @@ -108,7 +112,9 @@ typedef enum {
> SECTION_ID_PACKET,
> SECTION_ID_PACKETS,
> SECTION_ID_PACKETS_AND_FRAMES,
> + SECTION_ID_PROGRAM,
> SECTION_ID_PROGRAM_VERSION,
> + SECTION_ID_PROGRAMS,
> SECTION_ID_ROOT,
> SECTION_ID_STREAM,
> SECTION_ID_STREAM_DISPOSITION,
> @@ -131,10 +137,12 @@ static struct section sections[] = {
> [SECTION_ID_PACKETS] = { SECTION_ID_PACKETS, "packets", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PACKET, -1} },
> [SECTION_ID_PACKETS_AND_FRAMES] = { SECTION_ID_PACKETS_AND_FRAMES, "packets_and_frames", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PACKET, -1} },
> [SECTION_ID_PACKET] = { SECTION_ID_PACKET, "packet", 0, { -1 } },
> + [SECTION_ID_PROGRAM] = { SECTION_ID_PROGRAM, "program", 0, { SECTION_ID_STREAM, -1 } },
> [SECTION_ID_PROGRAM_VERSION] = { SECTION_ID_PROGRAM_VERSION, "program_version", 0, { -1 } },
> + [SECTION_ID_PROGRAMS] = { SECTION_ID_PROGRAMS, "programs", SECTION_FLAG_IS_ARRAY, { SECTION_ID_PROGRAM, -1 } },
> [SECTION_ID_ROOT] = { SECTION_ID_ROOT, "root", SECTION_FLAG_IS_WRAPPER,
> - { SECTION_ID_CHAPTERS, SECTION_ID_FORMAT, SECTION_ID_FRAMES, SECTION_ID_STREAMS, SECTION_ID_PACKETS,
> - SECTION_ID_ERROR, SECTION_ID_PROGRAM_VERSION, SECTION_ID_LIBRARY_VERSIONS, -1} },
> + { SECTION_ID_CHAPTERS, SECTION_ID_FORMAT, SECTION_ID_FRAMES, SECTION_ID_PROGRAMS, SECTION_ID_STREAMS,
> + SECTION_ID_PACKETS, SECTION_ID_ERROR, SECTION_ID_PROGRAM_VERSION, SECTION_ID_LIBRARY_VERSIONS, -1} },
> [SECTION_ID_STREAMS] = { SECTION_ID_STREAMS, "streams", SECTION_FLAG_IS_ARRAY, { SECTION_ID_STREAM, -1 } },
> [SECTION_ID_STREAM] = { SECTION_ID_STREAM, "stream", 0, { SECTION_ID_STREAM_DISPOSITION, SECTION_ID_STREAM_TAGS, -1 } },
> [SECTION_ID_STREAM_DISPOSITION] = { SECTION_ID_STREAM_DISPOSITION, "disposition", 0, { -1 }, .unique_name = "stream_disposition" },
> @@ -1758,6 +1766,33 @@ static void show_streams(WriterContext *w, AVFormatContext *fmt_ctx)
> writer_print_section_footer(w);
> }
>
> +static void show_program(WriterContext *w, AVFormatContext *fmt_ctx, AVProgram *program)
> +{
> + int i;
> +
> + writer_print_section_header(w, SECTION_ID_PROGRAM);
> + print_int("program_id", program->id);
> + for (i = 0; i < program->nb_stream_indexes; i++) {
> + if (selected_streams[program->stream_index[i]])
> + show_stream(w, fmt_ctx, program->stream_index[i]);
> + }
I dislike reprinting entirely the stream section here. You can simply
print the corresponding stream ID. Also there are other fields which
are not shown here (for example metadata, program_num, etc...).
> + writer_print_section_footer(w);
> +}
> +
> +static void show_programs(WriterContext *w, AVFormatContext *fmt_ctx)
> +{
> + int i;
> +
> + writer_print_section_header(w, SECTION_ID_PROGRAMS);
> + for (i = 0; i < fmt_ctx->nb_programs; i++) {
> + AVProgram *program = fmt_ctx->programs[i];
> + if (!program)
> + continue;
Can this happen?
> + show_program(w, fmt_ctx, program);
> + }
> + writer_print_section_footer(w);
> +}
> +
> static void show_chapters(WriterContext *w, AVFormatContext *fmt_ctx)
> {
> int i;
> @@ -1787,6 +1822,7 @@ static void show_format(WriterContext *w, AVFormatContext *fmt_ctx)
> writer_print_section_header(w, SECTION_ID_FORMAT);
> print_str("filename", fmt_ctx->filename);
> print_int("nb_streams", fmt_ctx->nb_streams);
> + print_int("nb_programs", fmt_ctx->nb_programs);
> print_str("format_name", fmt_ctx->iformat->name);
> if (!do_bitexact) {
> if (fmt_ctx->iformat->long_name) print_str ("format_long_name", fmt_ctx->iformat->long_name);
> @@ -1940,7 +1976,9 @@ static int probe_file(WriterContext *wctx, const char *filename)
> if (do_show_frames || do_show_packets)
> writer_print_section_footer(wctx);
> }
> - if (do_show_streams)
> + if (do_show_programs && have_show_programs)
> + show_programs(wctx, fmt_ctx);
> + if (do_show_streams && have_show_streams)
> show_streams(wctx, fmt_ctx);
> if (do_show_chapters)
> show_chapters(wctx, fmt_ctx);
> @@ -2191,6 +2229,20 @@ static int opt_show_versions(const char *opt, const char *arg)
> return 0;
> }
>
> +static int opt_show_programs(const char *opt, const char *arg)
> +{
> + have_show_programs = 1;
> + mark_section_show_entries(SECTION_ID_PROGRAMS, 1, NULL);
> + return 0;
> +}
> +
> +static int opt_show_streams(const char *opt, const char *arg)
> +{
> + have_show_streams = 1;
> + mark_section_show_entries(SECTION_ID_STREAMS, 1, NULL);
> + return 0;
> +}
> +
why this?
> #define DEFINE_OPT_SHOW_SECTION(section, target_section_id) \
> static int opt_show_##section(const char *opt, const char *arg) \
> { \
> @@ -2205,7 +2257,6 @@ DEFINE_OPT_SHOW_SECTION(frames, FRAMES);
> DEFINE_OPT_SHOW_SECTION(library_versions, LIBRARY_VERSIONS);
> DEFINE_OPT_SHOW_SECTION(packets, PACKETS);
> DEFINE_OPT_SHOW_SECTION(program_version, PROGRAM_VERSION);
> -DEFINE_OPT_SHOW_SECTION(streams, STREAMS);
[...]
--
FFmpeg = Faithful and Foolish Meaningless Pitiless Educated Gladiator
More information about the ffmpeg-devel
mailing list