[FFmpeg-devel] [PATCH] avcodec/ac3: add support for dependent stream
Hendrik Leppkes
h.leppkes at gmail.com
Tue Mar 27 17:41:28 EEST 2018
On Tue, Mar 27, 2018 at 1:57 PM, Paul B Mahol <onemda at gmail.com> wrote:
> /* keep last block for error concealment in next frame */
> for (ch = 0; ch < s->out_channels; ch++)
> - memcpy(s->output[ch], output[ch], AC3_BLOCK_SIZE*sizeof(SHORTFLOAT));
> + memcpy(s->output[ch + offset], output[ch], AC3_BLOCK_SIZE*sizeof(SHORTFLOAT));
> +
> + /* check if there is dependent frame */
> + if (buf_size > s->frame_size) {
> + AC3HeaderInfo hdr;
> + int err;
> +
> + if ((ret = init_get_bits8(&s->gbc, buf + s->frame_size, buf_size - s->frame_size)) < 0)
> + return ret;
> +
> + err = ff_ac3_parse_header(&s->gbc, &hdr);
> + if (err)
> + return err;
> +
> + if (hdr.frame_type == EAC3_FRAME_TYPE_DEPENDENT) {
> + buf += s->frame_size;
> + buf_size -= s->frame_size;
> + s->prev_output_mode = s->output_mode;
> + goto dependent_frame;
> + }
Maybe some general safety checks might be reasonable here? Like, same
sample rate, number of audio blocks being equal to the core? The 'hdr'
variable has all of that anyway.
> + }
> +
> + frame->decode_error_flags = err ? FF_DECODE_ERROR_INVALID_BITSTREAM : 0;
> +
> + for (ch = 0; ch < 16; ch++)
> + extended_channel_map[ch] = ch;
> +
> + if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT) {
> + uint64_t ich_layout = avpriv_ac3_channel_layout_tab[s->prev_output_mode & ~AC3_OUTPUT_LFEON];
> + uint64_t channel_layout;
> + int extend = 0;
> +
> + if (s->prev_output_mode & AC3_OUTPUT_LFEON)
> + ich_layout |= AV_CH_LOW_FREQUENCY;
> +
> + channel_layout = ich_layout;
> + for (ch = 0; ch < 16; ch++) {
> + if (s->channel_map & (1 << (15 - ch))) {
> + channel_layout |= custom_channel_map_locations[ch][1];
> + }
> + }
> +
> + avctx->channel_layout = channel_layout;
> + avctx->channels = av_get_channel_layout_nb_channels(channel_layout);
> +
> + for (ch = 0; ch < 16; ch++) {
> + if (s->channel_map & (1 << (15 - ch))) {
> + if (custom_channel_map_locations[ch][0]) {
> + int index = av_get_channel_layout_channel_index(channel_layout,
> + custom_channel_map_locations[ch][1]);
> + if (index < 0)
> + return AVERROR_INVALIDDATA;
> + extended_channel_map[index] = offset + channel_map[extend++];
> + } else {
> + int i;
> +
> + for (i = 0; i < 64; i++) {
> + if ((1LL << i) & custom_channel_map_locations[ch][1]) {
> + int index = av_get_channel_layout_channel_index(channel_layout,
> + 1LL << i);
> + if (index < 0)
> + return AVERROR_INVALIDDATA;
> + extended_channel_map[index] = offset + channel_map[extend++];
> + }
> + }
> + }
> + }
> + }
> + }
> +
The channel mapping code looks a bit confusing, but I don't have any
idea how to make it any better right now either, so..
--
Maybe a fate test might be useful?
- Hendrik
More information about the ffmpeg-devel
mailing list