From a6363e3d89e7a32078d28e7fb77bb5246e2cadee Mon Sep 17 00:00:00 2001 From: Duncan Salerno Date: Sat, 6 Oct 2012 01:57:32 +0300 Subject: [PATCH 01/19] url: Don't treat slashes in query parameters as directory separators MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Strip off query parameters from the original url before applying the new relative path. Signed-off-by: Martin Storsjö --- libavformat/utils.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libavformat/utils.c b/libavformat/utils.c index bba5b2ae35..1fd0ba3e8e 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -3389,7 +3389,7 @@ int ff_find_stream_index(AVFormatContext *s, int id) void ff_make_absolute_url(char *buf, int size, const char *base, const char *rel) { - char *sep; + char *sep, *path_query; /* Absolute path, relative to the current server */ if (base && strstr(base, "://") && rel[0] == '/') { if (base != buf) @@ -3411,6 +3411,12 @@ void ff_make_absolute_url(char *buf, int size, const char *base, } if (base != buf) av_strlcpy(buf, base, size); + + /* Strip off any query string from base */ + path_query = strchr(buf, '?'); + if (path_query != NULL) + *path_query = '\0'; + /* Remove the file name from the base url */ sep = strrchr(buf, '/'); if (sep) From eea003814cc5afaea546a6d229690350bd7481af Mon Sep 17 00:00:00 2001 From: Duncan Salerno Date: Sat, 6 Oct 2012 01:58:48 +0300 Subject: [PATCH 02/19] url: Handle relative urls being just a new query string MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/utils.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libavformat/utils.c b/libavformat/utils.c index 1fd0ba3e8e..9d0049a9ad 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -3417,6 +3417,12 @@ void ff_make_absolute_url(char *buf, int size, const char *base, if (path_query != NULL) *path_query = '\0'; + /* Is relative path just a new query part? */ + if (rel[0] == '?') { + av_strlcat(buf, rel, size); + return; + } + /* Remove the file name from the base url */ sep = strrchr(buf, '/'); if (sep) From 33893e6abcdca865c06c64547be56070c64aa590 Mon Sep 17 00:00:00 2001 From: Duncan Salerno Date: Sat, 6 Oct 2012 02:02:18 +0300 Subject: [PATCH 03/19] url: Handle relative urls starting with two slashes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is defined by RFC 3986 section 5.4.1 to be handled this way. Signed-off-by: Martin Storsjö --- libavformat/utils.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/libavformat/utils.c b/libavformat/utils.c index 9d0049a9ad..ca52469bdb 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -3396,10 +3396,16 @@ void ff_make_absolute_url(char *buf, int size, const char *base, av_strlcpy(buf, base, size); sep = strstr(buf, "://"); if (sep) { - sep += 3; - sep = strchr(sep, '/'); - if (sep) - *sep = '\0'; + /* Take scheme from base url */ + if (rel[1] == '/') { + sep[1] = '\0'; + } else { + /* Take scheme and host from base url */ + sep += 3; + sep = strchr(sep, '/'); + if (sep) + *sep = '\0'; + } } av_strlcat(buf, rel, size); return; From 7bc433b36dbb0747c0c03e8222044b06e63ff75f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 6 Oct 2012 01:38:37 +0300 Subject: [PATCH 04/19] fate: Add tests of the ff_make_absolute_url function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/Makefile | 3 +- libavformat/url-test.c | 58 ++++++++++++++++++++++++++++++++++++++ tests/Makefile | 2 ++ tests/fate/libavformat.mak | 5 ++++ tests/ref/fate/url | 13 +++++++++ 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 libavformat/url-test.c create mode 100644 tests/fate/libavformat.mak create mode 100644 tests/ref/fate/url diff --git a/libavformat/Makefile b/libavformat/Makefile index 057c058f19..e8729c0e8f 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -376,7 +376,8 @@ SKIPHEADERS-$(CONFIG_NETWORK) += network.h rtsp.h EXAMPLES = metadata \ output \ -TESTPROGS = seek +TESTPROGS = seek \ + url \ TOOLS = aviocat \ ismindex \ diff --git a/libavformat/url-test.c b/libavformat/url-test.c new file mode 100644 index 0000000000..58258e502a --- /dev/null +++ b/libavformat/url-test.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2012 Martin Storsjo + * + * 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 "internal.h" + +#undef printf +#undef exit + +static void test(const char *base, const char *rel) +{ + char buf[200], buf2[200]; + ff_make_absolute_url(buf, sizeof(buf), base, rel); + printf("%s\n", buf); + if (base) { + /* Test in-buffer replacement */ + snprintf(buf2, sizeof(buf2), "%s", base); + ff_make_absolute_url(buf2, sizeof(buf2), buf2, rel); + if (strcmp(buf, buf2)) { + printf("In-place handling of %s + %s failed\n", base, rel); + exit(1); + } + } +} + +int main(void) +{ + test(NULL, "baz"); + test("/foo/bar", "baz"); + test("/foo/bar", "../baz"); + test("/foo/bar", "/baz"); + test("http://server/foo/", "baz"); + test("http://server/foo/bar", "baz"); + test("http://server/foo/", "../baz"); + test("http://server/foo/bar/123", "../../baz"); + test("http://server/foo/bar/123", "/baz"); + test("http://server/foo/bar/123", "https://other/url"); + test("http://server/foo/bar?param=value/with/slashes", "/baz"); + test("http://server/foo/bar?param&otherparam", "?someparam"); + test("http://server/foo/bar", "//other/url"); + return 0; +} diff --git a/tests/Makefile b/tests/Makefile index 2af9a9144a..cb9954af12 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -47,6 +47,7 @@ include $(SRC_PATH)/tests/fate/h264.mak include $(SRC_PATH)/tests/fate/image.mak include $(SRC_PATH)/tests/fate/indeo.mak include $(SRC_PATH)/tests/fate/libavcodec.mak +include $(SRC_PATH)/tests/fate/libavformat.mak include $(SRC_PATH)/tests/fate/libavutil.mak include $(SRC_PATH)/tests/fate/lossless-audio.mak include $(SRC_PATH)/tests/fate/lossless-video.mak @@ -81,6 +82,7 @@ FATE_AVCONV += $(FATE_AVCONV-yes) FATE-$(CONFIG_AVCONV) += $(FATE_AVCONV) FATE-$(CONFIG_AVCODEC) += $(FATE_LIBAVCODEC) +FATE-$(CONFIG_AVFORMAT) += $(FATE_LIBAVFORMAT) FATE_SAMPLES-$(CONFIG_AVCONV) += $(FATE_SAMPLES_AVCONV) FATE_SAMPLES += $(FATE_SAMPLES-yes) diff --git a/tests/fate/libavformat.mak b/tests/fate/libavformat.mak new file mode 100644 index 0000000000..9e5a9f05b0 --- /dev/null +++ b/tests/fate/libavformat.mak @@ -0,0 +1,5 @@ +FATE_LIBAVFORMAT += fate-url +fate-url: libavformat/url-test$(EXESUF) +fate-url: CMD = run libavformat/url-test + +fate-libavformat: $(FATE_LIBAVFORMAT) diff --git a/tests/ref/fate/url b/tests/ref/fate/url new file mode 100644 index 0000000000..1a6051ee0f --- /dev/null +++ b/tests/ref/fate/url @@ -0,0 +1,13 @@ +baz +/foo/baz +/baz +/baz +http://server/foo/baz +http://server/foo/baz +http://server/baz +http://server/baz +http://server/baz +https://other/url +http://server/baz +http://server/foo/bar?someparam +http://other/url From 3fbda309e553428211b79ea0ca128b3aaf0f9033 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Tue, 9 Oct 2012 14:04:46 +0200 Subject: [PATCH 05/19] avcodec: free extended_data instead address of it Fixes CID732173. --- libavcodec/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/utils.c b/libavcodec/utils.c index bd80d7bf13..48d63489bc 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -322,7 +322,7 @@ static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame) if (buf->extended_data[0] && buf_size > buf->audio_data_size) { av_free(buf->extended_data[0]); if (buf->extended_data != buf->data) - av_free(&buf->extended_data); + av_free(buf->extended_data); buf->extended_data = NULL; buf->data[0] = NULL; } From 8dd0650fe67398d78214687b1a15e614239ff593 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Tue, 9 Oct 2012 14:24:36 +0200 Subject: [PATCH 06/19] rtpdec_mpeg4: au_headers is a single array, simple av_free is enough Fixes CID700204. --- libavformat/rtpdec_mpeg4.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/libavformat/rtpdec_mpeg4.c b/libavformat/rtpdec_mpeg4.c index d3e0754253..cc92c88636 100644 --- a/libavformat/rtpdec_mpeg4.c +++ b/libavformat/rtpdec_mpeg4.c @@ -93,15 +93,7 @@ static PayloadContext *new_context(void) static void free_context(PayloadContext * data) { - int i; - for (i = 0; i < data->nb_au_headers; i++) { - /* according to rtp_parse_mp4_au, we treat multiple - * au headers as one, so nb_au_headers is always 1. - * loop anyway in case this changes. - * (note: changes done carelessly might lead to a double free) - */ - av_free(&data->au_headers[i]); - } + av_free(data->au_headers); av_free(data->mode); av_free(data); } From ac56ff9cc9d442e4dc0cd01593d0f418e1e0cdaa Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 24 Aug 2012 02:10:20 +0200 Subject: [PATCH 07/19] build: non-x86: Only compile mpegvideo optimizations when necessary --- libavcodec/alpha/Makefile | 3 ++- libavcodec/arm/Makefile | 9 +++++---- libavcodec/bfin/Makefile | 3 ++- libavcodec/mips/Makefile | 3 ++- libavcodec/ppc/Makefile | 2 +- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/libavcodec/alpha/Makefile b/libavcodec/alpha/Makefile index e55fe49b7b..e28200d45a 100644 --- a/libavcodec/alpha/Makefile +++ b/libavcodec/alpha/Makefile @@ -2,5 +2,6 @@ OBJS += alpha/dsputil_alpha.o \ alpha/dsputil_alpha_asm.o \ alpha/motion_est_alpha.o \ alpha/motion_est_mvi_asm.o \ - alpha/mpegvideo_alpha.o \ alpha/simple_idct_alpha.o \ + +OBJS-$(CONFIG_MPEGVIDEO) += alpha/mpegvideo_alpha.o diff --git a/libavcodec/arm/Makefile b/libavcodec/arm/Makefile index 745a5bdfe2..f537e4f3e2 100644 --- a/libavcodec/arm/Makefile +++ b/libavcodec/arm/Makefile @@ -14,6 +14,7 @@ OBJS-$(CONFIG_FLAC_DECODER) += arm/flacdsp_init_arm.o \ OBJS-$(CONFIG_MPEGAUDIODSP) += arm/mpegaudiodsp_init_arm.o ARMV6-OBJS-$(CONFIG_MPEGAUDIODSP) += arm/mpegaudiodsp_fixed_armv6.o +OBJS-$(CONFIG_MPEGVIDEO) += arm/mpegvideo_arm.o OBJS-$(CONFIG_VP3DSP) += arm/vp3dsp_init_arm.o OBJS-$(CONFIG_VP5_DECODER) += arm/vp56dsp_init_arm.o OBJS-$(CONFIG_VP6_DECODER) += arm/vp56dsp_init_arm.o @@ -31,12 +32,12 @@ OBJS += arm/dsputil_init_arm.o \ arm/fft_fixed_init_arm.o \ arm/fmtconvert_init_arm.o \ arm/jrevdct_arm.o \ - arm/mpegvideo_arm.o \ arm/simple_idct_arm.o \ -ARMV5TE-OBJS += arm/dsputil_init_armv5te.o \ - arm/mpegvideo_armv5te.o \ +ARMV5TE-OBJS-$(CONFIG_MPEGVIDEO) += arm/mpegvideo_armv5te.o \ arm/mpegvideo_armv5te_s.o \ + +ARMV5TE-OBJS += arm/dsputil_init_armv5te.o \ arm/simple_idct_armv5te.o \ ARMV6-OBJS += arm/dsputil_init_armv6.o \ @@ -70,6 +71,7 @@ NEON-OBJS-$(CONFIG_AAC_DECODER) += arm/sbrdsp_neon.o \ NEON-OBJS-$(CONFIG_DCA_DECODER) += arm/dcadsp_neon.o \ arm/synth_filter_neon.o \ +NEON-OBJS-$(CONFIG_MPEGVIDEO) += arm/mpegvideo_neon.o NEON-OBJS-$(CONFIG_RV30_DECODER) += arm/rv34dsp_init_neon.o \ arm/rv34dsp_neon.o \ @@ -92,5 +94,4 @@ NEON-OBJS += arm/dsputil_init_neon.o \ arm/dsputil_neon.o \ arm/fmtconvert_neon.o \ arm/int_neon.o \ - arm/mpegvideo_neon.o \ arm/simple_idct_neon.o \ diff --git a/libavcodec/bfin/Makefile b/libavcodec/bfin/Makefile index 6b3e7cf67c..be81e6c39a 100644 --- a/libavcodec/bfin/Makefile +++ b/libavcodec/bfin/Makefile @@ -1,7 +1,8 @@ OBJS += bfin/dsputil_bfin.o \ bfin/fdct_bfin.o \ bfin/idct_bfin.o \ - bfin/mpegvideo_bfin.o \ bfin/pixels_bfin.o \ bfin/vp3_bfin.o \ bfin/vp3_idct_bfin.o \ + +OBJS-$(CONFIG_MPEGVIDEOENC) += bfin/mpegvideo_bfin.o diff --git a/libavcodec/mips/Makefile b/libavcodec/mips/Makefile index 37899b1f7a..5f00d70360 100644 --- a/libavcodec/mips/Makefile +++ b/libavcodec/mips/Makefile @@ -1,3 +1,4 @@ MMI-OBJS += mips/dsputil_mmi.o \ mips/idct_mmi.o \ - mips/mpegvideo_mmi.o \ + +MMI-OBJS-$(CONFIG_MPEGVIDEO) += mips/mpegvideo_mmi.o diff --git a/libavcodec/ppc/Makefile b/libavcodec/ppc/Makefile index e5d1d39d43..f7548e375a 100644 --- a/libavcodec/ppc/Makefile +++ b/libavcodec/ppc/Makefile @@ -7,6 +7,7 @@ ALTIVEC-OBJS-$(CONFIG_FFT) += ppc/fft_altivec.o \ $(FFT-OBJS-yes) ALTIVEC-OBJS-$(CONFIG_H264DSP) += ppc/h264_altivec.o ALTIVEC-OBJS-$(CONFIG_MPEGAUDIODSP) += ppc/mpegaudiodec_altivec.o +ALTIVEC-OBJS-$(CONFIG_MPEGVIDEO) += ppc/mpegvideo_altivec.o ALTIVEC-OBJS-$(CONFIG_VC1_DECODER) += ppc/vc1dsp_altivec.o ALTIVEC-OBJS-$(CONFIG_VP8_DECODER) += ppc/vp8dsp_altivec.o @@ -17,4 +18,3 @@ ALTIVEC-OBJS += ppc/dsputil_altivec.o \ ppc/gmc_altivec.o \ ppc/idct_altivec.o \ ppc/int_altivec.o \ - ppc/mpegvideo_altivec.o \ From 23d53c5473913975905772ee246fc4a36c338028 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 26 Aug 2012 01:10:51 -0400 Subject: [PATCH 08/19] atrac1: use planar sample format --- libavcodec/atrac1.c | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c index ec4b7c10e1..7e78c7321c 100644 --- a/libavcodec/atrac1.c +++ b/libavcodec/atrac1.c @@ -36,7 +36,6 @@ #include "get_bits.h" #include "dsputil.h" #include "fft.h" -#include "fmtconvert.h" #include "sinewin.h" #include "atrac.h" @@ -80,11 +79,9 @@ typedef struct { DECLARE_ALIGNED(32, float, mid)[256]; DECLARE_ALIGNED(32, float, high)[512]; float* bands[3]; - float *out_samples[AT1_MAX_CHANNELS]; FFTContext mdct_ctx[3]; int channels; DSPContext dsp; - FmtConvertContext fmt_conv; } AT1Ctx; /** size of the transform in samples in the long mode for each QMF band */ @@ -281,7 +278,6 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data, AT1Ctx *q = avctx->priv_data; int ch, ret; GetBitContext gb; - float *samples; if (buf_size < 212 * q->channels) { @@ -295,7 +291,6 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } - samples = (float *)q->frame.data[0]; for (ch = 0; ch < q->channels; ch++) { AT1SUCtx* su = &q->SUs[ch]; @@ -314,13 +309,7 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data, ret = at1_imdct_block(su, q); if (ret < 0) return ret; - at1_subband_synthesis(q, su, q->channels == 1 ? samples : q->out_samples[ch]); - } - - /* interleave */ - if (q->channels == 2) { - q->fmt_conv.float_interleave(samples, (const float **)q->out_samples, - AT1_SU_SAMPLES, 2); + at1_subband_synthesis(q, su, (float *)q->frame.extended_data[ch]); } *got_frame_ptr = 1; @@ -334,8 +323,6 @@ static av_cold int atrac1_decode_end(AVCodecContext * avctx) { AT1Ctx *q = avctx->priv_data; - av_freep(&q->out_samples[0]); - ff_mdct_end(&q->mdct_ctx[0]); ff_mdct_end(&q->mdct_ctx[1]); ff_mdct_end(&q->mdct_ctx[2]); @@ -349,7 +336,7 @@ static av_cold int atrac1_decode_init(AVCodecContext *avctx) AT1Ctx *q = avctx->priv_data; int ret; - avctx->sample_fmt = AV_SAMPLE_FMT_FLT; + avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; if (avctx->channels < 1 || avctx->channels > AT1_MAX_CHANNELS) { av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %d\n", @@ -358,15 +345,6 @@ static av_cold int atrac1_decode_init(AVCodecContext *avctx) } q->channels = avctx->channels; - if (avctx->channels == 2) { - q->out_samples[0] = av_malloc(2 * AT1_SU_SAMPLES * sizeof(*q->out_samples[0])); - q->out_samples[1] = q->out_samples[0] + AT1_SU_SAMPLES; - if (!q->out_samples[0]) { - av_freep(&q->out_samples[0]); - return AVERROR(ENOMEM); - } - } - /* Init the mdct transforms */ if ((ret = ff_mdct_init(&q->mdct_ctx[0], 6, 1, -1.0/ (1 << 15))) || (ret = ff_mdct_init(&q->mdct_ctx[1], 8, 1, -1.0/ (1 << 15))) || @@ -381,7 +359,6 @@ static av_cold int atrac1_decode_init(AVCodecContext *avctx) ff_atrac_generate_tables(); ff_dsputil_init(&q->dsp, avctx); - ff_fmt_convert_init(&q->fmt_conv, avctx); q->bands[0] = q->low; q->bands[1] = q->mid; @@ -410,4 +387,6 @@ AVCodec ff_atrac1_decoder = { .decode = atrac1_decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Atrac 1 (Adaptive TRansform Acoustic Coding)"), + .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, + AV_SAMPLE_FMT_NONE }, }; From c1a9cfd1feb281b1932b31895a1a9c1c795f6df5 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 27 Aug 2012 14:19:51 -0400 Subject: [PATCH 09/19] mace: use planar sample format --- libavcodec/mace.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/libavcodec/mace.c b/libavcodec/mace.c index 9d07180c52..8fef839d60 100644 --- a/libavcodec/mace.c +++ b/libavcodec/mace.c @@ -187,9 +187,7 @@ static int16_t read_table(ChannelData *chd, uint8_t val, int tab_idx) return current; } -static void chomp3(ChannelData *chd, int16_t *output, uint8_t val, - int tab_idx, - uint32_t numChannels) +static void chomp3(ChannelData *chd, int16_t *output, uint8_t val, int tab_idx) { int16_t current = read_table(chd, val, tab_idx); @@ -200,9 +198,7 @@ static void chomp3(ChannelData *chd, int16_t *output, uint8_t val, *output = QT_8S_2_16S(current); } -static void chomp6(ChannelData *chd, int16_t *output, uint8_t val, - int tab_idx, - uint32_t numChannels) +static void chomp6(ChannelData *chd, int16_t *output, uint8_t val, int tab_idx) { int16_t current = read_table(chd, val, tab_idx); @@ -222,8 +218,8 @@ static void chomp6(ChannelData *chd, int16_t *output, uint8_t val, output[0] = QT_8S_2_16S(chd->previous + chd->prev2 - ((chd->prev2-current) >> 2)); - output[numChannels] = QT_8S_2_16S(chd->previous + current + - ((chd->prev2-current) >> 2)); + output[1] = QT_8S_2_16S(chd->previous + current + + ((chd->prev2-current) >> 2)); chd->prev2 = chd->previous; chd->previous = current; } @@ -234,7 +230,7 @@ static av_cold int mace_decode_init(AVCodecContext * avctx) if (avctx->channels > 2) return -1; - avctx->sample_fmt = AV_SAMPLE_FMT_S16; + avctx->sample_fmt = AV_SAMPLE_FMT_S16P; avcodec_get_frame_defaults(&ctx->frame); avctx->coded_frame = &ctx->frame; @@ -247,7 +243,7 @@ static int mace_decode_frame(AVCodecContext *avctx, void *data, { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - int16_t *samples; + int16_t **samples; MACEContext *ctx = avctx->priv_data; int i, j, k, l, ret; int is_mace3 = (avctx->codec_id == AV_CODEC_ID_MACE3); @@ -258,10 +254,10 @@ static int mace_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } - samples = (int16_t *)ctx->frame.data[0]; + samples = (int16_t **)ctx->frame.extended_data; for(i = 0; i < avctx->channels; i++) { - int16_t *output = samples + i; + int16_t *output = samples[i]; for (j=0; j < buf_size / (avctx->channels << is_mace3); j++) for (k=0; k < (1 << is_mace3); k++) { @@ -273,13 +269,11 @@ static int mace_decode_frame(AVCodecContext *avctx, void *data, for (l=0; l < 3; l++) { if (is_mace3) - chomp3(&ctx->chd[i], output, val[1][l], l, - avctx->channels); + chomp3(&ctx->chd[i], output, val[1][l], l); else - chomp6(&ctx->chd[i], output, val[0][l], l, - avctx->channels); + chomp6(&ctx->chd[i], output, val[0][l], l); - output += avctx->channels << (1-is_mace3); + output += 1 << (1-is_mace3); } } } @@ -299,6 +293,8 @@ AVCodec ff_mace3_decoder = { .decode = mace_decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("MACE (Macintosh Audio Compression/Expansion) 3:1"), + .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, + AV_SAMPLE_FMT_NONE }, }; AVCodec ff_mace6_decoder = { @@ -310,4 +306,6 @@ AVCodec ff_mace6_decoder = { .decode = mace_decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("MACE (Macintosh Audio Compression/Expansion) 6:1"), + .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, + AV_SAMPLE_FMT_NONE }, }; From 7e5f0450390196c09f43cf706b4c5039213d644f Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 28 Aug 2012 11:45:39 -0400 Subject: [PATCH 10/19] pcmdec: use planar sample format for pcm_lxf --- libavcodec/pcm.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c index 24272d27fe..669a7e2c6b 100644 --- a/libavcodec/pcm.c +++ b/libavcodec/pcm.c @@ -443,26 +443,23 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data, case AV_CODEC_ID_PCM_LXF: { int i; - const uint8_t *src8; - dst_int32_t = (int32_t *)s->frame.data[0]; n /= avctx->channels; - // unpack and de-planarize - for (i = 0; i < n; i++) { - for (c = 0, src8 = src + i * 5; c < avctx->channels; c++, src8 += n * 5) { + for (c = 0; c < avctx->channels; c++) { + dst_int32_t = (int32_t *)s->frame.extended_data[c]; + for (i = 0; i < n; i++) { // extract low 20 bits and expand to 32 bits - *dst_int32_t++ = (src8[2] << 28) | - (src8[1] << 20) | - (src8[0] << 12) | - ((src8[2] & 0xF) << 8) | - src8[1]; - } - for (c = 0, src8 = src + i * 5; c < avctx->channels; c++, src8 += n * 5) { + *dst_int32_t++ = (src[2] << 28) | + (src[1] << 20) | + (src[0] << 12) | + ((src[2] & 0x0F) << 8) | + src[1]; // extract high 20 bits and expand to 32 bits - *dst_int32_t++ = (src8[4] << 24) | - (src8[3] << 16) | - ((src8[2] & 0xF0) << 8) | - (src8[4] << 4) | - (src8[3] >> 4); + *dst_int32_t++ = (src[4] << 24) | + (src[3] << 16) | + ((src[2] & 0xF0) << 8) | + (src[4] << 4) | + (src[3] >> 4); + src += 5; } } break; @@ -524,7 +521,7 @@ PCM_CODEC (AV_CODEC_ID_PCM_F32BE, AV_SAMPLE_FMT_FLT, pcm_f32be, " PCM_CODEC (AV_CODEC_ID_PCM_F32LE, AV_SAMPLE_FMT_FLT, pcm_f32le, "PCM 32-bit floating point little-endian"); PCM_CODEC (AV_CODEC_ID_PCM_F64BE, AV_SAMPLE_FMT_DBL, pcm_f64be, "PCM 64-bit floating point big-endian"); PCM_CODEC (AV_CODEC_ID_PCM_F64LE, AV_SAMPLE_FMT_DBL, pcm_f64le, "PCM 64-bit floating point little-endian"); -PCM_DECODER(AV_CODEC_ID_PCM_LXF, AV_SAMPLE_FMT_S32, pcm_lxf, "PCM signed 20-bit little-endian planar"); +PCM_DECODER(AV_CODEC_ID_PCM_LXF, AV_SAMPLE_FMT_S32P, pcm_lxf, "PCM signed 20-bit little-endian planar"); PCM_CODEC (AV_CODEC_ID_PCM_MULAW, AV_SAMPLE_FMT_S16, pcm_mulaw, "PCM mu-law"); PCM_CODEC (AV_CODEC_ID_PCM_S8, AV_SAMPLE_FMT_U8, pcm_s8, "PCM signed 8-bit"); PCM_CODEC (AV_CODEC_ID_PCM_S16BE, AV_SAMPLE_FMT_S16, pcm_s16be, "PCM signed 16-bit big-endian"); From 176db0b8928a1f1099a072604d512bf44de01404 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 28 Aug 2012 23:39:53 -0400 Subject: [PATCH 11/19] adpcmdec: use planar sample format for adpcm_ima_qt --- libavcodec/adpcm.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index f11b899dd3..2137c309a1 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -134,7 +134,14 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) default: break; } - avctx->sample_fmt = AV_SAMPLE_FMT_S16; + + switch(avctx->codec->id) { + case AV_CODEC_ID_ADPCM_IMA_QT: + avctx->sample_fmt = AV_SAMPLE_FMT_S16P; + break; + default: + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + } avcodec_get_frame_defaults(&c->frame); avctx->coded_frame = &c->frame; @@ -573,6 +580,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, ADPCMChannelStatus *cs; int n, m, channel, i; short *samples; + int16_t **samples_p; int st; /* stereo */ int count1, count2; int nb_samples, coded_samples, ret; @@ -592,6 +600,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, return ret; } samples = (short *)c->frame.data[0]; + samples_p = (int16_t **)c->frame.extended_data; /* use coded_samples when applicable */ /* it is always <= nb_samples, so the output buffer will be large enough */ @@ -636,14 +645,12 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - samples = (short *)c->frame.data[0] + channel; + samples = samples_p[channel]; - for (m = 0; m < 32; m++) { + for (m = 0; m < 64; m += 2) { int byte = bytestream2_get_byteu(&gb); - *samples = adpcm_ima_qt_expand_nibble(cs, byte & 0x0F, 3); - samples += avctx->channels; - *samples = adpcm_ima_qt_expand_nibble(cs, byte >> 4 , 3); - samples += avctx->channels; + samples[m ] = adpcm_ima_qt_expand_nibble(cs, byte & 0x0F, 3); + samples[m + 1] = adpcm_ima_qt_expand_nibble(cs, byte >> 4 , 3); } } break; @@ -1267,6 +1274,8 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, static const enum AVSampleFormat sample_fmts_s16[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }; +static const enum AVSampleFormat sample_fmts_s16p[] = { AV_SAMPLE_FMT_S16, + AV_SAMPLE_FMT_NONE }; #define ADPCM_DECODER(id_, sample_fmts_, name_, long_name_) \ AVCodec ff_ ## name_ ## _decoder = { \ @@ -1297,7 +1306,7 @@ ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_DK4, sample_fmts_s16, adpcm_ima_dk4, ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_EA_EACS, sample_fmts_s16, adpcm_ima_ea_eacs, "ADPCM IMA Electronic Arts EACS"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_EA_SEAD, sample_fmts_s16, adpcm_ima_ea_sead, "ADPCM IMA Electronic Arts SEAD"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_ISS, sample_fmts_s16, adpcm_ima_iss, "ADPCM IMA Funcom ISS"); -ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_QT, sample_fmts_s16, adpcm_ima_qt, "ADPCM IMA QuickTime"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_QT, sample_fmts_s16p, adpcm_ima_qt, "ADPCM IMA QuickTime"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_SMJPEG, sample_fmts_s16, adpcm_ima_smjpeg, "ADPCM IMA Loki SDL MJPEG"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WAV, sample_fmts_s16, adpcm_ima_wav, "ADPCM IMA WAV"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WS, sample_fmts_s16, adpcm_ima_ws, "ADPCM IMA Westwood"); From 1b9ac7290868a24b651f9143c4b6181e998a95f5 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 28 Aug 2012 23:58:08 -0400 Subject: [PATCH 12/19] adpcmdec: use planar sample format for adpcm_ima_wav --- libavcodec/adpcm.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 2137c309a1..35be5d07a5 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -137,6 +137,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) switch(avctx->codec->id) { case AV_CODEC_ID_ADPCM_IMA_QT: + case AV_CODEC_ID_ADPCM_IMA_WAV: avctx->sample_fmt = AV_SAMPLE_FMT_S16P; break; default: @@ -657,7 +658,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, case AV_CODEC_ID_ADPCM_IMA_WAV: for(i=0; ichannels; i++){ cs = &(c->status[i]); - cs->predictor = *samples++ = sign_extend(bytestream2_get_le16u(&gb), 16); + cs->predictor = samples_p[i][0] = sign_extend(bytestream2_get_le16u(&gb), 16); cs->step_index = sign_extend(bytestream2_get_le16u(&gb), 16); if (cs->step_index > 88u){ @@ -667,19 +668,16 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, } } - for (n = (nb_samples - 1) / 8; n > 0; n--) { + for (n = 0; n < (nb_samples - 1) / 8; n++) { for (i = 0; i < avctx->channels; i++) { cs = &c->status[i]; - for (m = 0; m < 4; m++) { + samples = &samples_p[i][1 + n * 8]; + for (m = 0; m < 8; m += 2) { int v = bytestream2_get_byteu(&gb); - *samples = adpcm_ima_expand_nibble(cs, v & 0x0F, 3); - samples += avctx->channels; - *samples = adpcm_ima_expand_nibble(cs, v >> 4 , 3); - samples += avctx->channels; + samples[m ] = adpcm_ima_expand_nibble(cs, v & 0x0F, 3); + samples[m + 1] = adpcm_ima_expand_nibble(cs, v >> 4 , 3); } - samples -= 8 * avctx->channels - 1; } - samples += 7 * avctx->channels; } break; case AV_CODEC_ID_ADPCM_4XM: @@ -1308,7 +1306,7 @@ ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_EA_SEAD, sample_fmts_s16, adpcm_ima_ea_sead ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_ISS, sample_fmts_s16, adpcm_ima_iss, "ADPCM IMA Funcom ISS"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_QT, sample_fmts_s16p, adpcm_ima_qt, "ADPCM IMA QuickTime"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_SMJPEG, sample_fmts_s16, adpcm_ima_smjpeg, "ADPCM IMA Loki SDL MJPEG"); -ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WAV, sample_fmts_s16, adpcm_ima_wav, "ADPCM IMA WAV"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WAV, sample_fmts_s16p, adpcm_ima_wav, "ADPCM IMA WAV"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WS, sample_fmts_s16, adpcm_ima_ws, "ADPCM IMA Westwood"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_MS, sample_fmts_s16, adpcm_ms, "ADPCM Microsoft"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_SBPRO_2, sample_fmts_s16, adpcm_sbpro_2, "ADPCM Sound Blaster Pro 2-bit"); From 4356d66d784cf03e8e640aa25fd27efe38ff9fdb Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 29 Aug 2012 15:40:26 -0400 Subject: [PATCH 13/19] adpcmdec: use planar sample format for adpcm_4xm --- libavcodec/adpcm.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 35be5d07a5..95e97c9161 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -138,6 +138,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) switch(avctx->codec->id) { case AV_CODEC_ID_ADPCM_IMA_QT: case AV_CODEC_ID_ADPCM_IMA_WAV: + case AV_CODEC_ID_ADPCM_4XM: avctx->sample_fmt = AV_SAMPLE_FMT_S16P; break; default: @@ -694,14 +695,12 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, } for (i = 0; i < avctx->channels; i++) { - samples = (short *)c->frame.data[0] + i; + samples = (int16_t *)c->frame.data[i]; cs = &c->status[i]; for (n = nb_samples >> 1; n > 0; n--) { int v = bytestream2_get_byteu(&gb); - *samples = adpcm_ima_expand_nibble(cs, v & 0x0F, 4); - samples += avctx->channels; - *samples = adpcm_ima_expand_nibble(cs, v >> 4 , 4); - samples += avctx->channels; + *samples++ = adpcm_ima_expand_nibble(cs, v & 0x0F, 4); + *samples++ = adpcm_ima_expand_nibble(cs, v >> 4 , 4); } } break; @@ -1289,7 +1288,7 @@ AVCodec ff_ ## name_ ## _decoder = { \ } /* Note: Do not forget to add new entries to the Makefile as well. */ -ADPCM_DECODER(AV_CODEC_ID_ADPCM_4XM, sample_fmts_s16, adpcm_4xm, "ADPCM 4X Movie"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_4XM, sample_fmts_s16p, adpcm_4xm, "ADPCM 4X Movie"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_CT, sample_fmts_s16, adpcm_ct, "ADPCM Creative Technology"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA, sample_fmts_s16, adpcm_ea, "ADPCM Electronic Arts"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_MAXIS_XA, sample_fmts_s16, adpcm_ea_maxis_xa, "ADPCM Electronic Arts Maxis CDROM XA"); From 8b854283c3463d28ceedb55456b362e914e8fe77 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 29 Aug 2012 15:54:39 -0400 Subject: [PATCH 14/19] adpcmdec: use planar sample format for adpcm_ima_ws for vqa version 3 --- libavcodec/adpcm.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 95e97c9161..fca5f1b88f 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -141,6 +141,10 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) case AV_CODEC_ID_ADPCM_4XM: avctx->sample_fmt = AV_SAMPLE_FMT_S16P; break; + case AV_CODEC_ID_ADPCM_IMA_WS: + avctx->sample_fmt = c->vqa_version == 3 ? AV_SAMPLE_FMT_S16P : + AV_SAMPLE_FMT_S16; + break; default: avctx->sample_fmt = AV_SAMPLE_FMT_S16; } @@ -862,14 +866,12 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, case AV_CODEC_ID_ADPCM_IMA_WS: if (c->vqa_version == 3) { for (channel = 0; channel < avctx->channels; channel++) { - int16_t *smp = samples + channel; + int16_t *smp = samples_p[channel]; for (n = nb_samples / 2; n > 0; n--) { int v = bytestream2_get_byteu(&gb); - *smp = adpcm_ima_expand_nibble(&c->status[channel], v >> 4 , 3); - smp += avctx->channels; - *smp = adpcm_ima_expand_nibble(&c->status[channel], v & 0x0F, 3); - smp += avctx->channels; + *smp++ = adpcm_ima_expand_nibble(&c->status[channel], v >> 4 , 3); + *smp++ = adpcm_ima_expand_nibble(&c->status[channel], v & 0x0F, 3); } } } else { @@ -1273,6 +1275,9 @@ static const enum AVSampleFormat sample_fmts_s16[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }; static const enum AVSampleFormat sample_fmts_s16p[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }; +static const enum AVSampleFormat sample_fmts_both[] = { AV_SAMPLE_FMT_S16, + AV_SAMPLE_FMT_S16P, + AV_SAMPLE_FMT_NONE }; #define ADPCM_DECODER(id_, sample_fmts_, name_, long_name_) \ AVCodec ff_ ## name_ ## _decoder = { \ @@ -1306,7 +1311,7 @@ ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_ISS, sample_fmts_s16, adpcm_ima_iss, ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_QT, sample_fmts_s16p, adpcm_ima_qt, "ADPCM IMA QuickTime"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_SMJPEG, sample_fmts_s16, adpcm_ima_smjpeg, "ADPCM IMA Loki SDL MJPEG"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WAV, sample_fmts_s16p, adpcm_ima_wav, "ADPCM IMA WAV"); -ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WS, sample_fmts_s16, adpcm_ima_ws, "ADPCM IMA Westwood"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_WS, sample_fmts_both, adpcm_ima_ws, "ADPCM IMA Westwood"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_MS, sample_fmts_s16, adpcm_ms, "ADPCM Microsoft"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_SBPRO_2, sample_fmts_s16, adpcm_sbpro_2, "ADPCM Sound Blaster Pro 2-bit"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_SBPRO_3, sample_fmts_s16, adpcm_sbpro_3, "ADPCM Sound Blaster Pro 2.6-bit"); From d2b6ae02aa4d80fb19137ec11f3cefb9f71b9b81 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 30 Aug 2012 18:08:59 -0400 Subject: [PATCH 15/19] adpcmdec: use planar sample format for adpcm_xa --- libavcodec/adpcm.c | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index fca5f1b88f..92c7943e4f 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -139,6 +139,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) case AV_CODEC_ID_ADPCM_IMA_QT: case AV_CODEC_ID_ADPCM_IMA_WAV: case AV_CODEC_ID_ADPCM_4XM: + case AV_CODEC_ID_ADPCM_XA: avctx->sample_fmt = AV_SAMPLE_FMT_S16P; break; case AV_CODEC_ID_ADPCM_IMA_WS: @@ -277,17 +278,22 @@ static inline short adpcm_yamaha_expand_nibble(ADPCMChannelStatus *c, unsigned c return c->predictor; } -static int xa_decode(AVCodecContext *avctx, - short *out, const unsigned char *in, - ADPCMChannelStatus *left, ADPCMChannelStatus *right, int inc) +static int xa_decode(AVCodecContext *avctx, int16_t *out0, int16_t *out1, + const uint8_t *in, ADPCMChannelStatus *left, + ADPCMChannelStatus *right, int channels, int sample_offset) { int i, j; int shift,filter,f0,f1; int s_1,s_2; int d,s,t; - for(i=0;i<4;i++) { + out0 += sample_offset; + if (channels == 1) + out1 = out0 + 28; + else + out1 += sample_offset; + for(i=0;i<4;i++) { shift = 12 - (in[4+i*2] & 15); filter = in[4+i*2] >> 4; if (filter > 4) { @@ -309,16 +315,14 @@ static int xa_decode(AVCodecContext *avctx, s = ( t<>6); s_2 = s_1; s_1 = av_clip_int16(s); - *out = s_1; - out += inc; + out0[j] = s_1; } - if (inc==2) { /* stereo */ + if (channels == 2) { left->sample1 = s_1; left->sample2 = s_2; s_1 = right->sample1; s_2 = right->sample2; - out = out + 1 - 28*2; } shift = 12 - (in[5+i*2] & 15); @@ -339,18 +343,19 @@ static int xa_decode(AVCodecContext *avctx, s = ( t<>6); s_2 = s_1; s_1 = av_clip_int16(s); - *out = s_1; - out += inc; + out1[j] = s_1; } - if (inc==2) { /* stereo */ + if (channels == 2) { right->sample1 = s_1; right->sample2 = s_2; - out -= 1; } else { left->sample1 = s_1; left->sample2 = s_2; } + + out0 += 28 * (3 - channels); + out1 += 28 * (3 - channels); } return 0; @@ -887,14 +892,21 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, bytestream2_seek(&gb, 0, SEEK_END); break; case AV_CODEC_ID_ADPCM_XA: + { + int16_t *out0 = samples_p[0]; + int16_t *out1 = samples_p[1]; + int samples_per_block = 28 * (3 - avctx->channels) * 4; + int sample_offset = 0; while (bytestream2_get_bytes_left(&gb) >= 128) { - if ((ret = xa_decode(avctx, samples, buf + bytestream2_tell(&gb), &c->status[0], - &c->status[1], avctx->channels)) < 0) + if ((ret = xa_decode(avctx, out0, out1, buf + bytestream2_tell(&gb), + &c->status[0], &c->status[1], + avctx->channels, sample_offset)) < 0) return ret; bytestream2_skipu(&gb, 128); - samples += 28 * 8; + sample_offset += samples_per_block; } break; + } case AV_CODEC_ID_ADPCM_IMA_EA_EACS: for (i=0; i<=st; i++) { c->status[i].step_index = bytestream2_get_le32u(&gb); @@ -1318,5 +1330,5 @@ ADPCM_DECODER(AV_CODEC_ID_ADPCM_SBPRO_3, sample_fmts_s16, adpcm_sbpro_3, ADPCM_DECODER(AV_CODEC_ID_ADPCM_SBPRO_4, sample_fmts_s16, adpcm_sbpro_4, "ADPCM Sound Blaster Pro 4-bit"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_SWF, sample_fmts_s16, adpcm_swf, "ADPCM Shockwave Flash"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_THP, sample_fmts_s16, adpcm_thp, "ADPCM Nintendo Gamecube THP"); -ADPCM_DECODER(AV_CODEC_ID_ADPCM_XA, sample_fmts_s16, adpcm_xa, "ADPCM CDROM XA"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_XA, sample_fmts_s16p, adpcm_xa, "ADPCM CDROM XA"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_YAMAHA, sample_fmts_s16, adpcm_yamaha, "ADPCM Yamaha"); From da9620e8e59335b986230c023c7900bdf7e1b8a5 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 30 Aug 2012 21:33:34 -0400 Subject: [PATCH 16/19] adpcmdec: use planar sample format for adpcm_ea_r1/r2/r3 --- libavcodec/adpcm.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 92c7943e4f..9b57b46ac9 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -140,6 +140,9 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) case AV_CODEC_ID_ADPCM_IMA_WAV: case AV_CODEC_ID_ADPCM_4XM: case AV_CODEC_ID_ADPCM_XA: + case AV_CODEC_ID_ADPCM_EA_R1: + case AV_CODEC_ID_ADPCM_EA_R2: + case AV_CODEC_ID_ADPCM_EA_R3: avctx->sample_fmt = AV_SAMPLE_FMT_S16P; break; case AV_CODEC_ID_ADPCM_IMA_WS: @@ -1037,7 +1040,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, for (channel=0; channelchannels; channel++) { bytestream2_seek(&gb, offsets[channel], SEEK_SET); - samplesC = samples + channel; + samplesC = samples_p[channel]; if (avctx->codec->id == AV_CODEC_ID_ADPCM_EA_R1) { current_sample = sign_extend(bytestream2_get_le16(&gb), 16); @@ -1053,10 +1056,8 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, current_sample = sign_extend(bytestream2_get_be16(&gb), 16); previous_sample = sign_extend(bytestream2_get_be16(&gb), 16); - for (count2=0; count2<28; count2++) { - *samplesC = sign_extend(bytestream2_get_be16(&gb), 16); - samplesC += avctx->channels; - } + for (count2=0; count2<28; count2++) + *samplesC++ = sign_extend(bytestream2_get_be16(&gb), 16); } else { coeff1 = ea_adpcm_table[ byte >> 4 ]; coeff2 = ea_adpcm_table[(byte >> 4) + 4]; @@ -1076,8 +1077,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, previous_sample = current_sample; current_sample = next_sample; - *samplesC = current_sample; - samplesC += avctx->channels; + *samplesC++ = current_sample; } } } @@ -1309,9 +1309,9 @@ ADPCM_DECODER(AV_CODEC_ID_ADPCM_4XM, sample_fmts_s16p, adpcm_4xm, ADPCM_DECODER(AV_CODEC_ID_ADPCM_CT, sample_fmts_s16, adpcm_ct, "ADPCM Creative Technology"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA, sample_fmts_s16, adpcm_ea, "ADPCM Electronic Arts"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_MAXIS_XA, sample_fmts_s16, adpcm_ea_maxis_xa, "ADPCM Electronic Arts Maxis CDROM XA"); -ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_R1, sample_fmts_s16, adpcm_ea_r1, "ADPCM Electronic Arts R1"); -ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_R2, sample_fmts_s16, adpcm_ea_r2, "ADPCM Electronic Arts R2"); -ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_R3, sample_fmts_s16, adpcm_ea_r3, "ADPCM Electronic Arts R3"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_R1, sample_fmts_s16p, adpcm_ea_r1, "ADPCM Electronic Arts R1"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_R2, sample_fmts_s16p, adpcm_ea_r2, "ADPCM Electronic Arts R2"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_R3, sample_fmts_s16p, adpcm_ea_r3, "ADPCM Electronic Arts R3"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_XAS, sample_fmts_s16, adpcm_ea_xas, "ADPCM Electronic Arts XAS"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_AMV, sample_fmts_s16, adpcm_ima_amv, "ADPCM IMA AMV"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_APC, sample_fmts_s16, adpcm_ima_apc, "ADPCM IMA CRYO APC"); From 327cdb04e354849010fad09f286d55b4dda89e41 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 31 Aug 2012 12:42:37 -0400 Subject: [PATCH 17/19] adpcmdec: use planar sample format for adpcm_ea_xas --- libavcodec/adpcm.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 9b57b46ac9..fe51553579 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -143,6 +143,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) case AV_CODEC_ID_ADPCM_EA_R1: case AV_CODEC_ID_ADPCM_EA_R2: case AV_CODEC_ID_ADPCM_EA_R3: + case AV_CODEC_ID_ADPCM_EA_XAS: avctx->sample_fmt = AV_SAMPLE_FMT_S16P; break; case AV_CODEC_ID_ADPCM_IMA_WS: @@ -1101,8 +1102,8 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, case AV_CODEC_ID_ADPCM_EA_XAS: for (channel=0; channelchannels; channel++) { int coeff[2][4], shift[4]; - short *s2, *s = &samples[channel]; - for (n=0; n<4; n++, s+=32*avctx->channels) { + int16_t *s = samples_p[channel]; + for (n = 0; n < 4; n++, s += 32) { int val = sign_extend(bytestream2_get_le16u(&gb), 16); for (i=0; i<2; i++) coeff[i][n] = ea_adpcm_table[(val&0x0F)+4*i]; @@ -1110,19 +1111,22 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, val = sign_extend(bytestream2_get_le16u(&gb), 16); shift[n] = 20 - (val & 0x0F); - s[avctx->channels] = val & ~0x0F; + s[1] = val & ~0x0F; } for (m=2; m<32; m+=2) { - s = &samples[m*avctx->channels + channel]; - for (n=0; n<4; n++, s+=32*avctx->channels) { + s = &samples_p[channel][m]; + for (n = 0; n < 4; n++, s += 32) { + int level, pred; int byte = bytestream2_get_byteu(&gb); - for (s2=s, i=0; i<8; i+=4, s2+=avctx->channels) { - int level = sign_extend(byte >> (4 - i), 4) << shift[n]; - int pred = s2[-1*avctx->channels] * coeff[0][n] - + s2[-2*avctx->channels] * coeff[1][n]; - s2[0] = av_clip_int16((level + pred + 0x80) >> 8); - } + + level = sign_extend(byte >> 4, 4) << shift[n]; + pred = s[-1] * coeff[0][n] + s[-2] * coeff[1][n]; + s[0] = av_clip_int16((level + pred + 0x80) >> 8); + + level = sign_extend(byte, 4) << shift[n]; + pred = s[0] * coeff[0][n] + s[-1] * coeff[1][n]; + s[1] = av_clip_int16((level + pred + 0x80) >> 8); } } } @@ -1312,7 +1316,7 @@ ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_MAXIS_XA, sample_fmts_s16, adpcm_ea_maxis_xa ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_R1, sample_fmts_s16p, adpcm_ea_r1, "ADPCM Electronic Arts R1"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_R2, sample_fmts_s16p, adpcm_ea_r2, "ADPCM Electronic Arts R2"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_R3, sample_fmts_s16p, adpcm_ea_r3, "ADPCM Electronic Arts R3"); -ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_XAS, sample_fmts_s16, adpcm_ea_xas, "ADPCM Electronic Arts XAS"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_EA_XAS, sample_fmts_s16p, adpcm_ea_xas, "ADPCM Electronic Arts XAS"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_AMV, sample_fmts_s16, adpcm_ima_amv, "ADPCM IMA AMV"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_APC, sample_fmts_s16, adpcm_ima_apc, "ADPCM IMA CRYO APC"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_IMA_DK3, sample_fmts_s16, adpcm_ima_dk3, "ADPCM IMA Duck DK3"); From 4ebd74cec75cb384c0297e9bffcab3ed06be6371 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 21 Sep 2012 10:32:21 -0400 Subject: [PATCH 18/19] adpcmdec: use planar sample format for adpcm_thp --- libavcodec/adpcm.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index fe51553579..b6a20e2c32 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -144,6 +144,7 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) case AV_CODEC_ID_ADPCM_EA_R2: case AV_CODEC_ID_ADPCM_EA_R3: case AV_CODEC_ID_ADPCM_EA_XAS: + case AV_CODEC_ID_ADPCM_THP: avctx->sample_fmt = AV_SAMPLE_FMT_S16P; break; case AV_CODEC_ID_ADPCM_IMA_WS: @@ -1240,7 +1241,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, prev[i][n] = sign_extend(bytestream2_get_be16u(&gb), 16); for (ch = 0; ch <= st; ch++) { - samples = (short *)c->frame.data[0] + ch; + samples = samples_p[ch]; /* Read in every sample for this channel. */ for (i = 0; i < nb_samples / 14; i++) { @@ -1266,10 +1267,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, *samples = av_clip_int16(sampledat); prev[ch][1] = prev[ch][0]; prev[ch][0] = *samples++; - - /* In case of stereo, skip one sample, this sample - is for the other channel. */ - samples += st; } } } @@ -1333,6 +1330,6 @@ ADPCM_DECODER(AV_CODEC_ID_ADPCM_SBPRO_2, sample_fmts_s16, adpcm_sbpro_2, ADPCM_DECODER(AV_CODEC_ID_ADPCM_SBPRO_3, sample_fmts_s16, adpcm_sbpro_3, "ADPCM Sound Blaster Pro 2.6-bit"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_SBPRO_4, sample_fmts_s16, adpcm_sbpro_4, "ADPCM Sound Blaster Pro 4-bit"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_SWF, sample_fmts_s16, adpcm_swf, "ADPCM Shockwave Flash"); -ADPCM_DECODER(AV_CODEC_ID_ADPCM_THP, sample_fmts_s16, adpcm_thp, "ADPCM Nintendo Gamecube THP"); +ADPCM_DECODER(AV_CODEC_ID_ADPCM_THP, sample_fmts_s16p, adpcm_thp, "ADPCM Nintendo Gamecube THP"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_XA, sample_fmts_s16p, adpcm_xa, "ADPCM CDROM XA"); ADPCM_DECODER(AV_CODEC_ID_ADPCM_YAMAHA, sample_fmts_s16, adpcm_yamaha, "ADPCM Yamaha"); From cbcd497f384f0f8ef3f76f85b29b644b900d6b9f Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 21 Sep 2012 10:48:12 -0400 Subject: [PATCH 19/19] adxdec: use planar sample format --- libavcodec/adxdec.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index 96847c03ed..4d2892b4b2 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -49,7 +49,7 @@ static av_cold int adx_decode_init(AVCodecContext *avctx) c->header_parsed = 1; } - avctx->sample_fmt = AV_SAMPLE_FMT_S16; + avctx->sample_fmt = AV_SAMPLE_FMT_S16P; avcodec_get_frame_defaults(&c->frame); avctx->coded_frame = &c->frame; @@ -64,7 +64,8 @@ static av_cold int adx_decode_init(AVCodecContext *avctx) * 2nd-order LPC filter applied to it to form the output signal for a single * channel. */ -static int adx_decode(ADXContext *c, int16_t *out, const uint8_t *in, int ch) +static int adx_decode(ADXContext *c, int16_t *out, int offset, + const uint8_t *in, int ch) { ADXChannelState *prev = &c->prev[ch]; GetBitContext gb; @@ -77,6 +78,7 @@ static int adx_decode(ADXContext *c, int16_t *out, const uint8_t *in, int ch) return -1; init_get_bits(&gb, in + 2, (BLOCK_SIZE - 2) * 8); + out += offset; s1 = prev->s1; s2 = prev->s2; for (i = 0; i < BLOCK_SAMPLES; i++) { @@ -84,8 +86,7 @@ static int adx_decode(ADXContext *c, int16_t *out, const uint8_t *in, int ch) s0 = ((d << COEFF_BITS) * scale + c->coeff[0] * s1 + c->coeff[1] * s2) >> COEFF_BITS; s2 = s1; s1 = av_clip_int16(s0); - *out = s1; - out += c->channels; + *out++ = s1; } prev->s1 = s1; prev->s2 = s2; @@ -98,7 +99,8 @@ static int adx_decode_frame(AVCodecContext *avctx, void *data, { int buf_size = avpkt->size; ADXContext *c = avctx->priv_data; - int16_t *samples; + int16_t **samples; + int samples_offset; const uint8_t *buf = avpkt->data; int num_blocks, ch, ret; @@ -144,11 +146,12 @@ static int adx_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } - samples = (int16_t *)c->frame.data[0]; + samples = (int16_t **)c->frame.extended_data; + samples_offset = 0; while (num_blocks--) { for (ch = 0; ch < c->channels; ch++) { - if (adx_decode(c, samples + ch, buf, ch)) { + if (adx_decode(c, samples[ch], samples_offset, buf, ch)) { c->eof = 1; buf = avpkt->data + avpkt->size; break; @@ -156,7 +159,7 @@ static int adx_decode_frame(AVCodecContext *avctx, void *data, buf_size -= BLOCK_SIZE; buf += BLOCK_SIZE; } - samples += BLOCK_SAMPLES * c->channels; + samples_offset += BLOCK_SAMPLES; } *got_frame_ptr = 1; @@ -182,4 +185,6 @@ AVCodec ff_adpcm_adx_decoder = { .flush = adx_decode_flush, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"), + .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, + AV_SAMPLE_FMT_NONE }, };