]> git.sesse.net Git - ffmpeg/commitdiff
lavf: add AVFMT_FLAG_BITEXACT.
authorAnton Khirnov <anton@khirnov.net>
Thu, 1 May 2014 08:43:10 +0000 (10:43 +0200)
committerAnton Khirnov <anton@khirnov.net>
Thu, 15 May 2014 05:42:07 +0000 (07:42 +0200)
Use it instead of checking CODEC_FLAG_BITEXACT in the first stream's
codec context.

Using codec options inside lavf is fragile and can easily break when the
muxing codec context is not the encoding context.

15 files changed:
doc/APIchanges
libavformat/avformat.h
libavformat/flacenc.c
libavformat/matroskaenc.c
libavformat/movenc.c
libavformat/mux.c
libavformat/mxfenc.c
libavformat/oggenc.c
libavformat/options_table.h
libavformat/version.h
tests/fate-run.sh
tests/fate/filter-audio.mak
tests/fate/video.mak
tests/fate/wavpack.mak
tests/regression-funcs.sh

index 91ec1067c749f757f000a8081bbb4f8e4f7d685d..57ef04f422655673daf0626cfb86e49f6b830b3a 100644 (file)
@@ -13,6 +13,10 @@ libavutil:     2013-12-xx
 
 API changes, most recent first:
 
+2014-05-xx - xxxxxxx - lavf 55.17.0 - avformat.h
+  Add AVMFT_FLAG_BITEXACT flag. Muxers now use it instead of checking
+  CODEC_FLAG_BITEXACT on the first stream.
+
 2014-xx-xx - xxxxxxx - lavu 53.14.0 - pixfmt.h
   Add AV_PIX_FMT_VDA for new-style VDA acceleration.
 
