From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id BE139419F9 for ; Wed, 19 Jan 2022 20:38:59 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 94B3868B185; Wed, 19 Jan 2022 22:38:47 +0200 (EET) Received: from mail-wm1-f47.google.com (mail-wm1-f47.google.com [209.85.128.47]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id D83A268B180 for ; Wed, 19 Jan 2022 22:38:40 +0200 (EET) Received: by mail-wm1-f47.google.com with SMTP id w26so7682358wmi.0 for ; Wed, 19 Jan 2022 12:38:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=martin-st.20210112.gappssmtp.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=4dMTFodMlVVVM+nQAT504S+g2hULqW976GjNoK2fK6Y=; b=rIbULCbnSFVy5LTqAkmTYBqrncTlpfPVf/29Ic5uY7Wb7Z+nuYVfUyXLEGVhF5Zn/1 3LweFZX3jYONZlQjJQDTUPmAv1u/TEazlQJjZwgBuNfAI/QjMgQmr/R4LVW8PsglpRn0 Pen7gVGv6TIXifJmssrJv25YlSJ/6MzD53wkOtiKawzCjRhGCPM1NVuoKr5o43dIV8g1 ecC0ATnPErITYBFKY0Yblx6kASTv1bMl71/8fnq6yaqcGN7HIcBFvhWbtzrdQ91U2Rso WjwC4IEwgWVsHcM0Pr2owLM4MGrHOm9rYtrzaNvBLnAs5UIWxg69SiaEIIx0uA91jWG6 g5gA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=4dMTFodMlVVVM+nQAT504S+g2hULqW976GjNoK2fK6Y=; b=KDD46aoU78NpPpEOdY3mNwaoeNPaozOO7hYevNeMSvX7YNYYjLtyiEyIAS8BzLP9XG PBVHubmvDnZY5OapJcOYJOqIXgKHI9+XO32izEcicXGh+MTcJrDuU60lGMUgEbA1Rexf 9yag9qMXZYe6U7HMouPHEykUlWfgLc7veyRVX/pMbcoDmGyNcbw7pY8QPxl9B/IfPkBq KjSbXSrhuKo6HM1kHtwTTfEV9wHbk7sdgJ74G4wLU+uB1PM9lf02nkjpPs91JknWyvv8 830noWDFC4OEVHjmelAdCNw9wO68s1HXc569QEgfi7pvpJlfehqwrJoduN4xfUBAi17N VOjg== X-Gm-Message-State: AOAM5329ty+QWb/3gIczzF5eQyOccxs6JlEEzzgOmlC4wWPdkzlPdyXU l4x/UoBdCpV81qQYsqI6RjYaLf0kjjoy9bP5 X-Google-Smtp-Source: ABdhPJwoNxZZUnQu5xK76Zutdtk4Pfwzkf0zB7XOuSiDb4u+BjGFK1HNaYqxKnk0WnZV8f0nxe12Og== X-Received: by 2002:adf:e44f:: with SMTP id t15mr22474453wrm.0.1642624720236; Wed, 19 Jan 2022 12:38:40 -0800 (PST) Received: from localhost (host-97-187.parnet.fi. [77.234.97.187]) by smtp.gmail.com with ESMTPSA id s9sm503779wmh.35.2022.01.19.12.38.39 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 19 Jan 2022 12:38:39 -0800 (PST) From: =?UTF-8?q?Martin=20Storsj=C3=B6?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 19 Jan 2022 22:38:37 +0200 Message-Id: <20220119203837.9047-2-martin@martin.st> X-Mailer: git-send-email 2.32.0 (Apple Git-132) In-Reply-To: <20220119203837.9047-1-martin@martin.st> References: <20220119203837.9047-1-martin@martin.st> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/2] libfdk-aacdec: Flush delayed samples at the end X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: Also trim off delay samples at the start instead of adjusting pts to compensate for them; this avoids unwanted offsets if working with raw samples without considering their pts. --- libavcodec/libfdk-aacdec.c | 80 +++++++++++++++++++++++++++++++------- 1 file changed, 65 insertions(+), 15 deletions(-) diff --git a/libavcodec/libfdk-aacdec.c b/libavcodec/libfdk-aacdec.c index 93b52023b0..d560e313ca 100644 --- a/libavcodec/libfdk-aacdec.c +++ b/libavcodec/libfdk-aacdec.c @@ -58,7 +58,11 @@ typedef struct FDKAACDecContext { int drc_cut; int album_mode; int level_limit; - int output_delay; +#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10 + int output_delay_set; + int flush_samples; + int delay_samples; +#endif } FDKAACDecContext; @@ -123,7 +127,12 @@ static int get_stream_info(AVCodecContext *avctx) avctx->sample_rate = info->sampleRate; avctx->frame_size = info->frameSize; #if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10 - s->output_delay = info->outputDelay; + if (!s->output_delay_set && info->outputDelay) { + // Set this only once. + s->flush_samples = info->outputDelay; + s->delay_samples = info->outputDelay; + s->output_delay_set = 1; + } #endif for (i = 0; i < info->numChannels; i++) { @@ -367,14 +376,31 @@ static int fdk_aac_decode_frame(AVCodecContext *avctx, void *data, int ret; AAC_DECODER_ERROR err; UINT valid = avpkt->size; + UINT flags = 0; + int input_offset = 0; - err = aacDecoder_Fill(s->handle, &avpkt->data, &avpkt->size, &valid); - if (err != AAC_DEC_OK) { - av_log(avctx, AV_LOG_ERROR, "aacDecoder_Fill() failed: %x\n", err); - return AVERROR_INVALIDDATA; + if (avpkt->size) { + err = aacDecoder_Fill(s->handle, &avpkt->data, &avpkt->size, &valid); + if (err != AAC_DEC_OK) { + av_log(avctx, AV_LOG_ERROR, "aacDecoder_Fill() failed: %x\n", err); + return AVERROR_INVALIDDATA; + } + } else { +#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10 + /* Handle decoder draining */ + if (s->flush_samples > 0) { + flags |= AACDEC_FLUSH; + } else { + return AVERROR_EOF; + } +#else + return AVERROR_EOF; +#endif } - err = aacDecoder_DecodeFrame(s->handle, (INT_PCM *) s->decoder_buffer, s->decoder_buffer_size / sizeof(INT_PCM), 0); + err = aacDecoder_DecodeFrame(s->handle, (INT_PCM *) s->decoder_buffer, + s->decoder_buffer_size / sizeof(INT_PCM), + flags); if (err == AAC_DEC_NOT_ENOUGH_BITS) { ret = avpkt->size - valid; goto end; @@ -390,16 +416,36 @@ static int fdk_aac_decode_frame(AVCodecContext *avctx, void *data, goto end; frame->nb_samples = avctx->frame_size; +#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10 + if (flags & AACDEC_FLUSH) { + // Only return the right amount of samples at the end; if calling the + // decoder with AACDEC_FLUSH, it will keep returning frames indefinitely. + frame->nb_samples = FFMIN(s->flush_samples, frame->nb_samples); + av_log(s, AV_LOG_DEBUG, "Returning %d/%d delayed samples.\n", + frame->nb_samples, s->flush_samples); + s->flush_samples -= frame->nb_samples; + } else { + // Trim off samples from the start to compensate for extra decoder + // delay. We could also just adjust the pts, but this avoids + // including the extra samples in the output altogether. + if (s->delay_samples) { + int drop_samples = FFMIN(s->delay_samples, frame->nb_samples); + av_log(s, AV_LOG_DEBUG, "Dropping %d/%d delayed samples.\n", + drop_samples, s->delay_samples); + s->delay_samples -= drop_samples; + frame->nb_samples -= drop_samples; + input_offset = drop_samples * avctx->channels; + if (frame->nb_samples <= 0) + return 0; + } + } +#endif + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) goto end; - if (frame->pts != AV_NOPTS_VALUE) - frame->pts -= av_rescale_q(s->output_delay, - (AVRational){1, avctx->sample_rate}, - avctx->time_base); - - memcpy(frame->extended_data[0], s->decoder_buffer, - avctx->channels * avctx->frame_size * + memcpy(frame->extended_data[0], s->decoder_buffer + input_offset, + avctx->channels * frame->nb_samples * av_get_bytes_per_sample(avctx->sample_fmt)); *got_frame_ptr = 1; @@ -432,7 +478,11 @@ const AVCodec ff_libfdk_aac_decoder = { .decode = fdk_aac_decode_frame, .close = fdk_aac_decode_close, .flush = fdk_aac_decode_flush, - .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, + .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF +#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10 + | AV_CODEC_CAP_DELAY +#endif + , .priv_class = &fdk_aac_dec_class, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, -- 2.32.0 (Apple Git-132) _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".