/** * Main frame decoding function * FIXME add arguments */ static int dca_decode_frame(AVCodecContext * avctx, void *data, int *data_size, const uint8_t * buf, int buf_size) { int i, j, k; int16_t *samples = data; DCAContext *s = avctx->priv_data; int channels; s->dca_buffer_size = dca_convert_bitstream(buf, buf_size, s->dca_buffer, DCA_MAX_FRAME_SIZE); if (s->dca_buffer_size == -1) { av_log(avctx, AV_LOG_ERROR, "Not a valid DCA frame\n"); return -1; } init_get_bits(&s->gb, s->dca_buffer, s->dca_buffer_size * 8); if (dca_parse_frame_header(s) < 0) { //seems like the frame is corrupt, try with the next one *data_size=0; return buf_size; } //set AVCodec values with parsed data avctx->sample_rate = s->sample_rate; avctx->bit_rate = s->bit_rate; channels = s->prim_channels + !!s->lfe; if(avctx->request_channels == 2 && s->prim_channels > 2) { channels = 2; s->output = DCA_STEREO; } avctx->channels = channels; if(*data_size < (s->sample_blocks / 8) * 256 * sizeof(int16_t) * channels) return -1; *data_size = 0; for (i = 0; i < (s->sample_blocks / 8); i++) { dca_decode_block(s); s->dsp.float_to_int16(s->tsamples, s->samples, 256 * channels); /* interleave samples */ for (j = 0; j < 256; j++) { for (k = 0; k < channels; k++) samples[k] = s->tsamples[j + k * 256]; samples += channels; } *data_size += 256 * sizeof(int16_t) * channels; } return buf_size; }
/** * Main frame decoding function * FIXME add arguments */ static int dca_decode_frame(AVCodecContext * avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; int i; int16_t *samples = data; DCAContext *s = avctx->priv_data; int channels; s->dca_buffer_size = dca_convert_bitstream(buf, buf_size, s->dca_buffer, DCA_MAX_FRAME_SIZE); if (s->dca_buffer_size == -1) { av_log(avctx, AV_LOG_ERROR, "Not a valid DCA frame\n"); return -1; } init_get_bits(&s->gb, s->dca_buffer, s->dca_buffer_size * 8); if (dca_parse_frame_header(s) < 0) { //seems like the frame is corrupt, try with the next one *data_size=0; return buf_size; } //set AVCodec values with parsed data avctx->sample_rate = s->sample_rate; avctx->bit_rate = s->bit_rate; channels = s->prim_channels + !!s->lfe; if (s->amode<16) { avctx->channel_layout = dca_core_channel_layout[s->amode]; if (s->lfe) { avctx->channel_layout |= CH_LOW_FREQUENCY; s->channel_order_tab = dca_channel_reorder_lfe[s->amode]; } else s->channel_order_tab = dca_channel_reorder_nolfe[s->amode]; if(avctx->request_channels == 2 && s->prim_channels > 2) { channels = 2; s->output = DCA_STEREO; avctx->channel_layout = CH_LAYOUT_STEREO; } } else { av_log(avctx, AV_LOG_ERROR, "Non standard configuration %d !\n",s->amode); return -1; } /* 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 (!avctx->channels) avctx->channels = channels; if(*data_size < (s->sample_blocks / 8) * 256 * sizeof(int16_t) * channels) return -1; *data_size = 256 / 8 * s->sample_blocks * sizeof(int16_t) * channels; for (i = 0; i < (s->sample_blocks / 8); i++) { dca_decode_block(s); s->dsp.float_to_int16_interleave(samples, s->samples_chanptr, 256, channels); samples += 256 * channels; } return buf_size; }