From 29a290439ba28fde00b2a27d5afef863c63abb37 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Fri, 1 Apr 2011 09:26:38 +0200 Subject: [PATCH 01/10] ape: check that number of seektable entries is equal to number of frames fixes issue2480 Signed-off-by: Anton Khirnov --- libavformat/ape.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavformat/ape.c b/libavformat/ape.c index 6c8880d2c0..5aac00c56a 100644 --- a/libavformat/ape.c +++ b/libavformat/ape.c @@ -250,6 +250,11 @@ static int ape_read_header(AVFormatContext * s, AVFormatParameters * ap) av_log(s, AV_LOG_ERROR, "Too many frames: %d\n", ape->totalframes); return -1; } + if (ape->seektablelength && (ape->seektablelength / sizeof(*ape->seektable)) < ape->totalframes) { + av_log(s, AV_LOG_ERROR, "Number of seek entries is less than number of frames: %d vs. %d\n", + ape->seektablelength / sizeof(*ape->seektable), ape->totalframes); + return AVERROR_INVALIDDATA; + } ape->frames = av_malloc(ape->totalframes * sizeof(APEFrame)); if(!ape->frames) return AVERROR(ENOMEM); From 6efe6028ed182d82d4ac8b9801fbcee91a88c053 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Wed, 30 Mar 2011 21:13:21 +0100 Subject: [PATCH 02/10] Fixed-point support in fft-test Signed-off-by: Mans Rullgard --- libavcodec/Makefile | 2 +- libavcodec/fft-fixed-test.c | 20 ++++++++++ libavcodec/fft-test.c | 73 ++++++++++++++++++++++++++----------- 3 files changed, 72 insertions(+), 23 deletions(-) create mode 100644 libavcodec/fft-fixed-test.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 4f3392fcf5..837f7e2d1d 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -656,7 +656,7 @@ SKIPHEADERS += mpegaudio3.h EXAMPLES = api -TESTPROGS = cabac dct eval fft h264 iirfilter rangecoder snow +TESTPROGS = cabac dct eval fft fft-fixed h264 iirfilter rangecoder snow TESTPROGS-$(HAVE_MMX) += motion TESTOBJS = dctref.o diff --git a/libavcodec/fft-fixed-test.c b/libavcodec/fft-fixed-test.c new file mode 100644 index 0000000000..63cd194576 --- /dev/null +++ b/libavcodec/fft-fixed-test.c @@ -0,0 +1,20 @@ +/* + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define CONFIG_FFT_FLOAT 0 +#include "fft-test.c" diff --git a/libavcodec/fft-test.c b/libavcodec/fft-test.c index acfc5631ce..0112c6fcbb 100644 --- a/libavcodec/fft-test.c +++ b/libavcodec/fft-test.c @@ -27,8 +27,10 @@ #include "libavutil/lfg.h" #include "libavutil/log.h" #include "fft.h" +#if CONFIG_FFT_FLOAT #include "dct.h" #include "rdft.h" +#endif #include #include #include @@ -47,7 +49,19 @@ pim += (MUL16(are, bim) + MUL16(bre, aim));\ } -FFTComplex *exptab; +#if CONFIG_FFT_FLOAT +# define RANGE 1.0 +# define REF_SCALE(x, bits) (x) +# define FMT "%10.6f" +#else +# define RANGE 16384 +# define REF_SCALE(x, bits) ((x) / (1<<(bits))) +# define FMT "%6d" +#endif + +struct { + float re, im; +} *exptab; static void fft_ref_init(int nbits, int inverse) { @@ -55,7 +69,7 @@ static void fft_ref_init(int nbits, int inverse) double c1, s1, alpha; n = 1 << nbits; - exptab = av_malloc((n / 2) * sizeof(FFTComplex)); + exptab = av_malloc((n / 2) * sizeof(*exptab)); for (i = 0; i < (n/2); i++) { alpha = 2 * M_PI * (float)i / (float)n; @@ -92,12 +106,12 @@ static void fft_ref(FFTComplex *tabr, FFTComplex *tab, int nbits) CMAC(tmp_re, tmp_im, c, s, q->re, q->im); q++; } - tabr[i].re = tmp_re; - tabr[i].im = tmp_im; + tabr[i].re = REF_SCALE(tmp_re, nbits); + tabr[i].im = REF_SCALE(tmp_im, nbits); } } -static void imdct_ref(float *out, float *in, int nbits) +static void imdct_ref(FFTSample *out, FFTSample *in, int nbits) { int n = 1<= 1e-3) { - av_log(NULL, AV_LOG_ERROR, "ERROR %5d: %10.6f %10.6f\n", + av_log(NULL, AV_LOG_ERROR, "ERROR %5d: "FMT" "FMT"\n", i, tab1[i], tab2[i]); err = 1; } @@ -233,8 +249,10 @@ int main(int argc, char **argv) int do_inverse = 0; FFTContext s1, *s = &s1; FFTContext m1, *m = &m1; +#if CONFIG_FFT_FLOAT RDFTContext r1, *r = &r1; DCTContext d1, *d = &d1; +#endif int fft_nbits, fft_size, fft_size_2; double scale = 1.0; AVLFG prng; @@ -297,6 +315,7 @@ int main(int argc, char **argv) ff_fft_init(s, fft_nbits, do_inverse); fft_ref_init(fft_nbits, do_inverse); break; +#if CONFIG_FFT_FLOAT case TRANSFORM_RDFT: if (do_inverse) av_log(NULL, AV_LOG_INFO,"IDFT_C2R"); @@ -312,6 +331,10 @@ int main(int argc, char **argv) av_log(NULL, AV_LOG_INFO,"DCT_II"); ff_dct_init(d, fft_nbits, do_inverse ? DCT_III : DCT_II); break; +#endif + default: + av_log(NULL, AV_LOG_ERROR, "Requested transform not supported\n"); + return 1; } av_log(NULL, AV_LOG_INFO," %d test\n", fft_size); @@ -328,15 +351,15 @@ int main(int argc, char **argv) switch (transform) { case TRANSFORM_MDCT: if (do_inverse) { - imdct_ref((float *)tab_ref, (float *)tab1, fft_nbits); - m->imdct_calc(m, tab2, (float *)tab1); - err = check_diff((float *)tab_ref, tab2, fft_size, scale); + imdct_ref((FFTSample *)tab_ref, (FFTSample *)tab1, fft_nbits); + m->imdct_calc(m, tab2, (FFTSample *)tab1); + err = check_diff((FFTSample *)tab_ref, tab2, fft_size, scale); } else { - mdct_ref((float *)tab_ref, (float *)tab1, fft_nbits); + mdct_ref((FFTSample *)tab_ref, (FFTSample *)tab1, fft_nbits); - m->mdct_calc(m, tab2, (float *)tab1); + m->mdct_calc(m, tab2, (FFTSample *)tab1); - err = check_diff((float *)tab_ref, tab2, fft_size / 2, scale); + err = check_diff((FFTSample *)tab_ref, tab2, fft_size / 2, scale); } break; case TRANSFORM_FFT: @@ -345,8 +368,9 @@ int main(int argc, char **argv) s->fft_calc(s, tab); fft_ref(tab_ref, tab1, fft_nbits); - err = check_diff((float *)tab_ref, (float *)tab, fft_size * 2, 1.0); + err = check_diff((FFTSample *)tab_ref, (FFTSample *)tab, fft_size * 2, 1.0); break; +#if CONFIG_FFT_FLOAT case TRANSFORM_RDFT: if (do_inverse) { tab1[ 0].im = 0; @@ -387,6 +411,7 @@ int main(int argc, char **argv) } err = check_diff((float *)tab_ref, (float *)tab, fft_size, 1.0); break; +#endif } /* do a speed test */ @@ -404,15 +429,16 @@ int main(int argc, char **argv) switch (transform) { case TRANSFORM_MDCT: if (do_inverse) { - m->imdct_calc(m, (float *)tab, (float *)tab1); + m->imdct_calc(m, (FFTSample *)tab, (FFTSample *)tab1); } else { - m->mdct_calc(m, (float *)tab, (float *)tab1); + m->mdct_calc(m, (FFTSample *)tab, (FFTSample *)tab1); } break; case TRANSFORM_FFT: memcpy(tab, tab1, fft_size * sizeof(FFTComplex)); s->fft_calc(s, tab); break; +#if CONFIG_FFT_FLOAT case TRANSFORM_RDFT: memcpy(tab2, tab1, fft_size * sizeof(FFTSample)); r->rdft_calc(r, tab2); @@ -421,6 +447,7 @@ int main(int argc, char **argv) memcpy(tab2, tab1, fft_size * sizeof(FFTSample)); d->dct_calc(d, tab2); break; +#endif } } duration = gettime() - time_start; @@ -441,12 +468,14 @@ int main(int argc, char **argv) case TRANSFORM_FFT: ff_fft_end(s); break; +#if CONFIG_FFT_FLOAT case TRANSFORM_RDFT: ff_rdft_end(r); break; case TRANSFORM_DCT: ff_dct_end(d); break; +#endif } av_free(tab); From b41a1089141ae819fee1e3d37967edb622bce841 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Thu, 31 Mar 2011 16:02:25 +0100 Subject: [PATCH 03/10] fate: add fixed-point fft/mdct tests Signed-off-by: Mans Rullgard --- tests/fate/fft.mak | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/fate/fft.mak b/tests/fate/fft.mak index 97da53ff1c..b1499e26f0 100644 --- a/tests/fate/fft.mak +++ b/tests/fate/fft.mak @@ -33,3 +33,17 @@ fate-idct1d: CMD = run libavcodec/fft-test -d -i FATE_TESTS += $(FATE_FFT) fate-fft-test: $(FATE_FFT) $(FATE_FFT): REF = /dev/null + +FATE_FFT_FIXED = fate-fft-fixed fate-ifft-fixed \ + fate-mdct-fixed fate-imdct-fixed + +fate-fft-fixed: CMD = run libavcodec/fft-fixed-test +fate-ifft-fixed: CMD = run libavcodec/fft-fixed-test -i +fate-mdct-fixed: CMD = run libavcodec/fft-fixed-test -m +fate-imdct-fixed: CMD = run libavcodec/fft-fixed-test -m -i + +fate-fft-fixed-test: $(FATE_FFT_FIXED) +$(FATE_FFT_FIXED): libavcodec/fft-fixed-test$(EXESUF) +$(FATE_FFT_FIXED): REF = /dev/null + +FATE_TESTS += $(FATE_FFT_FIXED) From 41327cca613e52a3030b0f133b38bcddff05243c Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sun, 27 Mar 2011 14:49:55 +0100 Subject: [PATCH 04/10] FFT: simplify fft8() Part of the fft8() function corresponds to the BUTTERFLIES macro, so use it. Signed-off-by: Mans Rullgard --- libavcodec/fft.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/libavcodec/fft.c b/libavcodec/fft.c index 2da5b43d5f..ff5d34baf3 100644 --- a/libavcodec/fft.c +++ b/libavcodec/fft.c @@ -246,21 +246,16 @@ static void fft4(FFTComplex *z) static void fft8(FFTComplex *z) { - FFTDouble t1, t2, t3, t4, t5, t6, t7, t8; + FFTDouble t1, t2, t3, t4, t5, t6; fft4(z); BF(t1, z[5].re, z[4].re, -z[5].re); BF(t2, z[5].im, z[4].im, -z[5].im); - BF(t3, z[7].re, z[6].re, -z[7].re); - BF(t4, z[7].im, z[6].im, -z[7].im); - BF(t8, t1, t3, t1); - BF(t7, t2, t2, t4); - BF(z[4].re, z[0].re, z[0].re, t1); - BF(z[4].im, z[0].im, z[0].im, t2); - BF(z[6].re, z[2].re, z[2].re, t7); - BF(z[6].im, z[2].im, z[2].im, t8); + BF(t5, z[7].re, z[6].re, -z[7].re); + BF(t6, z[7].im, z[6].im, -z[7].im); + BUTTERFLIES(z[0],z[2],z[4],z[6]); TRANSFORM(z[1],z[3],z[5],z[7],sqrthalf,sqrthalf); } From 0e635f3e86956bd85896831f3c7e6dfaef97bf7d Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Thu, 31 Mar 2011 10:42:22 -0400 Subject: [PATCH 05/10] sierravmd: fix Indeo3 videos Signed-off-by: Anton Khirnov --- libavformat/sierravmd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/sierravmd.c b/libavformat/sierravmd.c index c43d6ee93a..c0fb22211b 100644 --- a/libavformat/sierravmd.c +++ b/libavformat/sierravmd.c @@ -99,7 +99,7 @@ static int vmd_read_header(AVFormatContext *s, if (avio_read(pb, vmd->vmd_header, VMD_HEADER_SIZE) != VMD_HEADER_SIZE) return AVERROR(EIO); - if(vmd->vmd_header[16] == 'i' && vmd->vmd_header[17] == 'v' && vmd->vmd_header[18] == '3') + if(vmd->vmd_header[24] == 'i' && vmd->vmd_header[25] == 'v' && vmd->vmd_header[26] == '3') vmd->is_indeo3 = 1; else vmd->is_indeo3 = 0; @@ -249,7 +249,7 @@ static int vmd_read_packet(AVFormatContext *s, return AVERROR(ENOMEM); pkt->pos= avio_tell(pb); memcpy(pkt->data, frame->frame_record, BYTES_PER_FRAME_RECORD); - if(vmd->is_indeo3) + if(vmd->is_indeo3 && frame->frame_record[0] == 0x02) ret = avio_read(pb, pkt->data, frame->frame_size); else ret = avio_read(pb, pkt->data + BYTES_PER_FRAME_RECORD, From ab11317c1f97db19eddebe1bc5d4cb5a53718c9f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 1 Apr 2011 03:02:02 +0200 Subject: [PATCH 06/10] lavf: make compute_chapters_end less picky. In particular, now it assumes that a) chapters are chronologically ordered b) chapters have the same timebases c) duration of the stream is known and asserts if any of these is not met. Make it properly deal with harsher conditions. fixes issue2320 --- libavformat/utils.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/libavformat/utils.c b/libavformat/utils.c index 7ece0787f3..ca0bf7ec05 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2168,22 +2168,23 @@ enum CodecID av_codec_get_id(const AVCodecTag * const *tags, unsigned int tag) static void compute_chapters_end(AVFormatContext *s) { - unsigned int i; + unsigned int i, j; + int64_t max_time = s->duration + (s->start_time == AV_NOPTS_VALUE) ? 0 : s->start_time; - for (i=0; i+1nb_chapters; i++) + for (i = 0; i < s->nb_chapters; i++) if (s->chapters[i]->end == AV_NOPTS_VALUE) { - assert(s->chapters[i]->start <= s->chapters[i+1]->start); - assert(!av_cmp_q(s->chapters[i]->time_base, s->chapters[i+1]->time_base)); - s->chapters[i]->end = s->chapters[i+1]->start; + AVChapter *ch = s->chapters[i]; + int64_t end = max_time ? av_rescale_q(max_time, AV_TIME_BASE_Q, ch->time_base) + : INT64_MAX; + + for (j = 0; j < s->nb_chapters; j++) { + AVChapter *ch1 = s->chapters[j]; + int64_t next_start = av_rescale_q(ch1->start, ch1->time_base, ch->time_base); + if (j != i && next_start > ch->start && next_start < end) + end = next_start; + } + ch->end = (end == INT64_MAX) ? ch->start : end; } - - if (s->nb_chapters && s->chapters[i]->end == AV_NOPTS_VALUE) { - assert(s->start_time != AV_NOPTS_VALUE); - assert(s->duration > 0); - s->chapters[i]->end = av_rescale_q(s->start_time + s->duration, - AV_TIME_BASE_Q, - s->chapters[i]->time_base); - } } static int get_std_framerate(int i){ From 3c96c64821184247b46052dee74442024098f47f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 31 Mar 2011 13:57:48 +0200 Subject: [PATCH 07/10] avio: document avio_alloc_context. --- libavformat/avio.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/libavformat/avio.h b/libavformat/avio.h index 12fa2d586b..7c2726f656 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -458,6 +458,22 @@ attribute_deprecated void init_checksum(AVIOContext *s, attribute_deprecated unsigned long get_checksum(AVIOContext *s); #endif +/** + * Allocate and initialize an AVIOContext for buffered I/O. It must be later + * freed with av_free(). + * + * @param buffer Memory block for input/output operations via AVIOContext. + * @param buffer_size The buffer size is very important for performance. + * For protocols with fixed blocksize it should be set to this blocksize. + * For others a typical size is a cache page, e.g. 4kb. + * @param write_flag Set to 1 if the buffer should be writable, 0 otherwise. + * @param opaque An opaque pointer to user-specific data. + * @param read_packet A function for refilling the buffer, may be NULL. + * @param write_packet A function for writing the buffer contents, may be NULL. + * @param seek A function for seeking to specified byte position, may be NULL. + * + * @return Allocated AVIOContext or NULL on failure. + */ AVIOContext *avio_alloc_context( unsigned char *buffer, int buffer_size, From 5085a1a068d85cf68501d8efe09acfbd42ff3860 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Thu, 31 Mar 2011 16:46:36 +0100 Subject: [PATCH 08/10] fate: simplify fft test rules Signed-off-by: Mans Rullgard --- tests/fate/fft.mak | 46 ++++++++++++++-------------------------------- 1 file changed, 14 insertions(+), 32 deletions(-) diff --git a/tests/fate/fft.mak b/tests/fate/fft.mak index b1499e26f0..042a7bf322 100644 --- a/tests/fate/fft.mak +++ b/tests/fate/fft.mak @@ -1,37 +1,19 @@ -FATE_FFT += fate-fft -fate-fft: libavcodec/fft-test$(EXESUF) -fate-fft: CMD = run libavcodec/fft-test - -FATE_FFT += fate-ifft -fate-ifft: libavcodec/fft-test$(EXESUF) -fate-ifft: CMD = run libavcodec/fft-test -i - -FATE_FFT += fate-mdct -fate-mdct: libavcodec/fft-test$(EXESUF) -fate-mdct: CMD = run libavcodec/fft-test -m - -FATE_FFT += fate-imdct -fate-imdct: libavcodec/fft-test$(EXESUF) -fate-imdct: CMD = run libavcodec/fft-test -m -i - -FATE_FFT += fate-rdft -fate-rdft: libavcodec/fft-test$(EXESUF) -fate-rdft: CMD = run libavcodec/fft-test -r - -FATE_FFT += fate-irdft -fate-irdft: libavcodec/fft-test$(EXESUF) -fate-irdft: CMD = run libavcodec/fft-test -r -i - -FATE_FFT += fate-dct1d -fate-dct1d: libavcodec/fft-test$(EXESUF) -fate-dct1d: CMD = run libavcodec/fft-test -d - -FATE_FFT += fate-idct1d -fate-idct1d: libavcodec/fft-test$(EXESUF) +FATE_FFT = fate-fft fate-ifft \ + fate-mdct fate-imdct \ + fate-rdft fate-irdft \ + fate-dct1d fate-idct1d + +fate-fft: CMD = run libavcodec/fft-test +fate-ifft: CMD = run libavcodec/fft-test -i +fate-mdct: CMD = run libavcodec/fft-test -m +fate-imdct: CMD = run libavcodec/fft-test -m -i +fate-rdft: CMD = run libavcodec/fft-test -r +fate-irdft: CMD = run libavcodec/fft-test -r -i +fate-dct1d: CMD = run libavcodec/fft-test -d fate-idct1d: CMD = run libavcodec/fft-test -d -i -FATE_TESTS += $(FATE_FFT) fate-fft-test: $(FATE_FFT) +$(FATE_FFT): libavcodec/fft-test$(EXESUF) $(FATE_FFT): REF = /dev/null FATE_FFT_FIXED = fate-fft-fixed fate-ifft-fixed \ @@ -46,4 +28,4 @@ fate-fft-fixed-test: $(FATE_FFT_FIXED) $(FATE_FFT_FIXED): libavcodec/fft-fixed-test$(EXESUF) $(FATE_FFT_FIXED): REF = /dev/null -FATE_TESTS += $(FATE_FFT_FIXED) +FATE_TESTS += $(FATE_FFT) $(FATE_FFT_FIXED) From 182826c8846f2f7f0538c4b2a09e882e29881804 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Fri, 11 Mar 2011 02:50:57 +0000 Subject: [PATCH 09/10] ac3: armv6 optimised bit_alloc_calc_bap Signed-off-by: Mans Rullgard --- libavcodec/arm/Makefile | 2 + libavcodec/arm/ac3dsp_armv6.S | 83 ++++++++++++++++++++++++++++++++ libavcodec/arm/ac3dsp_init_arm.c | 9 ++++ 3 files changed, 94 insertions(+) create mode 100644 libavcodec/arm/ac3dsp_armv6.S diff --git a/libavcodec/arm/Makefile b/libavcodec/arm/Makefile index 08697da29b..27c2643de8 100644 --- a/libavcodec/arm/Makefile +++ b/libavcodec/arm/Makefile @@ -1,6 +1,8 @@ OBJS-$(CONFIG_AC3DSP) += arm/ac3dsp_init_arm.o OBJS-$(CONFIG_DCA_DECODER) += arm/dcadsp_init_arm.o \ +ARMV6-OBJS-$(CONFIG_AC3DSP) += arm/ac3dsp_armv6.o + OBJS-$(CONFIG_VP5_DECODER) += arm/vp56dsp_init_arm.o OBJS-$(CONFIG_VP6_DECODER) += arm/vp56dsp_init_arm.o OBJS-$(CONFIG_VP8_DECODER) += arm/vp8dsp_init_arm.o diff --git a/libavcodec/arm/ac3dsp_armv6.S b/libavcodec/arm/ac3dsp_armv6.S new file mode 100644 index 0000000000..7f01addbde --- /dev/null +++ b/libavcodec/arm/ac3dsp_armv6.S @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2011 Mans Rullgard + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "asm.S" + +function ff_ac3_bit_alloc_calc_bap_armv6, export=1 + ldr r12, [sp] + cmp r12, #-960 + beq 4f + push {r4-r11,lr} + add r5, sp, #40 + movrel r4, X(ff_ac3_bin_to_band_tab) + movrel lr, X(ff_ac3_band_start_tab) + ldm r5, {r5-r7} + ldrb r4, [r4, r2] + add r1, r1, r2, lsl #1 @ psd + start + add r0, r0, r4, lsl #1 @ mask + band + add r4, lr, r4 + add r7, r7, r2 @ bap + start + ldrb r10, [r4], #1 +1: + ldrsh r9, [r0], #2 @ mask[band] + movw r8, #0x1fe0 + sub r9, r9, r12 @ - snr_offset + mov r11, r10 + ldrb r10, [r4], #1 @ band_start_tab[band++] + subs r9, r9, r5 @ - floor + movlt r9, #0 + cmp r10, r3 @ - end + and r9, r9, r8 @ & 0x1fe0 + subgt r8, r3, r11 + suble r8, r10, r11 + add r9, r9, r5 @ + floor => m + tst r8, #1 + add r2, r7, r8 + bne 3f + b 5f +2: + ldrsh r8, [r1], #2 + ldrsh lr, [r1], #2 + sub r8, r8, r9 + sub lr, lr, r9 + usat r8, #6, r8, asr #5 @ address + usat lr, #6, lr, asr #5 + ldrb r8, [r6, r8] @ bap_tab[address] + ldrb lr, [r6, lr] + strb r8, [r7], #1 @ bap[bin] + strb lr, [r7], #1 +5: cmp r7, r2 + blo 2b + cmp r3, r11 + bgt 1b + pop {r4-r11,pc} +3: + ldrsh r8, [r1], #2 @ psd[bin] + sub r8, r8, r9 @ - m + usat r8, #6, r8, asr #5 @ address + ldrb r8, [r6, r8] @ bap_tab[address] + strb r8, [r7], #1 @ bap[bin] + b 5b +4: + ldr r0, [sp, #12] + mov r1, #0 + mov r2, #256 + b memset +endfunc diff --git a/libavcodec/arm/ac3dsp_init_arm.c b/libavcodec/arm/ac3dsp_init_arm.c index 03200e64cd..c1e96e2d1b 100644 --- a/libavcodec/arm/ac3dsp_init_arm.c +++ b/libavcodec/arm/ac3dsp_init_arm.c @@ -29,8 +29,17 @@ void ff_ac3_lshift_int16_neon(int16_t *src, unsigned len, unsigned shift); void ff_ac3_rshift_int32_neon(int32_t *src, unsigned len, unsigned shift); void ff_float_to_fixed24_neon(int32_t *dst, const float *src, unsigned int len); +void ff_ac3_bit_alloc_calc_bap_armv6(int16_t *mask, int16_t *psd, + int start, int end, + int snr_offset, int floor, + const uint8_t *bap_tab, uint8_t *bap); + av_cold void ff_ac3dsp_init_arm(AC3DSPContext *c, int bit_exact) { + if (HAVE_ARMV6) { + c->bit_alloc_calc_bap = ff_ac3_bit_alloc_calc_bap_armv6; + } + if (HAVE_NEON) { c->ac3_exponent_min = ff_ac3_exponent_min_neon; c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_neon; From aa05f2126e18d23432bde77e6f44e41691472fef Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Fri, 11 Mar 2011 17:25:45 +0000 Subject: [PATCH 10/10] ac3enc: ARM optimised ac3_compute_matissa_size Signed-off-by: Mans Rullgard --- libavcodec/arm/Makefile | 4 ++- libavcodec/arm/ac3dsp_arm.S | 52 ++++++++++++++++++++++++++++++++ libavcodec/arm/ac3dsp_init_arm.c | 4 +++ 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 libavcodec/arm/ac3dsp_arm.S diff --git a/libavcodec/arm/Makefile b/libavcodec/arm/Makefile index 27c2643de8..3b77a5548d 100644 --- a/libavcodec/arm/Makefile +++ b/libavcodec/arm/Makefile @@ -1,4 +1,6 @@ -OBJS-$(CONFIG_AC3DSP) += arm/ac3dsp_init_arm.o +OBJS-$(CONFIG_AC3DSP) += arm/ac3dsp_init_arm.o \ + arm/ac3dsp_arm.o + OBJS-$(CONFIG_DCA_DECODER) += arm/dcadsp_init_arm.o \ ARMV6-OBJS-$(CONFIG_AC3DSP) += arm/ac3dsp_armv6.o diff --git a/libavcodec/arm/ac3dsp_arm.S b/libavcodec/arm/ac3dsp_arm.S new file mode 100644 index 0000000000..d7d498e41f --- /dev/null +++ b/libavcodec/arm/ac3dsp_arm.S @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2011 Mans Rullgard + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "asm.S" + +function ff_ac3_compute_mantissa_size_arm, export=1 + push {r4-r8,lr} + ldm r0, {r4-r8} + mov r3, r0 + mov r0, #0 +1: + ldrb lr, [r1], #1 + subs r2, r2, #1 + blt 2f + cmp lr, #4 + bgt 3f + subs lr, lr, #1 + addlt r4, r4, #1 + addeq r5, r5, #1 + ble 1b + subs lr, lr, #2 + addlt r6, r6, #1 + addeq r7, r7, #1 + addgt r8, r8, #1 + b 1b +3: + cmp lr, #14 + sublt lr, lr, #1 + addgt r0, r0, #16 + addle r0, r0, lr + b 1b +2: + stm r3, {r4-r8} + pop {r4-r8,pc} +endfunc diff --git a/libavcodec/arm/ac3dsp_init_arm.c b/libavcodec/arm/ac3dsp_init_arm.c index c1e96e2d1b..92e4a4f291 100644 --- a/libavcodec/arm/ac3dsp_init_arm.c +++ b/libavcodec/arm/ac3dsp_init_arm.c @@ -34,8 +34,12 @@ void ff_ac3_bit_alloc_calc_bap_armv6(int16_t *mask, int16_t *psd, int snr_offset, int floor, const uint8_t *bap_tab, uint8_t *bap); +int ff_ac3_compute_mantissa_size_arm(int cnt[5], uint8_t *bap, int nb_coefs); + av_cold void ff_ac3dsp_init_arm(AC3DSPContext *c, int bit_exact) { + c->compute_mantissa_size = ff_ac3_compute_mantissa_size_arm; + if (HAVE_ARMV6) { c->bit_alloc_calc_bap = ff_ac3_bit_alloc_calc_bap_armv6; }