diff --git a/doc/APIchanges b/doc/APIchanges index a1c501d9d8..4137775fc1 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,10 @@ libavutil: 2012-10-22 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-05-15 - xxxxxxx - lswr 0.19.100 - swresample.h Add swr_close() diff --git a/libavformat/avformat.h b/libavformat/avformat.h index d09745acb8..55a3cfbd35 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1252,6 +1252,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 #define AVFMT_FLAG_MP4A_LATM 0x8000 ///< Enable RTP MP4A-LATM payload #define AVFMT_FLAG_SORT_DTS 0x10000 ///< try to interleave outputted packets by dts (using this flag can slow demuxing down) #define AVFMT_FLAG_PRIV_OPT 0x20000 ///< Enable use of private options by delaying codec open (this could be made default once all code is converted) diff --git a/libavformat/flacenc.c b/libavformat/flacenc.c index 0eca5aaccb..d92801807e 100644 --- a/libavformat/flacenc.c +++ b/libavformat/flacenc.c @@ -98,7 +98,7 @@ static int flac_write_header(struct AVFormatContext *s) return ret; ret = flac_write_block_comment(s->pb, &s->metadata, !padding, - 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 8b19ae3565..17eb318aad 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -1160,7 +1160,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 b3a7649454..adcbcf2c0f 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -3872,7 +3872,7 @@ static int mov_write_header(AVFormatContext *s) } for (i = 0; i < s->nb_streams; i++) - if (s->streams[i]->codec->flags & CODEC_FLAG_BITEXACT) + if (s->flags & AVFMT_FLAG_BITEXACT) mov->exact = 1; /* Set the FRAGMENT flag if any of the fragmentation methods are diff --git a/libavformat/mux.c b/libavformat/mux.c index cbe17f5d78..175f157741 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -235,6 +235,11 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options) (ret = av_opt_set_dict2(s->priv_data, &tmp, AV_OPT_SEARCH_CHILDREN)) < 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 to mux were specified\n"); @@ -340,7 +345,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); } else { av_dict_set(&s->metadata, "encoder", NULL, 0); diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index 5e77a3f068..6f3226b968 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -618,7 +618,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); @@ -1777,7 +1777,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 4ba6940d10..375abadd44 100644 --- a/libavformat/oggenc.c +++ b/libavformat/oggenc.c @@ -432,7 +432,7 @@ static int ogg_write_header(AVFormatContext *s) 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++) { @@ -448,7 +448,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, &st->metadata); if (err) { av_log(s, AV_LOG_ERROR, "Error writing FLAC headers\n"); @@ -457,7 +457,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, &st->metadata); if (err) { av_log(s, AV_LOG_ERROR, "Error writing Speex headers\n"); @@ -466,7 +466,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, &st->metadata); if (err) { av_log(s, AV_LOG_ERROR, "Error writing Opus headers\n"); @@ -487,7 +487,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], &st->metadata, framing_bit); oggstream->header[1] = p; diff --git a/libavformat/options_table.h b/libavformat/options_table.h index be5003403c..359b38483a 100644 --- a/libavformat/options_table.h +++ b/libavformat/options_table.h @@ -50,6 +50,7 @@ static const AVOption avformat_options[] = { {"latm", "enable RTP MP4A-LATM payload", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_MP4A_LATM }, INT_MIN, INT_MAX, E, "fflags"}, {"nobuffer", "reduce the latency introduced by optional buffering", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_NOBUFFER }, 0, INT_MAX, D, "fflags"}, {"seek2any", "allow seeking to non-keyframes on demuxer level when supported", OFFSET(seek2any), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, D}, +{"bitexact", "do not write random/volatile data", 0, AV_OPT_TYPE_CONST, { .i64 = AVFMT_FLAG_BITEXACT }, 0, 0, E, "fflags" }, {"analyzeduration", "specify how many microseconds are analyzed to probe the input", 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 8905fb5b25..c6667ca7bf 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -30,8 +30,8 @@ #include "libavutil/version.h" #define LIBAVFORMAT_VERSION_MAJOR 55 -#define LIBAVFORMAT_VERSION_MINOR 37 -#define LIBAVFORMAT_VERSION_MICRO 102 +#define LIBAVFORMAT_VERSION_MINOR 38 +#define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ @@ -51,6 +51,9 @@ #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 #ifndef FF_API_ALLOC_OUTPUT_CONTEXT #define FF_API_ALLOC_OUTPUT_CONTEXT (LIBAVFORMAT_VERSION_MAJOR < 56) diff --git a/tests/fate-run.sh b/tests/fate-run.sh index 74f4525b9e..60cb569faf 100755 --- a/tests/fate-run.sh +++ b/tests/fate-run.sh @@ -127,7 +127,7 @@ enc_dec_pcm(){ ffmpeg -flags +bitexact -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 725fb7ea27..210b89eb07 100644 --- a/tests/fate/filter-audio.mak +++ b/tests/fate/filter-audio.mak @@ -56,7 +56,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 = 428b8f9fac6d57147069b97335019ef5 @@ -64,7 +64,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 = e788890db6a11c2fb29d7c4229072d49 diff --git a/tests/fate/video.mak b/tests/fate/video.mak index fd42068eea..44c7c72260 100644 --- a/tests/fate/video.mak +++ b/tests/fate/video.mak @@ -181,7 +181,7 @@ FATE_VIDEO-$(call DEMDEC, MSNWC_TCP, MIMIC) += fate-mimic fate-mimic: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/mimic/mimic2-womanloveffmpeg.cam FATE_VIDEO-$(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_VIDEO-$(call DEMDEC, MVI, MOTIONPIXELS) += fate-motionpixels fate-motionpixels: CMD = framecrc -i $(TARGET_SAMPLES)/motion-pixels/INTRO-partial.MVI -an -pix_fmt rgb24 -vframes 111 @@ -270,7 +270,7 @@ fate-v410dec: CMD = framecrc -i $(TARGET_SAMPLES)/v410/lenav410.mov -pix_fmt yuv FATE_VIDEO-$(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_VIDEO-$(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 98e09980f7..240f5ead94 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 = a2987e2e51e01a35e47e7da13eb47a35 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 = ffba4ddea1ba71f7a5901d9ed1a267be diff --git a/tests/regression-funcs.sh b/tests/regression-funcs.sh index da17ac587f..86bc446a34 100755 --- a/tests/regression-funcs.sh +++ b/tests/regression-funcs.sh @@ -44,7 +44,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"