Browse code

avformat: add hash and framehash muxers

Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Moritz Barsnick <barsnick@gmx.net>
Signed-off-by: James Almer <jamrial@gmail.com>

Moritz Barsnick authored on 2016/04/12 23:16:18
Showing 7 changed files
... ...
@@ -22,6 +22,7 @@ version <next>:
22 22
 - musx demuxer
23 23
 - aix demuxer
24 24
 - remap filter
25
+- hash and framehash muxers
25 26
 
26 27
 version 3.0:
27 28
 - Common Encryption (CENC) MP4 encoding and decoding support
... ...
@@ -174,30 +174,70 @@ ffmpeg -i INPUT -c:a pcm_u8 -c:v mpeg2video -f framecrc -
174 174
 
175 175
 See also the @ref{crc} muxer.
176 176
 
177
-@anchor{framemd5}
178
-@section framemd5
177
+@anchor{framehash}
178
+@section framehash
179 179
 
180
-Per-packet MD5 testing format.
180
+Per-packet hash testing format.
181 181
 
182
-This muxer computes and prints the MD5 hash for each audio
183
-and video packet. By default audio frames are converted to signed
184
-16-bit raw audio and video frames to raw video before computing the
185
-hash.
182
+This muxer computes and prints a cryptographic hash for each audio
183
+and video packet. This can be used for packet-by-packet equality
184
+checks without having to individually do a binary comparison on each.
185
+
186
+By default audio frames are converted to signed 16-bit raw audio and
187
+video frames to raw video before computing the hash, but the output
188
+of explicit conversions to other codecs can also be used. It uses the
189
+SHA-256 cryptographic hash function by default, but supports several
190
+other algorithms.
186 191
 
187 192
 The output of the muxer consists of a line for each audio and video
188 193
 packet of the form:
189 194
 @example
190
-@var{stream_index}, @var{packet_dts}, @var{packet_pts}, @var{packet_duration}, @var{packet_size}, @var{MD5}
195
+@var{stream_index}, @var{packet_dts}, @var{packet_pts}, @var{packet_duration}, @var{packet_size}, @var{hash}
191 196
 @end example
192 197
 
193
-@var{MD5} is a hexadecimal number representing the computed MD5 hash
198
+@var{hash} is a hexadecimal number representing the computed hash
194 199
 for the packet.
195 200
 
201
+@table @option
202
+@item hash @var{algorithm}
203
+Use the cryptographic hash function specified by the string @var{algorithm}.
204
+Supported values include @code{MD5}, @code{murmur3}, @code{RIPEMD128},
205
+@code{RIPEMD160}, @code{RIPEMD256}, @code{RIPEMD320}, @code{SHA160},
206
+@code{SHA224}, @code{SHA256} (default), @code{SHA512/224}, @code{SHA512/256},
207
+@code{SHA384}, @code{SHA512}, @code{CRC32} and @code{adler32}.
208
+
209
+@end table
210
+
196 211
 @subsection Examples
197 212
 
198
-For example to compute the MD5 of the audio and video frames in
199
-@file{INPUT}, converted to raw audio and video packets, and store it
200
-in the file @file{out.md5}:
213
+To compute the SHA-256 hash of the audio and video frames in @file{INPUT},
214
+converted to raw audio and video packets, and store it in the file
215
+@file{out.sha256}:
216
+@example
217
+ffmpeg -i INPUT -f framehash out.sha256
218
+@end example
219
+
220
+To print the information to stdout, using the MD5 hash function, use
221
+the command:
222
+@example
223
+ffmpeg -i INPUT -f framehash -hash md5 -
224
+@end example
225
+
226
+See also the @ref{hash} muxer.
227
+
228
+@anchor{framemd5}
229
+@section framemd5
230
+
231
+Per-packet MD5 testing format.
232
+
233
+This is a variant of the @ref{framehash} muxer. Unlike that muxer,
234
+it defaults to using the MD5 hash function.
235
+
236
+@subsection Examples
237
+
238
+To compute the MD5 hash of the audio and video frames in @file{INPUT},
239
+converted to raw audio and video packets, and store it in the file
240
+@file{out.md5}:
201 241
 @example
202 242
 ffmpeg -i INPUT -f framemd5 out.md5
203 243
 @end example
