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.
pull/68/head
Anton Khirnov 11 years ago
parent b70d7a4ac7
commit 0c1959b056
  1. 4
      doc/APIchanges
  2. 7
      libavformat/avformat.h
  3. 2
      libavformat/flacenc.c
  4. 2
      libavformat/matroskaenc.c
  5. 2
      libavformat/movenc.c
  6. 7
      libavformat/mux.c
  7. 4
      libavformat/mxfenc.c
  8. 10
      libavformat/oggenc.c
  9. 1
      libavformat/options_table.h
  10. 5
      libavformat/version.h
  11. 2
      tests/fate-run.sh
  12. 4
      tests/fate/filter-audio.mak
  13. 4
      tests/fate/video.mak
  14. 4
      tests/fate/wavpack.mak
  15. 2
      tests/regression-funcs.sh

@ -13,6 +13,10 @@ libavutil: 2013-12-xx
API changes, most recent first: 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 2014-xx-xx - xxxxxxx - lavu 53.14.0 - pixfmt.h
Add AV_PIX_FMT_VDA for new-style VDA acceleration. Add AV_PIX_FMT_VDA for new-style VDA acceleration.

@ -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_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_DISCARD_CORRUPT 0x0100 ///< Discard frames marked corrupted
#define AVFMT_FLAG_FLUSH_PACKETS 0x0200 ///< Flush the AVIOContext every packet. #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 * Maximum size of the data read from input for determining

@ -84,7 +84,7 @@ static int flac_write_header(struct AVFormatContext *s)
return ret; return ret;
ret = flac_write_block_comment(s->pb, &s->metadata, 0, ret = flac_write_block_comment(s->pb, &s->metadata, 0,
codec->flags & CODEC_FLAG_BITEXACT); s->flags & AVFMT_FLAG_BITEXACT);
if (ret) if (ret)
return ret; return ret;

@ -970,7 +970,7 @@ static int mkv_write_header(AVFormatContext *s)
put_ebml_uint(pb, MATROSKA_ID_TIMECODESCALE, 1000000); put_ebml_uint(pb, MATROSKA_ID_TIMECODESCALE, 1000000);
if ((tag = av_dict_get(s->metadata, "title", NULL, 0))) if ((tag = av_dict_get(s->metadata, "title", NULL, 0)))
put_ebml_string(pb, MATROSKA_ID_TITLE, tag->value); 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]; uint32_t segment_uid[4];
AVLFG lfg; AVLFG lfg;

@ -2024,7 +2024,7 @@ static int mov_write_udta_tag(AVIOContext *pb, MOVMuxContext *mov,
uint8_t *buf; uint8_t *buf;
for (i = 0; i < s->nb_streams; i++) 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; return 0;
} }

