mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-01-14 03:11:20 +00:00
flacdec: split off channel decorrelation as flacdsp
Signed-off-by: Mans Rullgard <mans@mansr.com>
This commit is contained in:
parent
296d0da8bd
commit
4a8528349f
@ -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);
|
||||
|
49
libavcodec/flacdsp.c
Normal file
49
libavcodec/flacdsp.c
Normal file
@ -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;
|
||||
}
|
||||
}
|
32
libavcodec/flacdsp.h
Normal file
32
libavcodec/flacdsp.h
Normal file
@ -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 */
|
86
libavcodec/flacdsp_template.c
Normal file
86
libavcodec/flacdsp_template.c
Normal file
@ -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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user