#define AC3_OUTPUT_LFEON 8
typedef struct {
+ int num_blocks; ///< number of audio blocks
int channel_mode; ///< channel mode (acmod)
int block_switch[AC3_MAX_CHANNELS]; ///< block switch flags
int dither_flag[AC3_MAX_CHANNELS]; ///< dither flags
int sample_rate; ///< sample frequency, in Hz
int bit_rate; ///< stream bit rate, in bits-per-second
+ int frame_type; ///< frame type (strmtyp)
+ int substreamid; ///< substream identification
int frame_size; ///< current frame size, in bytes
int channels; ///< number of total channels
s->frame_size = hdr.frame_size;
s->center_mix_level = hdr.center_mix_level;
s->surround_mix_level = hdr.surround_mix_level;
+ s->num_blocks = hdr.num_blocks;
+ s->frame_type = hdr.frame_type;
+ s->substreamid = hdr.substreamid;
+
+ if(s->lfe_on) {
+ s->start_freq[s->lfe_ch] = 0;
+ s->end_freq[s->lfe_ch] = 7;
+ s->num_exp_groups[s->lfe_ch] = 2;
+ s->channel_in_cpl[s->lfe_ch] = 0;
+ }
/* read the rest of the bsi. read twice for dual mono mode. */
i = !(s->channel_mode);
s->exp_strategy[CPL_CH] = EXP_REUSE;
s->exp_strategy[s->lfe_ch] = EXP_REUSE;
for (ch = !s->cpl_in_use; ch <= s->channels; ch++) {
- if(ch == s->lfe_ch)
- s->exp_strategy[ch] = get_bits(gbc, 1);
- else
- s->exp_strategy[ch] = get_bits(gbc, 2);
+ s->exp_strategy[ch] = get_bits(gbc, 2 - (ch == s->lfe_ch));
if(s->exp_strategy[ch] != EXP_REUSE)
bit_alloc_stages[ch] = 3;
}
memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS);
}
}
- s->start_freq[s->lfe_ch] = 0;
- s->end_freq[s->lfe_ch] = 7;
- s->num_exp_groups[s->lfe_ch] = 2;
if (s->cpl_in_use && s->exp_strategy[CPL_CH] != EXP_REUSE) {
s->num_exp_groups[CPL_CH] = (s->end_freq[CPL_CH] - s->start_freq[CPL_CH]) /
(3 << (s->exp_strategy[CPL_CH] - 1));
}
}
- /* parse the syncinfo */
if(err && err != AC3_PARSE_ERROR_CRC) {
switch(err) {
case AC3_PARSE_ERROR_SYNC:
av_log(avctx, AV_LOG_ERROR, "frame sync error\n");
- break;
+ return -1;
case AC3_PARSE_ERROR_BSID:
av_log(avctx, AV_LOG_ERROR, "invalid bitstream id\n");
break;
av_log(avctx, AV_LOG_ERROR, "invalid frame size\n");
break;
case AC3_PARSE_ERROR_FRAME_TYPE:
+ /* skip frame if CRC is ok. otherwise use error concealment. */
+ /* TODO: add support for substreams and dependent frames */
+ if(s->frame_type == EAC3_FRAME_TYPE_DEPENDENT || s->substreamid) {
+ av_log(avctx, AV_LOG_ERROR, "unsupported frame type : skipping frame\n");
+ return s->frame_size;
+ } else {
av_log(avctx, AV_LOG_ERROR, "invalid frame type\n");
+ }
break;
default:
av_log(avctx, AV_LOG_ERROR, "invalid header\n");
}
/* parse the audio blocks */
- for (blk = 0; blk < NB_BLOCKS; blk++) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
if (!err && ac3_parse_audio_block(s, blk)) {
av_log(avctx, AV_LOG_ERROR, "error parsing the audio block\n");
}
+
+ /* interleave output samples */
for (i = 0; i < 256; i++)
for (ch = 0; ch < s->out_channels; ch++)
*(out_samples++) = s->int_output[ch][i];
}
- *data_size = NB_BLOCKS * 256 * avctx->channels * sizeof (int16_t);
+ *data_size = s->num_blocks * 256 * avctx->channels * sizeof (int16_t);
return s->frame_size;
}