From 32ac63ee10ca5daa149344a75d736c1b98177392 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 10 May 2011 11:29:08 -0400 Subject: [PATCH 01/17] mdec.c: fix overread. --- libavcodec/mdec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/mdec.c b/libavcodec/mdec.c index 545b919411..9b6e6b6dd9 100644 --- a/libavcodec/mdec.c +++ b/libavcodec/mdec.c @@ -125,7 +125,8 @@ static inline int decode_mb(MDECContext *a, DCTELEM block[6][64]){ a->dsp.clear_blocks(block[0]); for(i=0; i<6; i++){ - if( mdec_decode_block_intra(a, block[ block_index[i] ], block_index[i]) < 0) + if( mdec_decode_block_intra(a, block[ block_index[i] ], block_index[i]) < 0 || + get_bits_left(&a->gb) < 0) return -1; } return 0; From a64c58a24023b3e8c9b30bfb6908150b57117a3b Mon Sep 17 00:00:00 2001 From: Alexander Strange Date: Tue, 10 May 2011 11:29:09 -0400 Subject: [PATCH 02/17] mdec: enable frame-level multithreading. Signed-off-by: Ronald S. Bultje --- libavcodec/mdec.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/libavcodec/mdec.c b/libavcodec/mdec.c index 9b6e6b6dd9..02b69d045a 100644 --- a/libavcodec/mdec.c +++ b/libavcodec/mdec.c @@ -31,6 +31,7 @@ #include "dsputil.h" #include "mpegvideo.h" #include "mpeg12.h" +#include "thread.h" typedef struct MDECContext{ AVCodecContext *avctx; @@ -163,10 +164,10 @@ static int decode_frame(AVCodecContext *avctx, int i; if(p->data[0]) - avctx->release_buffer(avctx, p); + ff_thread_release_buffer(avctx, p); p->reference= 0; - if(avctx->get_buffer(avctx, p) < 0){ + if(ff_thread_get_buffer(avctx, p) < 0){ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } @@ -239,6 +240,18 @@ static av_cold int decode_init(AVCodecContext *avctx){ return 0; } +static av_cold int decode_init_thread_copy(AVCodecContext *avctx){ + MDECContext * const a = avctx->priv_data; + AVFrame *p = (AVFrame*)&a->picture; + + avctx->coded_frame = p; + a->avctx= avctx; + + p->qscale_table = av_mallocz( a->mb_width); + + return 0; +} + static av_cold int decode_end(AVCodecContext *avctx){ MDECContext * const a = avctx->priv_data; @@ -260,7 +273,8 @@ AVCodec ff_mdec_decoder = { NULL, decode_end, decode_frame, - CODEC_CAP_DR1, + CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, .long_name= NULL_IF_CONFIG_SMALL("Sony PlayStation MDEC (Motion DECoder)"), + .init_thread_copy= ONLY_IF_THREADS_ENABLED(decode_init_thread_copy) }; From 8d44cd2cd82e27e6b051fe0606dece3b0bec0bcd Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 17 May 2011 10:26:30 -0400 Subject: [PATCH 03/17] h264: copy pixel_shift between slice threading contexts. Fixes "make THREADS=2 THREAD_TYPE=2 fate-h264-conformance-frext-pph10i3_panasonic_a". --- libavcodec/h264.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 616d0a4804..6b262bc992 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -1965,6 +1965,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ c->h264dsp = h->h264dsp; c->sps = h->sps; c->pps = h->pps; + c->pixel_shift = h->pixel_shift; init_scan_tables(c); clone_tables(c, h, i); } From 508a24f8dc63e74bd9917e6f0c4cdbb744741ef0 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 17 May 2011 10:26:29 -0400 Subject: [PATCH 04/17] mpeg12: add slice-threading checks to slice-threading initializers. Fixes "make THREADS=2 THREAD_TYPE=1 fate-mpeg2-field-enc". --- libavcodec/mpeg12.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index ffe6b94c05..88ed5332ae 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -2262,7 +2262,7 @@ static int decode_chunks(AVCodecContext *avctx, buf_ptr = ff_find_start_code(buf_ptr,buf_end, &start_code); if (start_code > 0x1ff){ if(s2->pict_type != AV_PICTURE_TYPE_B || avctx->skip_frame <= AVDISCARD_DEFAULT){ - if(avctx->thread_count > 1){ + if((avctx->active_thread_type & FF_THREAD_SLICE) && avctx->thread_count > 1){ int i; avctx->execute(avctx, slice_decode_thread, &s2->thread_context[0], NULL, s->slice_count, sizeof(void*)); @@ -2430,7 +2430,7 @@ static int decode_chunks(AVCodecContext *avctx, break; } - if(avctx->thread_count > 1){ + if((avctx->active_thread_type & FF_THREAD_SLICE) && avctx->thread_count > 1){ int threshold= (s2->mb_height*s->slice_count + avctx->thread_count/2) / avctx->thread_count; if(threshold <= mb_y){ MpegEncContext *thread_context= s2->thread_context[s->slice_count]; @@ -2541,7 +2541,7 @@ AVCodec ff_mpegvideo_decoder = { #if CONFIG_MPEG_XVMC_DECODER static av_cold int mpeg_mc_decode_init(AVCodecContext *avctx){ - if( avctx->thread_count > 1) + if((avctx->active_thread_type & FF_THREAD_SLICE) && avctx->thread_count > 1) return -1; if( !(avctx->slice_flags & SLICE_FLAG_CODED_ORDER) ) return -1; From dede36bd024fb23da244dbfab32b7ef18ca51c82 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Tue, 17 May 2011 20:39:09 +0100 Subject: [PATCH 05/17] mpegaudio: sanitise compute_antialias_* names This makes the compute_antialias functions use the same naming convention as everything else. Signed-off-by: Mans Rullgard --- libavcodec/mpegaudiodec.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c index 77ecb44c9e..4802a04bc8 100644 --- a/libavcodec/mpegaudiodec.c +++ b/libavcodec/mpegaudiodec.c @@ -41,7 +41,6 @@ #if CONFIG_FLOAT # define SHR(a,b) ((a)*(1.0f/(1<<(b)))) -# define compute_antialias compute_antialias_float # define FIXR_OLD(a) ((int)((a) * FRAC_ONE + 0.5)) # define FIXR(x) ((float)(x)) # define FIXHR(x) ((float)(x)) @@ -51,7 +50,6 @@ # define OUT_FMT AV_SAMPLE_FMT_FLT #else # define SHR(a,b) ((a)>>(b)) -# define compute_antialias compute_antialias_integer /* WARNING: only correct for posititive numbers */ # define FIXR_OLD(a) ((int)((a) * FRAC_ONE + 0.5)) # define FIXR(a) ((int)((a) * FRAC_ONE + 0.5)) @@ -69,7 +67,7 @@ #include "mpegaudiodata.h" #include "mpegaudiodectab.h" -static void compute_antialias(MPADecodeContext *s, GranuleDef *g); +static void RENAME(compute_antialias)(MPADecodeContext *s, GranuleDef *g); static void apply_window_mp3_c(MPA_INT *synth_buf, MPA_INT *window, int *dither_state, OUT_INT *samples, int incr); @@ -1480,8 +1478,7 @@ static void compute_stereo(MPADecodeContext *s, } #if !CONFIG_FLOAT -static void compute_antialias_integer(MPADecodeContext *s, - GranuleDef *g) +static void compute_antialias_fixed(MPADecodeContext *s, GranuleDef *g) { int32_t *ptr, *csa; int n, i; @@ -1848,7 +1845,7 @@ static int mp_decode_layer3(MPADecodeContext *s) g = &s->granules[ch][gr]; reorder_block(s, g); - compute_antialias(s, g); + RENAME(compute_antialias)(s, g); compute_imdct(s, g, &s->sb_samples[ch][18 * gr][0], s->mdct_buf[ch]); } } /* gr */ From 70378ea1902b57ccb221157fbd3a411d11046ad0 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Wed, 18 May 2011 13:05:39 +0100 Subject: [PATCH 06/17] fate: run aref and vref as regular tests These tests create reference files used for psnr calculation in the other codec tests. Treating them as (mostly) regular tests simplifies the makefile and makes them visible in the fate reports. The latter makes errors in these runs easier to identify. Signed-off-by: Mans Rullgard --- Makefile | 16 +++++++--------- tests/codec-regression.sh | 4 ++-- tests/ref/acodec/aref | 2 ++ tests/ref/vsynth1/vref | 2 ++ tests/ref/vsynth2/vref | 2 ++ 5 files changed, 15 insertions(+), 11 deletions(-) create mode 100644 tests/ref/acodec/aref create mode 100644 tests/ref/vsynth1/vref create mode 100644 tests/ref/vsynth2/vref diff --git a/Makefile b/Makefile index d69004b474..a155eea58b 100644 --- a/Makefile +++ b/Makefile @@ -187,18 +187,16 @@ lavftest: fate-lavf lavfitest: fate-lavfi seektest: fate-seek -AREF = tests/data/acodec.ref.wav -VREF = tests/data/vsynth1.ref.yuv +AREF = fate-acodec-aref +VREF = fate-vsynth1-vref fate-vsynth2-vref REFS = $(AREF) $(VREF) -$(REFS): TAG = GEN - $(VREF): ffmpeg$(EXESUF) tests/vsynth1/00.pgm tests/vsynth2/00.pgm - $(M)$(SRC_PATH)/tests/codec-regression.sh vref vsynth1 tests/vsynth1 "$(TARGET_EXEC)" "$(TARGET_PATH)" - $(Q)$(SRC_PATH)/tests/codec-regression.sh vref vsynth2 tests/vsynth2 "$(TARGET_EXEC)" "$(TARGET_PATH)" - $(AREF): ffmpeg$(EXESUF) tests/data/asynth1.sw - $(M)$(SRC_PATH)/tests/codec-regression.sh aref acodec tests/acodec "$(TARGET_EXEC)" "$(TARGET_PATH)" + +fate-acodec-aref: CMD = codectest acodec +fate-vsynth1-vref: CMD = codectest vsynth1 +fate-vsynth2-vref: CMD = codectest vsynth2 ffservertest: ffserver$(EXESUF) tests/vsynth1/00.pgm tests/data/asynth1.sw @echo @@ -287,7 +285,7 @@ FATE_UTILS = base64 tiny_psnr fate: $(FATE) -$(FATE): ffmpeg$(EXESUF) $(FATE_UTILS:%=tests/%$(HOSTEXESUF)) +$(FATE) $(REFS): ffmpeg$(EXESUF) $(FATE_UTILS:%=tests/%$(HOSTEXESUF)) @echo "TEST $(@:fate-%=%)" $(Q)$(SRC_PATH)/tests/fate-run.sh $@ "$(SAMPLES)" "$(TARGET_EXEC)" "$(TARGET_PATH)" '$(CMD)' '$(CMP)' '$(REF)' '$(FUZZ)' '$(THREADS)' '$(THREAD_TYPE)' diff --git a/tests/codec-regression.sh b/tests/codec-regression.sh index 2ee6166c33..9b2aa6308d 100755 --- a/tests/codec-regression.sh +++ b/tests/codec-regression.sh @@ -16,10 +16,10 @@ rm -f "$benchfile" # generate reference for quality check if [ -n "$do_vref" ]; then -do_ffmpeg_nocheck $raw_ref -f image2 -vcodec pgmyuv -i $raw_src -an -f rawvideo $target_path/$raw_ref +do_ffmpeg $raw_ref -f image2 -vcodec pgmyuv -i $raw_src -an -f rawvideo fi if [ -n "$do_aref" ]; then -do_ffmpeg_nocheck $pcm_ref -ab 128k -ac 2 -ar 44100 -f s16le -i $pcm_src -f wav $target_path/$pcm_ref +do_ffmpeg $pcm_ref -ab 128k -ac 2 -ar 44100 -f s16le -i $pcm_src -f wav fi if [ -n "$do_mpeg" ] ; then diff --git a/tests/ref/acodec/aref b/tests/ref/acodec/aref new file mode 100644 index 0000000000..8e6773be3b --- /dev/null +++ b/tests/ref/acodec/aref @@ -0,0 +1,2 @@ +95e54b261530a1bcf6de6fe3b21dc5f6 *./tests/data/acodec.ref.wav +1058444 ./tests/data/acodec.ref.wav diff --git a/tests/ref/vsynth1/vref b/tests/ref/vsynth1/vref new file mode 100644 index 0000000000..2defdac870 --- /dev/null +++ b/tests/ref/vsynth1/vref @@ -0,0 +1,2 @@ +c5ccac874dbf808e9088bc3107860042 *./tests/data/vsynth1.ref.yuv +7603200 ./tests/data/vsynth1.ref.yuv diff --git a/tests/ref/vsynth2/vref b/tests/ref/vsynth2/vref new file mode 100644 index 0000000000..8f83b6c7ba --- /dev/null +++ b/tests/ref/vsynth2/vref @@ -0,0 +1,2 @@ +dde5895817ad9d219f79a52d0bdfb001 *./tests/data/vsynth2.ref.yuv +7603200 ./tests/data/vsynth2.ref.yuv From a06bf6368be2acb760a10289645eba1f65bf967b Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Mon, 16 May 2011 16:37:38 +0100 Subject: [PATCH 07/17] mpegaudiodec: remove decode_end() function This function is not needed since 721d6f2dc5 removed the DCT table allocations for the configuration used here. Signed-off-by: Mans Rullgard --- libavcodec/mpegaudiodec_float.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/libavcodec/mpegaudiodec_float.c b/libavcodec/mpegaudiodec_float.c index e9041fcb63..0ef85d19c1 100644 --- a/libavcodec/mpegaudiodec_float.c +++ b/libavcodec/mpegaudiodec_float.c @@ -80,13 +80,6 @@ static void compute_antialias_float(MPADecodeContext *s, } } -static av_cold int decode_end(AVCodecContext * avctx) -{ - MPADecodeContext *s = avctx->priv_data; - ff_dct_end(&s->dct); - return 0; -} - #if CONFIG_MP1FLOAT_DECODER AVCodec ff_mp1float_decoder = { @@ -96,7 +89,7 @@ AVCodec ff_mp1float_decoder = sizeof(MPADecodeContext), decode_init, NULL, - decode_end, + .close = NULL, decode_frame, CODEC_CAP_PARSE_ONLY, .flush= flush, @@ -112,7 +105,7 @@ AVCodec ff_mp2float_decoder = sizeof(MPADecodeContext), decode_init, NULL, - decode_end, + .close = NULL, decode_frame, CODEC_CAP_PARSE_ONLY, .flush= flush, @@ -128,7 +121,7 @@ AVCodec ff_mp3float_decoder = sizeof(MPADecodeContext), decode_init, NULL, - decode_end, + .close = NULL, decode_frame, CODEC_CAP_PARSE_ONLY, .flush= flush, @@ -144,7 +137,7 @@ AVCodec ff_mp3adufloat_decoder = sizeof(MPADecodeContext), decode_init, NULL, - decode_end, + .close = NULL, decode_frame_adu, CODEC_CAP_PARSE_ONLY, .flush= flush, From d4a7df423c7eda78185d79fb81ffe36b3d4253c4 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Wed, 18 May 2011 15:05:26 +0100 Subject: [PATCH 08/17] fate: do not collect -benchmark output The old regtest scripts pass -benchmark and collect the utime values. As these values are never used, this machinery can be removed. Signed-off-by: Mans Rullgard --- tests/codec-regression.sh | 1 - tests/lavf-regression.sh | 1 - tests/lavfi-regression.sh | 1 - tests/regression-funcs.sh | 17 ++++------------- 4 files changed, 4 insertions(+), 16 deletions(-) diff --git a/tests/codec-regression.sh b/tests/codec-regression.sh index 9b2aa6308d..335e1f70f7 100755 --- a/tests/codec-regression.sh +++ b/tests/codec-regression.sh @@ -12,7 +12,6 @@ set -e eval do_$test=y rm -f "$logfile" -rm -f "$benchfile" # generate reference for quality check if [ -n "$do_vref" ]; then diff --git a/tests/lavf-regression.sh b/tests/lavf-regression.sh index 28f53f78b0..32d92de0b9 100755 --- a/tests/lavf-regression.sh +++ b/tests/lavf-regression.sh @@ -44,7 +44,6 @@ do_audio_only() } rm -f "$logfile" -rm -f "$benchfile" if [ -n "$do_avi" ] ; then do_lavf avi diff --git a/tests/lavfi-regression.sh b/tests/lavfi-regression.sh index 17988192df..b2a195a90e 100755 --- a/tests/lavfi-regression.sh +++ b/tests/lavfi-regression.sh @@ -12,7 +12,6 @@ set -e eval do_$test=y rm -f "$logfile" -rm -f "$benchfile" do_video_filter() { label=$1 diff --git a/tests/regression-funcs.sh b/tests/regression-funcs.sh index 0e4ea44f46..035cbdb2f3 100755 --- a/tests/regression-funcs.sh +++ b/tests/regression-funcs.sh @@ -23,9 +23,6 @@ errfile="$datadir/$this.err" # various files ffmpeg="$target_exec ${target_path}/ffmpeg" tiny_psnr="tests/tiny_psnr" -benchfile="$datadir/$this.bench" -bench="$datadir/$this.bench.tmp" -bench2="$datadir/$this.bench2.tmp" raw_src="${target_path}/$raw_src_dir/%02d.pgm" raw_dst="$datadir/$this.out.yuv" raw_ref="$datadir/$test_ref.ref.yuv" @@ -35,7 +32,7 @@ pcm_ref="$datadir/$test_ref.ref.wav" crcfile="$datadir/$this.crc" target_crcfile="$target_datadir/$this.crc" -cleanfiles="$raw_dst $pcm_dst $crcfile $bench $bench2" +cleanfiles="$raw_dst $pcm_dst $crcfile" trap 'rm -f -- $cleanfiles' EXIT mkdir -p "$datadir" @@ -69,7 +66,7 @@ do_ffmpeg() f="$1" shift set -- $* ${target_path}/$f - run_ffmpeg -benchmark $* > $bench + run_ffmpeg $* do_md5sum $f >> $logfile if [ $f = $raw_dst ] ; then $tiny_psnr $f $raw_ref >> $logfile @@ -78,8 +75,6 @@ do_ffmpeg() else wc -c $f >> $logfile fi - expr "$(cat $bench)" : '.*utime=\(.*s\)' > $bench2 - echo $(cat $bench2) $f >> $benchfile } do_ffmpeg_nomd5() @@ -87,7 +82,7 @@ do_ffmpeg_nomd5() f="$1" shift set -- $* ${target_path}/$f - run_ffmpeg -benchmark $* > $bench + run_ffmpeg $* if [ $f = $raw_dst ] ; then $tiny_psnr $f $raw_ref >> $logfile elif [ $f = $pcm_dst ] ; then @@ -95,8 +90,6 @@ do_ffmpeg_nomd5() else wc -c $f >> $logfile fi - expr "$(cat $bench)" : '.*utime=\(.*s\)' > $bench2 - echo $(cat $bench2) $f >> $benchfile } do_ffmpeg_crc() @@ -111,9 +104,7 @@ do_ffmpeg_nocheck() { f="$1" shift - run_ffmpeg -benchmark $* > $bench - expr "$(cat $bench)" : '.*utime=\(.*s\)' > $bench2 - echo $(cat $bench2) $f >> $benchfile + run_ffmpeg $* } do_video_decoding() From 1a14a27603fec02498627b6f92cea7bd57c8d41f Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Wed, 18 May 2011 15:13:58 +0100 Subject: [PATCH 09/17] fate: remove do_ffmpeg_nocheck function This function is essentially an alias for run_ffmpeg and is only used in one place. This patch removes the function and replaces the call with the equivalent (simpler) run_ffmpeg call. Signed-off-by: Mans Rullgard --- tests/lavf-regression.sh | 4 ++-- tests/regression-funcs.sh | 7 ------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/tests/lavf-regression.sh b/tests/lavf-regression.sh index 32d92de0b9..94d258334b 100755 --- a/tests/lavf-regression.sh +++ b/tests/lavf-regression.sh @@ -226,8 +226,8 @@ conversions="yuv420p yuv422p yuv444p yuyv422 yuv410p yuv411p yuvj420p \ monob yuv440p yuvj440p" for pix_fmt in $conversions ; do file=${outfile}${pix_fmt}.yuv - do_ffmpeg_nocheck $file $DEC_OPTS -r 1 -t 1 -f image2 -vcodec pgmyuv -i $raw_src \ - $ENC_OPTS -f rawvideo -s 352x288 -pix_fmt $pix_fmt $target_path/$raw_dst + run_ffmpeg $DEC_OPTS -r 1 -t 1 -f image2 -vcodec pgmyuv -i $raw_src \ + $ENC_OPTS -f rawvideo -s 352x288 -pix_fmt $pix_fmt $target_path/$raw_dst do_ffmpeg $file $DEC_OPTS -f rawvideo -s 352x288 -pix_fmt $pix_fmt -i $target_path/$raw_dst \ $ENC_OPTS -f rawvideo -s 352x288 -pix_fmt yuv444p done diff --git a/tests/regression-funcs.sh b/tests/regression-funcs.sh index 035cbdb2f3..b79c258e77 100755 --- a/tests/regression-funcs.sh +++ b/tests/regression-funcs.sh @@ -100,13 +100,6 @@ do_ffmpeg_crc() echo "$f $(cat $crcfile)" >> $logfile } -do_ffmpeg_nocheck() -{ - f="$1" - shift - run_ffmpeg $* -} - do_video_decoding() { do_ffmpeg $raw_dst $DEC_OPTS $1 -i $target_path/$file -f rawvideo $ENC_OPTS $2 From 164c24c858047f304a81278615409503c6a7da17 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Wed, 18 May 2011 17:23:47 +0100 Subject: [PATCH 10/17] fate: remove redundant aref and vref references The ref targets are included in the FATE_[AV]CODEC lists created by configure so they do not need to be listed separately in the makefile. Filter them out when setting dependencies to avoid make warnings about circular deps. Signed-off-by: Mans Rullgard --- Makefile | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index a155eea58b..0ed6207961 100644 --- a/Makefile +++ b/Makefile @@ -194,10 +194,6 @@ REFS = $(AREF) $(VREF) $(VREF): ffmpeg$(EXESUF) tests/vsynth1/00.pgm tests/vsynth2/00.pgm $(AREF): ffmpeg$(EXESUF) tests/data/asynth1.sw -fate-acodec-aref: CMD = codectest acodec -fate-vsynth1-vref: CMD = codectest vsynth1 -fate-vsynth2-vref: CMD = codectest vsynth2 - ffservertest: ffserver$(EXESUF) tests/vsynth1/00.pgm tests/data/asynth1.sw @echo @echo "Unfortunately ffserver is broken and therefore its regression" @@ -250,8 +246,8 @@ FATE = $(FATE_ACODEC) \ $(FATE_LAVFI) \ $(FATE_SEEK) \ -$(FATE_ACODEC): $(AREF) -$(FATE_VCODEC): $(VREF) +$(filter-out %-aref,$(FATE_ACODEC)): $(AREF) +$(filter-out %-vref,$(FATE_VCODEC)): $(VREF) $(FATE_LAVF): $(REFS) $(FATE_LAVFI): $(REFS) tools/lavfi-showfiltfmts$(EXESUF) $(FATE_SEEK): fate-codec fate-lavf tests/seek_test$(EXESUF) @@ -285,7 +281,7 @@ FATE_UTILS = base64 tiny_psnr fate: $(FATE) -$(FATE) $(REFS): ffmpeg$(EXESUF) $(FATE_UTILS:%=tests/%$(HOSTEXESUF)) +$(FATE): ffmpeg$(EXESUF) $(FATE_UTILS:%=tests/%$(HOSTEXESUF)) @echo "TEST $(@:fate-%=%)" $(Q)$(SRC_PATH)/tests/fate-run.sh $@ "$(SAMPLES)" "$(TARGET_EXEC)" "$(TARGET_PATH)" '$(CMD)' '$(CMP)' '$(REF)' '$(FUZZ)' '$(THREADS)' '$(THREAD_TYPE)' From f907ad9b85d5e08e4a024e24734181940cd4fc48 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Wed, 18 May 2011 17:13:15 +0100 Subject: [PATCH 11/17] Remove unused make variable SEEK_REFFILE Signed-off-by: Mans Rullgard --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index 0ed6207961..afd783da5b 100644 --- a/Makefile +++ b/Makefile @@ -180,7 +180,6 @@ check: test checkheaders fulltest test: codectest lavftest lavfitest seektest FFSERVER_REFFILE = $(SRC_PATH)/tests/ffserver.regression.ref -SEEK_REFFILE = $(SRC_PATH)/tests/seek.regression.ref codectest: fate-codec lavftest: fate-lavf From 32f8fb8ecf8178b9c9ec8d7152f1fdd8537f7f3a Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 24 Apr 2011 17:50:17 -0400 Subject: [PATCH 12/17] Add float_interleave() to FmtConvertContext with x86-optimized versions. Partially based on patches by clsid2 in ffdshow-tryout. ff_float_interleave6() x86 improvements by Loren Merrit. --- libavcodec/fmtconvert.c | 20 +++++ libavcodec/fmtconvert.h | 9 ++ libavcodec/x86/fmtconvert.asm | 141 ++++++++++++++++++++++++++++++++ libavcodec/x86/fmtconvert_mmx.c | 30 +++++++ 4 files changed, 200 insertions(+) diff --git a/libavcodec/fmtconvert.c b/libavcodec/fmtconvert.c index e9707555af..58fece70b2 100644 --- a/libavcodec/fmtconvert.c +++ b/libavcodec/fmtconvert.c @@ -56,11 +56,31 @@ static void float_to_int16_interleave_c(int16_t *dst, const float **src, } } +void ff_float_interleave_c(float *dst, const float **src, unsigned int len, + int channels) +{ + int j, c; + unsigned int i; + if (channels == 2) { + for (i = 0; i < len; i++) { + dst[2*i] = src[0][i]; + dst[2*i+1] = src[1][i]; + } + } else if (channels == 1 && len < INT_MAX / sizeof(float)) { + memcpy(dst, src[0], len * sizeof(float)); + } else { + for (c = 0; c < channels; c++) + for (i = 0, j = c; i < len; i++, j += channels) + dst[j] = src[c][i]; + } +} + av_cold void ff_fmt_convert_init(FmtConvertContext *c, AVCodecContext *avctx) { c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_c; c->float_to_int16 = float_to_int16_c; c->float_to_int16_interleave = float_to_int16_interleave_c; + c->float_interleave = ff_float_interleave_c; if (ARCH_ARM) ff_fmt_convert_init_arm(c, avctx); if (HAVE_ALTIVEC) ff_fmt_convert_init_altivec(c, avctx); diff --git a/libavcodec/fmtconvert.h b/libavcodec/fmtconvert.h index e0afee47e1..d7741135b7 100644 --- a/libavcodec/fmtconvert.h +++ b/libavcodec/fmtconvert.h @@ -68,8 +68,17 @@ typedef struct FmtConvertContext { */ void (*float_to_int16_interleave)(int16_t *dst, const float **src, long len, int channels); + + /** + * Convert an array of interleaved float to multiple arrays of float. + */ + void (*float_interleave)(float *dst, const float **src, unsigned int len, + int channels); } FmtConvertContext; +void ff_float_interleave_c(float *dst, const float **src, unsigned int len, + int channels); + void ff_fmt_convert_init(FmtConvertContext *c, AVCodecContext *avctx); void ff_fmt_convert_init_arm(FmtConvertContext *c, AVCodecContext *avctx); diff --git a/libavcodec/x86/fmtconvert.asm b/libavcodec/x86/fmtconvert.asm index 5cd8f6c596..e023b48322 100644 --- a/libavcodec/x86/fmtconvert.asm +++ b/libavcodec/x86/fmtconvert.asm @@ -20,6 +20,7 @@ ;****************************************************************************** %include "x86inc.asm" +%include "x86util.asm" section .text align=16 @@ -89,3 +90,143 @@ FLOAT_TO_INT16_INTERLEAVE6 3dnow %undef pswapd FLOAT_TO_INT16_INTERLEAVE6 3dn2 %undef cvtps2pi + +;----------------------------------------------------------------------------- +; void ff_float_interleave6(float *dst, const float **src, unsigned int len); +;----------------------------------------------------------------------------- + +%macro BUTTERFLYPS 3 + movaps m%3, m%1 + unpcklps m%1, m%2 + unpckhps m%3, m%2 + SWAP %2, %3 +%endmacro + +%macro FLOAT_INTERLEAVE6 2 +cglobal float_interleave6_%1, 2,7,%2, dst, src, src1, src2, src3, src4, src5 +%ifdef ARCH_X86_64 + %define lend r10d + mov lend, r2d +%else + %define lend dword r2m +%endif + mov src1q, [srcq+1*gprsize] + mov src2q, [srcq+2*gprsize] + mov src3q, [srcq+3*gprsize] + mov src4q, [srcq+4*gprsize] + mov src5q, [srcq+5*gprsize] + mov srcq, [srcq] + sub src1q, srcq + sub src2q, srcq + sub src3q, srcq + sub src4q, srcq + sub src5q, srcq +.loop: +%ifidn %1, sse + movaps m0, [srcq] + movaps m1, [srcq+src1q] + movaps m2, [srcq+src2q] + movaps m3, [srcq+src3q] + movaps m4, [srcq+src4q] + movaps m5, [srcq+src5q] + + BUTTERFLYPS 0, 1, 6 + BUTTERFLYPS 2, 3, 6 + BUTTERFLYPS 4, 5, 6 + + movaps m6, m4 + shufps m4, m0, 0xe4 + movlhps m0, m2 + movhlps m6, m2 + movaps [dstq ], m0 + movaps [dstq+16], m4 + movaps [dstq+32], m6 + + movaps m6, m5 + shufps m5, m1, 0xe4 + movlhps m1, m3 + movhlps m6, m3 + movaps [dstq+48], m1 + movaps [dstq+64], m5 + movaps [dstq+80], m6 +%else ; mmx + movq m0, [srcq] + movq m1, [srcq+src1q] + movq m2, [srcq+src2q] + movq m3, [srcq+src3q] + movq m4, [srcq+src4q] + movq m5, [srcq+src5q] + + SBUTTERFLY dq, 0, 1, 6 + SBUTTERFLY dq, 2, 3, 6 + SBUTTERFLY dq, 4, 5, 6 + movq [dstq ], m0 + movq [dstq+ 8], m2 + movq [dstq+16], m4 + movq [dstq+24], m1 + movq [dstq+32], m3 + movq [dstq+40], m5 +%endif + add srcq, mmsize + add dstq, mmsize*6 + sub lend, mmsize/4 + jg .loop +%ifidn %1, mmx + emms +%endif + REP_RET +%endmacro + +INIT_MMX +FLOAT_INTERLEAVE6 mmx, 0 +INIT_XMM +FLOAT_INTERLEAVE6 sse, 7 + +;----------------------------------------------------------------------------- +; void ff_float_interleave2(float *dst, const float **src, unsigned int len); +;----------------------------------------------------------------------------- + +%macro FLOAT_INTERLEAVE2 2 +cglobal float_interleave2_%1, 3,4,%2, dst, src, len, src1 + mov src1q, [srcq+gprsize] + mov srcq, [srcq ] + sub src1q, srcq +.loop + MOVPS m0, [srcq ] + MOVPS m1, [srcq+src1q ] + MOVPS m3, [srcq +mmsize] + MOVPS m4, [srcq+src1q+mmsize] + + MOVPS m2, m0 + PUNPCKLDQ m0, m1 + PUNPCKHDQ m2, m1 + + MOVPS m1, m3 + PUNPCKLDQ m3, m4 + PUNPCKHDQ m1, m4 + + MOVPS [dstq ], m0 + MOVPS [dstq+1*mmsize], m2 + MOVPS [dstq+2*mmsize], m3 + MOVPS [dstq+3*mmsize], m1 + + add srcq, mmsize*2 + add dstq, mmsize*4 + sub lend, mmsize/2 + jg .loop +%ifidn %1, mmx + emms +%endif + REP_RET +%endmacro + +INIT_MMX +%define MOVPS movq +%define PUNPCKLDQ punpckldq +%define PUNPCKHDQ punpckhdq +FLOAT_INTERLEAVE2 mmx, 0 +INIT_XMM +%define MOVPS movaps +%define PUNPCKLDQ unpcklps +%define PUNPCKHDQ unpckhps +FLOAT_INTERLEAVE2 sse, 5 diff --git a/libavcodec/x86/fmtconvert_mmx.c b/libavcodec/x86/fmtconvert_mmx.c index 847bd80fcd..61a4272a69 100644 --- a/libavcodec/x86/fmtconvert_mmx.c +++ b/libavcodec/x86/fmtconvert_mmx.c @@ -235,11 +235,40 @@ static void float_to_int16_interleave_3dn2(int16_t *dst, const float **src, long float_to_int16_interleave_3dnow(dst, src, len, channels); } +void ff_float_interleave2_mmx(float *dst, const float **src, unsigned int len); +void ff_float_interleave2_sse(float *dst, const float **src, unsigned int len); + +void ff_float_interleave6_mmx(float *dst, const float **src, unsigned int len); +void ff_float_interleave6_sse(float *dst, const float **src, unsigned int len); + +static void float_interleave_mmx(float *dst, const float **src, + unsigned int len, int channels) +{ + if (channels == 2) { + ff_float_interleave2_mmx(dst, src, len); + } else if (channels == 6) + ff_float_interleave6_mmx(dst, src, len); + else + ff_float_interleave_c(dst, src, len, channels); +} + +static void float_interleave_sse(float *dst, const float **src, + unsigned int len, int channels) +{ + if (channels == 2) { + ff_float_interleave2_sse(dst, src, len); + } else if (channels == 6) + ff_float_interleave6_sse(dst, src, len); + else + ff_float_interleave_c(dst, src, len, channels); +} + void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx) { int mm_flags = av_get_cpu_flags(); if (mm_flags & AV_CPU_FLAG_MMX) { + c->float_interleave = float_interleave_mmx; if(mm_flags & AV_CPU_FLAG_3DNOW){ if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ @@ -256,6 +285,7 @@ void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx) c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_sse; c->float_to_int16 = float_to_int16_sse; c->float_to_int16_interleave = float_to_int16_interleave_sse; + c->float_interleave = float_interleave_sse; } if(mm_flags & AV_CPU_FLAG_SSE2){ c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_sse2; From 64150ff014708b4b00cb5d76237e9e908ac0fbfc Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 19 Apr 2011 19:47:01 -0400 Subject: [PATCH 13/17] Add request_sample_fmt field to AVCodecContext. This will allow audio decoders to support output of different sample formats as a runtime option. --- libavcodec/avcodec.h | 7 +++++++ libavcodec/options.c | 6 ++++++ libavcodec/version.h | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 2eb218ba4f..e067ee0273 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -2836,6 +2836,13 @@ typedef struct AVCodecContext { * - decoding: Set by libavcodec. */ enum AVAudioServiceType audio_service_type; + + /** + * Used to request a sample format from the decoder. + * - encoding: unused. + * - decoding: Set by user. + */ + enum AVSampleFormat request_sample_fmt; } AVCodecContext; /** diff --git a/libavcodec/options.c b/libavcodec/options.c index 9c714fb73e..8f9aec4ac2 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -441,6 +441,12 @@ static const AVOption options[]={ {"em", "Emergency", 0, FF_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_EMERGENCY }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, {"vo", "Voice Over", 0, FF_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_VOICE_OVER }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, {"ka", "Karaoke", 0, FF_OPT_TYPE_CONST, {.dbl = AV_AUDIO_SERVICE_TYPE_KARAOKE }, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"request_sample_fmt", NULL, OFFSET(request_sample_fmt), FF_OPT_TYPE_INT, {.dbl = AV_SAMPLE_FMT_NONE }, AV_SAMPLE_FMT_NONE, AV_SAMPLE_FMT_NB-1, A|D, "request_sample_fmt"}, +{"u8" , "8-bit unsigned integer", 0, FF_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_U8 }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, +{"s16", "16-bit signed integer", 0, FF_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_S16 }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, +{"s32", "32-bit signed integer", 0, FF_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_S32 }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, +{"flt", "32-bit float", 0, FF_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_FLT }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, +{"dbl", "64-bit double", 0, FF_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_DBL }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, {NULL}, }; diff --git a/libavcodec/version.h b/libavcodec/version.h index 1b454b8bd6..0def0d1ff9 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -21,7 +21,7 @@ #define AVCODEC_VERSION_H #define LIBAVCODEC_VERSION_MAJOR 53 -#define LIBAVCODEC_VERSION_MINOR 3 +#define LIBAVCODEC_VERSION_MINOR 4 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ From 00e5da893dc8f67cbc9ed940c4da9423a01e4f8c Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 21 Apr 2011 10:48:05 -0400 Subject: [PATCH 14/17] Add APIchanges entry for request_sample_fmt. --- doc/APIchanges | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/APIchanges b/doc/APIchanges index ee96ddf258..faa1698684 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2011-04-18 API changes, most recent first: +2011-xx-xx - xxxxxxx - lavc 53.4.0 - AVCodecContext.request_sample_fmt + Add request_sample_fmt field to AVCodecContext. + 2011-05-10 - 188dea1 - lavc 53.3.0 - avcodec.h Deprecate AVLPCType and the following fields in AVCodecContext: lpc_coeff_precision, prediction_order_method, From bc778a0cea3027941afa1ff6bbb424b3159a0b27 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 24 Apr 2011 16:48:42 -0400 Subject: [PATCH 15/17] Add support for request_sample_format in ffmpeg and ffplay. --- ffmpeg.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- ffplay.c | 17 +++++++++++++ 2 files changed, 87 insertions(+), 2 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index c99c4de024..71be22e05e 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -546,6 +546,46 @@ static void choose_sample_fmt(AVStream *st, AVCodec *codec) } } +/** + * Update the requested input sample format based on the output sample format. + * This is currently only used to request float output from decoders which + * support multiple sample formats, one of which is AV_SAMPLE_FMT_FLT. + * Ideally this will be removed in the future when decoders do not do format + * conversion and only output in their native format. + */ +static void update_sample_fmt(AVCodecContext *dec, AVCodec *dec_codec, + AVCodecContext *enc) +{ + /* if sample formats match or a decoder sample format has already been + requested, just return */ + if (enc->sample_fmt == dec->sample_fmt || + dec->request_sample_fmt > AV_SAMPLE_FMT_NONE) + return; + + /* if decoder supports more than one output format */ + if (dec_codec && dec_codec->sample_fmts && + dec_codec->sample_fmts[0] != AV_SAMPLE_FMT_NONE && + dec_codec->sample_fmts[1] != AV_SAMPLE_FMT_NONE) { + enum AVSampleFormat *p; + int min_dec = -1, min_inc = -1; + + /* find a matching sample format in the encoder */ + for (p = dec_codec->sample_fmts; *p != AV_SAMPLE_FMT_NONE; p++) { + if (*p == enc->sample_fmt) { + dec->request_sample_fmt = *p; + return; + } else if (*p > enc->sample_fmt) { + min_inc = FFMIN(min_inc, *p - enc->sample_fmt); + } else + min_dec = FFMIN(min_dec, enc->sample_fmt - *p); + } + + /* if none match, provide the one that matches quality closest */ + dec->request_sample_fmt = min_inc > 0 ? enc->sample_fmt + min_inc : + enc->sample_fmt - min_dec; + } +} + static void choose_sample_rate(AVStream *st, AVCodec *codec) { if(codec && codec->supported_samplerates){ @@ -751,7 +791,7 @@ need_realloc: ffmpeg_exit(1); } - if (enc->channels != dec->channels) + if (enc->channels != dec->channels || enc->sample_rate != dec->sample_rate) ost->audio_resample = 1; resample_changed = ost->resample_sample_fmt != dec->sample_fmt || @@ -777,7 +817,7 @@ need_realloc: ost->resample_sample_rate == enc->sample_rate) { ost->resample = NULL; ost->audio_resample = 0; - } else { + } else if (ost->audio_resample) { if (dec->sample_fmt != AV_SAMPLE_FMT_S16) fprintf(stderr, "Warning, using s16 intermediate sample format for resampling\n"); ost->resample = av_audio_resample_init(enc->channels, dec->channels, @@ -2308,6 +2348,17 @@ static int transcode(AVFormatContext **output_files, ret = AVERROR(EINVAL); goto dump_format; } + + /* update requested sample format for the decoder based on the + corresponding encoder sample format */ + for (j = 0; j < nb_ostreams; j++) { + ost = ost_table[j]; + if (ost->source_index == i) { + update_sample_fmt(ist->st->codec, codec, ost->st->codec); + break; + } + } + if (avcodec_open(ist->st->codec, codec) < 0) { snprintf(error, sizeof(error), "Error while opening decoder for input stream #%d.%d", ist->file_index, ist->index); @@ -3179,6 +3230,23 @@ static void opt_input_file(const char *filename) ic->loop_input = loop_input; + /* Set AVCodecContext options so they will be seen by av_find_stream_info() */ + for (i = 0; i < ic->nb_streams; i++) { + AVCodecContext *dec = ic->streams[i]->codec; + switch (dec->codec_type) { + case AVMEDIA_TYPE_AUDIO: + set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_AUDIO], + AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM, + NULL); + break; + case AVMEDIA_TYPE_VIDEO: + set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_VIDEO], + AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM, + NULL); + break; + } + } + /* If not enough info to get the stream parameters, we decode the first frames to get it. (used in mpeg case for example) */ ret = av_find_stream_info(ic); diff --git a/ffplay.c b/ffplay.c index a5dc358f72..c3dc970a1e 100644 --- a/ffplay.c +++ b/ffplay.c @@ -2412,6 +2412,23 @@ static int decode_thread(void *arg) if(genpts) ic->flags |= AVFMT_FLAG_GENPTS; + /* Set AVCodecContext options so they will be seen by av_find_stream_info() */ + for (i = 0; i < ic->nb_streams; i++) { + AVCodecContext *dec = ic->streams[i]->codec; + switch (dec->codec_type) { + case AVMEDIA_TYPE_AUDIO: + set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_AUDIO], + AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM, + NULL); + break; + case AVMEDIA_TYPE_VIDEO: + set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_VIDEO], + AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM, + NULL); + break; + } + } + err = av_find_stream_info(ic); if (err < 0) { fprintf(stderr, "%s: could not find codec parameters\n", is->filename); From 9aa8193a234ccb6a79cba5cc550531f62ffb0a17 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 22 Apr 2011 21:30:19 -0400 Subject: [PATCH 16/17] Add floating-point sample format support to the ac3, eac3, dca, aac, and vorbis decoders. Based on patches by clsid2 in ffdshow-tryout. --- libavcodec/aacdec.c | 34 ++++++++++++++++++++++++---------- libavcodec/aacsbr.c | 11 ++++++++--- libavcodec/aacsbr.h | 2 +- libavcodec/ac3dec.c | 32 ++++++++++++++++++++++++++------ libavcodec/dca.c | 34 +++++++++++++++++++++++++++------- libavcodec/vorbisdec.c | 23 ++++++++++++++++++----- 6 files changed, 104 insertions(+), 32 deletions(-) diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index 5f9dd834a0..f2d50f4aba 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -186,7 +186,7 @@ static av_cold int che_configure(AACContext *ac, if (che_pos[type][id]) { if (!ac->che[type][id] && !(ac->che[type][id] = av_mallocz(sizeof(ChannelElement)))) return AVERROR(ENOMEM); - ff_aac_sbr_ctx_init(&ac->che[type][id]->sbr); + ff_aac_sbr_ctx_init(ac, &ac->che[type][id]->sbr); if (type != TYPE_CCE) { ac->output_data[(*channels)++] = ac->che[type][id]->ch[0].ret; if (type == TYPE_CPE || @@ -546,6 +546,7 @@ static void reset_predictor_group(PredictorState *ps, int group_num) static av_cold int aac_decode_init(AVCodecContext *avctx) { AACContext *ac = avctx->priv_data; + float output_scale_factor; ac->avctx = avctx; ac->m4ac.sample_rate = avctx->sample_rate; @@ -557,7 +558,13 @@ static av_cold int aac_decode_init(AVCodecContext *avctx) return -1; } - avctx->sample_fmt = AV_SAMPLE_FMT_S16; + if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT) { + avctx->sample_fmt = AV_SAMPLE_FMT_FLT; + output_scale_factor = 1.0 / 32768.0; + } else { + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + output_scale_factor = 1.0; + } AAC_INIT_VLC_STATIC( 0, 304); AAC_INIT_VLC_STATIC( 1, 270); @@ -585,9 +592,9 @@ static av_cold int aac_decode_init(AVCodecContext *avctx) ff_aac_scalefactor_code, sizeof(ff_aac_scalefactor_code[0]), sizeof(ff_aac_scalefactor_code[0]), 352); - ff_mdct_init(&ac->mdct, 11, 1, 1.0/1024.0); - ff_mdct_init(&ac->mdct_small, 8, 1, 1.0/128.0); - ff_mdct_init(&ac->mdct_ltp, 11, 0, -2.0); + ff_mdct_init(&ac->mdct, 11, 1, output_scale_factor/1024.0); + ff_mdct_init(&ac->mdct_small, 8, 1, output_scale_factor/128.0); + ff_mdct_init(&ac->mdct_ltp, 11, 0, -2.0/output_scale_factor); // window initialization ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024); ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128); @@ -2169,7 +2176,8 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, avctx->frame_size = samples; } - data_size_tmp = samples * avctx->channels * sizeof(int16_t); + data_size_tmp = samples * avctx->channels * + (av_get_bits_per_sample_fmt(avctx->sample_fmt) / 8); if (*data_size < data_size_tmp) { av_log(avctx, AV_LOG_ERROR, "Output buffer too small (%d) or trying to output too many samples (%d) for this frame.\n", @@ -2178,8 +2186,14 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, } *data_size = data_size_tmp; - if (samples) - ac->fmt_conv.float_to_int16_interleave(data, (const float **)ac->output_data, samples, avctx->channels); + if (samples) { + if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) + ac->fmt_conv.float_interleave(data, (const float **)ac->output_data, + samples, avctx->channels); + else + ac->fmt_conv.float_to_int16_interleave(data, (const float **)ac->output_data, + samples, avctx->channels); + } if (ac->output_configured) ac->output_configured = OC_LOCKED; @@ -2497,7 +2511,7 @@ AVCodec ff_aac_decoder = { aac_decode_frame, .long_name = NULL_IF_CONFIG_SMALL("Advanced Audio Coding"), .sample_fmts = (const enum AVSampleFormat[]) { - AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE + AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, .channel_layouts = aac_channel_layout, }; @@ -2517,7 +2531,7 @@ AVCodec ff_aac_latm_decoder = { .decode = latm_decode_frame, .long_name = NULL_IF_CONFIG_SMALL("AAC LATM (Advanced Audio Codec LATM syntax)"), .sample_fmts = (const enum AVSampleFormat[]) { - AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE + AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, .channel_layouts = aac_channel_layout, }; diff --git a/libavcodec/aacsbr.c b/libavcodec/aacsbr.c index 7a217abfda..81b0b4c001 100644 --- a/libavcodec/aacsbr.c +++ b/libavcodec/aacsbr.c @@ -126,14 +126,19 @@ av_cold void ff_aac_sbr_init(void) ff_ps_init(); } -av_cold void ff_aac_sbr_ctx_init(SpectralBandReplication *sbr) +av_cold void ff_aac_sbr_ctx_init(AACContext *ac, SpectralBandReplication *sbr) { + float mdct_scale; sbr->kx[0] = sbr->kx[1] = 32; //Typo in spec, kx' inits to 32 sbr->data[0].e_a[1] = sbr->data[1].e_a[1] = -1; sbr->data[0].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128); sbr->data[1].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128); - ff_mdct_init(&sbr->mdct, 7, 1, 1.0/64); - ff_mdct_init(&sbr->mdct_ana, 7, 1, -2.0); + /* SBR requires samples to be scaled to +/-32768.0 to work correctly. + * mdct scale factors are adjusted to scale up from +/-1.0 at analysis + * and scale back down at synthesis. */ + mdct_scale = ac->avctx->sample_fmt == AV_SAMPLE_FMT_FLT ? 32768.0f : 1.0f; + ff_mdct_init(&sbr->mdct, 7, 1, 1.0 / (64 * mdct_scale)); + ff_mdct_init(&sbr->mdct_ana, 7, 1, -2.0 * mdct_scale); ff_ps_ctx_init(&sbr->ps); } diff --git a/libavcodec/aacsbr.h b/libavcodec/aacsbr.h index dca83305ad..153070d3f2 100644 --- a/libavcodec/aacsbr.h +++ b/libavcodec/aacsbr.h @@ -36,7 +36,7 @@ /** Initialize SBR. */ av_cold void ff_aac_sbr_init(void); /** Initialize one SBR context. */ -av_cold void ff_aac_sbr_ctx_init(SpectralBandReplication *sbr); +av_cold void ff_aac_sbr_ctx_init(AACContext *ac, SpectralBandReplication *sbr); /** Close one SBR context. */ av_cold void ff_aac_sbr_ctx_close(SpectralBandReplication *sbr); /** Decode one SBR element. */ diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 015ebaebec..2966c33b25 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -189,7 +189,13 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx) av_lfg_init(&s->dith_state, 0); /* set scale value for float to int16 conversion */ - s->mul_bias = 32767.0f; + if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT) { + s->mul_bias = 1.0f; + avctx->sample_fmt = AV_SAMPLE_FMT_FLT; + } else { + s->mul_bias = 32767.0f; + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + } /* allow downmixing to stereo or mono */ if (avctx->channels > 0 && avctx->request_channels > 0 && @@ -204,7 +210,6 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx) if (!s->input_buffer) return AVERROR(ENOMEM); - avctx->sample_fmt = AV_SAMPLE_FMT_S16; return 0; } @@ -1299,7 +1304,8 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; AC3DecodeContext *s = avctx->priv_data; - int16_t *out_samples = (int16_t *)data; + float *out_samples_flt = data; + int16_t *out_samples_s16 = data; int blk, ch, err; const uint8_t *channel_map; const float *output[AC3_MAX_CHANNELS]; @@ -1405,10 +1411,18 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, av_log(avctx, AV_LOG_ERROR, "error decoding the audio block\n"); err = 1; } - s->fmt_conv.float_to_int16_interleave(out_samples, output, 256, s->out_channels); - out_samples += 256 * s->out_channels; + if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) { + s->fmt_conv.float_interleave(out_samples_flt, output, 256, + s->out_channels); + out_samples_flt += 256 * s->out_channels; + } else { + s->fmt_conv.float_to_int16_interleave(out_samples_s16, output, 256, + s->out_channels); + out_samples_s16 += 256 * s->out_channels; + } } - *data_size = s->num_blocks * 256 * avctx->channels * sizeof (int16_t); + *data_size = s->num_blocks * 256 * avctx->channels * + (av_get_bits_per_sample_fmt(avctx->sample_fmt) / 8); return FFMIN(buf_size, s->frame_size); } @@ -1435,6 +1449,9 @@ AVCodec ff_ac3_decoder = { .close = ac3_decode_end, .decode = ac3_decode_frame, .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), + .sample_fmts = (const enum AVSampleFormat[]) { + AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE + }, }; #if CONFIG_EAC3_DECODER @@ -1447,5 +1464,8 @@ AVCodec ff_eac3_decoder = { .close = ac3_decode_end, .decode = ac3_decode_frame, .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52B (AC-3, E-AC-3)"), + .sample_fmts = (const enum AVSampleFormat[]) { + AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE + }, }; #endif diff --git a/libavcodec/dca.c b/libavcodec/dca.c index f1cd64e9ed..dbadebacff 100644 --- a/libavcodec/dca.c +++ b/libavcodec/dca.c @@ -1626,7 +1626,9 @@ static int dca_decode_frame(AVCodecContext * avctx, int lfe_samples; int num_core_channels = 0; int i; - int16_t *samples = data; + float *samples_flt = data; + int16_t *samples_s16 = data; + int out_size; DCAContext *s = avctx->priv_data; int channels; int core_ss_end; @@ -1812,9 +1814,11 @@ static int dca_decode_frame(AVCodecContext * avctx, return -1; } - if (*data_size < (s->sample_blocks / 8) * 256 * sizeof(int16_t) * channels) + out_size = 256 / 8 * s->sample_blocks * channels * + (av_get_bits_per_sample_fmt(avctx->sample_fmt) / 8); + if (*data_size < out_size) return -1; - *data_size = 256 / 8 * s->sample_blocks * sizeof(int16_t) * channels; + *data_size = out_size; /* filter to get final output */ for (i = 0; i < (s->sample_blocks / 8); i++) { @@ -1833,8 +1837,16 @@ static int dca_decode_frame(AVCodecContext * avctx, } } - s->fmt_conv.float_to_int16_interleave(samples, s->samples_chanptr, 256, channels); - samples += 256 * channels; + if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) { + s->fmt_conv.float_interleave(samples_flt, s->samples_chanptr, 256, + channels); + samples_flt += 256 * channels; + } else { + s->fmt_conv.float_to_int16_interleave(samples_s16, + s->samples_chanptr, 256, + channels); + samples_s16 += 256 * channels; + } } /* update lfe history */ @@ -1870,9 +1882,14 @@ static av_cold int dca_decode_init(AVCodecContext * avctx) for (i = 0; i < DCA_PRIM_CHANNELS_MAX+1; i++) s->samples_chanptr[i] = s->samples + i * 256; - avctx->sample_fmt = AV_SAMPLE_FMT_S16; - s->scale_bias = 1.0; + if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT) { + avctx->sample_fmt = AV_SAMPLE_FMT_FLT; + s->scale_bias = 1.0 / 32768.0; + } else { + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + s->scale_bias = 1.0; + } /* allow downmixing to stereo */ if (avctx->channels > 0 && avctx->request_channels < avctx->channels && @@ -1909,5 +1926,8 @@ AVCodec ff_dca_decoder = { .close = dca_decode_end, .long_name = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"), .capabilities = CODEC_CAP_CHANNEL_CONF, + .sample_fmts = (const enum AVSampleFormat[]) { + AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE + }, .profiles = NULL_IF_CONFIG_SMALL(profiles), }; diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c index 7443e98a64..f6ec74f4a1 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -979,7 +979,13 @@ static av_cold int vorbis_decode_init(AVCodecContext *avccontext) dsputil_init(&vc->dsp, avccontext); ff_fmt_convert_init(&vc->fmt_conv, avccontext); - vc->scale_bias = 32768.0f; + if (avccontext->request_sample_fmt == AV_SAMPLE_FMT_FLT) { + avccontext->sample_fmt = AV_SAMPLE_FMT_FLT; + vc->scale_bias = 1.0f; + } else { + avccontext->sample_fmt = AV_SAMPLE_FMT_S16; + vc->scale_bias = 32768.0f; + } if (!headers_len) { av_log(avccontext, AV_LOG_ERROR, "Extradata missing.\n"); @@ -1024,7 +1030,6 @@ static av_cold int vorbis_decode_init(AVCodecContext *avccontext) avccontext->channels = vc->audio_channels; avccontext->sample_rate = vc->audio_samplerate; avccontext->frame_size = FFMIN(vc->blocksize[0], vc->blocksize[1]) >> 2; - avccontext->sample_fmt = AV_SAMPLE_FMT_S16; return 0 ; } @@ -1634,9 +1639,14 @@ static int vorbis_decode_frame(AVCodecContext *avccontext, len * ff_vorbis_channel_layout_offsets[vc->audio_channels - 1][i]; } - vc->fmt_conv.float_to_int16_interleave(data, channel_ptrs, len, - vc->audio_channels); - *data_size = len * 2 * vc->audio_channels; + if (avccontext->sample_fmt == AV_SAMPLE_FMT_FLT) + vc->fmt_conv.float_interleave(data, channel_ptrs, len, vc->audio_channels); + else + vc->fmt_conv.float_to_int16_interleave(data, channel_ptrs, len, + vc->audio_channels); + + *data_size = len * vc->audio_channels * + (av_get_bits_per_sample_fmt(avccontext->sample_fmt) / 8); return buf_size ; } @@ -1663,5 +1673,8 @@ AVCodec ff_vorbis_decoder = { vorbis_decode_frame, .long_name = NULL_IF_CONFIG_SMALL("Vorbis"), .channel_layouts = ff_vorbis_channel_layouts, + .sample_fmts = (const enum AVSampleFormat[]) { + AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE + }, }; From 41e21e4db623ebd77f431a6f30cf21d62d9e1f33 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 18 May 2011 17:52:31 -0400 Subject: [PATCH 17/17] APIchanges: fill in date and commit for request_sample_fmt --- doc/APIchanges | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index faa1698684..853975e76d 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,7 +13,7 @@ libavutil: 2011-04-18 API changes, most recent first: -2011-xx-xx - xxxxxxx - lavc 53.4.0 - AVCodecContext.request_sample_fmt +2011-05-18 - 64150ff - lavc 53.4.0 - AVCodecContext.request_sample_fmt Add request_sample_fmt field to AVCodecContext. 2011-05-10 - 188dea1 - lavc 53.3.0 - avcodec.h