@ -149,6 +149,11 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options)
if ((ret = av_opt_set_dict(s, &tmp)) < 0) if ((ret = av_opt_set_dict(s, &tmp)) < 0)
goto fail; 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 // some sanity checks
if (s->nb_streams == 0 && !(of->flags & AVFMT_NOSTREAMS)) { if (s->nb_streams == 0 && !(of->flags & AVFMT_NOSTREAMS)) {
av_log(s, AV_LOG_ERROR, "no streams\n"); 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 */ /* 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); av_dict_set(&s->metadata, "encoder", LIBAVFORMAT_IDENT, 0);
} }

@ -507,7 +507,7 @@ static void mxf_write_identification(AVFormatContext *s)
mxf_write_metadata_key(pb, 0x013000); mxf_write_metadata_key(pb, 0x013000);
PRINT_KEY(s, "identification key", pb->buf_ptr - 16); 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); "0.0.0" : AV_STRINGIFY(LIBAVFORMAT_VERSION);
length = 84 + (strlen(company)+strlen(product)+strlen(version))*2; // utf-16 length = 84 + (strlen(company)+strlen(product)+strlen(version))*2; // utf-16
klv_encode_ber_length(pb, length); klv_encode_ber_length(pb, length);
@ -1512,7 +1512,7 @@ static int mxf_write_header(AVFormatContext *s)
mxf->essence_container_count = 1; mxf->essence_container_count = 1;
} }
if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) if (!(s->flags & AVFMT_FLAG_BITEXACT))
mxf_gen_umid(s); mxf_gen_umid(s);
for (i = 0; i < s->nb_streams; i++) { for (i = 0; i < s->nb_streams; i++) {

@ -425,7 +425,7 @@ static int ogg_write_header(AVFormatContext *s)
oggstream = av_mallocz(sizeof(*oggstream)); oggstream = av_mallocz(sizeof(*oggstream));
oggstream->page.stream_index = i; oggstream->page.stream_index = i;
if (!(st->codec->flags & CODEC_FLAG_BITEXACT)) if (!(s->flags & AVFMT_FLAG_BITEXACT))
do { do {
serial_num = av_get_random_seed(); serial_num = av_get_random_seed();
for (j = 0; j < i; j++) { for (j = 0; j < i; j++) {
@ -439,7 +439,7 @@ static int ogg_write_header(AVFormatContext *s)
st->priv_data = oggstream; st->priv_data = oggstream;
if (st->codec->codec_id == AV_CODEC_ID_FLAC) { if (st->codec->codec_id == AV_CODEC_ID_FLAC) {
int err = ogg_build_flac_headers(st->codec, oggstream, int err = ogg_build_flac_headers(st->codec, oggstream,
st->codec->flags & CODEC_FLAG_BITEXACT, s->flags & AVFMT_FLAG_BITEXACT,
&s->metadata); &s->metadata);
if (err) { if (err) {
av_log(s, AV_LOG_ERROR, "Error writing FLAC headers\n"); 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) { } else if (st->codec->codec_id == AV_CODEC_ID_SPEEX) {
int err = ogg_build_speex_headers(st->codec, oggstream, int err = ogg_build_speex_headers(st->codec, oggstream,
st->codec->flags & CODEC_FLAG_BITEXACT, s->flags & AVFMT_FLAG_BITEXACT,
&s->metadata); &s->metadata);
if (err) { if (err) {
av_log(s, AV_LOG_ERROR, "Error writing Speex headers\n"); 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) { } else if (st->codec->codec_id == AV_CODEC_ID_OPUS) {
int err = ogg_build_opus_headers(st->codec, oggstream, int err = ogg_build_opus_headers(st->codec, oggstream,
st->codec->flags & CODEC_FLAG_BITEXACT, s->flags & AVFMT_FLAG_BITEXACT,
&s->metadata); &s->metadata);
if (err) { if (err) {
av_log(s, AV_LOG_ERROR, "Error writing Opus headers\n"); av_log(s, AV_LOG_ERROR, "Error writing Opus headers\n");
@ -478,7 +478,7 @@ static int ogg_write_header(AVFormatContext *s)
return -1; 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, &oggstream->header_len[1], &s->metadata,
framing_bit); framing_bit);
oggstream->header[1] = p; oggstream->header[1] = p;

@ -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"}, {"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"}, {"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"}, {"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}, {"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}, {"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}, {"indexmem", "max memory used for timestamp index (per stream)", OFFSET(max_index_size), AV_OPT_TYPE_INT, {.i64 = 1<<20 }, 0, INT_MAX, D},

@ -30,7 +30,7 @@
#include "libavutil/version.h" #include "libavutil/version.h"
#define LIBAVFORMAT_VERSION_MAJOR 55 #define LIBAVFORMAT_VERSION_MAJOR 55
#define LIBAVFORMAT_VERSION_MINOR 16 #define LIBAVFORMAT_VERSION_MINOR 17
#define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_MICRO 0
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
@ -51,5 +51,8 @@
#ifndef FF_API_REFERENCE_DTS #ifndef FF_API_REFERENCE_DTS
#define FF_API_REFERENCE_DTS (LIBAVFORMAT_VERSION_MAJOR < 56) #define FF_API_REFERENCE_DTS (LIBAVFORMAT_VERSION_MAJOR < 56)
#endif #endif
#ifndef FF_API_LAVF_BITEXACT
#define FF_API_LAVF_BITEXACT (LIBAVFORMAT_VERSION_MAJOR < 56)
#endif
#endif /* AVFORMAT_VERSION_H */ #endif /* AVFORMAT_VERSION_H */

@ -118,7 +118,7 @@ enc_dec_pcm(){
avconv -f $out_fmt -i ${encfile} -c:a pcm_${pcm_fmt} -f ${dec_fmt} - 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" DEC_OPTS="-threads $threads -idct simple $FLAGS"
ENC_OPTS="-threads 1 -idct simple -dct fastint" ENC_OPTS="-threads 1 -idct simple -dct fastint"

@ -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: 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: 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: 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: CMP = oneline
fate-filter-channelmap-one-int: REF = 21f1977c4f9705e2057083f84764e685 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: 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: 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: 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: CMP = oneline
fate-filter-channelmap-one-str: REF = 9fe9bc452282dfd94fd80e9491607a0c fate-filter-channelmap-one-str: REF = 9fe9bc452282dfd94fd80e9491607a0c

@ -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-mimic: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/mimic/mimic2-womanloveffmpeg.cam
FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, MJPEGB) += fate-mjpegb 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_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 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_SAMPLES_AVCONV-$(call ENCDEC, V410 PGMYUV, AVI IMAGE2) += fate-v410enc
fate-v410enc: $(VREF) 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_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 fate-vb: CMD = framecrc -i $(TARGET_SAMPLES)/SIFF/INTRO_B.VB -t 3 -pix_fmt rgb24 -an

@ -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-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-$(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: CMP = oneline
fate-wavpack-matroska_mux-mono: REF = 6bd769b3f0e9d7fa6261c3b73a53eb7d fate-wavpack-matroska_mux-mono: REF = 6bd769b3f0e9d7fa6261c3b73a53eb7d
FATE_WAVPACK-$(call DEMMUX, WV, MATROSKA) += fate-wavpack-matroska_mux-61 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: CMP = oneline
fate-wavpack-matroska_mux-61: REF = 2d2f1e7f81a8b1983fcffc7f24de8a11 fate-wavpack-matroska_mux-61: REF = 2d2f1e7f81a8b1983fcffc7f24de8a11

@ -41,7 +41,7 @@ echov(){
. $(dirname $0)/md5.sh . $(dirname $0)/md5.sh
AVCONV_OPTS="-nostats -y -cpuflags $cpuflags" 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" DEC_OPTS="$COMMON_OPTS -threads $threads"
ENC_OPTS="$COMMON_OPTS -threads 1 -dct fastint" ENC_OPTS="$COMMON_OPTS -threads 1 -dct fastint"

Loading…
Cancel
Save