mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
fix 24bit flac support, revised from Thibaut Mattern <thibaut.mattern@gmail.com>
Originally committed as revision 5507 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
ea138e978a
commit
0187178e07
@ -296,7 +296,7 @@ static int decode_subframe_fixed(FLACContext *s, int channel, int pred_order)
|
|||||||
|
|
||||||
static int decode_subframe_lpc(FLACContext *s, int channel, int pred_order)
|
static int decode_subframe_lpc(FLACContext *s, int channel, int pred_order)
|
||||||
{
|
{
|
||||||
int sum, i, j;
|
int i, j;
|
||||||
int coeff_prec, qlevel;
|
int coeff_prec, qlevel;
|
||||||
int coeffs[pred_order];
|
int coeffs[pred_order];
|
||||||
|
|
||||||
@ -334,12 +334,24 @@ static int decode_subframe_lpc(FLACContext *s, int channel, int pred_order)
|
|||||||
if (decode_residuals(s, channel, pred_order) < 0)
|
if (decode_residuals(s, channel, pred_order) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
for (i = pred_order; i < s->blocksize; i++)
|
if (s->bps > 16) {
|
||||||
{
|
int64_t sum;
|
||||||
sum = 0;
|
for (i = pred_order; i < s->blocksize; i++)
|
||||||
for (j = 0; j < pred_order; j++)
|
{
|
||||||
sum += coeffs[j] * s->decoded[channel][i-j-1];
|
sum = 0;
|
||||||
s->decoded[channel][i] += sum >> qlevel;
|
for (j = 0; j < pred_order; j++)
|
||||||
|
sum += (int64_t)coeffs[j] * s->decoded[channel][i-j-1];
|
||||||
|
s->decoded[channel][i] += sum >> qlevel;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int sum;
|
||||||
|
for (i = pred_order; i < s->blocksize; i++)
|
||||||
|
{
|
||||||
|
sum = 0;
|
||||||
|
for (j = 0; j < pred_order; j++)
|
||||||
|
sum += coeffs[j] * s->decoded[channel][i-j-1];
|
||||||
|
s->decoded[channel][i] += sum >> qlevel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -538,6 +550,17 @@ static int decode_frame(FLACContext *s)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int16_t shift_to_16_bits(int32_t data, int bps)
|
||||||
|
{
|
||||||
|
if (bps == 24) {
|
||||||
|
return (data >> 8);
|
||||||
|
} else if (bps == 20) {
|
||||||
|
return (data >> 4);
|
||||||
|
} else {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int flac_decode_frame(AVCodecContext *avctx,
|
static int flac_decode_frame(AVCodecContext *avctx,
|
||||||
void *data, int *data_size,
|
void *data, int *data_size,
|
||||||
uint8_t *buf, int buf_size)
|
uint8_t *buf, int buf_size)
|
||||||
@ -680,23 +703,25 @@ static int flac_decode_frame(AVCodecContext *avctx,
|
|||||||
for (j = 0; j < s->blocksize; j++)
|
for (j = 0; j < s->blocksize; j++)
|
||||||
{
|
{
|
||||||
for (i = 0; i < s->channels; i++)
|
for (i = 0; i < s->channels; i++)
|
||||||
*(samples++) = s->decoded[i][j];
|
*(samples++) = shift_to_16_bits(s->decoded[i][j], s->bps);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LEFT_SIDE:
|
case LEFT_SIDE:
|
||||||
assert(s->channels == 2);
|
assert(s->channels == 2);
|
||||||
for (i = 0; i < s->blocksize; i++)
|
for (i = 0; i < s->blocksize; i++)
|
||||||
{
|
{
|
||||||
*(samples++) = s->decoded[0][i];
|
*(samples++) = shift_to_16_bits(s->decoded[0][i], s->bps);
|
||||||
*(samples++) = s->decoded[0][i] - s->decoded[1][i];
|
*(samples++) = shift_to_16_bits(s->decoded[0][i]
|
||||||
|
- s->decoded[1][i], s->bps);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RIGHT_SIDE:
|
case RIGHT_SIDE:
|
||||||
assert(s->channels == 2);
|
assert(s->channels == 2);
|
||||||
for (i = 0; i < s->blocksize; i++)
|
for (i = 0; i < s->blocksize; i++)
|
||||||
{
|
{
|
||||||
*(samples++) = s->decoded[0][i] + s->decoded[1][i];
|
*(samples++) = shift_to_16_bits(s->decoded[0][i]
|
||||||
*(samples++) = s->decoded[1][i];
|
+ s->decoded[1][i], s->bps);
|
||||||
|
*(samples++) = shift_to_16_bits(s->decoded[1][i], s->bps);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MID_SIDE:
|
case MID_SIDE:
|
||||||
@ -709,8 +734,8 @@ static int flac_decode_frame(AVCodecContext *avctx,
|
|||||||
|
|
||||||
#if 1 //needs to be checked but IMHO it should be binary identical
|
#if 1 //needs to be checked but IMHO it should be binary identical
|
||||||
mid -= side>>1;
|
mid -= side>>1;
|
||||||
*(samples++) = mid + side;
|
*(samples++) = shift_to_16_bits(mid + side, s->bps);
|
||||||
*(samples++) = mid;
|
*(samples++) = shift_to_16_bits(mid, s->bps);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
mid <<= 1;
|
mid <<= 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user