From patchwork Tue May 28 09:11:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Gaullier X-Patchwork-Id: 49311 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:612c:142:b0:460:55fa:d5ed with SMTP id h2csp275579vqi; Tue, 28 May 2024 02:11:45 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCX4W8KFWW7wsHUZ+6H2Wzt0lcLZPqH9LrrLmiB4abYoIpoYas5c0serSWPLjVQVPKDz8K8I60g7Gm6o5Iy5a/IF0iuroIhdp5HsTA== X-Google-Smtp-Source: AGHT+IEy5a+tQ8SS/YJ0+6Tm4o0rDyeSLZA0sp5TFXj/reM0gi81lGQFUTaRZtmlYby6DVp8emjh X-Received: by 2002:a50:9993:0:b0:578:5d83:bae5 with SMTP id 4fb4d7f45d1cf-5785d83c0d0mr7266035a12.29.1716887504746; Tue, 28 May 2024 02:11:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1716887504; cv=none; d=google.com; s=arc-20160816; b=H4X0TP7AmQfddhR1+vWCJvzcFNCd9QpVTVdqUrSrOnlNhdJxLizMR2TSoNAFDU9W3z UPVAPzZhwuJVQ/IFt05wDgv8pSvI1796wCQK/DD8XSz0TDzPn68ohz3vurvR0c/5y6Uy Fma1JhRA9qz6jSNyt5gHD9LDRRCbBtstp/RpUwafb/8QQ2gd15Uw0KPuXiXwXbPG4rN4 0ss8AYo1+ZPpX9T/7PEyANYoLGJ6o8Ac+htTpmh5S94LLMPPZgUsS7gmoeoxL5qi4ElP XwiiAb+ADbj6kjlmqniRybAHPfjEMt+C77Hyk0CckiIk0OiM5VZKTnwNwHICi4Nk7lOv 0r9g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:delivered-to; bh=lE+SQVqfJ3fT+6r6WvZFWBqg57jLQ6AcQEnqVIpXzzE=; fh=zgMS+X4RExv2k7fU8QdWClnqVJdqO/9UbUuBS5xxJDs=; b=WCLX4UdL638YbelzHKTfm+0u+yCdP6jdlPO+6Wx85z08vQxn6ponDisfUfKaLRP1y8 vOO09rx71zQLtInQRTtf8kecoILToy+/dHg7sOvIrUUGZTvEdP8mb+eRt8tuXOlS4/gF lmpMv6vFrJfepTxPC2JVCHc2dlR7gAmjqA7U35SRln/MAzMtogRXMM2+CLd/xQI2Gp/M 8bVl+7r04ddoPZ+OM7xlixKG9MPwchgxKVOQRtFe+poFMXJvgNWhLPktF7ps654eHCOF D1TA1fHYGNsYOwNH+3eO5tFmNuV08Tgpo8G/RK1K4oJn4v1fTrO1186TH3wytT/ArkN5 ETPA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; 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=NONE dis=NONE) header.from=cji.paris Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 4fb4d7f45d1cf-578524b45f0si4990343a12.515.2024.05.28.02.11.44; Tue, 28 May 2024 02:11:44 -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; 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=NONE dis=NONE) header.from=cji.paris Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 8D52D68D528; Tue, 28 May 2024 12:11:30 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from srv-infra-2.infra.inf.glb.tvvideoms.com (www.inf.tvvideoms.com [213.205.126.156]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 2062E68D28C for ; Tue, 28 May 2024 12:11:22 +0300 (EEST) Received: from cji.paris (unknown [172.16.3.159]) by srv-infra-2.infra.inf.glb.tvvideoms.com (Postfix) with ESMTP id 5A77A404FD; Tue, 28 May 2024 09:11:21 +0000 (UTC) From: Nicolas Gaullier To: ffmpeg-devel@ffmpeg.org Date: Tue, 28 May 2024 11:11:17 +0200 Message-Id: <20240528091117.139346-2-nicolas.gaullier@cji.paris> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20240528091117.139346-1-nicolas.gaullier@cji.paris> References: <20240528091117.139346-1-nicolas.gaullier@cji.paris> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/1] avfilter/framesync: fix forward EOF pts 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 Cc: Nicolas Gaullier Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: GTRA0J/t93jP Note1: when the EOF pts is not accurate enough, the last frame can be dropped by vf_fps with default rounding. Note2: vf_scale use framesync since e82a3997cdd6c0894869b33ba42430ac3, so this is a very commonplace scenario. For example: ./ffprobe -f lavfi testsrc=d=1,scale,fps -of flat \ -count_frames -show_entries stream=nb_read_frames Before: streams.stream.0.nb_read_frames="24" After: streams.stream.0.nb_read_frames="25" --- libavfilter/framesync.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/libavfilter/framesync.c b/libavfilter/framesync.c index 535fbe9c7c..28a992ba6d 100644 --- a/libavfilter/framesync.c +++ b/libavfilter/framesync.c @@ -103,14 +103,14 @@ int ff_framesync_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in) return 0; } -static void framesync_eof(FFFrameSync *fs) +static void framesync_eof(FFFrameSync *fs, int64_t pts) { fs->eof = 1; fs->frame_ready = 0; - ff_outlink_set_status(fs->parent->outputs[0], AVERROR_EOF, AV_NOPTS_VALUE); + ff_outlink_set_status(fs->parent->outputs[0], AVERROR_EOF, pts); } -static void framesync_sync_level_update(FFFrameSync *fs) +static void framesync_sync_level_update(FFFrameSync *fs, int64_t eof_pts) { unsigned i, level = 0; @@ -131,7 +131,7 @@ static void framesync_sync_level_update(FFFrameSync *fs) if (level) fs->sync_level = level; else - framesync_eof(fs); + framesync_eof(fs, eof_pts); } int ff_framesync_configure(FFFrameSync *fs) @@ -179,7 +179,7 @@ int ff_framesync_configure(FFFrameSync *fs) for (i = 0; i < fs->nb_in; i++) fs->in[i].pts = fs->in[i].pts_next = AV_NOPTS_VALUE; fs->sync_level = UINT_MAX; - framesync_sync_level_update(fs); + framesync_sync_level_update(fs, AV_NOPTS_VALUE); return 0; } @@ -200,7 +200,7 @@ static int framesync_advance(FFFrameSync *fs) if (fs->in[i].have_next && fs->in[i].pts_next < pts) pts = fs->in[i].pts_next; if (pts == INT64_MAX) { - framesync_eof(fs); + framesync_eof(fs, AV_NOPTS_VALUE); break; } for (i = 0; i < fs->nb_in; i++) { @@ -222,7 +222,7 @@ static int framesync_advance(FFFrameSync *fs) fs->frame_ready = 1; if (fs->in[i].state == STATE_EOF && fs->in[i].after == EXT_STOP) - framesync_eof(fs); + framesync_eof(fs, AV_NOPTS_VALUE); } } if (fs->frame_ready) @@ -255,15 +255,14 @@ static void framesync_inject_frame(FFFrameSync *fs, unsigned in, AVFrame *frame) fs->in[in].have_next = 1; } -static void framesync_inject_status(FFFrameSync *fs, unsigned in, int status, int64_t pts) +static void framesync_inject_status(FFFrameSync *fs, unsigned in, int status, int64_t eof_pts) { av_assert0(!fs->in[in].have_next); - pts = fs->in[in].state != STATE_RUN || fs->in[in].after == EXT_INFINITY - ? INT64_MAX : framesync_pts_extrapolate(fs, in, fs->in[in].pts); fs->in[in].sync = 0; - framesync_sync_level_update(fs); + framesync_sync_level_update(fs, status == AVERROR_EOF ? eof_pts : AV_NOPTS_VALUE); fs->in[in].frame_next = NULL; - fs->in[in].pts_next = pts; + fs->in[in].pts_next = fs->in[in].state != STATE_RUN || fs->in[in].after == EXT_INFINITY + ? INT64_MAX : framesync_pts_extrapolate(fs, in, fs->in[in].pts); fs->in[in].have_next = 1; }