* All 2 channel configurations -> AV_CH_LAYOUT_STEREO
*/
-static const int64_t dca_core_channel_layout[] = {
+static const uint64_t dca_core_channel_layout[] = {
AV_CH_FRONT_CENTER, ///< 1, A
AV_CH_LAYOUT_STEREO, ///< 2, A + B (dual mono)
AV_CH_LAYOUT_STEREO, ///< 2, L + R (stereo)
typedef struct {
AVCodecContext *avctx;
+ AVFrame frame;
/* Frame header */
int frame_type; ///< type of the current frame
int samples_deficit; ///< deficit sample count
/* Primary audio coding header */
int subframes; ///< number of subframes
- int is_channels_set; ///< check for if the channel number is already set
int total_channels; ///< number of channels including extensions
int prim_channels; ///< number of primary audio channels
int subband_activity[DCA_PRIM_CHANNELS_MAX]; ///< subband activity count
init_get_bits(&s->gb, s->dca_buffer, s->dca_buffer_size * 8);
/* Sync code */
- get_bits(&s->gb, 32);
+ skip_bits_long(&s->gb, 32);
/* Frame header */
s->frame_type = get_bits(&s->gb, 1);
s->sample_blocks = get_bits(&s->gb, 7) + 1;
s->frame_size = get_bits(&s->gb, 14) + 1;
if (s->frame_size < 95)
- return -1;
+ return AVERROR_INVALIDDATA;
s->amode = get_bits(&s->gb, 6);
s->sample_rate = dca_sample_rates[get_bits(&s->gb, 4)];
if (!s->sample_rate)
- return -1;
+ return AVERROR_INVALIDDATA;
s->bit_rate_index = get_bits(&s->gb, 5);
s->bit_rate = dca_bit_rates[s->bit_rate_index];
if (!s->bit_rate)
- return -1;
+ return AVERROR_INVALIDDATA;
s->downmix = get_bits(&s->gb, 1);
s->dynrange = get_bits(&s->gb, 1);
int j, k;
if (get_bits_left(&s->gb) < 0)
- return -1;
+ return AVERROR_INVALIDDATA;
if (!base_channel) {
s->subsubframes[s->current_subframe] = get_bits(&s->gb, 2) + 1;
else if (s->bitalloc_huffman[j] == 7) {
av_log(s->avctx, AV_LOG_ERROR,
"Invalid bit allocation index\n");
- return -1;
+ return AVERROR_INVALIDDATA;
} else {
s->bitalloc[j][k] =
get_bitalloc(&s->gb, &dca_bitalloc_index, s->bitalloc_huffman[j]);
if (s->bitalloc[j][k] > 26) {
// av_log(s->avctx,AV_LOG_DEBUG,"bitalloc index [%i][%i] too big (%i)\n",
// j, k, s->bitalloc[j][k]);
- return -1;
+ return AVERROR_INVALIDDATA;
}
}
}
}
if (get_bits_left(&s->gb) < 0)
- return -1;
+ return AVERROR_INVALIDDATA;
for (j = base_channel; j < s->prim_channels; j++) {
const uint32_t *scale_table;
}
if (get_bits_left(&s->gb) < 0)
- return -1;
+ return AVERROR_INVALIDDATA;
/* Scale factors for joint subband coding */
for (j = base_channel; j < s->prim_channels; j++) {
}
+#ifndef decode_blockcodes
/* Very compact version of the block code decoder that does not use table
* look-up but is slightly slower */
static int decode_blockcode(int code, int levels, int *values)
code = div;
}
- if (code == 0)
- return 0;
- else {
- av_log(NULL, AV_LOG_ERROR, "ERROR: block code look-up failed\n");
- return -1;
- }
+ return code;
+}
+
+static int decode_blockcodes(int code1, int code2, int levels, int *values)
+{
+ return decode_blockcode(code1, levels, values) |
+ decode_blockcode(code2, levels, values + 4);
}
+#endif
static const uint8_t abits_sizes[7] = { 7, 10, 12, 13, 15, 17, 19 };
static const uint8_t abits_levels[7] = { 3, 5, 7, 9, 13, 17, 25 };
for (k = base_channel; k < s->prim_channels; k++) {
if (get_bits_left(&s->gb) < 0)
- return -1;
+ return AVERROR_INVALIDDATA;
for (l = 0; l < s->vq_start_subband[k]; l++) {
int m;
if (abits >= 11 || !dca_smpl_bitalloc[abits].vlc[sel].table){
if (abits <= 7){
/* Block code */
- int block_code1, block_code2, size, levels;
+ int block_code1, block_code2, size, levels, err;
size = abits_sizes[abits-1];
levels = abits_levels[abits-1];
block_code1 = get_bits(&s->gb, size);
- /* FIXME Should test return value */
- decode_blockcode(block_code1, levels, block);
block_code2 = get_bits(&s->gb, size);
- decode_blockcode(block_code2, levels, &block[4]);
+ err = decode_blockcodes(block_code1, block_code2,
+ levels, block);
+ if (err) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "ERROR: block code look-up failed\n");
+ return AVERROR_INVALIDDATA;
+ }
}else{
/* no coding */
for (m = 0; m < 8; m++)
/* presumably optional information only appears in the core? */
if (!base_channel) {
if (s->timestamp)
- get_bits(&s->gb, 32);
+ skip_bits_long(&s->gb, 32);
if (s->aux_data)
aux_data_count = get_bits(&s->gb, 6);
static int dca_decode_block(DCAContext * s, int base_channel, int block_index)
{
+ int ret;
/* Sanity check */
if (s->current_subframe >= s->subframes) {
av_log(s->avctx, AV_LOG_DEBUG, "check failed: %i>%i",
s->current_subframe, s->subframes);
- return -1;
+ return AVERROR_INVALIDDATA;
}
if (!s->current_subsubframe) {
av_log(s->avctx, AV_LOG_DEBUG, "DSYNC dca_subframe_header\n");
#endif
/* Read subframe header */
- if (dca_subframe_header(s, base_channel, block_index))
- return -1;
+ if ((ret = dca_subframe_header(s, base_channel, block_index)))
+ return ret;
}
/* Read subsubframe */
#ifdef TRACE
av_log(s->avctx, AV_LOG_DEBUG, "DSYNC dca_subsubframe\n");
#endif
- if (dca_subsubframe(s, base_channel, block_index))
- return -1;
+ if ((ret = dca_subsubframe(s, base_channel, block_index)))
+ return ret;
/* Update state */
s->current_subsubframe++;
av_log(s->avctx, AV_LOG_DEBUG, "DSYNC dca_subframe_footer\n");
#endif
/* Read subframe footer */
- if (dca_subframe_footer(s, base_channel))
- return -1;
+ if ((ret = dca_subframe_footer(s, base_channel)))
+ return ret;
}
return 0;
flush_put_bits(&pb);
return (put_bits_count(&pb) + 7) >> 3;
default:
- return -1;
+ return AVERROR_INVALIDDATA;
}
}
* Main frame decoding function
* FIXME add arguments
*/
-static int dca_decode_frame(AVCodecContext * avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int dca_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
int lfe_samples;
int num_core_channels = 0;
- int i;
- float *samples_flt = data;
- int16_t *samples_s16 = data;
- int out_size;
+ int i, ret;
+ float *samples_flt;
+ int16_t *samples_s16;
DCAContext *s = avctx->priv_data;
int channels;
int core_ss_end;
s->dca_buffer_size = dca_convert_bitstream(buf, buf_size, s->dca_buffer,
DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE);
- if (s->dca_buffer_size == -1) {
+ if (s->dca_buffer_size == AVERROR_INVALIDDATA) {
av_log(avctx, AV_LOG_ERROR, "Not a valid DCA frame\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
init_get_bits(&s->gb, s->dca_buffer, s->dca_buffer_size * 8);
- if (dca_parse_frame_header(s) < 0) {
+ if ((ret = dca_parse_frame_header(s)) < 0) {
//seems like the frame is corrupt, try with the next one
- *data_size=0;
- return buf_size;
+ return ret;
}
//set AVCodec values with parsed data
avctx->sample_rate = s->sample_rate;
s->profile = FF_PROFILE_DTS;
for (i = 0; i < (s->sample_blocks / 8); i++) {
- dca_decode_block(s, 0, i);
+ if ((ret = dca_decode_block(s, 0, i))) {
+ av_log(avctx, AV_LOG_ERROR, "error decoding block\n");
+ return ret;
+ }
}
/* record number of core channels incase less than max channels are requested */
dca_parse_audio_coding_header(s, s->xch_base_channel);
for (i = 0; i < (s->sample_blocks / 8); i++) {
- dca_decode_block(s, s->xch_base_channel, i);
+ if ((ret = dca_decode_block(s, s->xch_base_channel, i))) {
+ av_log(avctx, AV_LOG_ERROR, "error decoding XCh extension\n");
+ continue;
+ }
}
s->xch_present = 1;
if (channels > !!s->lfe &&
s->channel_order_tab[channels - 1 - !!s->lfe] < 0)
- return -1;
+ return AVERROR_INVALIDDATA;
if (avctx->request_channels == 2 && s->prim_channels > 2) {
channels = 2;
}
} else {
av_log(avctx, AV_LOG_ERROR, "Non standard configuration %d !\n",s->amode);
- return -1;
+ return AVERROR_INVALIDDATA;
}
-
- /* There is nothing that prevents a dts frame to change channel configuration
- but FFmpeg doesn't support that so only set the channels if it is previously
- unset. Ideally during the first probe for channels the crc should be checked
- and only set avctx->channels when the crc is ok. Right now the decoder could
- set the channels based on a broken first frame.*/
- if (s->is_channels_set == 0) {
- s->is_channels_set = 1;
- avctx->channels = channels;
- }
if (avctx->channels != channels) {
- av_log(avctx, AV_LOG_ERROR, "DCA decoder does not support number of "
- "channels changing in stream. Skipping frame.\n");
- return -1;
+ if (avctx->channels)
+ av_log(avctx, AV_LOG_INFO, "Number of channels changed in DCA decoder (%d -> %d)\n", avctx->channels, channels);
+ avctx->channels = channels;
}
- out_size = 256 / 8 * s->sample_blocks * channels *
- av_get_bytes_per_sample(avctx->sample_fmt);
- if (*data_size < out_size)
- return -1;
- *data_size = out_size;
+ /* get output buffer */
+ s->frame.nb_samples = 256 * (s->sample_blocks / 8);
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ samples_flt = (float *)s->frame.data[0];
+ samples_s16 = (int16_t *)s->frame.data[0];
/* filter to get final output */
for (i = 0; i < (s->sample_blocks / 8); i++) {
s->lfe_data[i] = s->lfe_data[i + lfe_samples];
}
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
+
return buf_size;
}
avctx->channels = avctx->request_channels;
}
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
return 0;
}
.decode = dca_decode_frame,
.close = dca_decode_end,
.long_name = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"),
- .capabilities = CODEC_CAP_CHANNEL_CONF,
+ .capabilities = CODEC_CAP_CHANNEL_CONF | CODEC_CAP_DR1,
.sample_fmts = (const enum AVSampleFormat[]) {
AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE
},