From patchwork Sat Jul 8 19:00:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 42531 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:6d25:b0:130:f365:34ad with SMTP id fv37csp614637pzb; Sat, 8 Jul 2023 12:01:07 -0700 (PDT) X-Google-Smtp-Source: APBJJlGPgaRxycUoPiQEp36jVx4FhluePn/YlxsGwP1N2cE4S8Zcz2KF7ENJguKZhpBjCgXdrhqF X-Received: by 2002:a2e:8ec6:0:b0:2b6:e7ff:4b2e with SMTP id e6-20020a2e8ec6000000b002b6e7ff4b2emr6017772ljl.33.1688842867426; Sat, 08 Jul 2023 12:01:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1688842867; cv=none; d=google.com; s=arc-20160816; b=ujfk5lDVqSzk/ATFBw727IgyteWvT/n6Wh3G12uHT+UahmLcwkLJP3nPQgUd4i2WVe b842aBh3BK1OnY2eIBrPDsyallqc+zGMAg+fNnobZZOCq6eZdtM2DGGF4/CkLnz8YbYy /UhHsHbPe1UmvRMx/xYbN7b8EaXYZgx6HEeyRSQsAVqPCIfY/6gYLjVurnbf8zF5PmZy f0EzWvp25m3Pm2VEmxHa/gRfb7HAFbL8En2qQLvvYS1LD4jSuYut+/qmEbfYIt0ylezO j5zStX3IsjBe1F8XbkuWsqc7YckLk2iLIzjEPhCV5s7N/yWbOFyBuba4aj8hnxUIdafy Qq5Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:message-id:date:to:from :dkim-signature:delivered-to; bh=Pn7GuSJfnAW54QWyFLqwaG5g1nG9f5EZURWWgnnXsk8=; fh=J3zlMo7rVW2t2IQYogliBcMNuBh6YQg7NRChcrschf4=; b=mbsDzAPZbhByrJ2XpGE8edP6PBIDUH9YSMst+pCQhYqXBBo4dgPnFOMbYciGPdrbA2 HD9xcAH3Sl2XPKmQqWd4pe9n2MkIyMvVPg0Ip8eCNEPkXJaKhFf0SBbgJyEtDYIxW2wB zBrRGoAP9wuPCF9QYGF9P42t2QmS5BJ/pzgTluIJjzakumLx9DPimiA+SBR/jZWEakat 1o0+VqPqZQkoQLdEVcpMx9bHjd338J06DOn8/n/v6shYUuHb+//qTLUak2O+cINfTId4 xLfaNxWaPEz7xAwAJp8u0Geyvzo4sEIXGxpUVlOypRJb2Cv+2yu7Mh1h0eI80ohGD9Z1 g5Lg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20221208 header.b="Ci6/aOol"; 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 mf22-20020a170906cb9600b0098882e012dasi592890ejb.443.2023.07.08.12.01.06; Sat, 08 Jul 2023 12:01:07 -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=20221208 header.b="Ci6/aOol"; 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 5A7F868C50B; Sat, 8 Jul 2023 22:01:02 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-oa1-f49.google.com (mail-oa1-f49.google.com [209.85.160.49]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 1584C68C355 for ; Sat, 8 Jul 2023 22:00:55 +0300 (EEST) Received: by mail-oa1-f49.google.com with SMTP id 586e51a60fabf-1b0606bee45so3067171fac.3 for ; Sat, 08 Jul 2023 12:00:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1688842853; x=1691434853; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:from:to:cc:subject:date:message-id:reply-to; bh=EnY7P/nVHFoyOdAuKF+/XVZScGM824Puw7IAby2tvj4=; b=Ci6/aOolUy5zad7QQBFEvFSyhQ8IQPzP9S1lqYvsB4KK4YQrGu6v88tLJMUk9lLoTz KGqbPa7b5WKXDY8xZ2xQ3ScbCDBCQowkTdze3UnJ9nyaT2Z67VlEwu0s2YvTKXrkd/zc 4b2wSO/UrPU3AMagw8pmzFSjoDD8CT52OwxKiJcNmQsos3dqbNgDbrwCi5k3ZBWrfWdP P2vnhpHGYQawaOByj+M6ACngzIYkQfBxZaTZJleX0iAlqNhwZXiOjz82zq+zfQmfbNUp k0+gL6FuRLQ9KS27ChSoAmD0jmknkt+ApC5uz/eGVZ3rfVqSu/2SkHJy+7vyvqk70Sqr 9a4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688842853; x=1691434853; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=EnY7P/nVHFoyOdAuKF+/XVZScGM824Puw7IAby2tvj4=; b=lF7+2kQYDmaFQBLLqfkyIvstrBShISNtVVHVnsyaJOkY/YHf08EqCIaRioUvAEJ8Gf UcoEPYPPeLD/qx7vjgxj3TIv7owpW/stjDiA/FYSyOwavILciupC0Dh2kpn3twcM8cpa qFF6SBLqucnX+7x2XgYU6uz1yQmt+mPlxDTYHOt2LjlLAxxuTFK2KDCfJmhtspBVTAG1 yFg2tTjqs0bHS9FymbbLeoC412ziQG9fNc3l8xUF/agvQjFLjgrOVsy+0uYjd4FZB1ZZ U592ZrB1szumO7YK3idO65EJdQI0QKcpHgoxs3lDN2lQ7SMbSab5kNcq8RtiKElfN5+G cNXw== X-Gm-Message-State: ABy/qLZxiCLKoJsVkPQXJ/+rUqtOZNIloGAxRt7DwtKw7kgbh2Hgbby3 x8CFHcZoadqvihjDxY5PwB1D6NC4JBs= X-Received: by 2002:a05:6871:72b:b0:1b7:1a3d:b1d9 with SMTP id f43-20020a056871072b00b001b71a3db1d9mr408042oap.24.1688842852913; Sat, 08 Jul 2023 12:00:52 -0700 (PDT) Received: from localhost.localdomain (host197.190-225-105.telecom.net.ar. [190.225.105.197]) by smtp.gmail.com with ESMTPSA id p23-20020a0568301d5700b006b92c078d05sm988738oth.31.2023.07.08.12.00.51 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 08 Jul 2023 12:00:52 -0700 (PDT) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Sat, 8 Jul 2023 16:00:36 -0300 Message-ID: <20230708190038.24324-1-jamrial@gmail.com> X-Mailer: git-send-email 2.41.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/3] avcodec/decode: move processing discard samples to its own function 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: +g/BfztTcACO Signed-off-by: James Almer --- libavcodec/decode.c | 182 +++++++++++++++++++++++--------------------- 1 file changed, 94 insertions(+), 88 deletions(-) diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 269633ce10..793ab975f6 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -289,69 +289,14 @@ static int64_t guess_correct_pts(AVCodecContext *ctx, return pts; } -/* - * The core of the receive_frame_wrapper for the decoders implementing - * the simple API. Certain decoders might consume partial packets without - * returning any output, so this function needs to be called in a loop until it - * returns EAGAIN. - **/ -static inline int decode_simple_internal(AVCodecContext *avctx, AVFrame *frame, int64_t *discarded_samples) +static int discard_samples(AVCodecContext *avctx, AVFrame *frame, int64_t *discarded_samples) { - AVCodecInternal *avci = avctx->internal; - AVPacket *const pkt = avci->in_pkt; - const FFCodec *const codec = ffcodec(avctx->codec); - int got_frame, actual_got_frame; - int ret; - - if (!pkt->data && !avci->draining) { - av_packet_unref(pkt); - ret = ff_decode_get_packet(avctx, pkt); - if (ret < 0 && ret != AVERROR_EOF) - return ret; - } - - // Some codecs (at least wma lossless) will crash when feeding drain packets - // after EOF was signaled. - if (avci->draining_done) - return AVERROR_EOF; - - if (!pkt->data && - !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY || - avctx->active_thread_type & FF_THREAD_FRAME)) - return AVERROR_EOF; - - got_frame = 0; - - if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) { - ret = ff_thread_decode_frame(avctx, frame, &got_frame, pkt); - } else { - ret = codec->cb.decode(avctx, frame, &got_frame, pkt); - - if (!(codec->caps_internal & FF_CODEC_CAP_SETS_PKT_DTS)) - frame->pkt_dts = pkt->dts; - if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) { -#if FF_API_FRAME_PKT -FF_DISABLE_DEPRECATION_WARNINGS - if(!avctx->has_b_frames) - frame->pkt_pos = pkt->pos; -FF_ENABLE_DEPRECATION_WARNINGS -#endif - //FIXME these should be under if(!avctx->has_b_frames) - /* get_buffer is supposed to set frame parameters */ - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DR1)) { - if (!frame->sample_aspect_ratio.num) frame->sample_aspect_ratio = avctx->sample_aspect_ratio; - if (!frame->width) frame->width = avctx->width; - if (!frame->height) frame->height = avctx->height; - if (frame->format == AV_PIX_FMT_NONE) frame->format = avctx->pix_fmt; - } - } - } - emms_c(); - actual_got_frame = got_frame; + AVCodecInternal *avci = avctx->internal; + int ret = 0; if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) { if (frame->flags & AV_FRAME_FLAG_DISCARD) - got_frame = 0; + ret = AVERROR(EAGAIN); } else if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { uint8_t *side; size_t side_size; @@ -359,16 +304,10 @@ FF_ENABLE_DEPRECATION_WARNINGS uint8_t skip_reason = 0; uint8_t discard_reason = 0; - if (ret >= 0 && got_frame) { if (frame->format == AV_SAMPLE_FMT_NONE) frame->format = avctx->sample_fmt; - if (!frame->ch_layout.nb_channels) { - int ret2 = av_channel_layout_copy(&frame->ch_layout, &avctx->ch_layout); - if (ret2 < 0) { - ret = ret2; - got_frame = 0; - } - } + if (!frame->ch_layout.nb_channels) + ret = av_channel_layout_copy(&frame->ch_layout, &avctx->ch_layout); #if FF_API_OLD_CHANNEL_LAYOUT FF_DISABLE_DEPRECATION_WARNINGS if (!frame->channel_layout) @@ -380,7 +319,6 @@ FF_ENABLE_DEPRECATION_WARNINGS #endif if (!frame->sample_rate) frame->sample_rate = avctx->sample_rate; - } side= av_packet_get_side_data(avci->last_pkt_props, AV_PKT_DATA_SKIP_SAMPLES, &side_size); if(side && side_size>=10) { @@ -393,21 +331,21 @@ FF_ENABLE_DEPRECATION_WARNINGS discard_reason = AV_RL8(side + 9); } - if ((frame->flags & AV_FRAME_FLAG_DISCARD) && got_frame && + if ((frame->flags & AV_FRAME_FLAG_DISCARD) && !ret && !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) { avci->skip_samples = FFMAX(0, avci->skip_samples - frame->nb_samples); - got_frame = 0; *discarded_samples += frame->nb_samples; + ret = AVERROR(EAGAIN); } - if (avci->skip_samples > 0 && got_frame && + if (avci->skip_samples > 0 && !ret && !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) { if(frame->nb_samples <= avci->skip_samples){ - got_frame = 0; *discarded_samples += frame->nb_samples; avci->skip_samples -= frame->nb_samples; av_log(avctx, AV_LOG_DEBUG, "skip whole frame, skip left: %d\n", avci->skip_samples); + ret = AVERROR(EAGAIN); } else { av_samples_copy(frame->extended_data, frame->extended_data, 0, avci->skip_samples, frame->nb_samples - avci->skip_samples, avctx->ch_layout.nb_channels, frame->format); @@ -432,11 +370,11 @@ FF_ENABLE_DEPRECATION_WARNINGS } } - if (discard_padding > 0 && discard_padding <= frame->nb_samples && got_frame && + if (discard_padding > 0 && discard_padding <= frame->nb_samples && !ret && !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) { if (discard_padding == frame->nb_samples) { *discarded_samples += frame->nb_samples; - got_frame = 0; + ret = AVERROR(EAGAIN); } else { if(avctx->pkt_timebase.num && avctx->sample_rate) { int64_t diff_ts = av_rescale_q(frame->nb_samples - discard_padding, @@ -452,7 +390,7 @@ FF_ENABLE_DEPRECATION_WARNINGS } } - if ((avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL) && got_frame) { + if ((avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL) && !ret) { AVFrameSideData *fside = av_frame_new_side_data(frame, AV_FRAME_DATA_SKIP_SAMPLES, 10); if (fside) { AV_WL32(fside->data, avci->skip_samples); @@ -464,15 +402,88 @@ FF_ENABLE_DEPRECATION_WARNINGS } } - if (!got_frame) + return ret; +} + +/* + * The core of the receive_frame_wrapper for the decoders implementing + * the simple API. Certain decoders might consume partial packets without + * returning any output, so this function needs to be called in a loop until it + * returns EAGAIN. + **/ +static inline int decode_simple_internal(AVCodecContext *avctx, AVFrame *frame, int64_t *discarded_samples) +{ + AVCodecInternal *avci = avctx->internal; + AVPacket *const pkt = avci->in_pkt; + const FFCodec *const codec = ffcodec(avctx->codec); + int got_frame; + int consumed, ret; + + if (!pkt->data && !avci->draining) { + av_packet_unref(pkt); + ret = ff_decode_get_packet(avctx, pkt); + if (ret < 0 && ret != AVERROR_EOF) + return ret; + } + + // Some codecs (at least wma lossless) will crash when feeding drain packets + // after EOF was signaled. + if (avci->draining_done) + return AVERROR_EOF; + + if (!pkt->data && + !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY || + avctx->active_thread_type & FF_THREAD_FRAME)) + return AVERROR_EOF; + + got_frame = 0; + + if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) { + consumed = ff_thread_decode_frame(avctx, frame, &got_frame, pkt); + } else { + consumed = codec->cb.decode(avctx, frame, &got_frame, pkt); + + if (!(codec->caps_internal & FF_CODEC_CAP_SETS_PKT_DTS)) + frame->pkt_dts = pkt->dts; + if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) { +#if FF_API_FRAME_PKT +FF_DISABLE_DEPRECATION_WARNINGS + if(!avctx->has_b_frames) + frame->pkt_pos = pkt->pos; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + //FIXME these should be under if(!avctx->has_b_frames) + /* get_buffer is supposed to set frame parameters */ + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DR1)) { + if (!frame->sample_aspect_ratio.num) frame->sample_aspect_ratio = avctx->sample_aspect_ratio; + if (!frame->width) frame->width = avctx->width; + if (!frame->height) frame->height = avctx->height; + if (frame->format == AV_PIX_FMT_NONE) frame->format = avctx->pix_fmt; + } + } + } + emms_c(); + + if (got_frame) + ret = discard_samples(avctx, frame, discarded_samples); + else + ret = AVERROR(EAGAIN); + + if (consumed < 0) + ret = consumed; + if (consumed >= 0 && avctx->codec->type == AVMEDIA_TYPE_VIDEO) + consumed = pkt->size; + + if (!got_frame || ret == AVERROR(EAGAIN)) av_frame_unref(frame); - if (ret >= 0 && avctx->codec->type == AVMEDIA_TYPE_VIDEO) - ret = pkt->size; + if (!ret) + av_assert0(frame->buf[0]); + if (ret == AVERROR(EAGAIN)) + ret = 0; - /* do not stop draining when actual_got_frame != 0 or ret < 0 */ - /* got_frame == 0 but actual_got_frame != 0 when frame is discarded */ - if (avci->draining && !actual_got_frame) { + /* do not stop draining when got_frame != 0 or ret < 0 */ + if (avci->draining && !got_frame) { if (ret < 0) { /* prevent infinite loop if a decoder wrongly always return error on draining */ /* reasonable nb_errors_max = maximum b frames + thread count */ @@ -490,11 +501,9 @@ FF_ENABLE_DEPRECATION_WARNINGS } } - if (ret >= pkt->size || ret < 0) { + if (consumed >= pkt->size || ret < 0) { av_packet_unref(pkt); } else { - int consumed = ret; - pkt->data += consumed; pkt->size -= consumed; pkt->pts = AV_NOPTS_VALUE; @@ -509,10 +518,7 @@ FF_ENABLE_DEPRECATION_WARNINGS } } - if (got_frame) - av_assert0(frame->buf[0]); - - return ret < 0 ? ret : 0; + return ret; } #if CONFIG_LCMS2