... ...
@@ -207,7 +247,7 @@ To print the information to stdout, use the command:
207 207
 ffmpeg -i INPUT -f framemd5 -
208 208
 @end example
209 209
 
210
-See also the @ref{md5} muxer.
210
+See also the @ref{framehash} and @ref{md5} muxers.
211 211
 
212 212
 @anchor{gif}
213 213
 @section gif
... ...
@@ -243,6 +283,51 @@ ffmpeg -i INPUT -c:v gif -f image2 "out%d.gif"
243 243
 Note 2: the GIF format has a very small time base: the delay between two frames
244 244
 can not be smaller than one centi second.
245 245
 
246
+@anchor{hash}
247
+@section hash
248
+
249
+Hash testing format.
250
+
251
+This muxer computes and prints a cryptographic hash of all the input
252
+audio and video frames. This can be used for equality checks without
253
+having to do a complete binary comparison.
254
+
255
+By default audio frames are converted to signed 16-bit raw audio and
256
+video frames to raw video before computing the hash, but the output
257
+of explicit conversions to other codecs can also be used. Timestamps
258
+are ignored. It uses the SHA-256 cryptographic hash function by default,
259
+but supports several other algorithms.
260
+
261
+The output of the muxer consists of a single line of the form:
262
+@var{algo}=@var{hash}, where @var{algo} is a short string representing
263
+the hash function used, and @var{hash} is a hexadecimal number
264
+representing the computed hash.
265
+
266
+@table @option
267
+@item hash @var{algorithm}
268
+Use the cryptographic hash function specified by the string @var{algorithm}.
269
+Supported values include @code{MD5}, @code{murmur3}, @code{RIPEMD128},
270
+@code{RIPEMD160}, @code{RIPEMD256}, @code{RIPEMD320}, @code{SHA160},
271
+@code{SHA224}, @code{SHA256} (default), @code{SHA512/224}, @code{SHA512/256},
272
+@code{SHA384}, @code{SHA512}, @code{CRC32} and @code{adler32}.
273
+
274
+@end table
275
+
276
+@subsection Examples
277
+
278
+To compute the SHA-256 hash of the input converted to raw audio and
279
+video, and store it in the file @file{out.sha256}:
280
+@example
281
+ffmpeg -i INPUT -f hash out.sha256
282
+@end example
283
+
284
+To print an MD5 hash to stdout use the command:
285
+@example
286
+ffmpeg -i INPUT -f hash -hash md5 -
287
+@end example
288
+
289
+See also the @ref{framehash} muxer.
290
+
246 291
 @anchor{hls}
247 292
 @section hls
248 293
 
... ...
@@ -629,16 +714,12 @@ have no effect if it is not.
629 629
 
630 630
 MD5 testing format.
631 631
 
632
-This muxer computes and prints the MD5 hash of all the input audio
633
-and video frames. By default audio frames are converted to signed
634
-16-bit raw audio and video frames to raw video before computing the
635
-hash. Timestamps are ignored.
632
+This is a variant of the @ref{hash} muxer. Unlike that muxer, it
633
+defaults to using the MD5 hash function.
636 634
 
637
-The output of the muxer consists of a single line of the form:
638
-MD5=@var{MD5}, where @var{MD5} is a hexadecimal number representing
639
-the computed MD5 hash.
635
+@subsection Examples
640 636
 
641
-For example to compute the MD5 hash of the input converted to raw
637
+To compute the MD5 hash of the input converted to raw
642 638
 audio and video, and store it in the file @file{out.md5}:
643 639
 @example
644 640
 ffmpeg -i INPUT -f md5 out.md5
... ...
@@ -649,7 +730,7 @@ You can print the MD5 to stdout with the command:
649 649
 ffmpeg -i INPUT -f md5 -
650 650
 @end example
651 651
 
652
-See also the @ref{framemd5} muxer.
652
+See also the @ref{hash} and @ref{framemd5} muxers.
653 653
 
654 654
 @section mov, mp4, ismv
655 655
 
... ...
@@ -175,7 +175,8 @@ OBJS-$(CONFIG_LIVE_FLV_DEMUXER)          += flvdec.o
175 175
 OBJS-$(CONFIG_FLV_MUXER)                 += flvenc.o avc.o
176 176
 OBJS-$(CONFIG_FOURXM_DEMUXER)            += 4xm.o