index 1ce3eba67538dbaa4e52b4705f2e5495dd30d37e..8d134a0945eb81a4ae05449587530cd06d56c17e 100644 (file)
@@ -1004,6 +1004,13 @@ typedef struct AVFormatContext {
 #define AVFMT_FLAG_CUSTOM_IO    0x0080 ///< The caller has supplied a custom AVIOContext, don't avio_close() it.
 #define AVFMT_FLAG_DISCARD_CORRUPT  0x0100 ///< Discard frames marked corrupted
 #define AVFMT_FLAG_FLUSH_PACKETS    0x0200 ///< Flush the AVIOContext every packet.
+/**
+ * When muxing, try to avoid writing any random/volatile data to the output.
+ * This includes any random IDs, real-time timestamps/dates, muxer version, etc.
+ *
+ * This flag is mainly intended for testing.
+ */
+#define AVFMT_FLAG_BITEXACT         0x0400
 
     /**
      * Maximum size of the data read from input for determining
index 83ddf441e093f62e76cbc60bb0c7d4c37380bb28..8a2316377215d20f986a364b8160fec823a3f160 100644 (file)
@@ -84,7 +84,7 @@ static int flac_write_header(struct AVFormatContext *s)
         return ret;
 
     ret = flac_write_block_comment(s->pb, &s->metadata, 0,
-                                   codec->flags & CODEC_FLAG_BITEXACT);
+                                   s->flags & AVFMT_FLAG_BITEXACT);
     if (ret)
         return ret;
 
index d2e3ae497911c1426a60f74db8d794cd0345c41a..c71b32d411eedc3c760dbf6b6121af8b40d3f069 100644 (file)
@@ -970,7 +970,7 @@ static int mkv_write_header(AVFormatContext *s)
     put_ebml_uint(pb, MATROSKA_ID_TIMECODESCALE, 1000000);
     if ((tag = av_dict_get(s->metadata, "title", NULL, 0)))
         put_ebml_string(pb, MATROSKA_ID_TITLE, tag->value);
-    if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) {
+    if (!(s->flags & AVFMT_FLAG_BITEXACT)) {
         uint32_t segment_uid[4];
         AVLFG lfg;
 
index 73fbddc4519ca0002574fea40ebe15f17fac5b92..90874389987599b9ed97dd767b30f790d8fbc350 100644 (file)
@@ -2024,7 +2024,7 @@ static int mov_write_udta_tag(AVIOContext *pb, MOVMuxContext *mov,
     uint8_t *buf;
 
     for (i = 0; i < s->nb_streams; i++)
-        if (mov->tracks[i].enc->flags & CODEC_FLAG_BITEXACT) {
+        if (s->flags & AVFMT_FLAG_BITEXACT) {
             return 0;
         }
 
index 59f9c42cf1d76c8998b748573fe4dd53a928f5ac..33257ea147d3e74ec9d9a79d55ed7eff90c4f5b7 100644 (file)
@@ -149,6 +149,11 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options)
     if ((ret = av_opt_set_dict(s, &tmp)) < 0)
         goto fail;
 
+#if FF_API_LAVF_BITEXACT
+    if (s->nb_streams && s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)
+        s->flags |= AVFMT_FLAG_BITEXACT;
+#endif
+
     // some sanity checks
     if (s->nb_streams == 0 && !(of->flags & AVFMT_NOSTREAMS)) {
         av_log(s, AV_LOG_ERROR, "no streams\n");
@@ -252,7 +257,7 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options)
     }
 
     /* set muxer identification string */
-    if (s->nb_streams && !(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) {
+    if (!(s->flags & AVFMT_FLAG_BITEXACT)) {
         av_dict_set(&s->metadata, "encoder", LIBAVFORMAT_IDENT, 0);
     }
 
index 4fd5687beb8ea48c20dd9c90f1a9d8f94b7eb2ab..66beec294011e6997ec95b28047526cc08568339 100644 (file)
@@ -507,7 +507,7 @@ static void mxf_write_identification(AVFormatContext *s)
     mxf_write_metadata_key(pb, 0x013000);
     PRINT_KEY(s, "identification key", pb->buf_ptr - 16);
 
-    version = s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT ?
+    version = s->flags & AVFMT_FLAG_BITEXACT ?
         "0.0.0" : AV_STRINGIFY(LIBAVFORMAT_VERSION);
     length = 84 + (strlen(company)+strlen(product)+strlen(version))*2; // utf-16
     klv_encode_ber_length(pb, length);
@@ -1512,7 +1512,7 @@ static int mxf_write_header(AVFormatContext *s)
         mxf->essence_container_count = 1;
     }
 
-    if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT))
+    if (!(s->flags & AVFMT_FLAG_BITEXACT))
         mxf_gen_umid(s);
 
     for (i = 0; i < s->nb_streams; i++) {
index fd102c86adbd50d829f49fcd884aaa08671900c2..c52368dde3f79dbd0d82d128d87213f06524452d 100644 (file)
@@ -425,7 +425,7 @@ static int ogg_write_header(AVFormatContext *s)
         oggstream = av_mallocz(sizeof(*oggstream));
         oggstream->page.stream_index = i;
 
-        if (!(st->codec->flags & CODEC_FLAG_BITEXACT))
+        if (!(s->flags & AVFMT_FLAG_BITEXACT))
             do {
                 serial_num = av_get_random_seed();
                 for (j = 0; j < i; j++) {
@@ -439,7 +439,7 @@ static int ogg_write_header(AVFormatContext *s)
         st->priv_data = oggstream;
         if (st->codec->codec_id == AV_CODEC_ID_FLAC) {
             int err = ogg_build_flac_headers(st->codec, oggstream,
-                                             st->codec->flags & CODEC_FLAG_BITEXACT,
+                                             s->flags & AVFMT_FLAG_BITEXACT,
                                              &s->metadata);
             if (err) {
                 av_log(s, AV_LOG_ERROR, "Error writing FLAC headers\n");
@@ -448,7 +448,7 @@ static int ogg_write_header(AVFormatContext *s)
             }
         } else if (st->codec->codec_id == AV_CODEC_ID_SPEEX) {
             int err = ogg_build_speex_headers(st->codec, oggstream,
-                                              st->codec->flags & CODEC_FLAG_BITEXACT,
+                                              s->flags & AVFMT_FLAG_BITEXACT,
                                               &s->metadata);
             if (err) {
                 av_log(s, AV_LOG_ERROR, "Error writing Speex headers\n");
@@ -457,7 +457,7 @@ static int ogg_write_header(AVFormatContext *s)
             }
         } else if (st->codec->codec_id == AV_CODEC_ID_OPUS) {
             int err = ogg_build_opus_headers(st->codec, oggstream,
-                                             st->codec->flags & CODEC_FLAG_BITEXACT,
+                                             s->flags & AVFMT_FLAG_BITEXACT,
                                              &s->metadata);
             if (err) {
                 av_log(s, AV_LOG_ERROR, "Error writing Opus headers\n");
@@ -478,7 +478,7 @@ static int ogg_write_header(AVFormatContext *s)
                 return -1;
             }
 
-            p = ogg_write_vorbiscomment(7, st->codec->flags & CODEC_FLAG_BITEXACT,
+            p = ogg_write_vorbiscomment(7, s->flags & AVFMT_FLAG_BITEXACT,
                                         &oggstream->header_len[1], &s->metadata,
                                         framing_bit);
             oggstream->header[1] = p;
index cc84e1c02fccfdedfaf5a3b428cbf422d365fea9..70194202d7bc2e183e223d18e6905f3435288c32 100644 (file)
@@ -42,6 +42,7 @@ static const AVOption avformat_options[] = {
 {"igndts", "ignore dts", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_IGNDTS }, INT_MIN, INT_MAX, D, "fflags"},
 {"discardcorrupt", "discard corrupted frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_DISCARD_CORRUPT }, INT_MIN, INT_MAX, D, "fflags"},
 {"nobuffer", "reduce the latency introduced by optional buffering", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_NOBUFFER }, 0, INT_MAX, D, "fflags"},
+{"bitexact", "do not write random/volatile data", 0, AV_OPT_TYPE_CONST, { .i64 = AVFMT_FLAG_BITEXACT }, 0, 0, E, "fflags" },
 {"analyzeduration", "how many microseconds are analyzed to estimate duration", OFFSET(max_analyze_duration), AV_OPT_TYPE_INT, {.i64 = 5*AV_TIME_BASE }, 0, INT_MAX, D},
 {"cryptokey", "decryption key", OFFSET(key), AV_OPT_TYPE_BINARY, {.dbl = 0}, 0, 0, D},
 {"indexmem", "max memory used for timestamp index (per stream)", OFFSET(max_index_size), AV_OPT_TYPE_INT, {.i64 = 1<<20 }, 0, INT_MAX, D},
index b09d49c8189843c545b78391726d9cda45bfe570..248ecdfd6cf84ba7cd8f9ed71d39dac069ebde17 100644 (file)
@@ -30,7 +30,7 @@
 #include "libavutil/version.h"
 
 #define LIBAVFORMAT_VERSION_MAJOR 55
-#define LIBAVFORMAT_VERSION_MINOR 16
+#define LIBAVFORMAT_VERSION_MINOR 17
 #define LIBAVFORMAT_VERSION_MICRO  0
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
@@ -51,5 +51,8 @@
 #ifndef FF_API_REFERENCE_DTS
 #define FF_API_REFERENCE_DTS            (LIBAVFORMAT_VERSION_MAJOR < 56)
 #endif
+#ifndef FF_API_LAVF_BITEXACT
+#define FF_API_LAVF_BITEXACT            (LIBAVFORMAT_VERSION_MAJOR < 56)
+#endif
 
 #endif /* AVFORMAT_VERSION_H */
index b6c7384ff0e2db30a59c2ec65d400653dc5a30a8..a10a52307b4a4c054f0749788489154351fce9ac 100755 (executable)
@@ -118,7 +118,7 @@ enc_dec_pcm(){
     avconv -f $out_fmt -i ${encfile} -c:a pcm_${pcm_fmt} -f ${dec_fmt} -
 }
 
-FLAGS="-flags +bitexact -sws_flags +accurate_rnd+bitexact"
+FLAGS="-flags +bitexact -sws_flags +accurate_rnd+bitexact -fflags +bitexact"
 DEC_OPTS="-threads $threads -idct simple $FLAGS"
 ENC_OPTS="-threads 1        -idct simple -dct fastint"
 
index fc7ca4fbce0e139cb59afd63f9b817330d8f356b..363ae2e317245a8a789a4420318d21aa498b4642 100644 (file)
@@ -45,7 +45,7 @@ FATE_FILTER_CHANNELMAP += fate-filter-channelmap-one-int
 fate-filter-channelmap-one-int: tests/data/filtergraphs/channelmap_one_int
 fate-filter-channelmap-one-int: SRC = $(TARGET_PATH)/tests/data/asynth-44100-6.wav
 fate-filter-channelmap-one-int: tests/data/asynth-44100-6.wav
-fate-filter-channelmap-one-int: CMD = md5 -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/channelmap_one_int -f wav -flags +bitexact
+fate-filter-channelmap-one-int: CMD = md5 -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/channelmap_one_int -f wav -fflags +bitexact
 fate-filter-channelmap-one-int: CMP = oneline
 fate-filter-channelmap-one-int: REF = 21f1977c4f9705e2057083f84764e685
 
@@ -53,7 +53,7 @@ FATE_FILTER_CHANNELMAP += fate-filter-channelmap-one-str
 fate-filter-channelmap-one-str: tests/data/filtergraphs/channelmap_one_str
 fate-filter-channelmap-one-str: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav
 fate-filter-channelmap-one-str: tests/data/asynth-44100-2.wav
-fate-filter-channelmap-one-str: CMD = md5 -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/channelmap_one_str -f wav -flags +bitexact
+fate-filter-channelmap-one-str: CMD = md5 -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/channelmap_one_str -f wav -fflags +bitexact
 fate-filter-channelmap-one-str: CMP = oneline
 fate-filter-channelmap-one-str: REF = 9fe9bc452282dfd94fd80e9491607a0c
 
index 9698dbf9bc092165682a8c0738479362269283c2..5a48e10e8f0ae9ddd8e53c387564362bbe99a686 100644 (file)
@@ -176,7 +176,7 @@ FATE_SAMPLES_AVCONV-$(call DEMDEC, MSNWC_TCP, MIMIC) += fate-mimic
 fate-mimic: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/mimic/mimic2-womanloveffmpeg.cam
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, MJPEGB) += fate-mjpegb
-fate-mjpegb: CMD = framecrc -idct simple -flags +bitexact -i $(TARGET_SAMPLES)/mjpegb/mjpegb_part.mov -an
+fate-mjpegb: CMD = framecrc -idct simple -fflags +bitexact -i $(TARGET_SAMPLES)/mjpegb/mjpegb_part.mov -an
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, MVI, MOTIONPIXELS) += fate-motionpixels
 fate-motionpixels: CMD = framecrc -i $(TARGET_SAMPLES)/motion-pixels/INTRO-partial.MVI -an -pix_fmt rgb24 -vframes 111
@@ -265,7 +265,7 @@ fate-v410dec: CMD = framecrc -i $(TARGET_SAMPLES)/v410/lenav410.mov -pix_fmt yuv
 
 FATE_SAMPLES_AVCONV-$(call ENCDEC, V410 PGMYUV, AVI IMAGE2) += fate-v410enc
 fate-v410enc: $(VREF)
-fate-v410enc: CMD = md5 -f image2 -vcodec pgmyuv -i $(TARGET_PATH)/tests/vsynth1/%02d.pgm -flags +bitexact -vcodec v410 -f avi
+fate-v410enc: CMD = md5 -f image2 -vcodec pgmyuv -i $(TARGET_PATH)/tests/vsynth1/%02d.pgm -fflags +bitexact -vcodec v410 -f avi
 
 FATE_SAMPLES_AVCONV-$(call DEMDEC, SIFF, VB) += fate-vb
 fate-vb: CMD = framecrc -i $(TARGET_SAMPLES)/SIFF/INTRO_B.VB -t 3 -pix_fmt rgb24 -an
index 912c64a0f3a01459d62bc42dcd02dfbcc2f9988f..3432cc6e0dba5044e8720af8606180aa312ea792 100644 (file)
@@ -89,12 +89,12 @@ FATE_WAVPACK-$(call DEMDEC, MATROSKA, WAVPACK) += fate-wavpack-matroskamode
 fate-wavpack-matroskamode: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/special/matroska_mode.mka -f s16le
 
 FATE_WAVPACK-$(call DEMMUX, WV, MATROSKA) += fate-wavpack-matroska_mux-mono
-fate-wavpack-matroska_mux-mono: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/mono_16bit_int.wv -c copy -flags +bitexact -f matroska
+fate-wavpack-matroska_mux-mono: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/mono_16bit_int.wv -c copy -fflags +bitexact -f matroska
 fate-wavpack-matroska_mux-mono: CMP = oneline
 fate-wavpack-matroska_mux-mono: REF = 6bd769b3f0e9d7fa6261c3b73a53eb7d
 
 FATE_WAVPACK-$(call DEMMUX, WV, MATROSKA) += fate-wavpack-matroska_mux-61
-fate-wavpack-matroska_mux-61: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/eva_2.22_6.1_16bit-partial.wv -c copy -flags +bitexact -f matroska
+fate-wavpack-matroska_mux-61: CMD = md5 -i $(TARGET_SAMPLES)/wavpack/num_channels/eva_2.22_6.1_16bit-partial.wv -c copy -fflags +bitexact -f matroska
 fate-wavpack-matroska_mux-61: CMP = oneline
 fate-wavpack-matroska_mux-61: REF = 2d2f1e7f81a8b1983fcffc7f24de8a11
 
index ce5aee835a689d3af15bb172a314691ebf465a65..3728d4498085a869e6889fa8ac0710353e1aeb11 100755 (executable)
@@ -41,7 +41,7 @@ echov(){
 . $(dirname $0)/md5.sh
 
 AVCONV_OPTS="-nostats -y -cpuflags $cpuflags"
-COMMON_OPTS="-flags +bitexact -idct simple -sws_flags +accurate_rnd+bitexact"
+COMMON_OPTS="-flags +bitexact -idct simple -sws_flags +accurate_rnd+bitexact -fflags +bitexact"
 DEC_OPTS="$COMMON_OPTS -threads $threads"
 ENC_OPTS="$COMMON_OPTS -threads 1 -dct fastint"