Browse code

ffprobe: add -show_data_hash option.

Nicolas George authored on 2014/04/22 00:49:33
Showing 3 changed files
... ...
@@ -119,6 +119,10 @@ Show payload data, as a hexadecimal and ASCII dump. Coupled with
119 119
 
120 120
 The dump is printed as the "data" field. It may contain newlines.
121 121
 
122
+@item -show_data_hash @var{algorithm}
123
+Show a hash of payload data, for packets with @option{-show_packets} and for
124
+codec extradata with @option{-show_streams}.
125
+
122 126
 @item -show_error
123 127
 Show information about the error found when trying to probe the input.
124 128
 
... ...
@@ -50,6 +50,7 @@
50 50
       <xsd:attribute name="pos"           type="xsd:long"  />
51 51
       <xsd:attribute name="flags"         type="xsd:string" use="required" />
52 52
       <xsd:attribute name="data"          type="xsd:string" />
53
+      <xsd:attribute name="data_hash"     type="xsd:string" />
53 54
     </xsd:complexType>
54 55
 
55 56
     <xsd:complexType name="frameType">
... ...
@@ -153,6 +154,7 @@
153 153
       <xsd:attribute name="codec_tag"        type="xsd:string" use="required"/>
154 154
       <xsd:attribute name="codec_tag_string" type="xsd:string" use="required"/>
155 155
       <xsd:attribute name="extradata"        type="xsd:string" />
156
+      <xsd:attribute name="extradata_hash"   type="xsd:string" />
156 157
 
157 158
       <!-- video attributes -->
158 159
       <xsd:attribute name="width"                type="xsd:int"/>
... ...
@@ -33,6 +33,7 @@
33 33
 #include "libavutil/avassert.h"
34 34
 #include "libavutil/avstring.h"
35 35
 #include "libavutil/bprint.h"
36
+#include "libavutil/hash.h"
36 37
 #include "libavutil/opt.h"
37 38
 #include "libavutil/pixdesc.h"
38 39
 #include "libavutil/dict.h"
... ...
@@ -80,6 +81,7 @@ static int show_private_data            = 1;
80 80
 
81 81
 static char *print_format;
82 82
 static char *stream_specifier;
83
+static char *show_data_hash;
83 84
 
84 85
 typedef struct {
85 86
     int id;             ///< identifier
... ...
@@ -187,6 +189,8 @@ static const OptionDef *options;
187 187
 static const char *input_filename;
188 188
 static AVInputFormat *iformat = NULL;
189 189
 
190
+static struct AVHashContext *hash;
191
+
190 192
 static const char *const binary_unit_prefixes [] = { "", "Ki", "Mi", "Gi", "Ti", "Pi" };
191 193
 static const char *const decimal_unit_prefixes[] = { "", "K" , "M" , "G" , "T" , "P"  };
192 194
 
... ...
@@ -685,6 +689,21 @@ static void writer_print_data(WriterContext *wctx, const char *name,
685 685
     av_bprint_finalize(&bp, NULL);
686 686
 }
687 687
 
688
+static void writer_print_data_hash(WriterContext *wctx, const char *name,
689
+                                   uint8_t *data, int size)
690
+{
691
+    char *p, buf[AV_HASH_MAX_SIZE * 2 + 64] = { 0 };
692
+
693
+    if (!hash)
694
+        return;
695
+    av_hash_init(hash);
696
+    av_hash_update(hash, data, size);
697
+    snprintf(buf, sizeof(buf), "%s:", av_hash_get_name(hash));
698
+    p = buf + strlen(buf);
699
+    av_hash_final_hex(hash, p, buf + sizeof(buf) - p);
700
+    writer_print_string(wctx, name, buf, 0);
701
+}
702
+
688 703
 #define MAX_REGISTERED_WRITERS_NB 64
689 704
 
690 705
 static const Writer *registered_writers[MAX_REGISTERED_WRITERS_NB + 1];
... ...
@@ -1692,6 +1711,7 @@ static void show_packet(WriterContext *w, AVFormatContext *fmt_ctx, AVPacket *pk
1692 1692
     print_fmt("flags", "%c",      pkt->flags & AV_PKT_FLAG_KEY ? 'K' : '_');
1693 1693
     if (do_show_data)
1694 1694
         writer_print_data(w, "data", pkt->data, pkt->size);
1695
+    writer_print_data_hash(w, "data_hash", pkt->data, pkt->size);
1695 1696
     writer_print_section_footer(w);
1696 1697
 
1697 1698
     av_bprint_finalize(&pbuf, NULL);
... ...
@@ -2159,6 +2179,8 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id
2159 2159
     if (do_show_data)
2160 2160
         writer_print_data(w, "extradata", dec_ctx->extradata,
2161 2161
                                           dec_ctx->extradata_size);
2162
+    writer_print_data_hash(w, "extradata_hash", dec_ctx->extradata,
2163
+                                                dec_ctx->extradata_size);
2162 2164
 
2163 2165
     /* Print disposition information */
2164 2166
 #define PRINT_DISPOSITION(flagname, name) do {                                \
... ...
@@ -2887,6 +2909,7 @@ static const OptionDef real_options[] = {
2887 2887
     { "select_streams", OPT_STRING | HAS_ARG, {(void*)&stream_specifier}, "select the specified streams", "stream_specifier" },
2888 2888
     { "sections", OPT_EXIT, {.func_arg = opt_sections}, "print sections structure and section information, and exit" },
2889 2889
     { "show_data",    OPT_BOOL, {(void*)&do_show_data}, "show packets data" },
2890
+    { "show_data_hash", OPT_STRING | HAS_ARG, {(void*)&show_data_hash}, "show packets data hash" },
2890 2891
     { "show_error",   0, {(void*)&opt_show_error},  "show probing error" },
2891 2892
     { "show_format",  0, {(void*)&opt_show_format}, "show format/container info" },
2892 2893
     { "show_frames",  0, {(void*)&opt_show_frames}, "show frames info" },
... ...
@@ -2990,6 +3013,21 @@ int main(int argc, char **argv)
2990 2990
     w_name = av_strtok(print_format, "=", &buf);
2991 2991
     w_args = buf;
2992 2992
 
2993
+    if (show_data_hash) {
2994
+        if ((ret = av_hash_alloc(&hash, show_data_hash)) < 0) {
2995
+            if (ret == AVERROR(EINVAL)) {
2996
+                const char *n;
2997
+                av_log(NULL, AV_LOG_ERROR,
2998
+                       "Unknown hash algorithm '%s'\nKnown algorithms:",
2999
+                       show_data_hash);
3000
+                for (i = 0; (n = av_hash_names(i)); i++)
3001
+                    av_log(NULL, AV_LOG_ERROR, " %s", n);
3002
+                av_log(NULL, AV_LOG_ERROR, "\n");
3003
+            }
3004
+            goto end;
3005
+        }
3006
+    }
3007
+
2993 3008
     w = writer_get_by_name(w_name);
2994 3009
     if (!w) {
2995 3010
         av_log(NULL, AV_LOG_ERROR, "Unknown output format with name '%s'\n", w_name);
... ...
@@ -3029,6 +3067,7 @@ int main(int argc, char **argv)
3029 3029
 end:
3030 3030
     av_freep(&print_format);
3031 3031
     av_freep(&read_intervals);
3032
+    av_hash_freep(&hash);
3032 3033
 
3033 3034
     uninit_opts();
3034 3035
     for (i = 0; i < FF_ARRAY_ELEMS(sections); i++)