Browse code

ffprobe: add -select_streams option

Stefano Sabatini authored on 2012/10/05 00:38:43
Showing 3 changed files
... ...
@@ -5,6 +5,7 @@ version next:
5 5
 - stream disposition information printing in ffprobe
6 6
 - filter for loudness analysis following EBU R128
7 7
 - Opus encoder using libopus
8
+- ffprobe -select_streams option
8 9
 
9 10
 
10 11
 version 1.0:
... ...
@@ -94,6 +94,21 @@ For example for printing the output in JSON format, specify:
94 94
 For more details on the available output printing formats, see the
95 95
 Writers section below.
96 96
 
97
+@item -select_streams @var{stream_specifier}
98
+Select only the streams specified by @var{stream_specifier}. This
99
+option affects only the options related to streams
100
+(e.g. @code{show_streams}, @code{show_packets}, etc.).
101
+
102
+For example to show only audio streams, you can use the command:
103
+@example
104
+ffprobe -show_streams -select_streams a INPUT
105
+@end example
106
+
107
+To show only video packets belonging to the video stream with index 1:
108
+@example
109
+ffprobe -show_packets -select_streams v:1 INPUT
110
+@end example
111
+
97 112
 @item -show_data
98 113
 Show payload data, as an hexadecimal and ASCII dump. Coupled with
99 114
 @option{-show_packets}, it will dump the packets' data. Coupled with
... ...
@@ -69,6 +69,7 @@ static int use_value_sexagesimal_format = 0;
69 69
 static int show_private_data            = 1;
70 70
 
71 71
 static char *print_format;
72
+static char *stream_specifier;
72 73
 
73 74
 /* section structure definition */
74 75
 
... ...
@@ -138,8 +139,10 @@ static const char unit_second_str[]         = "s"    ;
138 138
 static const char unit_hertz_str[]          = "Hz"   ;
139 139
 static const char unit_byte_str[]           = "byte" ;
140 140
 static const char unit_bit_per_second_str[] = "bit/s";
141
+
141 142
 static uint64_t *nb_streams_packets;
142 143
 static uint64_t *nb_streams_frames;
144
+static int *selected_streams;
143 145
 
144 146
 static void exit_program(void)
145 147
 {
... ...
@@ -1614,6 +1617,7 @@ static void read_packets(WriterContext *w, AVFormatContext *fmt_ctx)
1614 1614
     av_init_packet(&pkt);
1615 1615
 
1616 1616
     while (!av_read_frame(fmt_ctx, &pkt)) {
1617
+        if (selected_streams[pkt.stream_index]) {
1617 1618
         if (do_read_packets) {
1618 1619
             if (do_show_packets)
1619 1620
                 show_packet(w, fmt_ctx, &pkt, i++);
... ...
@@ -1623,6 +1627,7 @@ static void read_packets(WriterContext *w, AVFormatContext *fmt_ctx)
1623 1623
             pkt1 = pkt;
1624 1624
             while (pkt1.size && process_frame(w, fmt_ctx, &frame, &pkt1) > 0);
1625 1625
         }
1626
+        }
1626 1627
         av_free_packet(&pkt);
1627 1628
     }
1628 1629
     av_init_packet(&pkt);
... ...
@@ -1789,7 +1794,8 @@ static void show_streams(WriterContext *w, AVFormatContext *fmt_ctx)
1789 1789
     int i;
1790 1790
     writer_print_section_header(w, SECTION_ID_STREAMS);
1791 1791
     for (i = 0; i < fmt_ctx->nb_streams; i++)
1792
-        show_stream(w, fmt_ctx, i);
1792
+        if (selected_streams[i])
1793
+            show_stream(w, fmt_ctx, i);
1793 1794
     writer_print_section_footer(w);
1794 1795
 }
1795 1796
 
... ...
@@ -1896,7 +1902,7 @@ static void close_input_file(AVFormatContext **ctx_ptr)
1896 1896
 static int probe_file(WriterContext *wctx, const char *filename)
1897 1897
 {
1898 1898
     AVFormatContext *fmt_ctx;
1899
-    int ret;
1899
+    int ret, i;
1900 1900
     int section_id;
1901 1901
 
1902 1902
     do_read_frames = do_show_frames || do_count_frames;
... ...
@@ -1906,6 +1912,22 @@ static int probe_file(WriterContext *wctx, const char *filename)
1906 1906
     if (ret >= 0) {
1907 1907
         nb_streams_frames  = av_calloc(fmt_ctx->nb_streams, sizeof(*nb_streams_frames));
1908 1908
         nb_streams_packets = av_calloc(fmt_ctx->nb_streams, sizeof(*nb_streams_packets));
1909
+        selected_streams   = av_calloc(fmt_ctx->nb_streams, sizeof(*selected_streams));
1910
+
1911
+        for (i = 0; i < fmt_ctx->nb_streams; i++) {
1912
+            if (stream_specifier) {
1913
+                ret = avformat_match_stream_specifier(fmt_ctx,
1914
+                                                      fmt_ctx->streams[i],
1915
+                                                      stream_specifier);
1916
+                if (ret < 0)
1917
+                    goto end;
1918
+                else
1919
+                    selected_streams[i] = ret;
1920
+            } else {
1921
+                selected_streams[i] = 1;
1922
+            }
1923
+        }
1924
+
1909 1925
         if (do_read_frames || do_read_packets) {
1910 1926
             if (do_show_frames && do_show_packets &&
1911 1927
                 wctx->writer->flags & WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER)
... ...
@@ -1925,9 +1947,11 @@ static int probe_file(WriterContext *wctx, const char *filename)
1925 1925
         if (do_show_format)
1926 1926
             show_format(wctx, fmt_ctx);
1927 1927
 
1928
+    end:
1928 1929
         close_input_file(&fmt_ctx);
1929 1930
         av_freep(&nb_streams_frames);
1930 1931
         av_freep(&nb_streams_packets);
1932
+        av_freep(&selected_streams);
1931 1933
     }
1932 1934
     return ret;
1933 1935
 }
... ...
@@ -2062,6 +2086,7 @@ static const OptionDef real_options[] = {
2062 2062
     { "print_format", OPT_STRING | HAS_ARG, {(void*)&print_format},
2063 2063
       "set the output printing format (available formats are: default, compact, csv, flat, ini, json, xml)", "format" },
2064 2064
     { "of", OPT_STRING | HAS_ARG, {(void*)&print_format}, "alias for -print_format", "format" },
2065
+    { "select_streams", OPT_STRING | HAS_ARG, {(void*)&stream_specifier}, "select the specified streams", "stream_specifier" },
2065 2066
     { "show_data",    OPT_BOOL, {(void*)&do_show_data}, "show packets data" },
2066 2067
     { "show_error",   OPT_BOOL, {(void*)&do_show_error} ,  "show probing error" },
2067 2068
     { "show_format",  OPT_BOOL, {&do_show_format} , "show format/container info" },