summaryrefslogtreecommitdiff
path: root/libavcodec/alac.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-07-27 23:42:19 +0200
committerMichael Niedermayer <michaelni@gmx.at>2012-07-27 23:42:19 +0200
commitc6963a220d5849fd5399c056b21ec66de7a0df37 (patch)
tree142ce617e997fd542f0f2ccd460212b5a3dc6835 /libavcodec/alac.c
parent94c3e11a6f62bf13a7e6f1b9287c6112bf6ee445 (diff)
parent5361e10a5e8740146c09a115477310c77b927215 (diff)
downloadffmpeg-c6963a220d5849fd5399c056b21ec66de7a0df37.tar.gz
Merge remote-tracking branch 'qatar/master'
* qatar/master: proresdsp: port x86 assembly to cpuflags. lavr: x86: improve non-SSE4 version of S16_TO_S32_SX macro lavfi: better channel layout negotiation alac: check for truncated packets alac: reverse lpc coeff order, simplify filter lavr: add x86-optimized mixing functions x86: add support for fmaddps fma4 instruction with abstraction to avx/sse tscc2: fix typo in array index build: use COMPILE template for HOSTOBJS build: do full flag handling for all compiler-type tools eval: fix printing of NaN in eval fate test. build: Rename aandct component to more descriptive aandcttables mpegaudio: bury inline asm under HAVE_INLINE_ASM. x86inc: automatically insert vzeroupper for YMM functions. rtmp: Check the buffer length of ping packets rtmp: Allow having more unknown data at the end of a chunk size packet without failing rtmp: Prevent reading outside of an allocate buffer when receiving server bandwidth packets Conflicts: Makefile configure libavcodec/x86/proresdsp.asm libavutil/eval.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/alac.c')
-rw-r--r--libavcodec/alac.c40
1 files changed, 23 insertions, 17 deletions
diff --git a/libavcodec/alac.c b/libavcodec/alac.c
index 4fa328539c..2d98456f8b 100644
--- a/libavcodec/alac.c
+++ b/libavcodec/alac.c
@@ -200,6 +200,7 @@ static void lpc_prediction(int32_t *error_buffer, int32_t *buffer_out,
int lpc_order, int lpc_quant)
{
int i;
+ int32_t *pred = buffer_out;
/* first sample always copies */
*buffer_out = *error_buffer;
@@ -223,37 +224,35 @@ static void lpc_prediction(int32_t *error_buffer, int32_t *buffer_out,
}
/* read warm-up samples */
- for (i = 0; i < lpc_order; i++) {
- buffer_out[i + 1] = sign_extend(buffer_out[i] + error_buffer[i + 1],
- bps);
- }
+ for (i = 1; i <= lpc_order; i++)
+ buffer_out[i] = sign_extend(buffer_out[i - 1] + error_buffer[i], bps);
/* NOTE: 4 and 8 are very common cases that could be optimized. */
- for (i = lpc_order; i < nb_samples - 1; i++) {
+ for (; i < nb_samples; i++) {
int j;
int val = 0;
- int error_val = error_buffer[i + 1];
+ int error_val = error_buffer[i];
int error_sign;
- int d = buffer_out[i - lpc_order];
+ int d = *pred++;
/* LPC prediction */
for (j = 0; j < lpc_order; j++)
- val += (buffer_out[i - j] - d) * lpc_coefs[j];
+ val += (pred[j] - d) * lpc_coefs[j];
val = (val + (1 << (lpc_quant - 1))) >> lpc_quant;
val += d + error_val;
- buffer_out[i + 1] = sign_extend(val, bps);
+ buffer_out[i] = sign_extend(val, bps);
/* adapt LPC coefficients */
error_sign = sign_only(error_val);
if (error_sign) {
- for (j = lpc_order - 1; j >= 0 && error_val * error_sign > 0; j--) {
+ for (j = 0; j < lpc_order && error_val * error_sign > 0; j++) {
int sign;
- val = d - buffer_out[i - j];
+ val = d - pred[j];
sign = sign_only(val) * error_sign;
lpc_coefs[j] -= sign;
val *= sign;
- error_val -= (val >> lpc_quant) * (lpc_order - j);
+ error_val -= (val >> lpc_quant) * (j + 1);
}
}
}
@@ -356,7 +355,7 @@ static int decode_element(AVCodecContext *avctx, void *data, int ch_index,
lpc_order[ch] = get_bits(&alac->gb, 5);
/* read the predictor table */
- for (i = 0; i < lpc_order[ch]; i++)
+ for (i = lpc_order[ch] - 1; i >= 0; i--)
lpc_coefs[ch][i] = get_sbits(&alac->gb, 16);
}
@@ -477,16 +476,19 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data,
ALACContext *alac = avctx->priv_data;
enum RawDataBlockType element;
int channels;
- int ch, ret;
+ int ch, ret, got_end;
init_get_bits(&alac->gb, avpkt->data, avpkt->size * 8);
+ got_end = 0;
alac->nb_samples = 0;
ch = 0;
- while (get_bits_left(&alac->gb)) {
+ while (get_bits_left(&alac->gb) >= 3) {
element = get_bits(&alac->gb, 3);
- if (element == TYPE_END)
+ if (element == TYPE_END) {
+ got_end = 1;
break;
+ }
if (element > TYPE_CPE && element != TYPE_LFE) {
av_log(avctx, AV_LOG_ERROR, "syntax element unsupported: %d", element);
return AVERROR_PATCHWELCOME;
@@ -501,11 +503,15 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data,
ret = decode_element(avctx, data,
alac_channel_layout_offsets[alac->channels - 1][ch],
channels);
- if (ret < 0)
+ if (ret < 0 && get_bits_left(&alac->gb))
return ret;
ch += channels;
}
+ if (!got_end) {
+ av_log(avctx, AV_LOG_ERROR, "no end tag found. incomplete packet.\n");
+ return AVERROR_INVALIDDATA;
+ }
if (avpkt->size * 8 - get_bits_count(&alac->gb) > 8) {
av_log(avctx, AV_LOG_ERROR, "Error : %d bits left\n",