typedef struct {
AVCodecContext *avctx;
+ AVFrame frame;
ALSSpecificConfig sconf;
GetBitContext gb;
DSPContext dsp;
init_get_bits(&gb, avctx->extradata, avctx->extradata_size * 8);
config_offset = avpriv_mpeg4audio_get_config(&m4ac, avctx->extradata,
- avctx->extradata_size);
+ avctx->extradata_size * 8, 1);
if (config_offset < 0)
return -1;
unsigned int count = 0;
while (b < b_max)
- count += div_blocks[b];
+ count += div_blocks[b++];
if (count)
memset(buf, 0, sizeof(*buf) * count);
/** Decode an ALS frame.
*/
-static int decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
AVPacket *avpkt)
{
ALSDecContext *ctx = avctx->priv_data;
ALSSpecificConfig *sconf = &ctx->sconf;
const uint8_t *buffer = avpkt->data;
int buffer_size = avpkt->size;
- int invalid_frame, size;
+ int invalid_frame, ret;
unsigned int c, sample, ra_frame, bytes_read, shift;
init_get_bits(&ctx->gb, buffer, buffer_size * 8);
ctx->frame_id++;
- // check for size of decoded data
- size = ctx->cur_frame_length * avctx->channels *
- av_get_bytes_per_sample(avctx->sample_fmt);
-
- if (size > *data_size) {
- av_log(avctx, AV_LOG_ERROR, "Decoded data exceeds buffer size.\n");
- return -1;
+ /* get output buffer */
+ ctx->frame.nb_samples = ctx->cur_frame_length;
+ if ((ret = avctx->get_buffer(avctx, &ctx->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
}
- *data_size = size;
-
// transform decoded frame into output format
#define INTERLEAVE_OUTPUT(bps) \
{ \
- int##bps##_t *dest = (int##bps##_t*) data; \
+ int##bps##_t *dest = (int##bps##_t*)ctx->frame.data[0]; \
shift = bps - ctx->avctx->bits_per_raw_sample; \
for (sample = 0; sample < ctx->cur_frame_length; sample++) \
for (c = 0; c < avctx->channels; c++) \
int swap = HAVE_BIGENDIAN != sconf->msb_first;
if (ctx->avctx->bits_per_raw_sample == 24) {
- int32_t *src = data;
+ int32_t *src = (int32_t *)ctx->frame.data[0];
for (sample = 0;
sample < ctx->cur_frame_length * avctx->channels;
if (swap) {
if (ctx->avctx->bits_per_raw_sample <= 16) {
- int16_t *src = (int16_t*) data;
+ int16_t *src = (int16_t*) ctx->frame.data[0];
int16_t *dest = (int16_t*) ctx->crc_buffer;
for (sample = 0;
sample < ctx->cur_frame_length * avctx->channels;
sample++)
*dest++ = av_bswap16(src[sample]);
} else {
- ctx->dsp.bswap_buf((uint32_t*)ctx->crc_buffer, data,
+ ctx->dsp.bswap_buf((uint32_t*)ctx->crc_buffer,
+ (uint32_t *)ctx->frame.data[0],
ctx->cur_frame_length * avctx->channels);
}
crc_source = ctx->crc_buffer;
} else {
- crc_source = data;
+ crc_source = ctx->frame.data[0];
}
- ctx->crc = av_crc(ctx->crc_table, ctx->crc, crc_source, size);
+ ctx->crc = av_crc(ctx->crc_table, ctx->crc, crc_source,
+ ctx->cur_frame_length * avctx->channels *
+ av_get_bytes_per_sample(avctx->sample_fmt));
}
}
}
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = ctx->frame;
+
bytes_read = invalid_frame ? buffer_size :
(get_bits_count(&ctx->gb) + 7) >> 3;
dsputil_init(&ctx->dsp, avctx);
+ avcodec_get_frame_defaults(&ctx->frame);
+ avctx->coded_frame = &ctx->frame;
+
return 0;
}
.close = decode_end,
.decode = decode_frame,
.flush = flush,
- .capabilities = CODEC_CAP_SUBFRAMES,
+ .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("MPEG-4 Audio Lossless Coding (ALS)"),
};