From patchwork Mon Sep 23 15:01:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 51762 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:d154:0:b0:48e:c0f8:d0de with SMTP id bt20csp2523253vqb; Mon, 23 Sep 2024 08:09:38 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCUCkdjTtetSK1+Fb/t/TBk3Wj38UUjCYbCkI5CBsrD+yMYCdPFt2fwGmBuqDOIqFRRncvaKda8DIqOPGRYLH6Pr@gmail.com X-Google-Smtp-Source: AGHT+IFcISnUQAyPfKW+Lxn7xQ8Cj0WH+c8U3R2zTl6ChidhEuvzy2bzlHjQQz3GxnaGWqct+Gy0 X-Received: by 2002:a2e:bc06:0:b0:2f1:75f4:a6c1 with SMTP id 38308e7fff4ca-2f7cb2fbb68mr20736381fa.3.1727104177944; Mon, 23 Sep 2024 08:09:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1727104177; cv=none; d=google.com; s=arc-20240605; b=URLUkhmEy1ToaysCrN5qSBqzBFH7INVhlKHjiQpRhTa0j//34u4a9uGS1lLEH3zaa9 dzayD9ExRYt5/p/+Jhc1xHdIGKTMM7wtLbtk9gm0oWNb8JTg3jT2r7e03RKs5c8EJ5G7 8ezRTgClrxo1YYvYrGDESAwOyK2X4VMjBnQJL4Zef7Pm1wdCHs8qbnMFNWRIDUChoMyI DSnszutQ3GefCHkyLwvYxVWLcDjYqfYoK1hIPstwOsIOemTxVIzXrlNqpiWsAfqyVOWf YHaUwRSLtc624qhSnpu5C4HB0ubUZUeKnc+ZI6Upm/C7qaNr7hyk63woEqY58CpRsx1+ 7N1w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; 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=XPgMaJ7JzkKW5PVWksQAZ8iB43/n0pizBHPtsL4aVKk=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=TPd7pK3A9wuI/Ah9OkzdLrRBEuNRi9NqO6aua0XXjghlE19tUoBNjgx2cu0ijxwBX9 TJeC51TKPqIYwfJbFseXGyNMnq8t9QzOj8coqulkhJhkKjBD6M0ev9cTSyZNnESgundW 0LDiZCRLyvTFCMJ36yC03ut8yIjqWK1NRnq5p20jLUvQSVyFbCkBpj58Ou2PRwcQ+kFp /c6UVXZrkPv/28DYSyINXBRkcTX9NKkXufgShZmsTuR60DXg7bwHixc04OqiFpUUPhNK uV33ucKICim1XHDt4U7lqtXhD5/LMOE8QO90jAGfJ/cZgL/56mBhwWuluo41J2TVpL4b YoRQ==; 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=XKXcKYdF; 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 38308e7fff4ca-2f79d37959fsi60091221fa.357.2024.09.23.08.09.37; Mon, 23 Sep 2024 08:09:37 -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=XKXcKYdF; 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 8B9C968DC75; Mon, 23 Sep 2024 18:02:18 +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 F052768DB97 for ; Mon, 23 Sep 2024 18:02:06 +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=XKXcKYdF; dkim-atps=neutral Received: from localhost (mail1.khirnov.net [IPv6:::1]) by mail1.khirnov.net (Postfix) with ESMTP id 8D6A14DEE for ; Mon, 23 Sep 2024 17:02:06 +0200 (CEST) Received: from mail1.khirnov.net ([IPv6:::1]) by localhost (mail1.khirnov.net [IPv6:::1]) (amavis, port 10024) with ESMTP id 3ZeJVzBJXAKi for ; Mon, 23 Sep 2024 17:02:06 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=khirnov.net; s=mail; t=1727103724; bh=am4urxokhIzp8JlufQwPNZVE2bmaCmEfCxL5tVM3QLI=; h=From:To:Subject:Date:From; b=XKXcKYdFwBuB+jQVrJWOTI+aT4+8aYVGhPCnl6VFi5GcbbLtZ25DP0PP3tcMZZ8P0 RiZHDG/wTmlVkc4Xcavv8olfpdDbJgq9fyxNhTSGHrwTTMnDzvUD+nzv2s6Yp0kZyo es+Z0RB1cq/AOOR0CRLToKA8UhRc+gcvvL58KTjPXThb5AXt9PtQdTnrMWdwKhKmkL TlAIl6u/C3FOC4oHs/I5xaG1hrnddnlhV1nM3GtJ/PnzgApNJ6lG+aV903xiYM7+Yp v1r5b0dQArJeI9PE41xoackMfmNImfkeVftz8iJDDSQBzLpHhGTC2s7Mnjl01KOOz9 D/bQBB5/4WbmQ== 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 5AB861F8 for ; Mon, 23 Sep 2024 17:02:04 +0200 (CEST) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 300793A03CA for ; Mon, 23 Sep 2024 17:02:04 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Mon, 23 Sep 2024 17:01:39 +0200 Message-ID: <20240923150146.31693-1-anton@khirnov.net> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/7] lavfi/buffersink: set AVFrame.time_base 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: RtQmUOOZDZ6P So the caller does not need to call av_buffersink_get_time_base() separately. --- doc/APIchanges | 3 +++ doc/examples/transcode.c | 1 - fftools/ffmpeg_filter.c | 2 -- fftools/ffplay.c | 10 ++-------- libavdevice/lavfi.c | 4 ++-- libavfilter/buffersink.c | 21 ++++++++++++++++----- libavfilter/version.h | 2 +- tools/uncoded_frame.c | 2 +- 8 files changed, 25 insertions(+), 20 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 2273c3bce7..b392c756d7 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -2,6 +2,9 @@ The last version increases of all libraries were on 2024-03-07 API changes, most recent first: +2024-09-xx - xxxxxxxxxx - lavfi 10.4.100 + Buffersink now sets AVFrame.time_base on the frames it outputs. + 2024-09-23 - xxxxxxxxxx - lavc 61.18.100 - avcodec.h Add a new flag AV_CODEC_EXPORT_DATA_ENHANCEMENTS for export_side_data. diff --git a/doc/examples/transcode.c b/doc/examples/transcode.c index cbe5088ef6..07d9ee9152 100644 --- a/doc/examples/transcode.c +++ b/doc/examples/transcode.c @@ -500,7 +500,6 @@ static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index) break; } - filter->filtered_frame->time_base = av_buffersink_get_time_base(filter->buffersink_ctx);; filter->filtered_frame->pict_type = AV_PICTURE_TYPE_NONE; ret = encode_write_frame(stream_index, 0); av_frame_unref(filter->filtered_frame); diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 529e631781..81c4911b03 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -2487,8 +2487,6 @@ static int fg_output_step(OutputFilterPriv *ofp, FilterGraphThread *fgt, return 0; } - frame->time_base = av_buffersink_get_time_base(filter); - if (debug_ts) av_log(ofp, AV_LOG_INFO, "filter_raw -> pts:%s pts_time:%s time_base:%d/%d\n", av_ts2str(frame->pts), av_ts2timestr(frame->pts, &frame->time_base), diff --git a/fftools/ffplay.c b/fftools/ffplay.c index 60d8874eab..4ea48e11bb 100644 --- a/fftools/ffplay.c +++ b/fftools/ffplay.c @@ -2076,7 +2076,6 @@ static int audio_thread(void *arg) int last_serial = -1; int reconfigure; int got_frame = 0; - AVRational tb; int ret = 0; if (!frame) @@ -2087,8 +2086,6 @@ static int audio_thread(void *arg) goto the_end; if (got_frame) { - tb = (AVRational){1, frame->sample_rate}; - reconfigure = cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.ch_layout.nb_channels, frame->format, frame->ch_layout.nb_channels) || @@ -2121,11 +2118,10 @@ static int audio_thread(void *arg) while ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, frame, 0)) >= 0) { FrameData *fd = frame->opaque_ref ? (FrameData*)frame->opaque_ref->data : NULL; - tb = av_buffersink_get_time_base(is->out_audio_filter); if (!(af = frame_queue_peek_writable(&is->sampq))) goto the_end; - af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb); + af->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(frame->time_base); af->pos = fd ? fd->pkt_pos : -1; af->serial = is->auddec.pkt_serial; af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate}); @@ -2164,7 +2160,6 @@ static int video_thread(void *arg) double pts; double duration; int ret; - AVRational tb = is->video_st->time_base; AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL); AVFilterGraph *graph = NULL; @@ -2242,9 +2237,8 @@ static int video_thread(void *arg) is->frame_last_filter_delay = av_gettime_relative() / 1000000.0 - is->frame_last_returned_time; if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0) is->frame_last_filter_delay = 0; - tb = av_buffersink_get_time_base(filt_out); duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0); - pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb); + pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(frame->time_base); ret = queue_picture(is, frame, pts, duration, fd ? fd->pkt_pos : -1, is->viddec.pkt_serial); av_frame_unref(frame); if (is->videoq.serial != is->viddec.pkt_serial) diff --git a/libavdevice/lavfi.c b/libavdevice/lavfi.c index ce10d61f8a..3b77a7396a 100644 --- a/libavdevice/lavfi.c +++ b/libavdevice/lavfi.c @@ -384,7 +384,6 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt) /* iterate through all the graph sinks. Select the sink with the * minimum PTS */ for (i = 0; i < lavfi->nb_sinks; i++) { - AVRational tb = av_buffersink_get_time_base(lavfi->sinks[i]); double d; if (lavfi->sink_eof[i]) @@ -398,7 +397,8 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt) continue; } else if (ret < 0) goto fail; - d = av_rescale_q_rnd(frame->pts, tb, AV_TIME_BASE_Q, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX); + d = av_rescale_q_rnd(frame->pts, frame->time_base, AV_TIME_BASE_Q, + AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX); ff_dlog(avctx, "sink_idx:%d time:%f\n", i, d); av_frame_unref(frame); diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c index 5811720c61..575075ff47 100644 --- a/libavfilter/buffersink.c +++ b/libavfilter/buffersink.c @@ -69,18 +69,29 @@ int attribute_align_arg av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *f return av_buffersink_get_frame_flags(ctx, frame, 0); } -static int return_or_keep_frame(BufferSinkContext *buf, AVFrame *out, AVFrame *in, int flags) +static int return_or_keep_frame(AVFilterContext *ctx, AVFrame *out, AVFrame *in, + int flags) { + BufferSinkContext *buf = ctx->priv; + if ((flags & AV_BUFFERSINK_FLAG_PEEK)) { buf->peeked_frame = in; - return out ? av_frame_ref(out, in) : 0; + if (out) { + int ret = av_frame_ref(out, in); + if (ret < 0) + return ret; + } } else { av_assert1(out); buf->peeked_frame = NULL; av_frame_move_ref(out, in); av_frame_free(&in); - return 0; } + + if (out) + out->time_base = ctx->inputs[0]->time_base; + + return 0; } static int get_frame_internal(AVFilterContext *ctx, AVFrame *frame, int flags, int samples) @@ -93,7 +104,7 @@ static int get_frame_internal(AVFilterContext *ctx, AVFrame *frame, int flags, i int64_t pts; if (buf->peeked_frame) - return return_or_keep_frame(buf, frame, buf->peeked_frame, flags); + return return_or_keep_frame(ctx, frame, buf->peeked_frame, flags); while (1) { ret = samples ? ff_inlink_consume_samples(inlink, samples, samples, &cur_frame) : @@ -102,7 +113,7 @@ static int get_frame_internal(AVFilterContext *ctx, AVFrame *frame, int flags, i return ret; } else if (ret) { /* TODO return the frame instead of copying it */ - return return_or_keep_frame(buf, frame, cur_frame, flags); + return return_or_keep_frame(ctx, frame, cur_frame, flags); } else if (ff_inlink_acknowledge_status(inlink, &status, &pts)) { return status; } else if ((flags & AV_BUFFERSINK_FLAG_NO_REQUEST)) { diff --git a/libavfilter/version.h b/libavfilter/version.h index 7e0eb9af97..4d8f28e512 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -31,7 +31,7 @@ #include "version_major.h" -#define LIBAVFILTER_VERSION_MINOR 3 +#define LIBAVFILTER_VERSION_MINOR 4 #define LIBAVFILTER_VERSION_MICRO 100 diff --git a/tools/uncoded_frame.c b/tools/uncoded_frame.c index 447bfc8b0d..a17d406417 100644 --- a/tools/uncoded_frame.c +++ b/tools/uncoded_frame.c @@ -237,7 +237,7 @@ int main(int argc, char **argv) } if (frame->pts != AV_NOPTS_VALUE) frame->pts = av_rescale_q(frame->pts, - av_buffersink_get_time_base(st->sink), + frame->time_base, st->stream->time_base); ret = av_interleaved_write_uncoded_frame(st->mux, st->stream->index,