[FFmpeg-cvslog] lavf: add AVFMT_FLAG_BITEXACT.

Anton Khirnov git at videolan.org
Thu May 15 19:21:49 CEST 2014


ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Thu May  1 10:43:10 2014 +0200| [0c1959b056f6ccaa2eee2c824352ba93c8e36d52] | committer: Anton Khirnov

lavf: add AVFMT_FLAG_BITEXACT.

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.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=0c1959b056f6ccaa2eee2c824352ba93c8e36d52
---

 doc/APIchanges              |    4 ++++
 libavformat/avformat.h      |    7 +++++++
 libavformat/flacenc.c       |    2 +-
 libavformat/matroskaenc.c   |    2 +-
 libavformat/movenc.c        |    2 +-
 libavformat/mux.c           |    7 ++++++-
 libavformat/mxfenc.c        |    4 ++--
 libavformat/oggenc.c        |   10 +++++-----
 libavformat/options_table.h |    1 +
 libavformat/version.h       |    5 ++++-
 tests/fate-run.sh           |    2 +-
 tests/fate/filter-audio.mak |    4 ++--
 tests/fate/video.mak        |    4 ++--
 tests/fate/wavpack.mak      |    4 ++--
 tests/regression-funcs.sh   |    2 +-
 15 files changed, 40 insertions(+), 20 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index 91ec106..57ef04f 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -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.
 
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 1ce3eba..8d134a0 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -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
diff --git a/libavformat/flacenc.c b/libavformat/flacenc.c
index 83ddf44..8a23163 100644
--- a/libavformat/flacenc.c
+++ b/libavformat/flacenc.c
@@ -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;
 
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index d2e3ae4..c71b32d 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -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;
 
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 73fbddc..9087438 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -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;
         }
 
diff --git a/libavformat/mux.c b/libavformat/mux.c
index 59f9c42..33257ea 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -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);
     }
 
diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c
index 4fd5687..66beec2 100644
--- a/libavformat/mxfenc.c
+++ b/libavformat/mxfenc.c
@@ -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++) {
diff --git a/libavformat/oggenc.c b/libavformat/oggenc.c
index fd102c8..c52368d 100644
--- a/libavformat/oggenc.c
+++ b/libavformat/oggenc.c
@@ -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;
diff --git a/libavformat/options_table.h b/libavformat/options_table.h
index cc84e1c..7019420 100644
--- a/libavformat/options_table.h
+++ b/libavformat/options_table.h
@@ -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},
diff --git a/libavformat/version.h b/libavformat/version.h
index b09d49c..248ecdf 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -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 */
diff --git a/tests/fate-run.sh b/tests/fate-run.sh
index b6c7384..a10a523 100755
--- a/tests/fate-run.sh
+++ b/tests/fate-run.sh
@@ -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"
 
diff --git a/tests/fate/filter-audio.mak b/tests/fate/filter-audio.mak
index fc7ca4f..363ae2e 100644
--- a/tests/fate/filter-audio.mak
+++ b/tests/fate/filter-audio.mak
@@ -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
 
diff --git a/tests/fate/video.mak b/tests/fate/video.mak
index 9698dbf..5a48e10 100644
--- a/tests/fate/video.mak
+++ b/tests/fate/video.mak
@@ -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
diff --git a/tests/fate/wavpack.mak b/tests/fate/wavpack.mak
index 912c64a..3432cc6 100644
--- a/tests/fate/wavpack.mak
+++ b/tests/fate/wavpack.mak
@@ -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
 
diff --git a/tests/regression-funcs.sh b/tests/regression-funcs.sh
index ce5aee8..3728d44 100755
--- a/tests/regression-funcs.sh
+++ b/tests/regression-funcs.sh
@@ -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"
 



More information about the ffmpeg-cvslog mailing list