177 177
 OBJS-$(CONFIG_FRAMECRC_MUXER)            += framecrcenc.o framehash.o
178
-OBJS-$(CONFIG_FRAMEMD5_MUXER)            += md5enc.o framehash.o
178
+OBJS-$(CONFIG_FRAMEHASH_MUXER)           += hashenc.o framehash.o
179
+OBJS-$(CONFIG_FRAMEMD5_MUXER)            += hashenc.o framehash.o
179 180
 OBJS-$(CONFIG_FRM_DEMUXER)               += frmdec.o
180 181
 OBJS-$(CONFIG_FSB_DEMUXER)               += fsb.o
181 182
 OBJS-$(CONFIG_GIF_MUXER)                 += gif.o
... ...
@@ -196,6 +197,7 @@ OBJS-$(CONFIG_H263_DEMUXER)              += h263dec.o rawdec.o
196 196
 OBJS-$(CONFIG_H263_MUXER)                += rawenc.o
197 197
 OBJS-$(CONFIG_H264_DEMUXER)              += h264dec.o rawdec.o
198 198
 OBJS-$(CONFIG_H264_MUXER)                += rawenc.o
199
+OBJS-$(CONFIG_HASH_MUXER)                += hashenc.o
199 200
 OBJS-$(CONFIG_HDS_MUXER)                 += hdsenc.o
200 201
 OBJS-$(CONFIG_HEVC_DEMUXER)              += hevcdec.o rawdec.o
201 202
 OBJS-$(CONFIG_HEVC_MUXER)                += rawenc.o
... ...
@@ -259,7 +261,7 @@ OBJS-$(CONFIG_MATROSKA_MUXER)            += matroskaenc.o matroska.o \
259 259
                                             avc.o hevc.o \
260 260
                                             flacenc_header.o avlanguage.o vorbiscomment.o wv.o \
261 261
                                             webmdashenc.o webm_chunk.o
262
-OBJS-$(CONFIG_MD5_MUXER)                 += md5enc.o
262
+OBJS-$(CONFIG_MD5_MUXER)                 += hashenc.o
263 263
 OBJS-$(CONFIG_MGSTS_DEMUXER)             += mgsts.o
264 264
 OBJS-$(CONFIG_MICRODVD_DEMUXER)          += microdvddec.o subtitles.o
265 265
 OBJS-$(CONFIG_MICRODVD_MUXER)            += microdvdenc.o
... ...
@@ -131,6 +131,7 @@ void av_register_all(void)
131 131
     REGISTER_DEMUXER (LIVE_FLV,         live_flv);
132 132
     REGISTER_DEMUXER (FOURXM,           fourxm);
133 133
     REGISTER_MUXER   (FRAMECRC,         framecrc);
134
+    REGISTER_MUXER   (FRAMEHASH,        framehash);
134 135
     REGISTER_MUXER   (FRAMEMD5,         framemd5);
135 136
     REGISTER_DEMUXER (FRM,              frm);
136 137
     REGISTER_DEMUXER (FSB,              fsb);
... ...
@@ -144,6 +145,7 @@ void av_register_all(void)
144 144
     REGISTER_MUXDEMUX(H261,             h261);
145 145
     REGISTER_MUXDEMUX(H263,             h263);
146 146
     REGISTER_MUXDEMUX(H264,             h264);
147
+    REGISTER_MUXER   (HASH,             hash);
147 148
     REGISTER_MUXER   (HDS,              hds);
148 149
     REGISTER_MUXDEMUX(HEVC,             hevc);
149 150
     REGISTER_MUXDEMUX(HLS,              hls);
