* Copyright (c) 2006-2008 Maxim Poliakovski
* Copyright (c) 2006-2008 Benjamin Larsson
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
}
-static av_cold void init_atrac3_transforms(ATRAC3Context *q) {
+static av_cold int init_atrac3_transforms(ATRAC3Context *q, int is_float) {
float enc_window[256];
int i;
}
/* Initialize the MDCT transform. */
- ff_mdct_init(&q->mdct_ctx, 9, 1, 1.0 / 32768);
+ return ff_mdct_init(&q->mdct_ctx, 9, 1, is_float ? 1.0 / 32768 : 1.0);
}
/**
coding_mode_selector = get_bits(gb,2);
if (coding_mode_selector == 2)
- return -1;
+ return AVERROR_INVALIDDATA;
coding_mode = coding_mode_selector & 1;
quant_step_index = get_bits(gb,3);
if (quant_step_index <= 1)
- return -1;
+ return AVERROR_INVALIDDATA;
if (coding_mode_selector == 3)
coding_mode = get_bits1(gb);
pLevel[cf]= get_bits(gb,4);
pLoc [cf]= get_bits(gb,5);
if(cf && pLoc[cf] <= pLoc[cf-1])
- return -1;
+ return AVERROR_INVALIDDATA;
}
}
if (codingMode == JOINT_STEREO && channelNum == 1) {
if (get_bits(gb,2) != 3) {
av_log(NULL,AV_LOG_ERROR,"JS mono Sound Unit id != 3.\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
} else {
if (get_bits(gb,6) != 0x28) {
av_log(NULL,AV_LOG_ERROR,"Sound Unit id != 0x28.\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
}
ptr1 = q->decoded_bytes_buffer;
for (i = 4; *ptr1 == 0xF8; i++, ptr1++) {
if (i >= q->bytes_per_frame)
- return -1;
+ return AVERROR_INVALIDDATA;
}
ATRAC3Context *q = avctx->priv_data;
int result = 0, out_size;
const uint8_t* databuf;
- float *samples = data;
+ float *samples_flt = data;
+ int16_t *samples_s16 = data;
if (buf_size < avctx->block_align) {
av_log(avctx, AV_LOG_ERROR,
databuf = buf;
}
- result = decodeFrame(q, databuf, q->channels == 2 ? q->outSamples : &samples);
+ if (q->channels == 1 && avctx->sample_fmt == AV_SAMPLE_FMT_FLT)
+ result = decodeFrame(q, databuf, &samples_flt);
+ else
+ result = decodeFrame(q, databuf, q->outSamples);
if (result != 0) {
av_log(NULL,AV_LOG_ERROR,"Frame decoding error!\n");
- return -1;
+ return result;
}
/* interleave */
- if (q->channels == 2) {
- q->fmt_conv.float_interleave(samples, (const float **)q->outSamples,
+ if (q->channels == 2 && avctx->sample_fmt == AV_SAMPLE_FMT_FLT) {
+ q->fmt_conv.float_interleave(samples_flt,
+ (const float **)q->outSamples,
SAMPLES_PER_FRAME, 2);
+ } else if (avctx->sample_fmt == AV_SAMPLE_FMT_S16) {
+ q->fmt_conv.float_to_int16_interleave(samples_s16,
+ (const float **)q->outSamples,
+ SAMPLES_PER_FRAME, q->channels);
}
*data_size = out_size;
static av_cold int atrac3_decode_init(AVCodecContext *avctx)
{
- int i;
+ int i, ret;
const uint8_t *edata_ptr = avctx->extradata;
ATRAC3Context *q = avctx->priv_data;
static VLC_TYPE atrac3_vlc_table[4096][2];
if ((q->bytes_per_frame == 96*q->channels*q->frame_factor) || (q->bytes_per_frame == 152*q->channels*q->frame_factor) || (q->bytes_per_frame == 192*q->channels*q->frame_factor)) {
} else {
av_log(avctx,AV_LOG_ERROR,"Unknown frame/channel/frame_factor configuration %d/%d/%d\n", q->bytes_per_frame, q->channels, q->frame_factor);
- return -1;
+ return AVERROR_INVALIDDATA;
}
} else if (avctx->extradata_size == 10) {
if (q->atrac3version != 4) {
av_log(avctx,AV_LOG_ERROR,"Version %d != 4.\n",q->atrac3version);
- return -1;
+ return AVERROR_INVALIDDATA;
}
if (q->samples_per_frame != SAMPLES_PER_FRAME && q->samples_per_frame != SAMPLES_PER_FRAME*2) {
av_log(avctx,AV_LOG_ERROR,"Unknown amount of samples per frame %d.\n",q->samples_per_frame);
- return -1;
+ return AVERROR_INVALIDDATA;
}
if (q->delay != 0x88E) {
av_log(avctx,AV_LOG_ERROR,"Unknown amount of delay %x != 0x88E.\n",q->delay);
- return -1;
+ return AVERROR_INVALIDDATA;
}
if (q->codingMode == STEREO) {
av_log(avctx,AV_LOG_DEBUG,"Joint stereo detected.\n");
} else {
av_log(avctx,AV_LOG_ERROR,"Unknown channel coding mode %x!\n",q->codingMode);
- return -1;
+ return AVERROR_INVALIDDATA;
}
if (avctx->channels <= 0 || avctx->channels > 2 /*|| ((avctx->channels * 1024) != q->samples_per_frame)*/) {
av_log(avctx,AV_LOG_ERROR,"Channel configuration error!\n");
- return -1;
+ return AVERROR(EINVAL);
}
if(avctx->block_align >= UINT_MAX/2)
- return -1;
+ return AVERROR(EINVAL);
/* Pad the data buffer with FF_INPUT_BUFFER_PADDING_SIZE,
* this is for the bitstream reader. */
vlcs_initialized = 1;
}
- init_atrac3_transforms(q);
+ if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT)
+ avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+ else
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+ if ((ret = init_atrac3_transforms(q, avctx->sample_fmt == AV_SAMPLE_FMT_FLT))) {
+ av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n");
+ av_freep(&q->decoded_bytes_buffer);
+ return ret;
+ }
atrac_generate_tables();
q->pUnits = av_mallocz(sizeof(channel_unit)*q->channels);
if (!q->pUnits) {
- av_free(q->decoded_bytes_buffer);
+ atrac3_decode_close(avctx);
return AVERROR(ENOMEM);
}
- if (avctx->channels > 1) {
- q->outSamples[0] = av_mallocz(SAMPLES_PER_FRAME * 2 * sizeof(*q->outSamples[0]));
+ if (avctx->channels > 1 || avctx->sample_fmt == AV_SAMPLE_FMT_S16) {
+ q->outSamples[0] = av_mallocz(SAMPLES_PER_FRAME * avctx->channels * sizeof(*q->outSamples[0]));
q->outSamples[1] = q->outSamples[0] + SAMPLES_PER_FRAME;
if (!q->outSamples[0]) {
atrac3_decode_close(avctx);
}
}
- avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
return 0;
}
.init = atrac3_decode_init,
.close = atrac3_decode_close,
.decode = atrac3_decode_frame,
+ .capabilities = CODEC_CAP_SUBFRAMES,
.long_name = NULL_IF_CONFIG_SMALL("Atrac 3 (Adaptive TRansform Acoustic Coding 3)"),
};