From patchwork Mon Mar 26 20:18:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul B Mahol X-Patchwork-Id: 8183 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.1.70 with SMTP id c67csp3966458jad; Mon, 26 Mar 2018 13:24:50 -0700 (PDT) X-Google-Smtp-Source: AG47ELtoxmT2ItYMrTVl0HoG2zs6DuCC5nzjWRNxaMF8OsDDaFZ9wsI0dxrKuHPLXyWOGsK0f5zN X-Received: by 10.223.226.66 with SMTP id n2mr15354916wri.228.1522095890107; Mon, 26 Mar 2018 13:24:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1522095890; cv=none; d=google.com; s=arc-20160816; b=0+s3nDvlq4nGJAkPqN/wpRjovUZXGwGxispcQMu+RHijAsUmhpxjTjhN0acsiRv3fU 8P8n/qmiXHJgSkWjaFSW68Q6aq8CgbqwbrUNs3V9/9kS91FXZFyzQGpuuCpKXFFxPX7V 4KciBR6dMIuyowgA6B5ox3Cs2oHTdFYKyzpxip9AJS8M56Nl8Ap0PJO0fWTjywjWDJeM JoYN+Xf3pTmNI4+MDc8Arzh1FLao2V4yT7W1yrhcrioAr0TtFpxcuI+3ScVWn4o2431A AOAT1n+4HtLh5X1X2fwif4+VbbT3nrIH3PgS2ejlN2gTilbOtFu6D7ZudziNgTFuDfCB 3Krw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:message-id:date:to:from:dkim-signature :delivered-to:arc-authentication-results; bh=AeeNda2Ic2l19NA6XEalKASwv4DSG8jSkoRZntVeaS0=; b=iyCUKDQClF5BDG0NkkUWajSvx0Xw8se7IN/LN5uurHz5UkFHJaKlV1no6lKb49CeOI 3YcL8nTF7MsOSHbGSDkcuRCWo5rsWFKVzl5ydQbpqin604TVv0q088xrb9T8Rxr/T5Ex gOPXYoXwRz+bAbEM6b48wIOllvVpOHupIh/Bl8LGUJVnDYOW6A2aUZdjx2K3v5lB+HuU lLUVmReO49EMz+M6XV4HGdWWd71fsTjcNr3Zk5fABajpobQvY9TkaGGSPL00Tn9TAqAc 7hKkY8HGWFw5IbH+csbjbIa7eQ8/HqF92ONHxSLkMHC2eA2YuxD07Djkb80mhewthv35 nsNw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=d5LCC24P; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id b138si10410010wmb.97.2018.03.26.13.24.48; Mon, 26 Mar 2018 13:24:50 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=d5LCC24P; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 264AD680764; Mon, 26 Mar 2018 23:24:30 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr0-f194.google.com (mail-wr0-f194.google.com [209.85.128.194]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C046768066E for ; Mon, 26 Mar 2018 23:24:23 +0300 (EEST) Received: by mail-wr0-f194.google.com with SMTP id s18so20174859wrg.9 for ; Mon, 26 Mar 2018 13:24:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id; bh=84+SINuiJHA22gK2UvviA7QMMRZequsk9fyr0BClFIU=; b=d5LCC24PQ1VtMbU9rXRYtaXNWJvtejkvE3KSrffhxUiNbbCwRZi4mUFEIeciqKuWJR 4EhZ0MeHUoWqhLiNYZkbNS+QyFYeB3fTEsJK7eg/jlj3+urGRoyXvR+SEh9NtJUc8zT1 UHDsp6eY+8mExuS7y/XTkEOqm8i0uSPel6eDHO2/IJ2h//nFZX7zc6mdRA0p+U1OZAiA WNQI2OFd77SDt0VGMehIDOvsLXrcxNlP1UEJrdEqN0wPjYlSkt+lzzMYx+Eh1zlPep3J UR1kgBZEVsyW1dxs+/Q5PwDBmjxPQmR8vT+Ov2LZux1lQc4hFj2QuSoyzAd905v1ad0j qxyQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id; bh=84+SINuiJHA22gK2UvviA7QMMRZequsk9fyr0BClFIU=; b=ZTauOPyXjJwEbm9RKyoZTX9O553W91/7KMNH3KmyWARDoaTmwiIZ9gMIo8YjvYYR0X gB4onLXLuy709vTtNP6LCOwhC7Y/UcVbgtkrmSlRQAxJFPmTGdWHC6NksPZeSRsueTkD BAQegEDZwOa0Yi771EMTzsKSuCe04eREezNiyMS+jUc/EixUuz7rZXio7KktQPLELWU3 bjBVU1ppjqb7++1yNetli0TRcHaeqIt6JD6EW5uhJZyquESAizc/3Mvae3Gg9XUD2dzr 6qN587wrXxRtnMEA9BjLVQYmRcJ5pccykG0nqGrTGM4S3OVKKHYZTS57OINCphObYZRT ihCw== X-Gm-Message-State: AElRT7EfiFX4AWQooyIqanenhSUp+nSahnacLtQQD9h9ecU7wNOPEek8 URjdJuT9z9zK2P9YREyCNz19jg== X-Received: by 10.223.157.132 with SMTP id p4mr19913509wre.245.1522095529129; Mon, 26 Mar 2018 13:18:49 -0700 (PDT) Received: from localhost.localdomain ([94.250.174.60]) by smtp.gmail.com with ESMTPSA id h190sm14088307wmd.22.2018.03.26.13.18.47 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 26 Mar 2018 13:18:48 -0700 (PDT) From: Paul B Mahol To: ffmpeg-devel@ffmpeg.org Date: Mon, 26 Mar 2018 22:18:08 +0200 Message-Id: <20180326201808.12802-1-onemda@gmail.com> X-Mailer: git-send-email 2.11.0 Subject: [FFmpeg-devel] [DEMO][PATCH] avcodec/eac3: add support for dependent stream X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: Paul B Mahol --- Need proper channel mapping support. libavcodec/aac_ac3_parser.c | 7 ++-- libavcodec/aac_ac3_parser.h | 2 ++ libavcodec/ac3_parser.c | 29 +++++++++++++-- libavcodec/ac3dec.c | 88 ++++++++++++++++++++++++++++++--------------- libavcodec/ac3dec.h | 8 +++-- libavcodec/eac3dec.c | 10 ++---- 6 files changed, 101 insertions(+), 43 deletions(-) diff --git a/libavcodec/aac_ac3_parser.c b/libavcodec/aac_ac3_parser.c index 4e834b4424..6f8d4b3b78 100644 --- a/libavcodec/aac_ac3_parser.c +++ b/libavcodec/aac_ac3_parser.c @@ -24,6 +24,7 @@ #include "libavutil/common.h" #include "parser.h" #include "aac_ac3_parser.h" +#include "ac3.h" int ff_aac_ac3_parse(AVCodecParserContext *s1, AVCodecContext *avctx, @@ -86,8 +87,10 @@ get_next: the frame). */ if (avctx->codec_id != AV_CODEC_ID_AAC) { avctx->sample_rate = s->sample_rate; - avctx->channels = s->channels; - avctx->channel_layout = s->channel_layout; + if (avctx->codec_id != AV_CODEC_ID_EAC3 || s->frame_type != EAC3_FRAME_TYPE_DEPENDENT) { + avctx->channels = s->channels; + avctx->channel_layout = s->channel_layout; + } s1->duration = s->samples; avctx->audio_service_type = s->service_type; } diff --git a/libavcodec/aac_ac3_parser.h b/libavcodec/aac_ac3_parser.h index c2506a5bfd..445ce0b9b2 100644 --- a/libavcodec/aac_ac3_parser.h +++ b/libavcodec/aac_ac3_parser.h @@ -44,6 +44,7 @@ typedef struct AACAC3ParseContext { int (*sync)(uint64_t state, struct AACAC3ParseContext *hdr_info, int *need_next_header, int *new_frame_start); + int frame_type; int channels; int sample_rate; int bit_rate; @@ -54,6 +55,7 @@ typedef struct AACAC3ParseContext { int remaining_size; uint64_t state; + int queued_headers; int need_next_header; enum AVCodecID codec_id; } AACAC3ParseContext; diff --git a/libavcodec/ac3_parser.c b/libavcodec/ac3_parser.c index 1015245a90..694b38c3b1 100644 --- a/libavcodec/ac3_parser.c +++ b/libavcodec/ac3_parser.c @@ -53,10 +53,12 @@ static const uint8_t surround_levels[4] = { 4, 6, 7, 6 }; int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) { - int frame_size_code; + int frame_size_code, i; memset(hdr, 0, sizeof(*hdr)); + hdr->channel_map = -1; + hdr->sync_word = get_bits(gbc, 16); if(hdr->sync_word != 0x0B77) return AAC_AC3_PARSE_ERROR_SYNC; @@ -109,6 +111,8 @@ int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) hdr->frame_type = EAC3_FRAME_TYPE_AC3_CONVERT; //EAC3_FRAME_TYPE_INDEPENDENT; hdr->substreamid = 0; } else { + int skipped_bits = 0; + /* Enhanced AC-3 */ hdr->crc1 = 0; hdr->frame_type = get_bits(gbc, 2); @@ -140,6 +144,27 @@ int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) hdr->bit_rate = 8LL * hdr->frame_size * hdr->sample_rate / (hdr->num_blocks * 256); hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on; + + skip_bits(gbc, 5); + skipped_bits += 5; + for (i = 0; i < (hdr->channel_mode ? 1 : 2); i++) { + skip_bits(gbc, 5); + skipped_bits += 6; + if (get_bits1(gbc)) { + skip_bits(gbc, 8); + skipped_bits += 8; + } + } + + if (hdr->frame_type == EAC3_FRAME_TYPE_DEPENDENT) { + skipped_bits += 1; + if (get_bits1(gbc)) { + hdr->channel_map = get_bits(gbc, 16); + skipped_bits += 16; + } + } + + skip_bits_long(gbc, -skipped_bits); } hdr->channel_layout = avpriv_ac3_channel_layout_tab[hdr->channel_mode]; if (hdr->lfe_on) @@ -218,8 +243,8 @@ static int ac3_sync(uint64_t state, AACAC3ParseContext *hdr_info, else if (hdr_info->codec_id == AV_CODEC_ID_NONE) hdr_info->codec_id = AV_CODEC_ID_AC3; - *need_next_header = (hdr.frame_type != EAC3_FRAME_TYPE_AC3_CONVERT); *new_frame_start = (hdr.frame_type != EAC3_FRAME_TYPE_DEPENDENT); + *need_next_header = *new_frame_start || (hdr.frame_type != EAC3_FRAME_TYPE_AC3_CONVERT); return hdr.frame_size; } diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 244a18323f..58db1c5045 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -309,6 +309,7 @@ static int parse_frame_header(AC3DecodeContext *s) s->bitstream_id = hdr.bitstream_id; s->bitstream_mode = hdr.bitstream_mode; s->channel_mode = hdr.channel_mode; + s->channel_map = hdr.channel_map; s->lfe_on = hdr.lfe_on; s->bit_alloc_params.sr_shift = hdr.sr_shift; s->sample_rate = hdr.sample_rate; @@ -317,6 +318,7 @@ static int parse_frame_header(AC3DecodeContext *s) s->fbw_channels = s->channels - s->lfe_on; s->lfe_ch = s->fbw_channels + 1; s->frame_size = hdr.frame_size; + s->superframe_size += hdr.frame_size; s->preferred_downmix = AC3_DMIXMOD_NOTINDICATED; s->center_mix_level = hdr.center_mix_level; s->center_mix_level_ltrt = 4; // -3.0dB @@ -683,7 +685,7 @@ static void do_rematrixing(AC3DecodeContext *s) * Convert frequency domain coefficients to time-domain audio samples. * reference: Section 7.9.4 Transformation Equations */ -static inline void do_imdct(AC3DecodeContext *s, int channels) +static inline void do_imdct(AC3DecodeContext *s, int channels, int offset) { int ch; @@ -695,25 +697,25 @@ static inline void do_imdct(AC3DecodeContext *s, int channels) x[i] = s->transform_coeffs[ch][2 * i]; s->imdct_256.imdct_half(&s->imdct_256, s->tmp_output, x); #if USE_FIXED - s->fdsp->vector_fmul_window_scaled(s->outptr[ch - 1], s->delay[ch - 1], + s->fdsp->vector_fmul_window_scaled(s->outptr[ch - 1], s->delay[ch - 1 + offset], s->tmp_output, s->window, 128, 8); #else - s->fdsp->vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1], + s->fdsp->vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1 + offset], s->tmp_output, s->window, 128); #endif for (i = 0; i < 128; i++) x[i] = s->transform_coeffs[ch][2 * i + 1]; - s->imdct_256.imdct_half(&s->imdct_256, s->delay[ch - 1], x); + s->imdct_256.imdct_half(&s->imdct_256, s->delay[ch - 1 + offset], x); } else { s->imdct_512.imdct_half(&s->imdct_512, s->tmp_output, s->transform_coeffs[ch]); #if USE_FIXED - s->fdsp->vector_fmul_window_scaled(s->outptr[ch - 1], s->delay[ch - 1], + s->fdsp->vector_fmul_window_scaled(s->outptr[ch - 1], s->delay[ch - 1 + offset], s->tmp_output, s->window, 128, 8); #else - s->fdsp->vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1], + s->fdsp->vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1 + offset], s->tmp_output, s->window, 128); #endif - memcpy(s->delay[ch - 1], s->tmp_output + 128, 128 * sizeof(FFTSample)); + memcpy(s->delay[ch - 1 + offset], s->tmp_output + 128, 128 * sizeof(FFTSample)); } } } @@ -1063,7 +1065,7 @@ static inline int coupling_coordinates(AC3DecodeContext *s, int blk) /** * Decode a single audio block from the AC-3 bitstream. */ -static int decode_audio_block(AC3DecodeContext *s, int blk) +static int decode_audio_block(AC3DecodeContext *s, int blk, int offset) { int fbw_channels = s->fbw_channels; int channel_mode = s->channel_mode; @@ -1426,7 +1428,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) ac3_upmix_delay(s); } - do_imdct(s, s->channels); + do_imdct(s, s->channels, offset); if (downmix_output) { #if USE_FIXED @@ -1449,7 +1451,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) s->out_channels, s->fbw_channels, 128); } - do_imdct(s, s->out_channels); + do_imdct(s, s->out_channels, offset); } return 0; @@ -1463,14 +1465,15 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, { AVFrame *frame = data; const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; + int buf_size, full_buf_size = avpkt->size; AC3DecodeContext *s = avctx->priv_data; - int blk, ch, err, ret; + int blk, ch, err, offset, ret; const uint8_t *channel_map; const SHORTFLOAT *output[AC3_MAX_CHANNELS]; enum AVMatrixEncoding matrix_encoding; AVDownmixInfo *downmix_info; + buf_size = full_buf_size; /* copy input buffer to decoder context to avoid reading past the end of the buffer, which can be caused by a damaged input stream. */ if (buf_size >= 2 && AV_RB16(buf) == 0x770B) { @@ -1488,6 +1491,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, av_lfg_init_from_data(&s->dith_state, s->input_buffer, FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE)); buf = s->input_buffer; +second_time: /* initialize the GetBitContext with the start of valid AC-3 Frame */ if ((ret = init_get_bits8(&s->gbc, buf, buf_size)) < 0) return ret; @@ -1511,7 +1515,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, break; case AAC_AC3_PARSE_ERROR_FRAME_TYPE: /* skip frame if CRC is ok. otherwise use error concealment. */ - /* TODO: add support for substreams and dependent frames */ + /* TODO: add support for substreams */ if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT || s->substreamid) { av_log(avctx, AV_LOG_DEBUG, "unsupported frame type %d: skipping frame\n", @@ -1532,7 +1536,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, } else { /* check that reported frame size fits in input buffer */ if (s->frame_size > buf_size) { - av_log(avctx, AV_LOG_ERROR, "incomplete frame\n"); + av_log(avctx, AV_LOG_ERROR, "incomplete frame %d %d\n", s->frame_size, buf_size); err = AAC_AC3_PARSE_ERROR_FRAME_SIZE; } else if (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_CAREFUL)) { /* check for crc mismatch */ @@ -1594,29 +1598,25 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, if (s->bitstream_mode == 0x7 && s->channels > 1) avctx->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE; - /* get output buffer */ - frame->nb_samples = s->num_blocks * AC3_BLOCK_SIZE; - if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) - return ret; - /* decode the audio blocks */ channel_map = ff_ac3_dec_channel_map[s->output_mode & ~AC3_OUTPUT_LFEON][s->lfe_on]; + offset = s->frame_type == EAC3_FRAME_TYPE_DEPENDENT ? AC3_MAX_CHANNELS : 0; for (ch = 0; ch < AC3_MAX_CHANNELS; ch++) { - output[ch] = s->output[ch]; - s->outptr[ch] = s->output[ch]; + output[ch] = s->output[ch + offset]; + s->outptr[ch] = s->output[ch + offset]; } for (ch = 0; ch < s->channels; ch++) { if (ch < s->out_channels) - s->outptr[channel_map[ch]] = (SHORTFLOAT *)frame->data[ch]; + s->outptr[channel_map[ch]] = s->output_buffer[ch + offset]; } for (blk = 0; blk < s->num_blocks; blk++) { - if (!err && decode_audio_block(s, blk)) { + if (!err && decode_audio_block(s, blk, offset)) { av_log(avctx, AV_LOG_ERROR, "error decoding the audio block\n"); err = 1; } if (err) for (ch = 0; ch < s->out_channels; ch++) - memcpy(((SHORTFLOAT*)frame->data[ch]) + AC3_BLOCK_SIZE*blk, output[ch], AC3_BLOCK_SIZE*sizeof(SHORTFLOAT)); + memcpy(s->output_buffer[ch + offset] + AC3_BLOCK_SIZE*blk, output[ch], AC3_BLOCK_SIZE*sizeof(SHORTFLOAT)); for (ch = 0; ch < s->out_channels; ch++) output[ch] = s->outptr[channel_map[ch]]; for (ch = 0; ch < s->out_channels; ch++) { @@ -1625,11 +1625,43 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, } } - frame->decode_error_flags = err ? FF_DECODE_ERROR_INVALID_BITSTREAM : 0; - /* 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; + goto second_time; + } + } + + frame->decode_error_flags = err ? FF_DECODE_ERROR_INVALID_BITSTREAM : 0; + + if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT) { + avctx->channels = 8; + avctx->channel_layout = AV_CH_LAYOUT_7POINT1; + } + + /* get output buffer */ + frame->nb_samples = s->num_blocks * AC3_BLOCK_SIZE; + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + return ret; + + for (ch = 0; ch < avctx->channels; ch++) + memcpy((SHORTFLOAT *)frame->data[ch], s->output_buffer[ch], s->num_blocks * AC3_BLOCK_SIZE * sizeof(SHORTFLOAT)); /* * AVMatrixEncoding @@ -1689,7 +1721,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, *got_frame_ptr = 1; - return FFMIN(buf_size, s->frame_size); + return FFMIN(full_buf_size, s->superframe_size); } /** diff --git a/libavcodec/ac3dec.h b/libavcodec/ac3dec.h index aa4cf04f8a..feeee780ac 100644 --- a/libavcodec/ac3dec.h +++ b/libavcodec/ac3dec.h @@ -76,6 +76,7 @@ typedef struct AC3DecodeContext { ///@{ int frame_type; ///< frame type (strmtyp) int substreamid; ///< substream identification + int superframe_size; ///< current superframe size, in bytes int frame_size; ///< current frame size, in bytes int bit_rate; ///< stream bit rate, in bits-per-second int sample_rate; ///< sample frequency, in Hz @@ -87,7 +88,7 @@ typedef struct AC3DecodeContext { int dialog_normalization[2]; ///< dialog level in dBFS (dialnorm) int compression_exists[2]; ///< compression field is valid for frame (compre) int compression_gain[2]; ///< gain to apply for heavy compression (compr) - int channel_map; ///< custom channel map + int channel_map; ///< custom channel map (chanmap) int preferred_downmix; ///< Preferred 2-channel downmix mode (dmixmod) int center_mix_level; ///< Center mix level index int center_mix_level_ltrt; ///< Center mix level index for Lt/Rt (ltrtcmixlev) @@ -239,11 +240,12 @@ typedef struct AC3DecodeContext { ///@name Aligned arrays DECLARE_ALIGNED(16, int, fixed_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< fixed-point transform coefficients DECLARE_ALIGNED(32, INTFLOAT, transform_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< transform coefficients - DECLARE_ALIGNED(32, INTFLOAT, delay)[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< delay - added to the next block + DECLARE_ALIGNED(32, INTFLOAT, delay)[2 * AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< delay - added to the next block DECLARE_ALIGNED(32, INTFLOAT, window)[AC3_BLOCK_SIZE]; ///< window coefficients DECLARE_ALIGNED(32, INTFLOAT, tmp_output)[AC3_BLOCK_SIZE]; ///< temporary storage for output before windowing - DECLARE_ALIGNED(32, SHORTFLOAT, output)[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< output after imdct transform and windowing + DECLARE_ALIGNED(32, SHORTFLOAT, output)[2 * AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< output after imdct transform and windowing DECLARE_ALIGNED(32, uint8_t, input_buffer)[AC3_FRAME_BUFFER_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; ///< temp buffer to prevent overread + DECLARE_ALIGNED(32, SHORTFLOAT, output_buffer)[2 * AC3_MAX_CHANNELS][AC3_BLOCK_SIZE * 6]; ///< final output buffer ///@} } AC3DecodeContext; diff --git a/libavcodec/eac3dec.c b/libavcodec/eac3dec.c index 6f6309f179..9921ec849f 100644 --- a/libavcodec/eac3dec.c +++ b/libavcodec/eac3dec.c @@ -303,13 +303,7 @@ static int ff_eac3_parse_header(AC3DecodeContext *s) /* An E-AC-3 stream can have multiple independent streams which the application can select from. each independent stream can also contain dependent streams which are used to add or replace channels. */ - if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT) { - if (!s->eac3_frame_dependent_found) { - s->eac3_frame_dependent_found = 1; - avpriv_request_sample(s->avctx, "Dependent substream decoding"); - } - return AAC_AC3_PARSE_ERROR_FRAME_TYPE; - } else if (s->frame_type == EAC3_FRAME_TYPE_RESERVED) { + if (s->frame_type == EAC3_FRAME_TYPE_RESERVED) { av_log(s->avctx, AV_LOG_ERROR, "Reserved frame type\n"); return AAC_AC3_PARSE_ERROR_FRAME_TYPE; } @@ -355,7 +349,7 @@ static int ff_eac3_parse_header(AC3DecodeContext *s) /* dependent stream channel map */ if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT) { if (get_bits1(gbc)) { - skip_bits(gbc, 16); // skip custom channel map + s->channel_map = get_bits(gbc, 16); } }