150 151
new file mode 100644
... ...
@@ -0,0 +1,231 @@
0
+/*
1
+ * Hash/MD5 encoder (for codec/format testing)
2
+ * Copyright (c) 2009 Reimar Döffinger, based on crcenc (c) 2002 Fabrice Bellard
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+#include "libavutil/avassert.h"
22
+#include "libavutil/avstring.h"
23
+#include "libavutil/hash.h"
24
+#include "libavutil/opt.h"
25
+#include "avformat.h"
26
+#include "internal.h"
27
+
28
+struct HashContext {
29
+    const AVClass *avclass;
30
+    struct AVHashContext *hash;
31
+    char *hash_name;
32
+    int format_version;
33
+};
34
+
35
+static void hash_finish(struct AVFormatContext *s, char *buf)
36
+{
37
+    struct HashContext *c = s->priv_data;
38
+    uint8_t hash[AV_HASH_MAX_SIZE];
39
+    int i, offset = strlen(buf);
40
+    int len = av_hash_get_size(c->hash);
41
+    av_assert0(len > 0 && len <= sizeof(hash));
42
+    av_hash_final(c->hash, hash);
43
+    for (i = 0; i < len; i++) {
44
+        snprintf(buf + offset, 3, "%02"PRIx8, hash[i]);
45
+        offset += 2;
46
+    }
47
+    buf[offset] = '\n';
48
+    buf[offset+1] = 0;
49
+
50
+    avio_write(s->pb, buf, strlen(buf));
51
+    avio_flush(s->pb);
52
+}
53
+
54
+#define OFFSET(x) offsetof(struct HashContext, x)
55
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
56
+#if CONFIG_HASH_MUXER || CONFIG_FRAMEHASH_MUXER
57
+static const AVOption hash_options[] = {
58
+    { "hash", "set hash to use", OFFSET(hash_name), AV_OPT_TYPE_STRING, {.str = "sha256"}, 0, 0, ENC },
59
+    { "format_version", "file format version", OFFSET(format_version), AV_OPT_TYPE_INT, {.i64 = 1}, 1, 1, ENC },
60
+    { NULL },
61
+};
62
+#endif
63
+
64
+#if CONFIG_MD5_MUXER || CONFIG_FRAMEMD5_MUXER
65
+static const AVOption md5_options[] = {
66
+    { "hash", "set hash to use", OFFSET(hash_name), AV_OPT_TYPE_STRING, {.str = "md5"}, 0, 0, ENC },
67
+    { "format_version", "file format version", OFFSET(format_version), AV_OPT_TYPE_INT, {.i64 = 1}, 1, 1, ENC },
68
+    { NULL },
69
+};
70
+#endif
71
+
72
+#if CONFIG_HASH_MUXER || CONFIG_MD5_MUXER
73
+static int hash_write_header(struct AVFormatContext *s)
74
+{
75
+    struct HashContext *c = s->priv_data;
76
+    int res = av_hash_alloc(&c->hash, c->hash_name);
77
+    if (res < 0)
78
+        return res;
79
+    av_hash_init(c->hash);
80
+    return 0;
81
+}
82
+
83
+static int hash_write_packet(struct AVFormatContext *s, AVPacket *pkt)
84
+{
85
+    struct HashContext *c = s->priv_data;
86
+    av_hash_update(c->hash, pkt->data, pkt->size);
87
+    return 0;
88
+}
89
+
90
+static int hash_write_trailer(struct AVFormatContext *s)
91
+{
92
+    struct HashContext *c = s->priv_data;
93
+    char buf[256];
94
+    av_strlcpy(buf, av_hash_get_name(c->hash), sizeof(buf) - 200);
95
+    av_strlcat(buf, "=", sizeof(buf) - 200);
96
+
97
+    hash_finish(s, buf);
98
+
99
+    av_hash_freep(&c->hash);
100
+    return 0;
101
+}
102
+#endif
103
+
104
+#if CONFIG_HASH_MUXER
105
+static const AVClass hashenc_class = {
106
+    .class_name = "hash encoder class",
107
+    .item_name  = av_default_item_name,
108
+    .option     = hash_options,
109
+    .version    = LIBAVUTIL_VERSION_INT,
110
+};
111
+
112
+AVOutputFormat ff_hash_muxer = {
113
+    .name              = "hash",
114
+    .long_name         = NULL_IF_CONFIG_SMALL("Hash testing"),
115
+    .priv_data_size    = sizeof(struct HashContext),
116
+    .audio_codec       = AV_CODEC_ID_PCM_S16LE,
117
+    .video_codec       = AV_CODEC_ID_RAWVIDEO,
118
+    .write_header      = hash_write_header,
119
+    .write_packet      = hash_write_packet,
120
+    .write_trailer     = hash_write_trailer,
121
+    .flags             = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT |
122
+                         AVFMT_TS_NEGATIVE,
123
+    .priv_class        = &hashenc_class,
124
+};
125
+#endif
126
+
127
+#if CONFIG_MD5_MUXER
128
+static const AVClass md5enc_class = {
129
+    .class_name = "MD5 encoder class",
130
+    .item_name  = av_default_item_name,
131
+    .option     = md5_options,
132
+    .version    = LIBAVUTIL_VERSION_INT,
133
+};
134
+
135
+AVOutputFormat ff_md5_muxer = {
136
+    .name              = "md5",
137
+    .long_name         = NULL_IF_CONFIG_SMALL("MD5 testing"),
138
+    .priv_data_size    = sizeof(struct HashContext),
139
+    .audio_codec       = AV_CODEC_ID_PCM_S16LE,
140
+    .video_codec       = AV_CODEC_ID_RAWVIDEO,
141
+    .write_header      = hash_write_header,
142
+    .write_packet      = hash_write_packet,
143
+    .write_trailer     = hash_write_trailer,
144
+    .flags             = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT |
145
+                         AVFMT_TS_NEGATIVE,
146
+    .priv_class        = &md5enc_class,
147
+};
148
+#endif
149
+
150
+#if CONFIG_FRAMEHASH_MUXER || CONFIG_FRAMEMD5_MUXER
151
+static int framehash_write_header(struct AVFormatContext *s)
152
+{
153
+    struct HashContext *c = s->priv_data;
154
+    int res = av_hash_alloc(&c->hash, c->hash_name);
155
+    if (res < 0)
156
+        return res;
157
+    avio_printf(s->pb, "#format: frame checksums\n");
158
+    avio_printf(s->pb, "#version: %d\n", c->format_version);
159
+    avio_printf(s->pb, "#hash: %s\n", av_hash_get_name(c->hash));
160
+    ff_framehash_write_header(s);
161
+    avio_printf(s->pb, "#stream#, dts,        pts, duration,     size, hash\n");
162
+    return 0;
163
+}
164
+
165
+static int framehash_write_packet(struct AVFormatContext *s, AVPacket *pkt)
166
+{
167
+    struct HashContext *c = s->priv_data;
168
+    char buf[256];
169
+    av_hash_init(c->hash);
170
+    av_hash_update(c->hash, pkt->data, pkt->size);
171
+
172
+    snprintf(buf, sizeof(buf) - 64, "%d, %10"PRId64", %10"PRId64", %8"PRId64", %8d, ",
173
+             pkt->stream_index, pkt->dts, pkt->pts, pkt->duration, pkt->size);
174
+    hash_finish(s, buf);
175
+    return 0;
176
+}
177
+
178
+static int framehash_write_trailer(struct AVFormatContext *s)
179
+{
180
+    struct HashContext *c = s->priv_data;
181
+    av_hash_freep(&c->hash);
182
+    return 0;
183
+}
184
+#endif
185
+
186
+#if CONFIG_FRAMEHASH_MUXER
187
+static const AVClass framehash_class = {
188
+    .class_name = "frame hash encoder class",
189
+    .item_name  = av_default_item_name,
190
+    .option     = hash_options,
191
+    .version    = LIBAVUTIL_VERSION_INT,
192
+};
193
+
194
+AVOutputFormat ff_framehash_muxer = {
195
+    .name              = "framehash",
196
+    .long_name         = NULL_IF_CONFIG_SMALL("Per-frame hash testing"),
197
+    .priv_data_size    = sizeof(struct HashContext),
198
+    .audio_codec       = AV_CODEC_ID_PCM_S16LE,
199
+    .video_codec       = AV_CODEC_ID_RAWVIDEO,
200
+    .write_header      = framehash_write_header,
201
+    .write_packet      = framehash_write_packet,
202
+    .write_trailer     = framehash_write_trailer,
203
+    .flags             = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT |
204
+                         AVFMT_TS_NEGATIVE,
205
+    .priv_class        = &framehash_class,
206
+};
207
+#endif
208
+
209
+#if CONFIG_FRAMEMD5_MUXER
210
+static const AVClass framemd5_class = {
211
+    .class_name = "frame hash encoder class",
212
+    .item_name  = av_default_item_name,
213
+    .option     = md5_options,
214
+    .version    = LIBAVUTIL_VERSION_INT,
215
+};
216
+
217
+AVOutputFormat ff_framemd5_muxer = {
218
+    .name              = "framemd5",
219
+    .long_name         = NULL_IF_CONFIG_SMALL("Per-frame MD5 testing"),
220
+    .priv_data_size    = sizeof(struct HashContext),
221
+    .audio_codec       = AV_CODEC_ID_PCM_S16LE,
222
+    .video_codec       = AV_CODEC_ID_RAWVIDEO,
223
+    .write_header      = framehash_write_header,
224
+    .write_packet      = framehash_write_packet,
225
+    .write_trailer     = framehash_write_trailer,
226
+    .flags             = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT |
227
+                         AVFMT_TS_NEGATIVE,
228
+    .priv_class        = &framemd5_class,
229
+};
230
+#endif
0 231
deleted file mode 100644
... ...
@@ -1,171 +0,0 @@
1
-/*
2
- * MD5 encoder (for codec/format testing)
3
- * Copyright (c) 2009 Reimar Döffinger, based on crcenc (c) 2002 Fabrice Bellard
4
- *
5
- * This file is part of FFmpeg.
6
- *
7
- * FFmpeg is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU Lesser General Public
9
- * License as published by the Free Software Foundation; either
10
- * version 2.1 of the License, or (at your option) any later version.
11
- *
12
- * FFmpeg is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
- * Lesser General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU Lesser General Public
18
- * License along with FFmpeg; if not, write to the Free Software
19
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
- */
21
-
22
-#include "libavutil/avassert.h"
23
-#include "libavutil/avstring.h"
24
-#include "libavutil/hash.h"
25
-#include "libavutil/opt.h"
26
-#include "avformat.h"
27
-#include "internal.h"
28
-
29
-struct MD5Context {
30
-    const AVClass *avclass;
31
-    struct AVHashContext *hash;
32
-    char *hash_name;
33
-    int format_version;
34
-};
35
-
36
-static void md5_finish(struct AVFormatContext *s, char *buf)
37
-{
38
-    struct MD5Context *c = s->priv_data;
39
-    uint8_t md5[AV_HASH_MAX_SIZE];
40
-    int i, offset = strlen(buf);
41
-    int len = av_hash_get_size(c->hash);
42
-    av_assert0(len > 0 && len <= sizeof(md5));
43
-    av_hash_final(c->hash, md5);
44
-    for (i = 0; i < len; i++) {
45
-        snprintf(buf + offset, 3, "%02"PRIx8, md5[i]);
46
-        offset += 2;
47
-    }
48
-    buf[offset] = '\n';
49
-    buf[offset+1] = 0;
50
-
51
-    avio_write(s->pb, buf, strlen(buf));
52
-    avio_flush(s->pb);
53
-}
54
-
55
-#define OFFSET(x) offsetof(struct MD5Context, x)
56
-#define ENC AV_OPT_FLAG_ENCODING_PARAM
57
-static const AVOption hash_options[] = {
58
-    { "hash", "set hash to use", OFFSET(hash_name), AV_OPT_TYPE_STRING, {.str = "md5"}, 0, 0, ENC },
59
-    { "format_version", "file format version", OFFSET(format_version), AV_OPT_TYPE_INT, {.i64 = 1}, 1, 1, ENC },
60
-    { NULL },
61
-};
62
-
63
-static const AVClass md5enc_class = {
64
-    .class_name = "hash encoder class",
65
-    .item_name  = av_default_item_name,
66
-    .option     = hash_options,
67
-    .version    = LIBAVUTIL_VERSION_INT,
68
-};
69
-
70
-#if CONFIG_MD5_MUXER
71
-static int write_header(struct AVFormatContext *s)
72
-{
73
-    struct MD5Context *c = s->priv_data;
74
-    int res = av_hash_alloc(&c->hash, c->hash_name);
75
-    if (res < 0)
76
-        return res;
77
-    av_hash_init(c->hash);
78
-    return 0;
79
-}
80
-
81
-static int write_packet(struct AVFormatContext *s, AVPacket *pkt)
82
-{
83
-    struct MD5Context *c = s->priv_data;
84
-    av_hash_update(c->hash, pkt->data, pkt->size);
85
-    return 0;
86
-}
87
-
88
-static int write_trailer(struct AVFormatContext *s)
89
-{
90
-    struct MD5Context *c = s->priv_data;
91
-    char buf[256];
92
-    av_strlcpy(buf, av_hash_get_name(c->hash), sizeof(buf) - 200);
93
-    av_strlcat(buf, "=", sizeof(buf) - 200);
94
-
95
-    md5_finish(s, buf);
96
-
97
-    av_hash_freep(&c->hash);
98
-    return 0;
99
-}
100
-
101
-AVOutputFormat ff_md5_muxer = {
102
-    .name              = "md5",
103
-    .long_name         = NULL_IF_CONFIG_SMALL("MD5 testing"),
104
-    .priv_data_size    = sizeof(struct MD5Context),
105
-    .audio_codec       = AV_CODEC_ID_PCM_S16LE,
106
-    .video_codec       = AV_CODEC_ID_RAWVIDEO,
107
-    .write_header      = write_header,
108
-    .write_packet      = write_packet,
109
-    .write_trailer     = write_trailer,
110
-    .flags             = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT |
111
-                         AVFMT_TS_NEGATIVE,
112
-    .priv_class        = &md5enc_class,
113
-};
114
-#endif
115
-
116
-#if CONFIG_FRAMEMD5_MUXER
117
-static int framemd5_write_header(struct AVFormatContext *s)
118
-{
119
-    struct MD5Context *c = s->priv_data;
120
-    int res = av_hash_alloc(&c->hash, c->hash_name);
121
-    if (res < 0)
122
-        return res;
123
-    avio_printf(s->pb, "#format: frame checksums\n");
124
-    avio_printf(s->pb, "#version: %d\n", c->format_version);
125
-    avio_printf(s->pb, "#hash: %s\n", av_hash_get_name(c->hash));
126
-    ff_framehash_write_header(s);
127
-    avio_printf(s->pb, "#stream#, dts,        pts, duration,     size, hash\n");
128
-    return 0;
129
-}
130
-
131
-static int framemd5_write_packet(struct AVFormatContext *s, AVPacket *pkt)
132
-{
133
-    struct MD5Context *c = s->priv_data;
134
-    char buf[256];
135
-    av_hash_init(c->hash);
136
-    av_hash_update(c->hash, pkt->data, pkt->size);
137
-
138
-    snprintf(buf, sizeof(buf) - 64, "%d, %10"PRId64", %10"PRId64", %8"PRId64", %8d, ",
139
-             pkt->stream_index, pkt->dts, pkt->pts, pkt->duration, pkt->size);
140
-    md5_finish(s, buf);
141
-    return 0;
142
-}
143
-
144
-static int framemd5_write_trailer(struct AVFormatContext *s)
145
-{
146
-    struct MD5Context *c = s->priv_data;
147
-    av_hash_freep(&c->hash);
148
-    return 0;
149
-}
150
-
151
-static const AVClass framemd5_class = {
152
-    .class_name = "frame hash encoder class",
153
-    .item_name  = av_default_item_name,
154
-    .option     = hash_options,
155
-    .version    = LIBAVUTIL_VERSION_INT,
156
-};
157
-
158
-AVOutputFormat ff_framemd5_muxer = {
159
-    .name              = "framemd5",
160
-    .long_name         = NULL_IF_CONFIG_SMALL("Per-frame MD5 testing"),
161
-    .priv_data_size    = sizeof(struct MD5Context),
162
-    .audio_codec       = AV_CODEC_ID_PCM_S16LE,
163
-    .video_codec       = AV_CODEC_ID_RAWVIDEO,
164
-    .write_header      = framemd5_write_header,
165
-    .write_packet      = framemd5_write_packet,
166
-    .write_trailer     = framemd5_write_trailer,
167
-    .flags             = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT |
168
-                         AVFMT_TS_NEGATIVE,
169
-    .priv_class        = &framemd5_class,
170
-};
171
-#endif
... ...
@@ -30,7 +30,7 @@
30 30
 #include "libavutil/version.h"
31 31
 
32 32
 #define LIBAVFORMAT_VERSION_MAJOR  57
33
-#define LIBAVFORMAT_VERSION_MINOR  33
33
+#define LIBAVFORMAT_VERSION_MINOR  34
34 34
 #define LIBAVFORMAT_VERSION_MICRO 100
35 35
 
36 36
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \