From patchwork Fri Apr 5 16:11:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 47850 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:24a8:b0:1a3:b6bb:3029 with SMTP id m40csp1071114pzd; Fri, 5 Apr 2024 09:16:33 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCU+8VuFcHGnH14nXzwNTfWYnuIRug27xdxLpBiTlnb4DVcUDLK9zTOvz7E16muz1TrMja0DicMu3sulwTZMMZ8q4ILSik4qCC0opg== X-Google-Smtp-Source: AGHT+IF8CsdDUNbEos8i8LBdkamYCi/SDsvxjQTCHb4CDBR+PSCL/7m+ETco1Zyg+QkaPnQhy91W X-Received: by 2002:a17:906:6a1a:b0:a4e:4278:8a01 with SMTP id qw26-20020a1709066a1a00b00a4e42788a01mr1866043ejc.11.1712333793428; Fri, 05 Apr 2024 09:16:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1712333793; cv=none; d=google.com; s=arc-20160816; b=P/1ska02evQkjuv0ol0HF/GAwlir4qdtmCr9OMXnOs5pWOkmhIHyXRLuwPy0nmxzst xz5YcKSOkeXN7gq5FY0W1SX1Wlwx5ObhiMuWOmcnL+rjJkWR4BPzw4UhQ+v59Ik/9sLm PSJJC0TXjSInfDzc/gAAz6/VI2c/MudhJVaO/54buCov0ph5HVSRCuazt4c+LgoMDVtZ T9j4RcYNDjF+y2k/WZMLOsRruX+dY2njuwpoJ6qz3goF5Vy/oyt82C7DjFHmJeSUqSrX H5WtPk4eFOxzwsgG6O7E0qIOQABUSFCryUb9CPn/Lc9h7TCcxo+H7nh3N9uKZrYY2ilE Nd4Q== 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:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=DUbNg9Oac9/PhSZ2N79RI26LhIPEzTzN8CyCGVh5AK8=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=lEULMgSQXv+D6s6UVGNs62YRjUIXlIfEwOlUTlLN0csq762AfeLjKUYvMg73tYr0NF tC+wspmz6KkpGCqRTgXpzmW7eSRe5/84+UZbJU7znrNJ3l3hhy88tgmRdg7Z0BLGAw7G g0ZAIRzzNv17dsIu8ip6qh6UnXjLlNwE2qVxSFRlLJnd2JVP9aFKmdvxuoOqfLMNME5X R4DJeFYaNRg2jMdTaqb/je7/h9btq/ZjtqssBHshoD8ssUyZZaJChS0wHYA7N5CF8MSa AE7iDqHFxNxD+34KqRcG0a1gzvJuGwI+IOZWaye7YWg7QkkTmUMVagKUuArRdo6VmZJ/ QwOg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@khirnov.net header.s=mail header.b=DnleQnKk; 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id p22-20020a170906229600b00a519413794dsi818418eja.218.2024.04.05.09.16.32; Fri, 05 Apr 2024 09:16:33 -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=@khirnov.net header.s=mail header.b=DnleQnKk; 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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 08F7A68D2E4; Fri, 5 Apr 2024 19:13:33 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail1.khirnov.net (quelana.khirnov.net [94.230.150.81]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 7172268D158 for ; Fri, 5 Apr 2024 19:13:10 +0300 (EEST) Authentication-Results: mail1.khirnov.net; dkim=pass (2048-bit key; unprotected) header.d=khirnov.net header.i=@khirnov.net header.a=rsa-sha256 header.s=mail header.b=DnleQnKk; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id 28B1D4D9D for ; Fri, 5 Apr 2024 18:13:09 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id qvoLktBHUMgj for ; Fri, 5 Apr 2024 18:13:08 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1712333584; bh=sdwGf+jXopf+LjVHjXtu5JUX0A0sTl/TpYRUIlWcOrI=; h=From:To:Subject:Date:In-Reply-To:References:From; b=DnleQnKkYX78hL16Qd/cjQmfccQCF1rHe1jnrF0DJ70KPChzsUBAW5hznfD7sXwvi TaLQevSqDgggq125kDcXwRd7teYkf9psBxAiUPxgMS2ZQ4CC33Ud0s83M3zdx2N3ku yJmvpbvVFnCX+Ug1A850Aovb4PhZtsMfS4LM3Ls9v25hdROJeerrICUTlSWsStA2H6 4LnyZDGSsw7k7csJG6UiCl7bIXExHwjUg3SMUByVvhXL+OP1BgBONricxx9Mg4I2m8 4cgwMF3ugqlH5OGezrQLXEm1ymahzah0YK1exFfCV3EmdQ4G0VlVI3U16yDtaNWVSF KekUD5qWfcJIA== Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail1.khirnov.net (Postfix) with ESMTPS id 4C4C84D81 for ; Fri, 5 Apr 2024 18:13:02 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id F3ADF3A1050 for ; Fri, 5 Apr 2024 18:12:55 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Fri, 5 Apr 2024 18:11:53 +0200 Message-ID: <20240405161212.26167-12-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240405161212.26167-1-anton@khirnov.net> References: <20240405161212.26167-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 12/31] fftools/ffmpeg_filter: pass vsync method through OutputFilterOptions 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: alI1fUhyyMAi Do not read it from OutputStream directly. Will allow decoupling filtering from encoding in future commits. --- fftools/ffmpeg.h | 3 ++- fftools/ffmpeg_filter.c | 9 +++++--- fftools/ffmpeg_mux.c | 2 +- fftools/ffmpeg_mux.h | 3 +++ fftools/ffmpeg_mux_init.c | 45 ++++++++++++++++++++++----------------- 5 files changed, 38 insertions(+), 24 deletions(-) diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 598ca2fa96..fa8f7d8324 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -287,6 +287,8 @@ typedef struct OutputFilterOptions { int width; int height; + enum VideoSyncMethod vsync_method; + int sample_rate; AVChannelLayout ch_layout; } OutputFilterOptions; @@ -549,7 +551,6 @@ typedef struct OutputStream { /* video only */ AVRational frame_rate; AVRational max_frame_rate; - enum VideoSyncMethod vsync_method; int is_cfr; int force_fps; #if FFMPEG_OPT_TOP diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 3c25d2ed65..d906b72576 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -175,6 +175,8 @@ typedef struct FPSConvContext { int last_dropped; int dropped_keyframe; + enum VideoSyncMethod vsync_method; + AVRational framerate; AVRational framerate_max; const AVRational *framerate_supported; @@ -799,6 +801,7 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream *ost, if (!ofp->fps.last_frame) return AVERROR(ENOMEM); + ofp->fps.vsync_method = opts->vsync_method; ofp->fps.framerate = ost->frame_rate; ofp->fps.framerate_max = ost->max_frame_rate; ofp->fps.framerate_supported = ost->force_fps && opts->enc ? @@ -2072,9 +2075,9 @@ static void video_sync_process(OutputFilterPriv *ofp, AVFrame *frame, if (delta0 < 0 && delta > 0 && - ost->vsync_method != VSYNC_PASSTHROUGH + fps->vsync_method != VSYNC_PASSTHROUGH #if FFMPEG_OPT_VSYNC_DROP - && ost->vsync_method != VSYNC_DROP + && fps->vsync_method != VSYNC_DROP #endif ) { if (delta0 < -0.6) { @@ -2086,7 +2089,7 @@ static void video_sync_process(OutputFilterPriv *ofp, AVFrame *frame, delta0 = 0; } - switch (ost->vsync_method) { + switch (fps->vsync_method) { case VSYNC_VSCFR: if (fps->frame_number == 0 && delta0 >= 0.5) { av_log(ost, AV_LOG_DEBUG, "Not duplicating %d initial frames\n", (int)lrintf(delta0)); diff --git a/fftools/ffmpeg_mux.c b/fftools/ffmpeg_mux.c index e8e5c677b8..253c2e58d4 100644 --- a/fftools/ffmpeg_mux.c +++ b/fftools/ffmpeg_mux.c @@ -140,7 +140,7 @@ static int mux_fixup_ts(Muxer *mux, MuxStream *ms, AVPacket *pkt) OutputStream *ost = &ms->ost; #if FFMPEG_OPT_VSYNC_DROP - if (ost->type == AVMEDIA_TYPE_VIDEO && ost->vsync_method == VSYNC_DROP) + if (ost->type == AVMEDIA_TYPE_VIDEO && ms->ts_drop) pkt->pts = pkt->dts = AV_NOPTS_VALUE; #endif diff --git a/fftools/ffmpeg_mux.h b/fftools/ffmpeg_mux.h index 16af6d38ba..f8b6f7a790 100644 --- a/fftools/ffmpeg_mux.h +++ b/fftools/ffmpeg_mux.h @@ -75,6 +75,9 @@ typedef struct MuxStream { int copy_initial_nonkeyframes; int copy_prior_start; int streamcopy_started; +#if FFMPEG_OPT_VSYNC_DROP + int ts_drop; +#endif } MuxStream; typedef struct Muxer { diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c index b031cc59d2..6ffa4b7491 100644 --- a/fftools/ffmpeg_mux_init.c +++ b/fftools/ffmpeg_mux_init.c @@ -580,8 +580,10 @@ static enum AVPixelFormat pix_fmt_parse(OutputStream *ost, const char *name) } static int new_stream_video(Muxer *mux, const OptionsContext *o, - OutputStream *ost, int *keep_pix_fmt) + OutputStream *ost, int *keep_pix_fmt, + enum VideoSyncMethod *vsync_method) { + MuxStream *ms = ms_from_ost(ost); AVFormatContext *oc = mux->fc; AVStream *st; char *frame_rate = NULL, *max_frame_rate = NULL, *frame_aspect_ratio = NULL; @@ -773,49 +775,52 @@ static int new_stream_video(Muxer *mux, const OptionsContext *o, #endif #if FFMPEG_OPT_VSYNC - ost->vsync_method = video_sync_method; + *vsync_method = video_sync_method; #else - ost->vsync_method = VSYNC_AUTO; + *vsync_method = VSYNC_AUTO; #endif MATCH_PER_STREAM_OPT(fps_mode, str, fps_mode, oc, st); if (fps_mode) { - ret = parse_and_set_vsync(fps_mode, &ost->vsync_method, ost->file->index, ost->index, 0); + ret = parse_and_set_vsync(fps_mode, vsync_method, ost->file->index, ost->index, 0); if (ret < 0) return ret; } if ((ost->frame_rate.num || ost->max_frame_rate.num) && - !(ost->vsync_method == VSYNC_AUTO || - ost->vsync_method == VSYNC_CFR || ost->vsync_method == VSYNC_VSCFR)) { + !(*vsync_method == VSYNC_AUTO || + *vsync_method == VSYNC_CFR || *vsync_method == VSYNC_VSCFR)) { av_log(ost, AV_LOG_FATAL, "One of -r/-fpsmax was specified " "together a non-CFR -vsync/-fps_mode. This is contradictory.\n"); return AVERROR(EINVAL); } - if (ost->vsync_method == VSYNC_AUTO) { + if (*vsync_method == VSYNC_AUTO) { if (ost->frame_rate.num || ost->max_frame_rate.num) { - ost->vsync_method = VSYNC_CFR; + *vsync_method = VSYNC_CFR; } else if (!strcmp(oc->oformat->name, "avi")) { - ost->vsync_method = VSYNC_VFR; + *vsync_method = VSYNC_VFR; } else { - ost->vsync_method = (oc->oformat->flags & AVFMT_VARIABLE_FPS) ? - ((oc->oformat->flags & AVFMT_NOTIMESTAMPS) ? - VSYNC_PASSTHROUGH : VSYNC_VFR) : - VSYNC_CFR; + *vsync_method = (oc->oformat->flags & AVFMT_VARIABLE_FPS) ? + ((oc->oformat->flags & AVFMT_NOTIMESTAMPS) ? + VSYNC_PASSTHROUGH : VSYNC_VFR) : VSYNC_CFR; } - if (ost->ist && ost->vsync_method == VSYNC_CFR) { + if (ost->ist && *vsync_method == VSYNC_CFR) { const InputFile *ifile = ost->ist->file; if (ifile->nb_streams == 1 && ifile->input_ts_offset == 0) - ost->vsync_method = VSYNC_VSCFR; + *vsync_method = VSYNC_VSCFR; } - if (ost->vsync_method == VSYNC_CFR && copy_ts) { - ost->vsync_method = VSYNC_VSCFR; + if (*vsync_method == VSYNC_CFR && copy_ts) { + *vsync_method = VSYNC_VSCFR; } } - ost->is_cfr = (ost->vsync_method == VSYNC_CFR || ost->vsync_method == VSYNC_VSCFR); + ost->is_cfr = (*vsync_method == VSYNC_CFR || *vsync_method == VSYNC_VSCFR); +#if FFMPEG_OPT_VSYNC_DROP + if (*vsync_method == VSYNC_DROP) + ms->ts_drop = 1; +#endif } return 0; @@ -1043,6 +1048,7 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, AVStream *st; int ret = 0, keep_pix_fmt = 0; AVRational enc_tb = { 0, 0 }; + enum VideoSyncMethod vsync_method = VSYNC_AUTO; const char *bsfs = NULL, *time_base = NULL; char *filters = NULL, *next, *codec_tag = NULL; double qscale = -1; @@ -1361,7 +1367,7 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, ms->copy_initial_nonkeyframes, oc, st); switch (type) { - case AVMEDIA_TYPE_VIDEO: ret = new_stream_video (mux, o, ost, &keep_pix_fmt); break; + case AVMEDIA_TYPE_VIDEO: ret = new_stream_video (mux, o, ost, &keep_pix_fmt, &vsync_method); break; case AVMEDIA_TYPE_AUDIO: ret = new_stream_audio (mux, o, ost); break; case AVMEDIA_TYPE_SUBTITLE: ret = new_stream_subtitle (mux, o, ost); break; } @@ -1382,6 +1388,7 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, ost->enc_ctx->pix_fmt : ost->enc_ctx->sample_fmt, .width = ost->enc_ctx->width, .height = ost->enc_ctx->height, + .vsync_method = vsync_method, .sample_rate = ost->enc_ctx->sample_rate, .ch_layout = ost->enc_ctx->ch_layout, .output_tb = enc_tb,