From patchwork Tue May 21 19:38:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Gaullier X-Patchwork-Id: 49113 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a21:9214:b0:1af:fc2d:ff5a with SMTP id tl20csp200037pzb; Tue, 21 May 2024 12:38:54 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCVUUD4APPv6FrdoFtbVbTtWKo1Fro5GPPNlkBuug9X55cS1r1155dn6c/a9DF4ZI4Tw9o8lo7+EkaZyKGjvejWunMXMr94LulJ/4g== X-Google-Smtp-Source: AGHT+IFAzXR0E2vj/UXrb9Sko3GU0Lf4of/l6XTJmJwF6XtxhOxuUuDC/NFjuYc4ISd1Dd8x7rSp X-Received: by 2002:a05:600c:3b0a:b0:418:2719:6b14 with SMTP id 5b1f17b1804b1-41feac5a400mr250603475e9.3.1716320333981; Tue, 21 May 2024 12:38:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1716320333; cv=none; d=google.com; s=arc-20160816; b=asrZZ12SkCUsoDYENVewk1AluKheAXVIwfzui9iH1115Y/wCCdgG21D7fift7EP6ac ZencK6kwhHrOnqoynGqw/nnOGyfdlXwlcf2pmtg9qDcADc5GADgZbZgBmBbONnwxwRc9 GH0po6BnsuGjihEIxgwDc7t+6BSG8QX86HrgNjjdFxd49S+1HNwVoO72r3Pvu4VdZd/3 GnD5eMH79zQzBRUO5RUjWOgtN7sw9+2rFKZh1CQ3+xKmu22F1bx1aqkgy9lPRqHHd5vh GK3omqeESrpN+9jymqH2OuKbx31BcdXdcyjFsmz5MaOIKgPdvQbAwF1b0xfazD6CCEpq S+Mg== 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:message-id:date:to:from :delivered-to; bh=lE+SQVqfJ3fT+6r6WvZFWBqg57jLQ6AcQEnqVIpXzzE=; fh=zgMS+X4RExv2k7fU8QdWClnqVJdqO/9UbUuBS5xxJDs=; b=KnwgRtBp4kRI5c1va6X6ab9DDnHkEb/1cyqn3B06XA5HQLPWK7r41+iphq9cZ/Uc4q Pk8od6orI6HHVKgEJ+8XyMBp5wrFSJL6WgcrPkxxVHHMJTCut/RFeygPwfkI4I0HInP9 H4TdQzrF/AbHBKWqZaji+cL0kIKzT7TC/hrShYBhWFaCsXuqgPSf1rxr1zONON4/8C3j jFbtmU9KGMMZkj1FANt7sTCEaj0s3JbwWXblqUMhCgXlWojUR9IW3bBQeehlaxSAFSZH gFiUk51ZqCl58elp87+1jp9Vjx3c1hmj3T+7jS+W3zq0EgcoLhbO9HVJNYh5BzL8XYBJ 3BDg==; 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-576bb7e4825si3053564a12.648.2024.05.21.12.38.53; Tue, 21 May 2024 12:38:53 -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 1EA6C68D2AB; Tue, 21 May 2024 22:38:50 +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 87CE268C10E for ; Tue, 21 May 2024 22:38:43 +0300 (EEST) Received: from cji.paris (unknown [172.16.3.159]) by srv-infra-2.infra.inf.glb.tvvideoms.com (Postfix) with ESMTP id 99F543FD79; Tue, 21 May 2024 19:38:41 +0000 (UTC) From: Nicolas Gaullier To: ffmpeg-devel@ffmpeg.org Date: Tue, 21 May 2024 21:38:36 +0200 Message-Id: <20240521193836.136062-1-nicolas.gaullier@cji.paris> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] 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: O2hmKEPUflo3 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; }