diff options
| author | Andree Buschmann <AndreeBuschmann@t-online.de> | 2011-12-10 22:28:16 +0000 |
|---|---|---|
| committer | Andree Buschmann <AndreeBuschmann@t-online.de> | 2011-12-10 22:28:16 +0000 |
| commit | a6653a9bb6c35e01dc44365b51f816198656acf7 (patch) | |
| tree | 4a271828aa91694403a4e3688b9106b062084dcd /apps/codecs/libffmpegFLAC | |
| parent | 09722dd28db02bf7cb34d1a7d42729ce66ebe302 (diff) | |
| download | rockbox-a6653a9bb6c35e01dc44365b51f816198656acf7.zip rockbox-a6653a9bb6c35e01dc44365b51f816198656acf7.tar.gz rockbox-a6653a9bb6c35e01dc44365b51f816198656acf7.tar.bz2 rockbox-a6653a9bb6c35e01dc44365b51f816198656acf7.tar.xz | |
Fix decoding of multichannel flac, refactor sample buffer handling and decorrelation (taken from ffmpeg sources) and add some flac details to the manual. Solves FS#12371.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31207 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libffmpegFLAC')
| -rw-r--r-- | apps/codecs/libffmpegFLAC/decoder.c | 80 | ||||
| -rw-r--r-- | apps/codecs/libffmpegFLAC/decoder.h | 8 |
2 files changed, 22 insertions, 66 deletions
diff --git a/apps/codecs/libffmpegFLAC/decoder.c b/apps/codecs/libffmpegFLAC/decoder.c index 1fafec1..2dbedf3 100644 --- a/apps/codecs/libffmpegFLAC/decoder.c +++ b/apps/codecs/libffmpegFLAC/decoder.c @@ -381,17 +381,13 @@ static inline int decode_subframe(FLACContext *s, int channel, int32_t* decoded) } static int decode_frame(FLACContext *s, - int32_t* decoded0, - int32_t* decoded1, void (*yield)(void)) ICODE_ATTR_FLAC; static int decode_frame(FLACContext *s, - int32_t* decoded0, - int32_t* decoded1, void (*yield)(void)) { int blocksize_code, sample_rate_code, sample_size_code, assignment, crc8; int decorrelation, bps, blocksize, samplerate; - int res; + int res, ch; blocksize_code = get_bits(&s->gb, 4); @@ -477,16 +473,10 @@ static int decode_frame(FLACContext *s, s->bps = bps; s->decorrelation= decorrelation; - yield(); - /* subframes */ - if ((res=decode_subframe(s, 0, decoded0)) < 0) - return res-100; - - yield(); - - if (s->channels==2) { - if ((res=decode_subframe(s, 1, decoded1)) < 0) - return res-200; + for (ch=0; ch<s->channels; ++ch) { + yield(); + if ((res=decode_subframe(s, ch, s->decoded[ch])) < 0) + return res-100; } yield(); @@ -499,8 +489,6 @@ static int decode_frame(FLACContext *s, } int flac_decode_frame(FLACContext *s, - int32_t* decoded0, - int32_t* decoded1, uint8_t *buf, int buf_size, void (*yield)(void)) { @@ -516,68 +504,36 @@ int flac_decode_frame(FLACContext *s, return -41; } - if ((framesize=decode_frame(s,decoded0,decoded1,yield)) < 0){ + if ((framesize=decode_frame(s,yield)) < 0){ s->bitstream_size=0; s->bitstream_index=0; return framesize; } yield(); + +#define DECORRELATE(left, right)\ + for (i = 0; i < s->blocksize; i++) {\ + int a = s->decoded[0][i];\ + int b = s->decoded[1][i];\ + s->decoded[0][i] = (left) << scale;\ + s->decoded[1][i] = (right) << scale;\ + }\ scale=FLAC_OUTPUT_DEPTH-s->bps; switch(s->decorrelation) { case INDEPENDENT: - if (s->channels==1) {; - for (i = 0; i < s->blocksize; i++) - { - decoded0[i] = decoded0[i] << scale; - } - } else { - for (i = 0; i < s->blocksize; i++) - { - decoded0[i] = decoded0[i] << scale; - decoded1[i] = decoded1[i] << scale; - } - } + DECORRELATE(a, b) /* Always decorrelate exactly the two supported channels. */ break; case LEFT_SIDE: - //assert(s->channels == 2); - for (i = 0; i < s->blocksize; i++) - { - decoded1[i] = (decoded0[i] - decoded1[i]) << scale; - decoded0[i] = decoded0[i] << scale; - } + DECORRELATE(a, a-b) break; case RIGHT_SIDE: - //assert(s->channels == 2); - for (i = 0; i < s->blocksize; i++) - { - decoded0[i] = (decoded0[i] + decoded1[i]) << scale; - decoded1[i] = decoded1[i] << scale; - } + DECORRELATE(a+b, a) break; case MID_SIDE: - //assert(s->channels == 2); - for (i = 0; i < s->blocksize; i++) - { - int mid, side; - mid = decoded0[i]; - side = decoded1[i]; - -#if 1 //needs to be checked but IMHO it should be binary identical - mid -= side>>1; - decoded0[i] = (mid + side) << scale; - decoded1[i] = mid << scale; -#else - - mid <<= 1; - if (side & 1) - mid++; - decoded0[i] = ((mid + side) >> 1) << scale; - decoded1[i] = ((mid - side) >> 1) << scale; -#endif - } + DECORRELATE( (a-=b>>1) + b, a) break; } diff --git a/apps/codecs/libffmpegFLAC/decoder.h b/apps/codecs/libffmpegFLAC/decoder.h index 0b148df..677a21a 100644 --- a/apps/codecs/libffmpegFLAC/decoder.h +++ b/apps/codecs/libffmpegFLAC/decoder.h @@ -3,9 +3,9 @@ #include "bitstream.h" -#define MAX_CHANNELS 2 /* Maximum supported channels */ +#define MAX_CHANNELS 6 /* Maximum supported channels, only left/right will be played back */ #define MAX_BLOCKSIZE 4608 /* Maxsize in samples of one uncompressed frame */ -#define MAX_FRAMESIZE 32768 /* Maxsize in bytes of one compressed frame */ +#define MAX_FRAMESIZE 65536 /* Maxsize in bytes of one compressed frame */ #define FLAC_OUTPUT_DEPTH 29 /* Provide samples left-shifted to 28 bits+sign */ @@ -38,11 +38,11 @@ typedef struct FLACContext { int sample_skip; int framesize; + + int32_t *decoded[MAX_CHANNELS]; } FLACContext; int flac_decode_frame(FLACContext *s, - int32_t* decoded0, - int32_t* decoded1, uint8_t *buf, int buf_size, void (*yield)(void)) ICODE_ATTR_FLAC; |