Signed-off-by: Mans Rullgard <mans@mansr.com>tags/n1.0
| @@ -158,7 +158,7 @@ OBJS-$(CONFIG_FFV1_DECODER) += ffv1.o rangecoder.o | |||
| OBJS-$(CONFIG_FFV1_ENCODER) += ffv1.o rangecoder.o | |||
| OBJS-$(CONFIG_FFVHUFF_DECODER) += huffyuv.o | |||
| OBJS-$(CONFIG_FFVHUFF_ENCODER) += huffyuv.o | |||
| OBJS-$(CONFIG_FLAC_DECODER) += flacdec.o flacdata.o flac.o | |||
| OBJS-$(CONFIG_FLAC_DECODER) += flacdec.o flacdata.o flac.o flacdsp.o | |||
| OBJS-$(CONFIG_FLAC_ENCODER) += flacenc.o flacdata.o flac.o | |||
| OBJS-$(CONFIG_FLASHSV_DECODER) += flashsv.o | |||
| OBJS-$(CONFIG_FLASHSV_ENCODER) += flashsvenc.o | |||
| @@ -42,6 +42,7 @@ | |||
| #include "golomb.h" | |||
| #include "flac.h" | |||
| #include "flacdata.h" | |||
| #include "flacdsp.h" | |||
| #undef NDEBUG | |||
| #include <assert.h> | |||
| @@ -55,11 +56,12 @@ typedef struct FLACContext { | |||
| int blocksize; ///< number of samples in the current frame | |||
| int sample_shift; ///< shift required to make output samples 16-bit or 32-bit | |||
| int is32; ///< flag to indicate if output should be 32-bit instead of 16-bit | |||
| int ch_mode; ///< channel decorrelation type in the current frame | |||
| int got_streaminfo; ///< indicates if the STREAMINFO has been read | |||
| int32_t *decoded[FLAC_MAX_CHANNELS]; ///< decoded samples | |||
| FLACDSPContext dsp; | |||
| } FLACContext; | |||
| static const int64_t flac_channel_layouts[6] = { | |||
| @@ -105,11 +107,9 @@ static void flac_set_bps(FLACContext *s) | |||
| if (s->bps > 16) { | |||
| s->avctx->sample_fmt = AV_SAMPLE_FMT_S32; | |||
| s->sample_shift = 32 - s->bps; | |||
| s->is32 = 1; | |||
| } else { | |||
| s->avctx->sample_fmt = AV_SAMPLE_FMT_S16; | |||
| s->sample_shift = 16 - s->bps; | |||
| s->is32 = 0; | |||
| } | |||
| } | |||
| @@ -132,6 +132,7 @@ static av_cold int flac_decode_init(AVCodecContext *avctx) | |||
| avpriv_flac_parse_streaminfo(avctx, (FLACStreaminfo *)s, streaminfo); | |||
| allocate_buffers(s); | |||
| flac_set_bps(s); | |||
| ff_flacdsp_init(&s->dsp, avctx->sample_fmt); | |||
| s->got_streaminfo = 1; | |||
| avcodec_get_frame_defaults(&s->frame); | |||
| @@ -231,6 +232,8 @@ static int parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size) | |||
| } | |||
| avpriv_flac_parse_streaminfo(s->avctx, (FLACStreaminfo *)s, &buf[8]); | |||
| allocate_buffers(s); | |||
| flac_set_bps(s); | |||
| ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt); | |||
| s->got_streaminfo = 1; | |||
| return 0; | |||
| @@ -548,6 +551,7 @@ static int decode_frame(FLACContext *s) | |||
| if (!s->got_streaminfo) { | |||
| allocate_buffers(s); | |||
| ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt); | |||
| s->got_streaminfo = 1; | |||
| dump_headers(s->avctx, (FLACStreaminfo *)s); | |||
| } | |||
| @@ -574,9 +578,7 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data, | |||
| const uint8_t *buf = avpkt->data; | |||
| int buf_size = avpkt->size; | |||
| FLACContext *s = avctx->priv_data; | |||
| int i, j = 0, bytes_read = 0; | |||
| int16_t *samples_16; | |||
| int32_t *samples_32; | |||
| int bytes_read = 0; | |||
| int ret; | |||
| *got_frame_ptr = 0; | |||
| @@ -616,42 +618,9 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data, | |||
| av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |||
| return ret; | |||
| } | |||
| samples_16 = (int16_t *)s->frame.data[0]; | |||
| samples_32 = (int32_t *)s->frame.data[0]; | |||
| #define DECORRELATE(left, right)\ | |||
| assert(s->channels == 2);\ | |||
| for (i = 0; i < s->blocksize; i++) {\ | |||
| int a= s->decoded[0][i];\ | |||
| int b= s->decoded[1][i];\ | |||
| if (s->is32) {\ | |||
| *samples_32++ = (left) << s->sample_shift;\ | |||
| *samples_32++ = (right) << s->sample_shift;\ | |||
| } else {\ | |||
| *samples_16++ = (left) << s->sample_shift;\ | |||
| *samples_16++ = (right) << s->sample_shift;\ | |||
| }\ | |||
| }\ | |||
| break; | |||
| switch (s->ch_mode) { | |||
| case FLAC_CHMODE_INDEPENDENT: | |||
| for (j = 0; j < s->blocksize; j++) { | |||
| for (i = 0; i < s->channels; i++) { | |||
| if (s->is32) | |||
| *samples_32++ = s->decoded[i][j] << s->sample_shift; | |||
| else | |||
| *samples_16++ = s->decoded[i][j] << s->sample_shift; | |||
| } | |||
| } | |||
| break; | |||
| case FLAC_CHMODE_LEFT_SIDE: | |||
| DECORRELATE(a,a-b) | |||
| case FLAC_CHMODE_RIGHT_SIDE: | |||
| DECORRELATE(a+b,b) | |||
| case FLAC_CHMODE_MID_SIDE: | |||
| DECORRELATE( (a-=b>>1) + b, a) | |||
| } | |||
| s->dsp.decorrelate[s->ch_mode](s->frame.data, s->decoded, s->channels, | |||
| s->blocksize, s->sample_shift); | |||
| if (bytes_read > buf_size) { | |||
| av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", bytes_read - buf_size); | |||
| @@ -0,0 +1,49 @@ | |||
| /* | |||
| * Copyright (c) 2012 Mans Rullgard <mans@mansr.com> | |||
| * | |||
| * 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 "libavutil/attributes.h" | |||
| #include "libavutil/samplefmt.h" | |||
| #include "flacdsp.h" | |||
| #define SAMPLE_SIZE 16 | |||
| #include "flacdsp_template.c" | |||
| #undef SAMPLE_SIZE | |||
| #define SAMPLE_SIZE 32 | |||
| #include "flacdsp_template.c" | |||
| av_cold void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt) | |||
| { | |||
| switch (fmt) { | |||
| case AV_SAMPLE_FMT_S32: | |||
| c->decorrelate[0] = flac_decorrelate_indep_c_32; | |||
| c->decorrelate[1] = flac_decorrelate_ls_c_32; | |||
| c->decorrelate[2] = flac_decorrelate_rs_c_32; | |||
| c->decorrelate[3] = flac_decorrelate_ms_c_32; | |||
| break; | |||
| case AV_SAMPLE_FMT_S16: | |||
| c->decorrelate[0] = flac_decorrelate_indep_c_16; | |||
| c->decorrelate[1] = flac_decorrelate_ls_c_16; | |||
| c->decorrelate[2] = flac_decorrelate_rs_c_16; | |||
| c->decorrelate[3] = flac_decorrelate_ms_c_16; | |||
| break; | |||
| } | |||
| } | |||
| @@ -0,0 +1,32 @@ | |||
| /* | |||
| * 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 | |||
| */ | |||
| #ifndef AVCODEC_FLACDSP_H | |||
| #define AVCODEC_FLACDSP_H | |||
| #include <stdint.h> | |||
| #include "libavutil/samplefmt.h" | |||
| typedef struct FLACDSPContext { | |||
| void (*decorrelate[4])(uint8_t **out, int32_t **in, int channels, | |||
| int len, int shift); | |||
| } FLACDSPContext; | |||
| void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt); | |||
| #endif /* AVCODEC_FLACDSP_H */ | |||
| @@ -0,0 +1,86 @@ | |||
| /* | |||
| * Copyright (c) 2012 Mans Rullgard <mans@mansr.com> | |||
| * | |||
| * 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 <stdint.h> | |||
| #undef FUNC | |||
| #undef sample | |||
| #if SAMPLE_SIZE == 32 | |||
| # define FUNC(n) n ## _32 | |||
| # define sample int32_t | |||
| #else | |||
| # define FUNC(n) n ## _16 | |||
| # define sample int16_t | |||
| #endif | |||
| static void FUNC(flac_decorrelate_indep_c)(uint8_t **out, int32_t **in, | |||
| int channels, int len, int shift) | |||
| { | |||
| sample *samples = (sample *) out[0]; | |||
| int i, j; | |||
| for (j = 0; j < len; j++) | |||
| for (i = 0; i < channels; i++) | |||
| *samples++ = in[i][j] << shift; | |||
| } | |||
| static void FUNC(flac_decorrelate_ls_c)(uint8_t **out, int32_t **in, | |||
| int channels, int len, int shift) | |||
| { | |||
| sample *samples = (sample *) out[0]; | |||
| int i; | |||
| for (i = 0; i < len; i++) { | |||
| int a = in[0][i]; | |||
| int b = in[1][i]; | |||
| *samples++ = a << shift; | |||
| *samples++ = (a - b) << shift; | |||
| } | |||
| } | |||
| static void FUNC(flac_decorrelate_rs_c)(uint8_t **out, int32_t **in, | |||
| int channels, int len, int shift) | |||
| { | |||
| sample *samples = (sample *) out[0]; | |||
| int i; | |||
| for (i = 0; i < len; i++) { | |||
| int a = in[0][i]; | |||
| int b = in[1][i]; | |||
| *samples++ = (a + b) << shift; | |||
| *samples++ = b << shift; | |||
| } | |||
| } | |||
| static void FUNC(flac_decorrelate_ms_c)(uint8_t **out, int32_t **in, | |||
| int channels, int len, int shift) | |||
| { | |||
| sample *samples = (sample *) out[0]; | |||
| int i; | |||
| for (i = 0; i < len; i++) { | |||
| int a = in[0][i]; | |||
| int b = in[1][i]; | |||
| a -= b >> 1; | |||
| *samples++ = (a + b) << shift; | |||
| *samples++ = a << shift; | |||
| } | |||
| } | |||