summaryrefslogtreecommitdiff
path: root/apps/codecs/libffmpegFLAC
diff options
context:
space:
mode:
authorAndree Buschmann <AndreeBuschmann@t-online.de>2011-12-10 22:28:16 +0000
committerAndree Buschmann <AndreeBuschmann@t-online.de>2011-12-10 22:28:16 +0000
commita6653a9bb6c35e01dc44365b51f816198656acf7 (patch)
tree4a271828aa91694403a4e3688b9106b062084dcd /apps/codecs/libffmpegFLAC
parent09722dd28db02bf7cb34d1a7d42729ce66ebe302 (diff)
downloadrockbox-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.c80
-rw-r--r--apps/codecs/libffmpegFLAC/decoder.h8
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;