#define ALT_BITSTREAM_READER_LE
#include "avcodec.h"
#include "dsputil.h"
-#include "bitstream.h"
+#include "get_bits.h"
#include "bytestream.h"
/**
- * @file apedec.c
+ * @file libavcodec/apedec.c
* Monkey's Audio lossless audio decoder
*/
};
/** Filter fraction bits depending on compression level */
-static const uint16_t ape_filter_fracbits[5][APE_FILTER_LEVELS] = {
+static const uint8_t ape_filter_fracbits[5][APE_FILTER_LEVELS] = {
{ 0, 0, 0 },
{ 11, 0, 0 },
{ 11, 0, 0 },
uint8_t *data; ///< current frame data
uint8_t *data_end; ///< frame data end
- uint8_t *ptr; ///< current position in frame data
- uint8_t *last_ptr; ///< position where last 4608-sample block ended
-} APEContext;
+ const uint8_t *ptr; ///< current position in frame data
+ const uint8_t *last_ptr; ///< position where last 4608-sample block ended
-// TODO: dsputilize
-static inline void vector_add(int16_t * v1, int16_t * v2, int order)
-{
- while (order--)
- *v1++ += *v2++;
-}
-
-// TODO: dsputilize
-static inline void vector_sub(int16_t * v1, int16_t * v2, int order)
-{
- while (order--)
- *v1++ -= *v2++;
-}
+ int error;
+} APEContext;
// TODO: dsputilize
-static inline int32_t scalarproduct(int16_t * v1, int16_t * v2, int order)
-{
- int res = 0;
-
- while (order--)
- res += *v1++ * *v2++;
- return res;
-}
-
-static int ape_decode_init(AVCodecContext * avctx)
+static av_cold int ape_decode_init(AVCodecContext * avctx)
{
APEContext *s = avctx->priv_data;
int i;
av_log(avctx, AV_LOG_ERROR, "Incorrect extradata\n");
return -1;
}
- if (avctx->bits_per_sample != 16) {
+ if (avctx->bits_per_coded_sample != 16) {
av_log(avctx, AV_LOG_ERROR, "Only 16-bit samples are supported\n");
return -1;
}
}
dsputil_init(&s->dsp, avctx);
+ avctx->sample_fmt = SAMPLE_FMT_S16;
+ avctx->channel_layout = (avctx->channels==2) ? CH_LAYOUT_STEREO : CH_LAYOUT_MONO;
return 0;
}
-static int ape_decode_close(AVCodecContext * avctx)
+static av_cold int ape_decode_close(AVCodecContext * avctx)
{
APEContext *s = avctx->priv_data;
int i;
static inline void range_dec_normalize(APEContext * ctx)
{
while (ctx->rc.range <= BOTTOM_VALUE) {
- ctx->rc.buffer = (ctx->rc.buffer << 8) | bytestream_get_byte(&ctx->ptr);
+ ctx->rc.buffer <<= 8;
+ if(ctx->ptr < ctx->data_end)
+ ctx->rc.buffer += *ctx->ptr;
+ ctx->ptr++;
ctx->rc.low = (ctx->rc.low << 8) | ((ctx->rc.buffer >> 1) & 0xFF);
ctx->rc.range <<= 8;
}
/**
* Calculate culmulative frequency for next symbol. Does NO update!
+ * @param ctx decoder context
* @param tot_f is the total frequency or (code_value)1<<shift
* @return the culmulative frequency
*/
/**
* Decode value with given size in bits
+ * @param ctx decoder context
* @param shift number of bits to decode
*/
static inline int range_decode_culshift(APEContext * ctx, int shift)
/**
* Update decoding state
+ * @param ctx decoder context
* @param sy_f the interval length (frequency of the symbol)
* @param lt_f the lower end (frequency sum of < symbols)
*/
/**
* Fixed probabilities for symbols in Monkey Audio version 3.97
*/
-static const uint32_t counts_3970[65] = {
+static const uint16_t counts_3970[22] = {
0, 14824, 28224, 39348, 47855, 53994, 58171, 60926,
62682, 63786, 64463, 64878, 65126, 65276, 65365, 65419,
- 65450, 65469, 65480, 65487, 65491, 65493, 65494, 65495,
- 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503,
- 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511,
- 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519,
- 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527,
- 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535,
- 65536
+ 65450, 65469, 65480, 65487, 65491, 65493,
};
/**
* Probability ranges for symbols in Monkey Audio version 3.97
*/
-static const uint16_t counts_diff_3970[64] = {
+static const uint16_t counts_diff_3970[21] = {
14824, 13400, 11124, 8507, 6139, 4177, 2755, 1756,
1104, 677, 415, 248, 150, 89, 54, 31,
- 19, 11, 7, 4, 2, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1
+ 19, 11, 7, 4, 2,
};
/**
* Fixed probabilities for symbols in Monkey Audio version 3.98
*/
-static const uint32_t counts_3980[65] = {
+static const uint16_t counts_3980[22] = {
0, 19578, 36160, 48417, 56323, 60899, 63265, 64435,
64971, 65232, 65351, 65416, 65447, 65466, 65476, 65482,
- 65485, 65488, 65490, 65491, 65492, 65493, 65494, 65495,
- 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503,
- 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511,
- 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519,
- 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527,
- 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535,
- 65536
+ 65485, 65488, 65490, 65491, 65492, 65493,
};
/**
* Probability ranges for symbols in Monkey Audio version 3.98
*/
-static const uint16_t counts_diff_3980[64] = {
+static const uint16_t counts_diff_3980[21] = {
19578, 16582, 12257, 7906, 4576, 2366, 1170, 536,
261, 119, 65, 31, 19, 10, 6, 3,
- 3, 2, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1
+ 3, 2, 1, 1, 1,
};
/**
* Decode symbol
+ * @param ctx decoder context
* @param counts probability range start position
- * @param count_diffs probability range widths
+ * @param counts_diff probability range widths
*/
static inline int range_get_symbol(APEContext * ctx,
- const uint32_t counts[],
+ const uint16_t counts[],
const uint16_t counts_diff[])
{
int symbol, cf;
cf = range_decode_culshift(ctx, 16);
+ if(cf > 65492){
+ symbol= cf - 65535 + 63;
+ range_decode_update(ctx, 1, cf);
+ if(cf > 65535)
+ ctx->error=1;
+ return symbol;
+ }
/* figure out the symbol inefficiently; a binary search would be much better */
for (symbol = 0; counts[symbol + 1] <= cf; symbol++);
static inline void update_rice(APERice *rice, int x)
{
+ int lim = rice->k ? (1 << (rice->k + 4)) : 0;
rice->ksum += ((x + 1) / 2) - ((rice->ksum + 16) >> 5);
- if (rice->k == 0)
- rice->k = 1;
- else if (rice->ksum < (1 << (rice->k + 4)))
+ if (rice->ksum < lim)
rice->k--;
else if (rice->ksum >= (1 << (rice->k + 5)))
rice->k++;
{
int x, overflow;
- if (ctx->fileversion < 3980) {
+ if (ctx->fileversion < 3990) {
int tmpk;
overflow = range_get_symbol(ctx, counts_3970, counts_diff_3970);
overflow |= range_decode_bits(ctx, 16);
}
- base = range_decode_culfreq(ctx, pivot);
- range_decode_update(ctx, 1, base);
+ if (pivot < 0x10000) {
+ base = range_decode_culfreq(ctx, pivot);
+ range_decode_update(ctx, 1, base);
+ } else {
+ int base_hi = pivot, base_lo;
+ int bbits = 0;
+
+ while (base_hi & ~0xFFFF) {
+ base_hi >>= 1;
+ bbits++;
+ }
+ base_hi = range_decode_culfreq(ctx, base_hi + 1);
+ range_decode_update(ctx, 1, base_hi);
+ base_lo = range_decode_culfreq(ctx, 1 << bbits);
+ range_decode_update(ctx, 1, base_lo);
+
+ base = (base_hi << bbits) + base_lo;
+ }
x = base + overflow * pivot;
}
memset(p->historybuffer, 0, PREDICTOR_SIZE * sizeof(int32_t));
p->buf = p->historybuffer;
- /* Initialize and zero the co-efficients */
+ /* Initialize and zero the coefficients */
memcpy(p->coeffsA[0], initial_coeffs, sizeof(initial_coeffs));
memcpy(p->coeffsA[1], initial_coeffs, sizeof(initial_coeffs));
memset(p->coeffsB, 0, sizeof(p->coeffsB));
return (x < 0) - (x > 0);
}
-static int predictor_update_filter(APEPredictor *p, const int decoded, const int filter, const int delayA, const int delayB, const int adaptA, const int adaptB)
+static av_always_inline int predictor_update_filter(APEPredictor *p, const int decoded, const int filter, const int delayA, const int delayB, const int adaptA, const int adaptB)
{
- int32_t predictionA, predictionB;
+ int32_t predictionA, predictionB, sign;
p->buf[delayA] = p->lastA[filter];
p->buf[adaptA] = APESIGN(p->buf[delayA]);
p->lastA[filter] = decoded + ((predictionA + (predictionB >> 1)) >> 10);
p->filterA[filter] = p->lastA[filter] + ((p->filterA[filter] * 31) >> 5);
- if (!decoded) // no need updating filter coefficients
- return p->filterA[filter];
+ sign = APESIGN(decoded);
+ p->coeffsA[filter][0] += p->buf[adaptA ] * sign;
+ p->coeffsA[filter][1] += p->buf[adaptA - 1] * sign;
+ p->coeffsA[filter][2] += p->buf[adaptA - 2] * sign;
+ p->coeffsA[filter][3] += p->buf[adaptA - 3] * sign;
+ p->coeffsB[filter][0] += p->buf[adaptB ] * sign;
+ p->coeffsB[filter][1] += p->buf[adaptB - 1] * sign;
+ p->coeffsB[filter][2] += p->buf[adaptB - 2] * sign;
+ p->coeffsB[filter][3] += p->buf[adaptB - 3] * sign;
+ p->coeffsB[filter][4] += p->buf[adaptB - 4] * sign;
- if (decoded > 0) {
- p->coeffsA[filter][0] -= p->buf[adaptA ];
- p->coeffsA[filter][1] -= p->buf[adaptA - 1];
- p->coeffsA[filter][2] -= p->buf[adaptA - 2];
- p->coeffsA[filter][3] -= p->buf[adaptA - 3];
-
- p->coeffsB[filter][0] -= p->buf[adaptB ];
- p->coeffsB[filter][1] -= p->buf[adaptB - 1];
- p->coeffsB[filter][2] -= p->buf[adaptB - 2];
- p->coeffsB[filter][3] -= p->buf[adaptB - 3];
- p->coeffsB[filter][4] -= p->buf[adaptB - 4];
- } else {
- p->coeffsA[filter][0] += p->buf[adaptA ];
- p->coeffsA[filter][1] += p->buf[adaptA - 1];
- p->coeffsA[filter][2] += p->buf[adaptA - 2];
- p->coeffsA[filter][3] += p->buf[adaptA - 3];
-
- p->coeffsB[filter][0] += p->buf[adaptB ];
- p->coeffsB[filter][1] += p->buf[adaptB - 1];
- p->coeffsB[filter][2] += p->buf[adaptB - 2];
- p->coeffsB[filter][3] += p->buf[adaptB - 3];
- p->coeffsB[filter][4] += p->buf[adaptB - 4];
- }
return p->filterA[filter];
}
static void predictor_decode_stereo(APEContext * ctx, int count)
{
- int32_t predictionA, predictionB;
APEPredictor *p = &ctx->predictor;
int32_t *decoded0 = ctx->decoded0;
int32_t *decoded1 = ctx->decoded1;
while (count--) {
/* Predictor Y */
- predictionA = predictor_update_filter(p, *decoded0, 0, YDELAYA, YDELAYB, YADAPTCOEFFSA, YADAPTCOEFFSB);
- predictionB = predictor_update_filter(p, *decoded1, 1, XDELAYA, XDELAYB, XADAPTCOEFFSA, XADAPTCOEFFSB);
- *(decoded0++) = predictionA;
- *(decoded1++) = predictionB;
+ *decoded0 = predictor_update_filter(p, *decoded0, 0, YDELAYA, YDELAYB, YADAPTCOEFFSA, YADAPTCOEFFSB);
+ decoded0++;
+ *decoded1 = predictor_update_filter(p, *decoded1, 1, XDELAYA, XDELAYB, XADAPTCOEFFSA, XADAPTCOEFFSB);
+ decoded1++;
/* Combined */
p->buf++;
{
APEPredictor *p = &ctx->predictor;
int32_t *decoded0 = ctx->decoded0;
- int32_t predictionA, currentA, A;
+ int32_t predictionA, currentA, A, sign;
currentA = p->lastA[0];
p->buf[YADAPTCOEFFSA] = APESIGN(p->buf[YDELAYA ]);
p->buf[YADAPTCOEFFSA - 1] = APESIGN(p->buf[YDELAYA - 1]);
- if (A > 0) {
- p->coeffsA[0][0] -= p->buf[YADAPTCOEFFSA ];
- p->coeffsA[0][1] -= p->buf[YADAPTCOEFFSA - 1];
- p->coeffsA[0][2] -= p->buf[YADAPTCOEFFSA - 2];
- p->coeffsA[0][3] -= p->buf[YADAPTCOEFFSA - 3];
- } else if (A < 0) {
- p->coeffsA[0][0] += p->buf[YADAPTCOEFFSA ];
- p->coeffsA[0][1] += p->buf[YADAPTCOEFFSA - 1];
- p->coeffsA[0][2] += p->buf[YADAPTCOEFFSA - 2];
- p->coeffsA[0][3] += p->buf[YADAPTCOEFFSA - 3];
- }
+ sign = APESIGN(A);
+ p->coeffsA[0][0] += p->buf[YADAPTCOEFFSA ] * sign;
+ p->coeffsA[0][1] += p->buf[YADAPTCOEFFSA - 1] * sign;
+ p->coeffsA[0][2] += p->buf[YADAPTCOEFFSA - 2] * sign;
+ p->coeffsA[0][3] += p->buf[YADAPTCOEFFSA - 3] * sign;
p->buf++;
do_init_filter(&f[1], buf + order * 3 + HISTORY_SIZE, order);
}
-static inline void do_apply_filter(int version, APEFilter *f, int32_t *data, int count, int order, int fracbits)
+static void do_apply_filter(APEContext * ctx, int version, APEFilter *f, int32_t *data, int count, int order, int fracbits)
{
int res;
int absres;
while (count--) {
/* round fixedpoint scalar product */
- res = (scalarproduct(f->delay - order, f->coeffs, order) + (1 << (fracbits - 1))) >> fracbits;
-
- if (*data < 0)
- vector_add(f->coeffs, f->adaptcoeffs - order, order);
- else if (*data > 0)
- vector_sub(f->coeffs, f->adaptcoeffs - order, order);
-
+ res = ctx->dsp.scalarproduct_and_madd_int16(f->coeffs, f->delay - order, f->adaptcoeffs - order, order, APESIGN(*data));
+ res = (res + (1 << (fracbits - 1))) >> fracbits;
res += *data;
-
*data++ = res;
/* Update the output history */
/* Version 3.98 and later files */
/* Update the adaption coefficients */
- absres = (res < 0 ? -res : res);
-
- if (absres > (f->avg * 3))
- *f->adaptcoeffs = ((res >> 25) & 64) - 32;
- else if (absres > (f->avg * 4) / 3)
- *f->adaptcoeffs = ((res >> 26) & 32) - 16;
- else if (absres > 0)
- *f->adaptcoeffs = ((res >> 27) & 16) - 8;
+ absres = FFABS(res);
+ if (absres)
+ *f->adaptcoeffs = ((res & (1<<31)) - (1<<30)) >> (25 + (absres <= f->avg*3) + (absres <= f->avg*4/3));
else
*f->adaptcoeffs = 0;
int32_t * data0, int32_t * data1,
int count, int order, int fracbits)
{
- do_apply_filter(ctx->fileversion, &f[0], data0, count, order, fracbits);
+ do_apply_filter(ctx, ctx->fileversion, &f[0], data0, count, order, fracbits);
if (data1)
- do_apply_filter(ctx->fileversion, &f[1], data1, count, order, fracbits);
+ do_apply_filter(ctx, ctx->fileversion, &f[1], data1, count, order, fracbits);
}
static void ape_apply_filters(APEContext * ctx, int32_t * decoded0,
static int ape_decode_frame(AVCodecContext * avctx,
void *data, int *data_size,
- uint8_t * buf, int buf_size)
+ AVPacket *avpkt)
{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
APEContext *s = avctx->priv_data;
int16_t *samples = data;
int nblocks;
if(!s->samples){
s->data = av_realloc(s->data, (buf_size + 3) & ~3);
- s->dsp.bswap_buf(s->data, buf, buf_size >> 2);
+ s->dsp.bswap_buf((uint32_t*)s->data, (const uint32_t*)buf, buf_size >> 2);
s->ptr = s->last_ptr = s->data;
s->data_end = s->data + buf_size;
nblocks = s->samples;
blockstodecode = FFMIN(BLOCKS_PER_LOOP, nblocks);
+ s->error=0;
+
if ((s->channels == 1) || (s->frameflags & APE_FRAMECODE_PSEUDO_STEREO))
ape_unpack_mono(s, blockstodecode);
else
ape_unpack_stereo(s, blockstodecode);
+ emms_c();
+
+ if(s->error || s->ptr > s->data_end){
+ s->samples=0;
+ av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n");
+ return -1;
+ }
for (i = 0; i < blockstodecode; i++) {
*samples++ = s->decoded0[i];
NULL,
ape_decode_close,
ape_decode_frame,
+ .capabilities = CODEC_CAP_SUBFRAMES,
+ .long_name = NULL_IF_CONFIG_SMALL("Monkey's Audio"),
};