From patchwork Sat Mar 25 19:15:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 40819 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7a30:b0:df:834d:2c1a with SMTP id t48csp225274pzh; Sat, 25 Mar 2023 12:16:13 -0700 (PDT) X-Google-Smtp-Source: AK7set/yhR/N7RdddqkwQWLbdCyI1lKDicFuJ3dmSjBdrNYDN34AFSJua0XwwUDmQhlyFDDNWHTC X-Received: by 2002:a17:907:6d91:b0:8af:2f5e:93e3 with SMTP id sb17-20020a1709076d9100b008af2f5e93e3mr15906194ejc.29.1679771773368; Sat, 25 Mar 2023 12:16:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679771773; cv=none; d=google.com; s=arc-20160816; b=bZcgKqjpwTrM502V14NlFKI3/qd+SMSj7iMPnYAV+Dte4N/yl1COJfSRLvYUo/bqYT 1hFIYgDrF2w1ZxBqOIjeag44qdtvAfdj3ypx2Sk7kc2OqzlwpIKU+TmXUDGiG62wiRz5 9v8eg47kCJGO2oRSn/Qtxng0RZVaqF3ui7gXOsMxKxjgWI2RXUiHQ3F93pi2+xwIudsI GroeI08SZ3UUDhkuklCNjAZjEQ5GxigiRDPT8xV6e95LHH0Lx8gOVK3sdMLf+/jeGUml xeYYvtAbjVm7VEmpxHCMgs/zgAZXfahvmX4ABirHjs7MvEnaSJuPkT73KRj9h7ckFbZh RfFQ== 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 :delivered-to; bh=iJfHhFzuFQBel8aMlihaM1Nyprdozch3cWxl6mUf7wc=; b=xYpQzaun6JXfy6zoe72y07I2tj2vwbprkLkjsVGWj83P/61KS7xmnxyOhvWpZYlOFT hCPUtnkAk1nFLYSAoa3gYS1tYBIFgOvjU/C2iijuX60HvzAiTTVlXpdRjnalQuZrpoyz u7THNpSXnJOnefhP2uId+aJEpCVylOac4S4SeA0k/5rXmZnRkzqQ4EiOPg/wE6vXGYil ZzUGX4jjDy8FrHGvAbtbAjO1vjnVQyDTgxNVgx83bKKatBcavoxOEPcV6gMwrOp4mHTK EyAbs6If+Csr0sMjaI5rQorsh1bc71pyCNGtrZVLl2tMnNKOEJ/sRANMBMPMDPezxwak VQmQ== 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id bo4-20020a170906d04400b00920fd209aadsi22436380ejb.758.2023.03.25.12.16.12; Sat, 25 Mar 2023 12:16:13 -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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 2196268C956; Sat, 25 Mar 2023 21:16:09 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail0.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 5487C68C810 for ; Sat, 25 Mar 2023 21:16:02 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id 8796E240D1D for ; Sat, 25 Mar 2023 20:16:01 +0100 (CET) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id JpwyWwpavVy0 for ; Sat, 25 Mar 2023 20:16:00 +0100 (CET) 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 mail0.khirnov.net (Postfix) with ESMTPS id D5C0C240178 for ; Sat, 25 Mar 2023 20:16:00 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 583653A00B6 for ; Sat, 25 Mar 2023 20:15:54 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 25 Mar 2023 20:15:07 +0100 Message-Id: <20230325191529.10578-1-anton@khirnov.net> X-Mailer: git-send-email 2.39.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 01/23] fftools/ffmpeg: drop InputStream.processing_needed 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: oz31aSQSrOub It is equivalent to !InputStream.discard. --- fftools/ffmpeg.c | 4 ++-- fftools/ffmpeg.h | 1 - fftools/ffmpeg_filter.c | 1 - fftools/ffmpeg_mux_init.c | 3 --- 4 files changed, 2 insertions(+), 7 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 438bee8fef..aa9284ecd5 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -3648,7 +3648,7 @@ static void decode_flush(InputFile *ifile) InputStream *ist = ifile->streams[i]; int ret; - if (!ist->processing_needed) + if (ist->discard) continue; do { @@ -3793,7 +3793,7 @@ static int process_input(int file_index) for (i = 0; i < ifile->nb_streams; i++) { ist = ifile->streams[i]; - if (ist->processing_needed) { + if (!ist->discard) { ret = process_input_packet(ist, NULL, 0); if (ret>0) return 0; diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index 823218e214..791deedc07 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -342,7 +342,6 @@ typedef struct InputStream { int decoding_needed; /* non zero if the packets must be decoded in 'raw_fifo', see DECODING_FOR_* */ #define DECODING_FOR_OST 1 #define DECODING_FOR_FILTER 2 - int processing_needed; /* non zero if the packets must be processed */ // should attach FrameData as opaque_ref after decoding int want_frame_data; diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 4fde120067..314b89b585 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -296,7 +296,6 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in) ist->discard = 0; ist->decoding_needed |= DECODING_FOR_FILTER; - ist->processing_needed = 1; ist->st->discard = AVDISCARD_NONE; ifilter = ALLOC_ARRAY_ELEM(fg->inputs, fg->nb_inputs); diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c index 09d24ba8e5..ebc17059f9 100644 --- a/fftools/ffmpeg_mux_init.c +++ b/fftools/ffmpeg_mux_init.c @@ -2283,7 +2283,6 @@ int of_open(const OptionsContext *o, const char *filename) if (ost->enc_ctx && ost->ist) { InputStream *ist = ost->ist; ist->decoding_needed |= DECODING_FOR_OST; - ist->processing_needed = 1; if (ost->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO || ost->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { @@ -2294,8 +2293,6 @@ int of_open(const OptionsContext *o, const char *filename) exit_program(1); } } - } else if (ost->ist) { - ost->ist->processing_needed = 1; } /* set the filter output constraints */ From patchwork Sat Mar 25 19:15:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 40821 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7a30:b0:df:834d:2c1a with SMTP id t48csp225417pzh; Sat, 25 Mar 2023 12:16:31 -0700 (PDT) X-Google-Smtp-Source: AKy350aY4SxxLkcV1dfPNxt9YF4xDP/1r+wARFVbKZtF4WNYcTLefNihvjtl66z20N2LHaPX7zeN X-Received: by 2002:aa7:de92:0:b0:4fb:fd22:29c0 with SMTP id j18-20020aa7de92000000b004fbfd2229c0mr6637026edv.26.1679771791734; Sat, 25 Mar 2023 12:16:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679771791; cv=none; d=google.com; s=arc-20160816; b=zgmGkOHkzTYX120VvQNxRtEbybyTH03CF4Zn77o5g7vKXpu9B4tdqBJvkgCiyalfjN cM1SRXxJRFQ+BgAMTL4gpqrl6mNIAknIF0EFBRqtak+uyoszk1q2VSMOq5w7T2v7tlL7 7p2XYpqKwOlyQKEAYcF7N65M+ifc1xn5LrmkX7QKAhG9SVBt7+UYe6O7erymjrFhRBLb GhtghZrbcOHgPDBE2sJFcl9c9QZCr0SP+N7bgQkMhgPA0SUjYwqZWOI6viqFqgjtDbsc XkppI/fin/qlL5haeOfvgQP52GytjY3H2yhRXuqvJXjuvTcHUfWKBcEsm8Eo9ynA9tVp eJCQ== 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:delivered-to; bh=IlQSmfSzisBHd14zgVdkw420FKq9gKgvbscGY2ZW+c0=; b=aGx3tjJxOxdRIOXrMUA08+DL7TXRMYkGdcQb6PwIYnNBqM/4G9i9B86wzojZWIk6ex uu3Wnd9d91sa/eMISg9DehngmyrLdQ6TcgcdDCCtI8T+legPVY6nPIBDAMecvZvzXioE EF2B4cx65URkRfvGHNx1U5h/0h/4YenNwXggg2Yo/PbCtwgWFN+cl7Y9N9kcfEazIgTB LC77gucXkVBKMaz0Bm1KWRNJdO3IxUzt0nB3CtdIoIq9LKkl8E99PpJBmN6FQeygNHz0 9mFcjMBxLVq39zOqZ13OunLa6Vs7xg/HxrYEpVsPe8U7XtF3zN68DKQ7MzG+mZNEhlFs 3TJQ== 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id k16-20020a05640212d000b004acb7e10eb1si8353462edx.238.2023.03.25.12.16.31; Sat, 25 Mar 2023 12:16:31 -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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 4F03868C915; Sat, 25 Mar 2023 21:16:11 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail0.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id BEA1A68C810 for ; Sat, 25 Mar 2023 21:16:02 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id 7D2D82404F8 for ; Sat, 25 Mar 2023 20:16:02 +0100 (CET) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id cVH5F1SBbGFU for ; Sat, 25 Mar 2023 20:16:00 +0100 (CET) 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 mail0.khirnov.net (Postfix) with ESMTPS id D8D2C2404EE for ; Sat, 25 Mar 2023 20:16:00 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 6620F3A039B for ; Sat, 25 Mar 2023 20:15:54 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 25 Mar 2023 20:15:08 +0100 Message-Id: <20230325191529.10578-2-anton@khirnov.net> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230325191529.10578-1-anton@khirnov.net> References: <20230325191529.10578-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 02/23] fftools/ffmpeg: move initializing next_[pd]ts to add_input_streams() 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: JhYE2LsA16AQ They are initialized to constants, so it makes most sense to do it as soon as possible. --- fftools/ffmpeg.c | 3 --- fftools/ffmpeg_demux.c | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index aa9284ecd5..abda713ddb 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -2848,9 +2848,6 @@ static int init_input_stream(InputStream *ist, char *error, int error_len) assert_avoptions(ist->decoder_opts); } - ist->next_pts = AV_NOPTS_VALUE; - ist->next_dts = AV_NOPTS_VALUE; - return 0; } diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c index db05ddb8e9..354d3165c9 100644 --- a/fftools/ffmpeg_demux.c +++ b/fftools/ffmpeg_demux.c @@ -675,6 +675,9 @@ static void add_input_streams(const OptionsContext *o, Demuxer *d) st->discard = AVDISCARD_ALL; ist->nb_samples = 0; ist->first_dts = AV_NOPTS_VALUE; + ist->next_pts = AV_NOPTS_VALUE; + ist->next_dts = AV_NOPTS_VALUE; + ds->min_pts = INT64_MAX; ds->max_pts = INT64_MIN; From patchwork Sat Mar 25 19:15:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 40823 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7a30:b0:df:834d:2c1a with SMTP id t48csp225541pzh; Sat, 25 Mar 2023 12:16:48 -0700 (PDT) X-Google-Smtp-Source: AKy350bAY/B2FS7e84Es8A9bS0jnQTlW/3jObleMlcz6kS4wcPaLYV8WTbQGW1vIcB0dSx6/CA0s X-Received: by 2002:a17:906:4ed4:b0:878:61d8:d7c2 with SMTP id i20-20020a1709064ed400b0087861d8d7c2mr7446975ejv.39.1679771808728; Sat, 25 Mar 2023 12:16:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679771808; cv=none; d=google.com; s=arc-20160816; b=bwpDdepPGXuIAgKa5tTJRjq/VbhbFpD1Hy/qIvInpEiN6J/bbdTVMGCaeV8PHrLyyA rICTj3peEyPyiEwKcbovqlhdPob4thhl30aRylRBAt4kRMSnowvih1iMEvKho1UUSm3H gLtqWK/Jnpfp9n6jxfr3xQbh1b7IjRawCsZVIJu6pqAGxLwUvVcOUEudcYYxII0MSKAI DFmJ/QYUhqdYyUeot7/4DOaSHum0Q8k6X5FiRZ4Kbq9YgJ1nkcQRzmDZt5vzDw7mUptP T+6m2ymW6+SIuBRC/f1daoYFFQpaNz0skbPwu++ODtrDgi3e2IHkvyFS3BIeYNla/E4H U5+w== 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:delivered-to; bh=fiQrI/UMlyUH+C2ApHN3APuoNbEODjnrszYeeCbq8n4=; b=jpfj3al2jLEiNMKZX6b5kmlWYhk+oVV4dN9l3I7ccDydW8S1fPUtBHdbQ1ny1qUTbR AuSWvGIq/qFmENitSs7Ej7HK0YYU/MxXvFyT8EN/mlOUC1Eb3dib08vUnDF58m6iaoNv vvB6BY4pTfhL0+V6lF4n97KVIt29Z2/TTWOoNE5w7CGvDzwIDydGeqlnoMm9T+zQVL5t QOkqnkRgT4E5DflLZrMaSg0mKelPgyOEJ74T5eJ06yPWI45jhiv/NFeIAfmlQda4uehY t2gjvBj71KR2wY5hQd2oyQdmAiqEz+ia6JDXQAB/Qy1y1XPhGTS04Jeq4lYWZcdRlurX 7IRA== 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id h22-20020a1709062dd600b0092800a29047si21856786eji.253.2023.03.25.12.16.48; Sat, 25 Mar 2023 12:16:48 -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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 5C7C768C9B4; Sat, 25 Mar 2023 21:16:13 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail0.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 72C6068C810 for ; Sat, 25 Mar 2023 21:16:03 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id 282AB2404F5 for ; Sat, 25 Mar 2023 20:16:03 +0100 (CET) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id N5NwJgCIfoM1 for ; Sat, 25 Mar 2023 20:16:02 +0100 (CET) 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 mail0.khirnov.net (Postfix) with ESMTPS id D80112404EA for ; Sat, 25 Mar 2023 20:16:00 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 717433A03E5 for ; Sat, 25 Mar 2023 20:15:54 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 25 Mar 2023 20:15:09 +0100 Message-Id: <20230325191529.10578-3-anton@khirnov.net> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230325191529.10578-1-anton@khirnov.net> References: <20230325191529.10578-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 03/23] fftools/sync_queue: use timebase from input frames/packets 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: shc0sk/T3M/v They are always properly set now. Avoid a separate timebase-setting call, which duplicates the knowledge of the timebase being used. --- fftools/ffmpeg.c | 3 --- fftools/ffmpeg_mux.c | 3 --- fftools/sync_queue.c | 39 ++++++++++++++++++++++----------------- fftools/sync_queue.h | 6 ------ 4 files changed, 22 insertions(+), 29 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index abda713ddb..3a205a3b01 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -3194,9 +3194,6 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame) if (ost->bitexact) enc_ctx->flags |= AV_CODEC_FLAG_BITEXACT; - if (ost->sq_idx_encode >= 0) - sq_set_tb(of->sq_encode, ost->sq_idx_encode, enc_ctx->time_base); - ost->mux_timebase = enc_ctx->time_base; return 0; diff --git a/fftools/ffmpeg_mux.c b/fftools/ffmpeg_mux.c index cf58051949..1937bc2aa7 100644 --- a/fftools/ffmpeg_mux.c +++ b/fftools/ffmpeg_mux.c @@ -586,9 +586,6 @@ int of_stream_init(OutputFile *of, OutputStream *ost) MuxStream *ms = ms_from_ost(ost); int ret; - if (ost->sq_idx_mux >= 0) - sq_set_tb(mux->sq_mux, ost->sq_idx_mux, ost->mux_timebase); - /* initialize bitstream filters for the output stream * needs to be done here, because the codec id for streamcopy is not * known until now */ diff --git a/fftools/sync_queue.c b/fftools/sync_queue.c index c2b23ee4f5..7c348af300 100644 --- a/fftools/sync_queue.c +++ b/fftools/sync_queue.c @@ -84,6 +84,26 @@ static int frame_null(const SyncQueue *sq, SyncQueueFrame frame) return (sq->type == SYNC_QUEUE_PACKETS) ? (frame.p == NULL) : (frame.f == NULL); } +static void tb_update(const SyncQueue *sq, SyncQueueStream *st, + const SyncQueueFrame frame) +{ + AVRational tb = (sq->type == SYNC_QUEUE_PACKETS) ? + frame.p->time_base : frame.f->time_base; + + av_assert0(tb.num > 0 && tb.den > 0); + + if (tb.num == st->tb.num && tb.den == st->tb.den) + return; + + // timebase should not change after the first frame + av_assert0(!av_fifo_can_read(st->fifo)); + + if (st->head_ts != AV_NOPTS_VALUE) + st->head_ts = av_rescale_q(st->head_ts, st->tb, tb); + + st->tb = tb; +} + static void finish_stream(SyncQueue *sq, unsigned int stream_idx) { SyncQueueStream *st = &sq->streams[stream_idx]; @@ -241,8 +261,6 @@ int sq_send(SyncQueue *sq, unsigned int stream_idx, SyncQueueFrame frame) av_assert0(stream_idx < sq->nb_streams); st = &sq->streams[stream_idx]; - av_assert0(st->tb.num > 0 && st->tb.den > 0); - if (frame_null(sq, frame)) { finish_stream(sq, stream_idx); return 0; @@ -250,6 +268,8 @@ int sq_send(SyncQueue *sq, unsigned int stream_idx, SyncQueueFrame frame) if (st->finished) return AVERROR_EOF; + tb_update(sq, st, frame); + ret = objpool_get(sq->pool, (void**)&dst); if (ret < 0) return ret; @@ -375,21 +395,6 @@ int sq_add_stream(SyncQueue *sq, int limiting) return sq->nb_streams++; } -void sq_set_tb(SyncQueue *sq, unsigned int stream_idx, AVRational tb) -{ - SyncQueueStream *st; - - av_assert0(stream_idx < sq->nb_streams); - st = &sq->streams[stream_idx]; - - av_assert0(!av_fifo_can_read(st->fifo)); - - if (st->head_ts != AV_NOPTS_VALUE) - st->head_ts = av_rescale_q(st->head_ts, st->tb, tb); - - st->tb = tb; -} - void sq_limit_frames(SyncQueue *sq, unsigned int stream_idx, uint64_t frames) { SyncQueueStream *st; diff --git a/fftools/sync_queue.h b/fftools/sync_queue.h index 3f823ff0d9..17d282c38c 100644 --- a/fftools/sync_queue.h +++ b/fftools/sync_queue.h @@ -59,12 +59,6 @@ void sq_free(SyncQueue **sq); */ int sq_add_stream(SyncQueue *sq, int limiting); -/** - * Set the timebase for the stream with index stream_idx. Should be called - * before sending any frames for this stream. - */ -void sq_set_tb(SyncQueue *sq, unsigned int stream_idx, AVRational tb); - /** * Limit the number of output frames for stream with index stream_idx * to max_frames. From patchwork Sat Mar 25 19:15:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 40820 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7a30:b0:df:834d:2c1a with SMTP id t48csp225337pzh; Sat, 25 Mar 2023 12:16:23 -0700 (PDT) X-Google-Smtp-Source: AKy350aYjaXmh1WmdLavLuX+jpJdwL0xepuMZljKNYzTSeUFXp7KgA5nvj3CIJU57Y4bY2IeE8hI X-Received: by 2002:aa7:cfce:0:b0:502:2386:d22 with SMTP id r14-20020aa7cfce000000b0050223860d22mr5230436edy.12.1679771782912; Sat, 25 Mar 2023 12:16:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679771782; cv=none; d=google.com; s=arc-20160816; b=N3EK24+gb2Db+MV7AAwKc6nrmTRyKIkoQgOaZiNWTqjaaKkJE6cdDFAckipvJSObOY czaD4nWbpQkLLACoOStcQpR8WtfHjIGLbAICkjFeddpgkH3nWs7xfS74GqtEoRpHxMdg ZdKahuPKZOw1Qj/Pm9M7KsqtR0AnZyVo/Zf7sc3pTv/t/oNlewiXCj4Sha4VO2loQxbN DmHKkJRHO+hoQRpObfVTP/d/C42rBN5Z/3CttnbWLGhzBeDh4c+DllptNReOo1UJEVi4 vqrAV7L/fwr0qTIg082YkIjYD9VzJHPAsWLpaqPEd5hS2IeLGqjS3Y/joMOri2vRUq2h T1Rw== 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:delivered-to; bh=lxyw4XfTCedPFmJ32cT/I2XBX8ccwmVpMOmw5vCibPo=; b=p9/HQk+ddXbE7qWTF4kRnm/vMjKlYfrACh6Pi2Hu/8KzURn08mJB8vVBDlCVqzcLP/ 3ZH7IcpV+Z1SpW6j7lDGnRFJZ725AenmuugzPtmTH6eTu+gAvd/pXJYOluPbAtWHUJuz ZRzTdrdmiqRZRrueIQENlUR7p2UPi31uWywG6UKFdlQ1YxMMtMHvaylTJJDBAGEmqVSV zMFgvJOfhQL4en+2ezJNVKw2amE7w/Xt/TUlgJrQqyOWk7valbij72o3EPzTIRPRN8eH WMf26fa6cj9BtSj67EGQ9e6Vsw+beXWS5zhkxFoCITpTCC4kGQjmkxFv9d6fGL0TBQlh ea5Q== 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id bc18-20020a056402205200b004ab9fed6acesi23961609edb.384.2023.03.25.12.16.22; Sat, 25 Mar 2023 12:16:22 -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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 4F85D68C976; Sat, 25 Mar 2023 21:16:10 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail0.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 7A4C668C810 for ; Sat, 25 Mar 2023 21:16:02 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id 37538240178 for ; Sat, 25 Mar 2023 20:16:02 +0100 (CET) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id cKpPRRGGjXvn for ; Sat, 25 Mar 2023 20:16:01 +0100 (CET) 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 mail0.khirnov.net (Postfix) with ESMTPS id DF2EE2404F8 for ; Sat, 25 Mar 2023 20:16:00 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 7D0BC3A0404 for ; Sat, 25 Mar 2023 20:15:54 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 25 Mar 2023 20:15:10 +0100 Message-Id: <20230325191529.10578-4-anton@khirnov.net> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230325191529.10578-1-anton@khirnov.net> References: <20230325191529.10578-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 04/23] fftools/sync_queue: document overall design 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: lbmVt1/QSa0g --- fftools/sync_queue.c | 35 +++++++++++++++++++++++++++++++++++ fftools/sync_queue.h | 5 +++++ 2 files changed, 40 insertions(+) diff --git a/fftools/sync_queue.c b/fftools/sync_queue.c index 7c348af300..0aee4ef5ff 100644 --- a/fftools/sync_queue.c +++ b/fftools/sync_queue.c @@ -28,6 +28,41 @@ #include "objpool.h" #include "sync_queue.h" +/* + * How this works: + * -------------- + * time: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 + * ------------------------------------------------------------------- + * | | | | | | | | | | | | | | + * | ┌───┐┌────────┐┌───┐┌─────────────┐ + * stream 0| │d=1││ d=2 ││d=1││ d=3 │ + * | └───┘└────────┘└───┘└─────────────┘ + * ┌───┐ ┌───────────────────────┐ + * stream 1│d=1│ │ d=5 │ + * └───┘ └───────────────────────┘ + * | ┌───┐┌───┐┌───┐┌───┐ + * stream 2| │d=1││d=1││d=1││d=1│ <- stream 2 is the head stream of the queue + * | └───┘└───┘└───┘└───┘ + * ^ ^ + * [stream 2 tail] [stream 2 head] + * + * We have N streams (N=3 in the diagram), each stream is a FIFO. The *tail* of + * each FIFO is the frame with smallest end time, the *head* is the frame with + * the largest end time. Frames submitted to the queue with sq_send() are placed + * after the head, frames returned to the caller with sq_receive() are taken + * from the tail. + * + * The head stream of the whole queue (SyncQueue.head_stream) is the limiting + * stream with the *smallest* head timestamp, i.e. the stream whose source lags + * furthest behind all other streams. It determines which frames can be output + * from the queue. + * + * In the diagram, the head stream is 2, because it head time is t=5, while + * streams 0 and 1 end at t=8 and t=9 respectively. All frames that _end_ at + * or before t=5 can be output, i.e. the first 3 frames from stream 0, first + * frame from stream 1, and all 4 frames from stream 2. + */ + typedef struct SyncQueueStream { AVFifo *fifo; AVRational tb; diff --git a/fftools/sync_queue.h b/fftools/sync_queue.h index 17d282c38c..9659ee5d50 100644 --- a/fftools/sync_queue.h +++ b/fftools/sync_queue.h @@ -38,6 +38,11 @@ typedef union SyncQueueFrame { #define SQFRAME(frame) ((SyncQueueFrame){ .f = (frame) }) #define SQPKT(pkt) ((SyncQueueFrame){ .p = (pkt) }) +/** + * A sync queue provides timestamp synchronization between multiple streams. + * Some of these streams are marked as "limiting", then the queue ensures no + * stream gets ahead of any of the limiting streams. + */ typedef struct SyncQueue SyncQueue; /** From patchwork Sat Mar 25 19:15:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 40822 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7a30:b0:df:834d:2c1a with SMTP id t48csp225495pzh; Sat, 25 Mar 2023 12:16:40 -0700 (PDT) X-Google-Smtp-Source: AKy350bcTjomTw56qaGb2+K2wQ6PZP2J19vA8ksqYMJaR9hZh22A9Pyohz164x2kDrKGtx0pxUMV X-Received: by 2002:a17:906:641:b0:8b1:77bf:3bdd with SMTP id t1-20020a170906064100b008b177bf3bddmr7112633ejb.36.1679771800184; Sat, 25 Mar 2023 12:16:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679771800; cv=none; d=google.com; s=arc-20160816; b=Vs3+WqYsDsx9dEXfeUQw65Zalc2Ht9cr4cbFSXOryvIAM6QGoGOVbD4ulwlqIBR40w EOYgtp7l9sXKXIHcfxBsuvyfo1+9kMLi85LwL8gfJPFbXHIEL5jV/2VM/MLfHABDBDSx yVZsPYM7NLi2+YRyw1w9r+6ZXOq18TuoRpsbNtIw/3Qs3ppEfe9yuj7Cd6KHYeVnisaB ICBtfS/codJ9yYwCW4aqSs8e1OrFexRxgZIoePFJoZp/MgJNr7FCRuOr/k1IvkgjkmDh 4/xjcDbIE6E2ZDshrimLhbEAu5lkbfqoMONSvvczYtPyDzSNAmnK+4MT0ZN9te1oDzzF du5A== 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:delivered-to; bh=Rig2OoYPQl8gbxOO/ps2ddFH9ETeU3bvHslA4GswpWA=; b=Qr2nLXRv1bWN/iSjzo2+q5jqA4/+vixSWtNP7KDgjeOvnFGUOaawxC9RA2mdX60oMj mQvq4ruwmLHPjQqsOCIC6b2IpVSj7MvemFc4yEo40q/gfsTBDj65brrEaRbyQ+7FOr2Q TH+AQ0TBGFY+76HhAQy+49vAu4WkyvUIZDGTF4eYuq9YYGDLazCqD+l2KZ9KPZfyNx4B uuIQ7S0oNyWiizLh0ApxdE9Bomge2t+GkomMgS7Cn4PHABpNnzlOy0i4J2XxdFFq4/na 0Upzky+p26PlLCrhAylJDeuMXPYqiqdTv/AKMiz44R/745hl1kX6dkFJVgZ6L67wYuXK LzEg== 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id c13-20020aa7c98d000000b004fd29e75157si25429337edt.343.2023.03.25.12.16.39; Sat, 25 Mar 2023 12:16:40 -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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 492B768C904; Sat, 25 Mar 2023 21:16:12 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail0.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id F3ABD68C810 for ; Sat, 25 Mar 2023 21:16:02 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id B44F12404EE for ; Sat, 25 Mar 2023 20:16:02 +0100 (CET) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id e0-iI5yg5qKR for ; Sat, 25 Mar 2023 20:16:02 +0100 (CET) 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 mail0.khirnov.net (Postfix) with ESMTPS id DDD402404F5 for ; Sat, 25 Mar 2023 20:16:00 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 87C153A042D for ; Sat, 25 Mar 2023 20:15:54 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 25 Mar 2023 20:15:11 +0100 Message-Id: <20230325191529.10578-5-anton@khirnov.net> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230325191529.10578-1-anton@khirnov.net> References: <20230325191529.10578-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 05/23] fftools/sync_queue: support operation with no limiting streams 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: WX/tjZzp9+t7 ffmpeg CLI will not create such queues currently, but this will become useful in following commits. --- fftools/sync_queue.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fftools/sync_queue.c b/fftools/sync_queue.c index 0aee4ef5ff..4204a821c1 100644 --- a/fftools/sync_queue.c +++ b/fftools/sync_queue.c @@ -96,6 +96,8 @@ struct SyncQueue { // pool of preallocated frames to avoid constant allocations ObjPool *pool; + + int have_limiting; }; static void frame_move(const SyncQueue *sq, SyncQueueFrame dst, @@ -354,8 +356,9 @@ static int receive_for_stream(SyncQueue *sq, unsigned int stream_idx, /* We can release frames that do not end after the queue head. * Frames with no timestamps are just passed through with no conditions. + * Frames are also passed through when there are no limiting streams. */ - if (cmp <= 0 || ts == AV_NOPTS_VALUE) { + if (cmp <= 0 || ts == AV_NOPTS_VALUE || !sq->have_limiting) { frame_move(sq, frame, peek); objpool_release(sq->pool, (void**)&peek); av_fifo_drain2(st->fifo, 1); @@ -427,6 +430,8 @@ int sq_add_stream(SyncQueue *sq, int limiting) st->frames_max = UINT64_MAX; st->limiting = limiting; + sq->have_limiting |= limiting; + return sq->nb_streams++; } From patchwork Sat Mar 25 19:15:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 40833 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7a30:b0:df:834d:2c1a with SMTP id t48csp226172pzh; Sat, 25 Mar 2023 12:18:17 -0700 (PDT) X-Google-Smtp-Source: AKy350YFDYXF64Jcmr/Rn67quSO3KOXbXwhZVTI46qeib+KwDw/b48zj+iQcWptt5IGfHFUL/+pd X-Received: by 2002:a17:906:7193:b0:931:7adf:547e with SMTP id h19-20020a170906719300b009317adf547emr7523016ejk.70.1679771897578; Sat, 25 Mar 2023 12:18:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679771897; cv=none; d=google.com; s=arc-20160816; b=dznk/ULuV7PRhZyp495GKpZqj0zyUvoeKqbKukj9eG44c2OP2+RMmRxldv7EXNlqtp fjbeKM7W23PEMcIl3sDUz3Dinrtp4PVZ4HcaFePge+hgr48EO1X7YIxtXXuHJ1kbGzx0 SVni0YUMGomp4bcCYPDMXwCpllpJqEWJ1MZmBVL4qrlj4A788nh7ZX5pau2PO9eRqtCV kRZ5HB7FOAtC+MtcerfieTMz0yWXmQtBQuwA6sdb5znW45S+HXEyUKujGwo4eUM98aoi 8W8sH/luJU+lxCsncBj9mhK5Uu7MpxIUxlGaDBt3WAfCGXLaGkmEZT50lJPV/dHh0ePL uxgQ== 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:delivered-to; bh=2+hvJxsfAlX23/X+u5eLQrrft6H9KuFPbzsfTBM41zM=; b=j83Il2sSBjJnfJeeHWUchY3l+C7ejFYxhuyY7jsrF5JneJzt/GPPYqSdQ3nEpJLwec dIwI8rAaAyJ7E5Fwhtg8pqB7lSCXoTI+sFHZL9Qw3LhFmIgTadDoxfmpWuBkwWA5UnJ9 jsjnULv7wm3VzliBvVriBcCYShvJk1NEXoQwlX2XwN8kxiW/AKqlZaV8az9rZnLS4M/g nVl6m8ALoqaNiTfS3GI0jsLQZiJ4W2ubTL0APQuUE7gQwhF84NUw3V0T00oFJ5Pb/o/w uHKX6+uztTq1VZn55tWPOdi4D0NqYxN5+XqTBc9pRbP8prjgMU4yMQA6k2LRnQC/uQTI wtmg== 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id t18-20020a17090616d200b0093149d8926csi21927716ejd.335.2023.03.25.12.18.17; Sat, 25 Mar 2023 12:18:17 -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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 689DB68CA1A; Sat, 25 Mar 2023 21:16:23 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail0.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 900F068C9AB for ; Sat, 25 Mar 2023 21:16:07 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id 53C702404EA for ; Sat, 25 Mar 2023 20:16:03 +0100 (CET) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id rITrd0o57OHk for ; Sat, 25 Mar 2023 20:16:02 +0100 (CET) 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 mail0.khirnov.net (Postfix) with ESMTPS id E84C3240591 for ; Sat, 25 Mar 2023 20:16:00 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 928A53A0567 for ; Sat, 25 Mar 2023 20:15:54 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 25 Mar 2023 20:15:12 +0100 Message-Id: <20230325191529.10578-6-anton@khirnov.net> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230325191529.10578-1-anton@khirnov.net> References: <20230325191529.10578-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 06/23] fftools/sync_queue: make sure audio duration matches sample count 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: 9HqsboN2FIPY For audio AVFrames, nb_samples is typically more trustworthy than duration. Since sync queues look at durations, make sure they match the sample count. The last audio frame in the fate-shortest test is now gone. This is more correct, since it outlasts the last video frame. --- fftools/sync_queue.c | 15 ++++++++++++++- tests/ref/fate/shortest | 1 - 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/fftools/sync_queue.c b/fftools/sync_queue.c index 4204a821c1..5b98253a4a 100644 --- a/fftools/sync_queue.c +++ b/fftools/sync_queue.c @@ -116,6 +116,11 @@ static int64_t frame_ts(const SyncQueue *sq, SyncQueueFrame frame) frame.f->pts + frame.f->duration; } +static int frame_samples(const SyncQueue *sq, SyncQueueFrame frame) +{ + return (sq->type == SYNC_QUEUE_PACKETS) ? 0 : frame.f->nb_samples; +} + static int frame_null(const SyncQueue *sq, SyncQueueFrame frame) { return (sq->type == SYNC_QUEUE_PACKETS) ? (frame.p == NULL) : (frame.f == NULL); @@ -293,7 +298,7 @@ int sq_send(SyncQueue *sq, unsigned int stream_idx, SyncQueueFrame frame) SyncQueueStream *st; SyncQueueFrame dst; int64_t ts; - int ret; + int ret, nb_samples; av_assert0(stream_idx < sq->nb_streams); st = &sq->streams[stream_idx]; @@ -313,6 +318,14 @@ int sq_send(SyncQueue *sq, unsigned int stream_idx, SyncQueueFrame frame) frame_move(sq, dst, frame); + nb_samples = frame_samples(sq, dst); + // make sure frame duration is consistent with sample count + if (nb_samples) { + av_assert0(dst.f->sample_rate > 0); + dst.f->duration = av_rescale_q(nb_samples, (AVRational){ 1, dst.f->sample_rate }, + dst.f->time_base); + } + ts = frame_ts(sq, dst); ret = av_fifo_write(st->fifo, &dst, 1); diff --git a/tests/ref/fate/shortest b/tests/ref/fate/shortest index be93ff0da1..b5845508cf 100644 --- a/tests/ref/fate/shortest +++ b/tests/ref/fate/shortest @@ -115,4 +115,3 @@ 0, 48, 48, 1, 11212, 0xc61a3f0a, S=1, 8 1, 85760, 85760, 1536, 418, 0xae06ca91 0, 49, 49, 1, 1423, 0x45fba9e4, F=0x0, S=1, 8 -1, 87296, 87296, 1536, 418, 0x7bdcc3c7 From patchwork Sat Mar 25 19:15:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 40826 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7a30:b0:df:834d:2c1a with SMTP id t48csp225797pzh; Sat, 25 Mar 2023 12:17:17 -0700 (PDT) X-Google-Smtp-Source: AKy350ZyaLtOZpCBg/kKXv5o2BDHwF3Tx+4+stkoeBPBOfBdaUN/v5sgA0jYHweRvLmV2U9YUZ7B X-Received: by 2002:a17:906:148d:b0:8b1:7e23:5041 with SMTP id x13-20020a170906148d00b008b17e235041mr6564581ejc.39.1679771836842; Sat, 25 Mar 2023 12:17:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679771836; cv=none; d=google.com; s=arc-20160816; b=hpu2/mQGw6ZK3XdgqwZwjIfnH74d2ZGTKJXaILMYWgIJK8HgN8DAvLGyMiEmwWbFQ8 HgOJK3hB1CIirMXD9zdx2tnRLKrhMxvyX9lDjEgK8x+06Xbp2g1ODAs8o0cxcWoMdGpI NU1zB7GG/ClOvKobYrmBVJZ/HpJXtqvtxFbmBXMZDh5qyibP44KI4vGQpCbPH33Fugan qy1Ne0HIoiuF9FSnEEqX+EZ+gsc59Ptt9JjArW7VLtLOE9vhU42yLVJvqZxeGafzGyyS 9XXrPiBQXGUxZv2I29YNzwQPxbFifidvZaMeg60oMStXgwrsbzDvs0G/Znt0+PscGqce Odzg== 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:delivered-to; bh=ZJQ8uz0NEw6vFGbv+zRgksHZTomhS1oBMrnhvf2Zp2Q=; b=VZoq9CVod3VH2L3OqCoDxnu0O2/IqbT/VtSyaAL/Tq4ypWIjAyMnaB1YIBbMVY5BLy qcocVGG5eCbItZSRihhsCHap7rwnih3kbKN1TkbqdrmIowJUb0u9N2WmD1U7qGFaTJfy R56+eefQF3AcaZYvbYtY0harBKbN0dF83QbJ2RiifMvqQiN2f5s4twyuKVBCsFyULPyy U1jj9KA3X5bWyhPEUiIozUCYK8K379SB/TEANYGVZLCOxfvF7sI8v0Q8R+fi9qBSdGNT iLK+2KZyBX+lfiofW6gstU02xTqvL7wy23QlH7OmEjKXGoOaoswfdWxueogvJ0t7E8od PIgw== 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id la21-20020a170906ad9500b009309c7f5650si2949614ejb.23.2023.03.25.12.17.16; Sat, 25 Mar 2023 12:17:16 -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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 91BFF68C9BB; Sat, 25 Mar 2023 21:16:16 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail0.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 1191068BEC9 for ; Sat, 25 Mar 2023 21:16:08 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id B5ABC2404F5 for ; Sat, 25 Mar 2023 20:16:08 +0100 (CET) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id NTbrRfUVQTIB for ; Sat, 25 Mar 2023 20:16:07 +0100 (CET) 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 mail0.khirnov.net (Postfix) with ESMTPS id 34F742406D0 for ; Sat, 25 Mar 2023 20:16:01 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 9DA373A0586 for ; Sat, 25 Mar 2023 20:15:54 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 25 Mar 2023 20:15:13 +0100 Message-Id: <20230325191529.10578-7-anton@khirnov.net> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230325191529.10578-1-anton@khirnov.net> References: <20230325191529.10578-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 07/23] fftools/sync_queue: allow requesting a specific number of audio samples 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: dHSZSQfKb9oT This will be made useful in following commits. --- fftools/sync_queue.c | 164 ++++++++++++++++++++++++++++++++++++++++--- fftools/sync_queue.h | 10 +++ 2 files changed, 165 insertions(+), 9 deletions(-) diff --git a/fftools/sync_queue.c b/fftools/sync_queue.c index 5b98253a4a..758357940f 100644 --- a/fftools/sync_queue.c +++ b/fftools/sync_queue.c @@ -20,10 +20,13 @@ #include #include "libavutil/avassert.h" +#include "libavutil/channel_layout.h" +#include "libavutil/cpu.h" #include "libavutil/error.h" #include "libavutil/fifo.h" #include "libavutil/mathematics.h" #include "libavutil/mem.h" +#include "libavutil/samplefmt.h" #include "objpool.h" #include "sync_queue.h" @@ -67,6 +70,8 @@ typedef struct SyncQueueStream { AVFifo *fifo; AVRational tb; + /* number of audio samples in fifo */ + uint64_t samples_queued; /* stream head: largest timestamp seen */ int64_t head_ts; int limiting; @@ -74,7 +79,9 @@ typedef struct SyncQueueStream { int finished; uint64_t frames_sent; + uint64_t samples_sent; uint64_t frames_max; + int frame_samples; } SyncQueueStream; struct SyncQueue { @@ -109,8 +116,18 @@ static void frame_move(const SyncQueue *sq, SyncQueueFrame dst, av_frame_move_ref(dst.f, src.f); } -static int64_t frame_ts(const SyncQueue *sq, SyncQueueFrame frame) +/** + * Compute the end timestamp of a frame. If nb_samples is provided, consider + * the frame to have this number of audio samples, otherwise use frame duration. + */ +static int64_t frame_end(const SyncQueue *sq, SyncQueueFrame frame, int nb_samples) { + if (nb_samples) { + int64_t d = av_rescale_q(nb_samples, (AVRational){ 1, frame.f->sample_rate}, + frame.f->time_base); + return frame.f->pts + d; + } + return (sq->type == SYNC_QUEUE_PACKETS) ? frame.p->pts + frame.p->duration : frame.f->pts + frame.f->duration; @@ -265,7 +282,7 @@ static int overflow_heartbeat(SyncQueue *sq, int stream_idx) /* get the chosen stream's tail timestamp */ for (size_t i = 0; tail_ts == AV_NOPTS_VALUE && av_fifo_peek(st->fifo, &frame, 1, i) >= 0; i++) - tail_ts = frame_ts(sq, frame); + tail_ts = frame_end(sq, frame, 0); /* overflow triggers when the tail is over specified duration behind the head */ if (tail_ts == AV_NOPTS_VALUE || tail_ts >= st->head_ts || @@ -326,7 +343,7 @@ int sq_send(SyncQueue *sq, unsigned int stream_idx, SyncQueueFrame frame) dst.f->time_base); } - ts = frame_ts(sq, dst); + ts = frame_end(sq, dst, 0); ret = av_fifo_write(st->fifo, &dst, 1); if (ret < 0) { @@ -337,13 +354,116 @@ int sq_send(SyncQueue *sq, unsigned int stream_idx, SyncQueueFrame frame) stream_update_ts(sq, stream_idx, ts); - st->frames_sent++; + st->samples_queued += nb_samples; + st->samples_sent += nb_samples; + + if (st->frame_samples) + st->frames_sent = st->samples_sent / st->frame_samples; + else + st->frames_sent++; + if (st->frames_sent >= st->frames_max) finish_stream(sq, stream_idx); return 0; } +static void offset_audio(AVFrame *f, int nb_samples) +{ + const int planar = av_sample_fmt_is_planar(f->format); + const int planes = planar ? f->ch_layout.nb_channels : 1; + const int bps = av_get_bytes_per_sample(f->format); + const int offset = nb_samples * bps * (planar ? 1 : f->ch_layout.nb_channels); + + av_assert0(bps > 0); + av_assert0(nb_samples < f->nb_samples); + + for (int i = 0; i < planes; i++) { + f->extended_data[i] += offset; + if (i < FF_ARRAY_ELEMS(f->data)) + f->data[i] = f->extended_data[i]; + } + f->linesize[0] -= offset; + f->nb_samples -= nb_samples; + f->duration = av_rescale_q(f->nb_samples, (AVRational){ 1, f->sample_rate }, + f->time_base); + f->pts += av_rescale_q(nb_samples, (AVRational){ 1, f->sample_rate }, + f->time_base); +} + +static int receive_samples(SyncQueue *sq, SyncQueueStream *st, + AVFrame *dst, int nb_samples) +{ + SyncQueueFrame src; + int ret; + + av_assert0(st->samples_queued >= nb_samples); + + ret = av_fifo_peek(st->fifo, &src, 1, 0); + av_assert0(ret >= 0); + + // peeked frame has enough samples and its data is aligned + // -> we can just make a reference and limit its sample count + if (src.f->nb_samples > nb_samples && + !((uintptr_t)src.f->data[0] & (av_cpu_max_align() - 1))) { + ret = av_frame_ref(dst, src.f); + if (ret < 0) + return ret; + + dst->nb_samples = nb_samples; + offset_audio(src.f, nb_samples); + st->samples_queued -= nb_samples; + + return 0; + } + + // otherwise allocate a new frame and copy the data + ret = av_channel_layout_copy(&dst->ch_layout, &src.f->ch_layout); + if (ret < 0) + return ret; + + dst->format = src.f->format; + dst->nb_samples = nb_samples; + + ret = av_frame_get_buffer(dst, 0); + if (ret < 0) + goto fail; + + ret = av_frame_copy_props(dst, src.f); + if (ret < 0) + goto fail; + + dst->nb_samples = 0; + while (dst->nb_samples < nb_samples) { + int to_copy; + + ret = av_fifo_peek(st->fifo, &src, 1, 0); + av_assert0(ret >= 0); + + to_copy = FFMIN(nb_samples - dst->nb_samples, src.f->nb_samples); + + av_samples_copy(dst->extended_data, src.f->extended_data, dst->nb_samples, + 0, to_copy, dst->ch_layout.nb_channels, dst->format); + + if (to_copy < src.f->nb_samples) + offset_audio(src.f, to_copy); + else { + av_frame_unref(src.f); + objpool_release(sq->pool, (void**)&src); + av_fifo_drain2(st->fifo, 1); + } + st->samples_queued -= to_copy; + + dst->nb_samples += to_copy; + } + + return 0; + +fail: + av_frame_unref(dst); + return ret; +} + static int receive_for_stream(SyncQueue *sq, unsigned int stream_idx, SyncQueueFrame frame) { @@ -354,13 +474,18 @@ static int receive_for_stream(SyncQueue *sq, unsigned int stream_idx, av_assert0(stream_idx < sq->nb_streams); st = &sq->streams[stream_idx]; - if (av_fifo_can_read(st->fifo)) { + if (av_fifo_can_read(st->fifo) && + (st->frame_samples <= st->samples_queued || st->finished)) { + int nb_samples = st->frame_samples; SyncQueueFrame peek; int64_t ts; int cmp = 1; + if (st->finished) + nb_samples = FFMIN(nb_samples, st->samples_queued); + av_fifo_peek(st->fifo, &peek, 1, 0); - ts = frame_ts(sq, peek); + ts = frame_end(sq, peek, nb_samples); /* check if this stream's tail timestamp does not overtake * the overall queue head */ @@ -372,9 +497,18 @@ static int receive_for_stream(SyncQueue *sq, unsigned int stream_idx, * Frames are also passed through when there are no limiting streams. */ if (cmp <= 0 || ts == AV_NOPTS_VALUE || !sq->have_limiting) { - frame_move(sq, frame, peek); - objpool_release(sq->pool, (void**)&peek); - av_fifo_drain2(st->fifo, 1); + if (nb_samples && nb_samples != peek.f->nb_samples) { + int ret = receive_samples(sq, st, frame.f, nb_samples); + if (ret < 0) + return ret; + } else { + frame_move(sq, frame, peek); + objpool_release(sq->pool, (void**)&peek); + av_fifo_drain2(st->fifo, 1); + av_assert0(st->samples_queued >= frame_samples(sq, frame)); + st->samples_queued -= frame_samples(sq, frame); + } + return 0; } } @@ -460,6 +594,18 @@ void sq_limit_frames(SyncQueue *sq, unsigned int stream_idx, uint64_t frames) finish_stream(sq, stream_idx); } +void sq_frame_samples(SyncQueue *sq, unsigned int stream_idx, + int frame_samples) +{ + SyncQueueStream *st; + + av_assert0(sq->type == SYNC_QUEUE_FRAMES); + av_assert0(stream_idx < sq->nb_streams); + st = &sq->streams[stream_idx]; + + st->frame_samples = frame_samples; +} + SyncQueue *sq_alloc(enum SyncQueueType type, int64_t buf_size_us) { SyncQueue *sq = av_mallocz(sizeof(*sq)); diff --git a/fftools/sync_queue.h b/fftools/sync_queue.h index 9659ee5d50..bc7cd42390 100644 --- a/fftools/sync_queue.h +++ b/fftools/sync_queue.h @@ -71,6 +71,16 @@ int sq_add_stream(SyncQueue *sq, int limiting); void sq_limit_frames(SyncQueue *sq, unsigned int stream_idx, uint64_t max_frames); +/** + * Set a constant output audio frame size, in samples. Can only be used with + * SYNC_QUEUE_FRAMES queues and audio streams. + * + * All output frames will have exactly frame_samples audio samples, except + * possibly for the last one, which may have fewer. + */ +void sq_frame_samples(SyncQueue *sq, unsigned int stream_idx, + int frame_samples); + /** * Submit a frame for the stream with index stream_idx. * From patchwork Sat Mar 25 19:15:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 40834 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7a30:b0:df:834d:2c1a with SMTP id t48csp226226pzh; Sat, 25 Mar 2023 12:18:26 -0700 (PDT) X-Google-Smtp-Source: AKy350blyv23oR5DerxwMBBmaNtwExXNlrMv2uPkdmSYmKY7/WR6304/qNcZ7niV+fyIHrscJ8AH X-Received: by 2002:aa7:c74d:0:b0:4ac:bbaa:867a with SMTP id c13-20020aa7c74d000000b004acbbaa867amr5920064eds.24.1679771906135; Sat, 25 Mar 2023 12:18:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679771906; cv=none; d=google.com; s=arc-20160816; b=BkUQ97w1rnR1lDL2Mt+oljX7fyHUQw1MSr2qm2P95jCd/LJENeSG0xiIxuZPEW2kh5 ZHikK+p1cf+4jHs/k9ruz2dGrVACpeeSgtVdAFqkwGBDcUIOR77Vh+pjPoxiS7FxEn2u jbBTYwxdspM0aC9e5DjkLEdP88W42CpFCy3hd3GxhoR5eB3l6FNg2zU7VsN/Oi/mfJ9x spC5oNJUkuVCkhWTwldkjS84lNc4nIO9iOt73zZLR7wmYvgea9W5QQJvO4u8gP0I6D3w ppzV5O6kh5437aMRPqyuYE/5xS0fBWjGjnLznh2x/mZu8RnMhyXNoumYxbWXppF1DNxE g2Yw== 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:delivered-to; bh=QYXiBZTCGDJToYtBIliJCAgk1LG84ZZsoGNn1I61txM=; b=W5BpH6ABUEe/4Ncxq+k4eDkItXBGljClv0KrTA8QNAt6tDnPT+Pz7/LRmM8RzPdam9 7VIEy1PggSiHCItDW6JUIASWnHBzBOAzVwJevkzlmSK5sOJl31rdU51RLEemm2WbiOYP DSOTI8gk7TsjCpbV9FWDKV7XgCE8IA1SN63iwMCla1TKq8vHIrwf7zHajiKAbP41Yz5U nKZl6Qn9ZxheyEApi2twQniK0HuTJ7k0G3IW7RM+TyAtmJxZXEAuVAAYob4n1Z8ShVNu z//onxC4K1LLtjOKXxaGHFLZ91E9qJIw2r4iWu6DCKjFoNFLQvRmcOQik+jexKCA6Bkj PfGQ== 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id f2-20020a056402068200b004fd2b05171csi19202614edy.153.2023.03.25.12.18.25; Sat, 25 Mar 2023 12:18:26 -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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 7656868CA1B; Sat, 25 Mar 2023 21:16:24 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail0.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 98E0468C9AD for ; Sat, 25 Mar 2023 21:16:07 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id B2E9A240591 for ; Sat, 25 Mar 2023 20:16:03 +0100 (CET) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id gmonrBlcqi2y for ; Sat, 25 Mar 2023 20:16:03 +0100 (CET) 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 mail0.khirnov.net (Postfix) with ESMTPS id F24092405EC for ; Sat, 25 Mar 2023 20:16:00 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id BFED23A05F0 for ; Sat, 25 Mar 2023 20:15:54 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 25 Mar 2023 20:15:16 +0100 Message-Id: <20230325191529.10578-10-anton@khirnov.net> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230325191529.10578-1-anton@khirnov.net> References: <20230325191529.10578-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 10/23] fftools/ffmpeg: drop unnecessarily indirection 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: MT+QqFRmcZ9t init_output_stream() can print log messages directly, there is no need to ship them to the caller. --- fftools/ffmpeg.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index a424c69725..77c41c7cc9 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -724,23 +724,18 @@ early_exit: return float_pts; } -static int init_output_stream(OutputStream *ost, AVFrame *frame, - char *error, int error_len); +static int init_output_stream(OutputStream *ost, AVFrame *frame); static int init_output_stream_wrapper(OutputStream *ost, AVFrame *frame, unsigned int fatal) { int ret = AVERROR_BUG; - char error[1024] = {0}; if (ost->initialized) return 0; - ret = init_output_stream(ost, frame, error, sizeof(error)); + ret = init_output_stream(ost, frame); if (ret < 0) { - av_log(ost, AV_LOG_ERROR, "Error initializing output stream: %s\n", - error); - if (fatal) exit_program(1); } @@ -3188,8 +3183,7 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame) return 0; } -static int init_output_stream(OutputStream *ost, AVFrame *frame, - char *error, int error_len) +static int init_output_stream(OutputStream *ost, AVFrame *frame) { int ret = 0; @@ -3212,19 +3206,16 @@ static int init_output_stream(OutputStream *ost, AVFrame *frame, ret = hw_device_setup_for_encode(ost); if (ret < 0) { - snprintf(error, error_len, "Device setup failed for " - "encoder on output stream #%d:%d : %s", - ost->file_index, ost->index, av_err2str(ret)); + av_log(ost, AV_LOG_ERROR, + "Encoding hardware device setup failed: %s\n", av_err2str(ret)); return ret; } if ((ret = avcodec_open2(ost->enc_ctx, codec, &ost->encoder_opts)) < 0) { if (ret == AVERROR_EXPERIMENTAL) abort_codec_experimental(codec, 1); - snprintf(error, error_len, - "Error while opening encoder for output stream #%d:%d - " - "maybe incorrect parameters such as bit_rate, rate, width or height", - ost->file_index, ost->index); + av_log(ost, AV_LOG_ERROR, "Error while opening encoder - maybe " + "incorrect parameters such as bit_rate, rate, width or height.\n"); return ret; } From patchwork Sat Mar 25 19:15:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 40832 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7a30:b0:df:834d:2c1a with SMTP id t48csp226122pzh; Sat, 25 Mar 2023 12:18:08 -0700 (PDT) X-Google-Smtp-Source: AKy350bXYbD6VosYetELU9eIU9DabvTdoGVRf5OjUzTODGMeKwuQCTiTL2UsNNNqGyGEti63LJ10 X-Received: by 2002:aa7:d815:0:b0:4fd:2533:f56 with SMTP id v21-20020aa7d815000000b004fd25330f56mr6408093edq.39.1679771888639; Sat, 25 Mar 2023 12:18:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679771888; cv=none; d=google.com; s=arc-20160816; b=mbE2z9E6yRI2iDC+qkVeX7wh8+93BYRzYTyhEOIYR7Hc/FRjUAa7Nmj99N9dYoTO5e mmBa5UZFKbWJAzbTx5+QLMzXVQ6ZwGJW9dei/8Hr4cnX3oSMCfkyPIam4patChlwaS2R d+WSail/uTOdPGyTbbKGqyNLcvmeEO+h6vncrFG7E1BTmRkACuE8huW5ajFe2OqmA9m1 0Ivv7JOVfqjULZAY7FF9OEZTzwIq6/nElzH3ffGNvTRDF3GQ8ZNBbBjD0JDTlNvTOOxk 4S0w0gyEPtl1ELWgtoeUZnQzX3J0ESnoXh40A+5q3JbzCCQvXX9P3dhIsOcDH1aFltn3 eJFg== 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:delivered-to; bh=0pNESJb5gn2AglH3Lx11+TG9Q2INc/UdQQt7RuKQ52Q=; b=ezgtaW1FSzjd6rbyW0RfRy6/y2jFw7O3mpxNB0izITjIyYmwDMKc9dzPP2eObcF79x FxPi+hkBL3IZesD60RXoio0+hMZDDFdGZPs39deAqY5TfqvxYx3XF4bq7L+1rwTkcIBE 99/RFqo6k88qSul/akAISHy8tNmnXI5C1UiF+tc+wj5G+CWDFsJGc76deWQlKhrQ0DNj h2esryZQ0mOu8C29li2VbXl9P70S2wo2t71MtrMiveSWJNxNska7kRDQtryIriZoGAY7 hOxahaV9L6kYny2/NXezg6KYWWIjKVevYknqxekfK+DMRmFTn2naf7owkUK6R9eRVqcr u+Mw== 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id r9-20020aa7d589000000b004fd23c65267si25699891edq.569.2023.03.25.12.18.08; Sat, 25 Mar 2023 12:18:08 -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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 60C4768CA10; Sat, 25 Mar 2023 21:16:22 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail0.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 3438E68C990 for ; Sat, 25 Mar 2023 21:16:12 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id F28042404F5 for ; Sat, 25 Mar 2023 20:16:11 +0100 (CET) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id EqdRzXQ8aG0N for ; Sat, 25 Mar 2023 20:16:11 +0100 (CET) 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 mail0.khirnov.net (Postfix) with ESMTPS id 4013C240706 for ; Sat, 25 Mar 2023 20:16:01 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id CB6BB3A0616 for ; Sat, 25 Mar 2023 20:15:54 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 25 Mar 2023 20:15:17 +0100 Message-Id: <20230325191529.10578-11-anton@khirnov.net> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230325191529.10578-1-anton@khirnov.net> References: <20230325191529.10578-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 11/23] fftools/ffmpeg: use stack variables to shorten code 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: KEIf1d2h5NfA --- fftools/ffmpeg.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 77c41c7cc9..7b7db03bde 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -3018,6 +3018,7 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame) InputStream *ist = ost->ist; AVCodecContext *enc_ctx = ost->enc_ctx; AVCodecContext *dec_ctx = NULL; + const AVCodec *enc = enc_ctx->codec; OutputFile *of = output_files[ost->file_index]; int ret; @@ -3044,9 +3045,9 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame) !ost->frame_rate.den)) ost->frame_rate = ost->max_frame_rate; - if (enc_ctx->codec->supported_framerates && !ost->force_fps) { - int idx = av_find_nearest_q_idx(ost->frame_rate, enc_ctx->codec->supported_framerates); - ost->frame_rate = enc_ctx->codec->supported_framerates[idx]; + if (enc->supported_framerates && !ost->force_fps) { + int idx = av_find_nearest_q_idx(ost->frame_rate, enc->supported_framerates); + ost->frame_rate = enc->supported_framerates[idx]; } // reduce frame rate for mpeg4 to be within the spec limits if (enc_ctx->codec_id == AV_CODEC_ID_MPEG4) { @@ -3119,7 +3120,7 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame) frame->top_field_first = !!ost->top_field_first; if (frame->interlaced_frame) { - if (enc_ctx->codec->id == AV_CODEC_ID_MJPEG) + if (enc->id == AV_CODEC_ID_MJPEG) enc_ctx->field_order = frame->top_field_first ? AV_FIELD_TT:AV_FIELD_BB; else enc_ctx->field_order = frame->top_field_first ? AV_FIELD_TB:AV_FIELD_BT; @@ -3143,12 +3144,12 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame) } if (dec_ctx && dec_ctx->subtitle_header) { /* ASS code assumes this buffer is null terminated so add extra byte. */ - ost->enc_ctx->subtitle_header = av_mallocz(dec_ctx->subtitle_header_size + 1); - if (!ost->enc_ctx->subtitle_header) + enc_ctx->subtitle_header = av_mallocz(dec_ctx->subtitle_header_size + 1); + if (!enc_ctx->subtitle_header) return AVERROR(ENOMEM); - memcpy(ost->enc_ctx->subtitle_header, dec_ctx->subtitle_header, + memcpy(enc_ctx->subtitle_header, dec_ctx->subtitle_header, dec_ctx->subtitle_header_size); - ost->enc_ctx->subtitle_header_size = dec_ctx->subtitle_header_size; + enc_ctx->subtitle_header_size = dec_ctx->subtitle_header_size; } if (ist && ist->dec->type == AVMEDIA_TYPE_SUBTITLE && enc_ctx->codec_type == AVMEDIA_TYPE_SUBTITLE) { @@ -3156,7 +3157,7 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame) AVCodecDescriptor const *input_descriptor = avcodec_descriptor_get(ist->dec->id); AVCodecDescriptor const *output_descriptor = - avcodec_descriptor_get(ost->enc_ctx->codec_id); + avcodec_descriptor_get(enc_ctx->codec_id); if (input_descriptor) input_props = input_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB); if (output_descriptor) From patchwork Sat Mar 25 19:15:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 40835 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7a30:b0:df:834d:2c1a with SMTP id t48csp226288pzh; Sat, 25 Mar 2023 12:18:34 -0700 (PDT) X-Google-Smtp-Source: AKy350ZzFSt39ZhDM0H2Xg5B+0/VGlXUKjOrCicXmNhJIHs88s10vlummUkUeuBCQzMdAxX8bOr0 X-Received: by 2002:a05:6402:1012:b0:4fb:7ccf:3b33 with SMTP id c18-20020a056402101200b004fb7ccf3b33mr6813814edu.31.1679771914694; Sat, 25 Mar 2023 12:18:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679771914; cv=none; d=google.com; s=arc-20160816; b=KQ/tqaahvEOMkugy9GN8JqDVsBxhf90J8/Ofl7U+9n7EFvPD/VdK5kdgZ3Co9TWLWG jg3AeIa5YqoQBJfu2Npxkm7xieH2umLSWUgHs5XigZf+uUyegp9DEFaKZ0DUs61O+ZUV CS9DOcKen0ogm5P1Cl/SfFIaFPhDgkw3ZJRhAHLCt3GbALh3OVy9/mMOYZ3zP339r4ya d49m+ct/kuMZk2aWbHdGw3THhlsbpMkARqzqfE4Csf4O3lVeJpG8CiW5kKuEFK2vkClr eH5ehMBktXI9guq+UxVhfnPGNTdSqqwXBN5z/+bXCt+yl1Qe4LTzqX1WdiN042JYqxIU fBTw== 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:delivered-to; bh=796wIF7vnCnna3dlv+IYrEC+mcUzqB4mD6tBQ6how6E=; b=QOzjH7Tjg8Ac5REwc6ZpFppUQnnCVq3tkSXNuRpfJPX+0HCbsF7kkR5znkqWmJfSYx b2c+i4dSWp5oexcNFvujtcJJgoI5RYNQ3RqfKT1mJT7O5Gn9pHGSdLNQOUYwFULddJ3g wrO1D5DvTC4q2rx5j2y9yZLSeMkolmrJ0iBs8EoK+WLB3W0oGagUkDLcU8mQYPS/JSD/ S9N55FukBIDLwjMYwP2xxeDrZulH9qKUa+ST9Fc/UFoeNCvMfGund8V21PmdtBrWcPnD T5ezVVYnDkxMQFIVvU2QSbgoK3ri6EIp84u4+yC84a0CsZtLnQMvMFryBlaY1Lbrr9Wf 6q2A== 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id f9-20020a50ee89000000b004ced100b0b7si10330816edr.316.2023.03.25.12.18.34; Sat, 25 Mar 2023 12:18:34 -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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 90FA468CA26; Sat, 25 Mar 2023 21:16:25 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail0.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id B566C68C9AB for ; Sat, 25 Mar 2023 21:16:07 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id E416D2405EC for ; Sat, 25 Mar 2023 20:16:03 +0100 (CET) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id b9dbTvlvVkL3 for ; Sat, 25 Mar 2023 20:16:03 +0100 (CET) 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 mail0.khirnov.net (Postfix) with ESMTPS id 062202405F9 for ; Sat, 25 Mar 2023 20:16:01 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id D72A03A0664 for ; Sat, 25 Mar 2023 20:15:54 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 25 Mar 2023 20:15:18 +0100 Message-Id: <20230325191529.10578-12-anton@khirnov.net> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230325191529.10578-1-anton@khirnov.net> References: <20230325191529.10578-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 12/23] fftools/ffmpeg: move encoder initialization to init_output_stream_encode 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: nSVFxSeC/EfT Encoder initialization is currently split rather arbitrarily between init_output_stream_encode() and init_output_stream(). Move all of it to init_output_stream_encode(). --- fftools/ffmpeg.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 7b7db03bde..9ae3d3891f 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -3179,27 +3179,10 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame) if (ost->bitexact) enc_ctx->flags |= AV_CODEC_FLAG_BITEXACT; - ost->mux_timebase = enc_ctx->time_base; - - return 0; -} - -static int init_output_stream(OutputStream *ost, AVFrame *frame) -{ - int ret = 0; - - if (ost->enc_ctx) { - const AVCodec *codec = ost->enc_ctx->codec; - InputStream *ist = ost->ist; - - ret = init_output_stream_encode(ost, frame); - if (ret < 0) - return ret; - if (!av_dict_get(ost->encoder_opts, "threads", NULL, 0)) av_dict_set(&ost->encoder_opts, "threads", "auto", 0); - if (codec->capabilities & AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE) { + if (enc->capabilities & AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE) { ret = av_dict_set(&ost->encoder_opts, "flags", "+copy_opaque", AV_DICT_MULTIKEY); if (ret < 0) return ret; @@ -3212,9 +3195,9 @@ static int init_output_stream(OutputStream *ost, AVFrame *frame) return ret; } - if ((ret = avcodec_open2(ost->enc_ctx, codec, &ost->encoder_opts)) < 0) { + if ((ret = avcodec_open2(ost->enc_ctx, enc, &ost->encoder_opts)) < 0) { if (ret == AVERROR_EXPERIMENTAL) - abort_codec_experimental(codec, 1); + abort_codec_experimental(enc, 1); av_log(ost, AV_LOG_ERROR, "Error while opening encoder - maybe " "incorrect parameters such as bit_rate, rate, width or height.\n"); return ret; @@ -3282,6 +3265,20 @@ static int init_output_stream(OutputStream *ost, AVFrame *frame) // copy estimated duration as a hint to the muxer if (ost->st->duration <= 0 && ist && ist->st->duration > 0) ost->st->duration = av_rescale_q(ist->st->duration, ist->st->time_base, ost->st->time_base); + + ost->mux_timebase = enc_ctx->time_base; + + return 0; +} + +static int init_output_stream(OutputStream *ost, AVFrame *frame) +{ + int ret = 0; + + if (ost->enc_ctx) { + ret = init_output_stream_encode(ost, frame); + if (ret < 0) + return ret; } else if (ost->ist) { ret = init_output_stream_streamcopy(ost); if (ret < 0) From patchwork Sat Mar 25 19:15:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 40828 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7a30:b0:df:834d:2c1a with SMTP id t48csp225914pzh; Sat, 25 Mar 2023 12:17:34 -0700 (PDT) X-Google-Smtp-Source: AKy350ZsGSRM/riQchptMVCW9wDK91Ozkep/BqUEpiKWzAJVS2HYqHnLIsYRcAE6SzkGVyDD9m1J X-Received: by 2002:a17:906:7f1a:b0:8b1:29ed:e206 with SMTP id d26-20020a1709067f1a00b008b129ede206mr5979644ejr.28.1679771854700; Sat, 25 Mar 2023 12:17:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679771854; cv=none; d=google.com; s=arc-20160816; b=qq/gBHsir1d9IQ9aYmICgj8uITdEqBK3VbilQhYFQ1R+JwnCDq7HIFLV3oR2xDNKHu mWunLph2b3Aai9mQAaWB7HAMxRyjYpkPwEJEAmNqxmKDhSyttYZFXBZ8DHs+dJyMaMaq k8+JUP0NXkjhGw6bQVfqwiHOxojeNl6TxtO9bJLX+zuQ93n+PMOOW7hVSnA2pkK9GIdc TwCUIn8OlW3cuT8vIrRUKC6wRC7loaKnA/IcUXtO4Ll8NX3eLrEc75+CcmIG/qe4xWiM slwSRyk/K4yiYmtkdC8RUzp+Ka4paVoftkg+de4yX0l/5yEgpTfexxzBD1Pz33i7YQOE FIbQ== 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:delivered-to; bh=vaIHfa+Z7RLjVGX4uZFksXVThZrcdvB3TILvO6VRwC8=; b=LxxjpovLtF6HCIIi0Ou0wR2EpC4RBiC2wnxox7pL/zPVUIcHT41FCVW64qKX83f24A iLuGt9kGM/OtwCVK0SU1DV7bQVKDg4b3KJXa3RgBR7eDfGICyJ/wnFKzwUrADZmrpYVf WN8SSDvnWvpwZMf7QHb+FQw0hB5xY1Mcfjg0/kBBhBeMvil8ajHcxGqTSbV47fMI5PdW oeycwRn9XaUa7IuiH6MUvT1zeomQqPVoY22eivmM8zJ96xOZKUfRL6CqZVI623LAMbT7 iy0Qf3nOmi/+bD/Wv0K80+J/Hyqltc0j4tRWoB9CJTwZpz/cPiy2ahMergtnEGr3HMsV TwEQ== 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id i15-20020a1709061ccf00b0092b97d144d0si25227629ejh.157.2023.03.25.12.17.34; Sat, 25 Mar 2023 12:17:34 -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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 8F9EA68C9AE; Sat, 25 Mar 2023 21:16:18 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail0.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 5FD0A68C97B for ; Sat, 25 Mar 2023 21:16:10 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id 130642404EE for ; Sat, 25 Mar 2023 20:16:10 +0100 (CET) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id GQAhmzpWI8_f for ; Sat, 25 Mar 2023 20:16:08 +0100 (CET) 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 mail0.khirnov.net (Postfix) with ESMTPS id 3BD1B240705 for ; Sat, 25 Mar 2023 20:16:01 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id E2DB23A0676 for ; Sat, 25 Mar 2023 20:15:54 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 25 Mar 2023 20:15:19 +0100 Message-Id: <20230325191529.10578-13-anton@khirnov.net> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230325191529.10578-1-anton@khirnov.net> References: <20230325191529.10578-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 13/23] fftools/ffmpeg: reindent after previous commit 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: HDC0HbaiQ/Yp --- fftools/ffmpeg.c | 142 +++++++++++++++++++++++------------------------ 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 9ae3d3891f..5bfe465e97 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -3179,92 +3179,92 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame) if (ost->bitexact) enc_ctx->flags |= AV_CODEC_FLAG_BITEXACT; - if (!av_dict_get(ost->encoder_opts, "threads", NULL, 0)) - av_dict_set(&ost->encoder_opts, "threads", "auto", 0); + if (!av_dict_get(ost->encoder_opts, "threads", NULL, 0)) + av_dict_set(&ost->encoder_opts, "threads", "auto", 0); - if (enc->capabilities & AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE) { - ret = av_dict_set(&ost->encoder_opts, "flags", "+copy_opaque", AV_DICT_MULTIKEY); - if (ret < 0) - return ret; - } - - ret = hw_device_setup_for_encode(ost); - if (ret < 0) { - av_log(ost, AV_LOG_ERROR, - "Encoding hardware device setup failed: %s\n", av_err2str(ret)); + if (enc->capabilities & AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE) { + ret = av_dict_set(&ost->encoder_opts, "flags", "+copy_opaque", AV_DICT_MULTIKEY); + if (ret < 0) return ret; - } + } - if ((ret = avcodec_open2(ost->enc_ctx, enc, &ost->encoder_opts)) < 0) { - if (ret == AVERROR_EXPERIMENTAL) - abort_codec_experimental(enc, 1); - av_log(ost, AV_LOG_ERROR, "Error while opening encoder - maybe " - "incorrect parameters such as bit_rate, rate, width or height.\n"); - return ret; - } + ret = hw_device_setup_for_encode(ost); + if (ret < 0) { + av_log(ost, AV_LOG_ERROR, + "Encoding hardware device setup failed: %s\n", av_err2str(ret)); + return ret; + } - if (ost->enc_ctx->frame_size) { - av_assert0(ost->sq_idx_encode >= 0); - sq_frame_samples(output_files[ost->file_index]->sq_encode, - ost->sq_idx_encode, ost->enc_ctx->frame_size); - } + if ((ret = avcodec_open2(ost->enc_ctx, enc, &ost->encoder_opts)) < 0) { + if (ret == AVERROR_EXPERIMENTAL) + abort_codec_experimental(enc, 1); + av_log(ost, AV_LOG_ERROR, "Error while opening encoder - maybe " + "incorrect parameters such as bit_rate, rate, width or height.\n"); + return ret; + } - assert_avoptions(ost->encoder_opts); - if (ost->enc_ctx->bit_rate && ost->enc_ctx->bit_rate < 1000 && - ost->enc_ctx->codec_id != AV_CODEC_ID_CODEC2 /* don't complain about 700 bit/s modes */) - av_log(ost, AV_LOG_WARNING, "The bitrate parameter is set too low." - " It takes bits/s as argument, not kbits/s\n"); + if (ost->enc_ctx->frame_size) { + av_assert0(ost->sq_idx_encode >= 0); + sq_frame_samples(output_files[ost->file_index]->sq_encode, + ost->sq_idx_encode, ost->enc_ctx->frame_size); + } - ret = avcodec_parameters_from_context(ost->st->codecpar, ost->enc_ctx); - if (ret < 0) { - av_log(ost, AV_LOG_FATAL, - "Error initializing the output stream codec context.\n"); - exit_program(1); - } + assert_avoptions(ost->encoder_opts); + if (ost->enc_ctx->bit_rate && ost->enc_ctx->bit_rate < 1000 && + ost->enc_ctx->codec_id != AV_CODEC_ID_CODEC2 /* don't complain about 700 bit/s modes */) + av_log(ost, AV_LOG_WARNING, "The bitrate parameter is set too low." + " It takes bits/s as argument, not kbits/s\n"); - if (ost->enc_ctx->nb_coded_side_data) { - int i; + ret = avcodec_parameters_from_context(ost->st->codecpar, ost->enc_ctx); + if (ret < 0) { + av_log(ost, AV_LOG_FATAL, + "Error initializing the output stream codec context.\n"); + exit_program(1); + } - for (i = 0; i < ost->enc_ctx->nb_coded_side_data; i++) { - const AVPacketSideData *sd_src = &ost->enc_ctx->coded_side_data[i]; - uint8_t *dst_data; + if (ost->enc_ctx->nb_coded_side_data) { + int i; - dst_data = av_stream_new_side_data(ost->st, sd_src->type, sd_src->size); - if (!dst_data) - return AVERROR(ENOMEM); - memcpy(dst_data, sd_src->data, sd_src->size); - } + for (i = 0; i < ost->enc_ctx->nb_coded_side_data; i++) { + const AVPacketSideData *sd_src = &ost->enc_ctx->coded_side_data[i]; + uint8_t *dst_data; + + dst_data = av_stream_new_side_data(ost->st, sd_src->type, sd_src->size); + if (!dst_data) + return AVERROR(ENOMEM); + memcpy(dst_data, sd_src->data, sd_src->size); } + } - /* - * Add global input side data. For now this is naive, and copies it - * from the input stream's global side data. All side data should - * really be funneled over AVFrame and libavfilter, then added back to - * packet side data, and then potentially using the first packet for - * global side data. - */ - if (ist) { - int i; - for (i = 0; i < ist->st->nb_side_data; i++) { - AVPacketSideData *sd = &ist->st->side_data[i]; - if (sd->type != AV_PKT_DATA_CPB_PROPERTIES) { - uint8_t *dst = av_stream_new_side_data(ost->st, sd->type, sd->size); - if (!dst) - return AVERROR(ENOMEM); - memcpy(dst, sd->data, sd->size); - if (ist->autorotate && sd->type == AV_PKT_DATA_DISPLAYMATRIX) - av_display_rotation_set((int32_t *)dst, 0); - } + /* + * Add global input side data. For now this is naive, and copies it + * from the input stream's global side data. All side data should + * really be funneled over AVFrame and libavfilter, then added back to + * packet side data, and then potentially using the first packet for + * global side data. + */ + if (ist) { + int i; + for (i = 0; i < ist->st->nb_side_data; i++) { + AVPacketSideData *sd = &ist->st->side_data[i]; + if (sd->type != AV_PKT_DATA_CPB_PROPERTIES) { + uint8_t *dst = av_stream_new_side_data(ost->st, sd->type, sd->size); + if (!dst) + return AVERROR(ENOMEM); + memcpy(dst, sd->data, sd->size); + if (ist->autorotate && sd->type == AV_PKT_DATA_DISPLAYMATRIX) + av_display_rotation_set((int32_t *)dst, 0); } } + } - // copy timebase while removing common factors - if (ost->st->time_base.num <= 0 || ost->st->time_base.den <= 0) - ost->st->time_base = av_add_q(ost->enc_ctx->time_base, (AVRational){0, 1}); + // copy timebase while removing common factors + if (ost->st->time_base.num <= 0 || ost->st->time_base.den <= 0) + ost->st->time_base = av_add_q(ost->enc_ctx->time_base, (AVRational){0, 1}); - // copy estimated duration as a hint to the muxer - if (ost->st->duration <= 0 && ist && ist->st->duration > 0) - ost->st->duration = av_rescale_q(ist->st->duration, ist->st->time_base, ost->st->time_base); + // copy estimated duration as a hint to the muxer + if (ost->st->duration <= 0 && ist && ist->st->duration > 0) + ost->st->duration = av_rescale_q(ist->st->duration, ist->st->time_base, ost->st->time_base); ost->mux_timebase = enc_ctx->time_base; From patchwork Sat Mar 25 19:15:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 40830 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7a30:b0:df:834d:2c1a with SMTP id t48csp225997pzh; Sat, 25 Mar 2023 12:17:52 -0700 (PDT) X-Google-Smtp-Source: AKy350ZMB1h1pmM+8Y5E+4vrWZEGnwqk6mRreA819iUEx2PuhIqbpiQKGJVxjJSkfpcj/957XO4B X-Received: by 2002:a17:907:9725:b0:93f:9594:d97d with SMTP id jg37-20020a170907972500b0093f9594d97dmr2244295ejc.14.1679771871765; Sat, 25 Mar 2023 12:17:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679771871; cv=none; d=google.com; s=arc-20160816; b=bn/9Lfpl53vQ7+rxY3D62IfZ5kADApXqI/u7uKafbbXvVGvwsvjGXszv716q7l7/gf JLpo4M+zWbeReGAmFkeGLjUTcD3E0IjryM9WaPEjeU1qD5CSwiSsZ7e0s4KT9glmRUDm od+zKacKg8lLOJMRAAwhhMt0ehI7xHrwLKpWFUDMexSfvFA57CAJojIAtbHxBTafqxmk 3wWeLuWeduDSPGaZ39VxBB3ovpKTvnKlkj8jDE2PiUawJIj/ulXoSAiPq/B9U6LxcWge TwN1nEvWElVqVkagRQAA2hrru4GxTAUPaIC5P5Vco1qw52gYcSVwTqLTtQC+39ztjRfG PluQ== 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:delivered-to; bh=FYyjtuwH4FzMAgIMEpl8E78IzIC+VPArsG3JVHq9Zpk=; b=nQRthSVsXQwv0bCRWDy0Y8N4Dq30eTTJOAgBpqUQcLIC82u0Bk4trvHJwwDVvvN9mk doa+VQecKgrdrmlPF7J/aJ7eysgrcafUJgzWTlZUU75gA6AbACy4tREhx62DrJLvvgeF H3JziVMwMD8PLrL8WF++6JqCjPxtOKmK11t3doblmLGnZ3DxWKrflkjL4l7C7Xv7wFLB R4NcZmWBfcDQsrgeRsT54P8fp9w2+lvBClzz9TsTVkAia12lXtibabTXDMpaf9BWe9qd MtJsvVH0vOf8ISTtf3OXKBTj6g2X7nFbm/aZUP7C0jjnSsk53dLKoQJLkoY7cgCdX1TH NW2A== 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id t8-20020a1709067c0800b0093129677645si10703538ejo.671.2023.03.25.12.17.51; Sat, 25 Mar 2023 12:17:51 -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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 4C12C68C9D8; Sat, 25 Mar 2023 21:16:20 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail0.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id A385268C97F for ; Sat, 25 Mar 2023 21:16:11 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id 5C00A2404EE for ; Sat, 25 Mar 2023 20:16:11 +0100 (CET) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id BkTuPfZfEToo for ; Sat, 25 Mar 2023 20:16:10 +0100 (CET) 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 mail0.khirnov.net (Postfix) with ESMTPS id 4364D240D03 for ; Sat, 25 Mar 2023 20:16:01 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 0630D3A06E4 for ; Sat, 25 Mar 2023 20:15:55 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 25 Mar 2023 20:15:21 +0100 Message-Id: <20230325191529.10578-15-anton@khirnov.net> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230325191529.10578-1-anton@khirnov.net> References: <20230325191529.10578-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 15/23] fftools/ffmpeg: simplify output stream initialization call graph 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: dpN7V/5fhFPn Several places in the code currently call init_output_stream_wrapper(), which in turn calls init_output_stream(), which then calls either enc_init() or init_output_stream_streamcopy(), followed by of_stream_init(), which tells the muxer the stream is ready for muxing. All except one of these callers are in the encoding code, which will be moved to ffmpeg_enc.c. Keeping this structure would then necessitate ffmpeg_enc.c calling back into the common code in ffmpeg.c, which would then just call ffmpeg_mux, thus making the already convoluted call chain even more so. Simplify the situation by using separate paths for filter-fed output streams (audio and video encoders) and others (subtitles, streamcopy, data, attachments). --- fftools/ffmpeg.c | 51 +++++++++++++++++--------------------------- fftools/ffmpeg_enc.c | 7 ++++++ 2 files changed, 27 insertions(+), 31 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 03e5391970..1969ce9295 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -724,25 +724,6 @@ early_exit: return float_pts; } -static int init_output_stream(OutputStream *ost, AVFrame *frame); - -static int init_output_stream_wrapper(OutputStream *ost, AVFrame *frame, - unsigned int fatal) -{ - int ret = AVERROR_BUG; - - if (ost->initialized) - return 0; - - ret = init_output_stream(ost, frame); - if (ret < 0) { - if (fatal) - exit_program(1); - } - - return ret; -} - static double psnr(double d) { return -10.0 * log10(d); @@ -1023,7 +1004,9 @@ static void do_audio_out(OutputFile *of, OutputStream *ost, AVCodecContext *enc = ost->enc_ctx; int ret; - init_output_stream_wrapper(ost, frame, 1); + ret = enc_open(ost, frame); + if (ret < 0) + exit_program(1); if (frame->pts == AV_NOPTS_VALUE) frame->pts = ost->next_pts; @@ -1264,7 +1247,9 @@ static void do_video_out(OutputFile *of, InputStream *ist = ost->ist; AVFilterContext *filter = ost->filter->filter; - init_output_stream_wrapper(ost, next_picture, 1); + ret = enc_open(ost, next_picture); + if (ret < 0) + exit_program(1); frame_rate = av_buffersink_get_frame_rate(filter); if (frame_rate.num > 0 && frame_rate.den > 0) @@ -1820,7 +1805,9 @@ static void flush_encoders(void) of_output_packet(of, ost->pkt, ost, 1); } - init_output_stream_wrapper(ost, NULL, 1); + ret = enc_open(ost, NULL); + if (ret < 0) + exit_program(1); } if (enc->codec_type != AVMEDIA_TYPE_VIDEO && enc->codec_type != AVMEDIA_TYPE_AUDIO) @@ -2967,24 +2954,26 @@ static int init_output_stream_streamcopy(OutputStream *ost) return 0; } -static int init_output_stream(OutputStream *ost, AVFrame *frame) +static int init_output_stream_nofilter(OutputStream *ost) { int ret = 0; if (ost->enc_ctx) { - ret = enc_open(ost, frame); + ret = enc_open(ost, NULL); if (ret < 0) return ret; - } else if (ost->ist) { - ret = init_output_stream_streamcopy(ost); + } else { + if (ost->ist) { + ret = init_output_stream_streamcopy(ost); + if (ret < 0) + return ret; + } + + ret = of_stream_init(output_files[ost->file_index], ost); if (ret < 0) return ret; } - ret = of_stream_init(output_files[ost->file_index], ost); - if (ret < 0) - return ret; - return ret; } @@ -3017,7 +3006,7 @@ static int transcode_init(void) ost->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)) continue; - ret = init_output_stream_wrapper(ost, NULL, 0); + ret = init_output_stream_nofilter(ost); if (ret < 0) goto dump_format; } diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c index 9db2ff5ef3..a4660051a2 100644 --- a/fftools/ffmpeg_enc.c +++ b/fftools/ffmpeg_enc.c @@ -93,6 +93,9 @@ int enc_open(OutputStream *ost, AVFrame *frame) OutputFile *of = output_files[ost->file_index]; int ret; + if (ost->initialized) + return 0; + set_encoder_id(output_files[ost->file_index], ost); if (ist) { @@ -338,5 +341,9 @@ int enc_open(OutputStream *ost, AVFrame *frame) ost->mux_timebase = enc_ctx->time_base; + ret = of_stream_init(of, ost); + if (ret < 0) + return ret; + return 0; } From patchwork Sat Mar 25 19:15:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 40827 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7a30:b0:df:834d:2c1a with SMTP id t48csp225852pzh; Sat, 25 Mar 2023 12:17:26 -0700 (PDT) X-Google-Smtp-Source: AKy350YXLOfp9SV21jye/uEN3BFwq8w+KWZxc/Oq7Nfp3ACwazqmTN5V+gpZLtxDPO24IqXsvM75 X-Received: by 2002:a05:6402:48e:b0:4ff:844a:ed4c with SMTP id k14-20020a056402048e00b004ff844aed4cmr7188285edv.0.1679771846003; Sat, 25 Mar 2023 12:17:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679771845; cv=none; d=google.com; s=arc-20160816; b=rD41BlwU9J/47LoUn70a3u6vVR1J0LPxZgmpuoA6oM0wPx7Mx7PK6hH8x1SZ2Fj17x sQk+Z4bcX/GPOe8YV/VnWZ/LS5Pvsp2HaRfd64KnnC+/+ZCfxVtgxOsl8kZaC+1qZ+U/ kPiidsY3+99pj04wM/LcsODWZOnAHTtAOxTiH0rGATV425qniN8CfUdOd2Z30QSOlJL+ yeA+jrLi79shjUClZMDtWcX5APVLBccY/ByuZst3hOzWKpN/ozX58L8vKoqekvmXVU7D ERpebeAOeB3LdpKgQIcMVfljhfr9aSOozC6eXEvUyjGpg5voQuNBHZ7bDwoEcX6yiZZB dUmg== 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:delivered-to; bh=yqbZl/qIegs8jquuo4oBgpdNfd3bQZKKcAtCGhG4R1k=; b=j18UEZV+fwulA/4MslLF2XHEsHxHJzTROQJntQeN3uQLUh1Xr+JEIn0fJgczxVAwsp y2vsLjyMtasOCVnqNwf5UvXq9Y4pIArMy44M21CStNhnj3pm4sDo9C15sls0X7rtYDYY 4aWeKsgF9FvJpfuURW2ZclYjJ0Ch3HW30tq8tT9WgMBVostJD/8610ZWl2eDNXRSgaD+ bLZ+1I7KVW9KcldhopkqoHav3mLLCf4dLTujDNVtbM4vm94fnknXXtrttdzGR0GJOaV6 zU3E82gRSNPuOtogk43o2L8f9UXSG/qHQZsQC8k2XGqbdevfqdEFdwV2DvOelHg5IOJ2 a1cg== 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id bv18-20020a170906b1d200b0092971a9d5e6si21438447ejb.966.2023.03.25.12.17.25; Sat, 25 Mar 2023 12:17:25 -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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 98CE168C9E8; Sat, 25 Mar 2023 21:16:17 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail0.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 72EFE68BEC9 for ; Sat, 25 Mar 2023 21:16:09 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id 3E2D9240178 for ; Sat, 25 Mar 2023 20:16:09 +0100 (CET) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id vArgWvyNlZuv for ; Sat, 25 Mar 2023 20:16:08 +0100 (CET) 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 mail0.khirnov.net (Postfix) with ESMTPS id 44DC0240D0E for ; Sat, 25 Mar 2023 20:16:01 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 11E1F3A06FD for ; Sat, 25 Mar 2023 20:15:55 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 25 Mar 2023 20:15:22 +0100 Message-Id: <20230325191529.10578-16-anton@khirnov.net> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230325191529.10578-1-anton@khirnov.net> References: <20230325191529.10578-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 16/23] fftools/ffmpeg: replace ff_dlog() with av_log() 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: uBOIhL5apZa9 ff_dlog() is a lavu internal macro, and av_log() at trace level is just as good here. --- fftools/ffmpeg.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 1969ce9295..0324e45afa 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -49,7 +49,6 @@ #include "libavutil/samplefmt.h" #include "libavutil/fifo.h" #include "libavutil/hwcontext.h" -#include "libavutil/internal.h" #include "libavutil/intreadwrite.h" #include "libavutil/dict.h" #include "libavutil/display.h" @@ -1202,13 +1201,14 @@ static enum AVPictureType forced_kf_apply(void *logctx, KeyframeForceCtx *kf, kf->expr_const_values[FKF_T] = pts_time; res = av_expr_eval(kf->pexpr, kf->expr_const_values, NULL); - ff_dlog(NULL, "force_key_frame: n:%f n_forced:%f prev_forced_n:%f t:%f prev_forced_t:%f -> res:%f\n", - kf->expr_const_values[FKF_N], - kf->expr_const_values[FKF_N_FORCED], - kf->expr_const_values[FKF_PREV_FORCED_N], - kf->expr_const_values[FKF_T], - kf->expr_const_values[FKF_PREV_FORCED_T], - res); + av_log(logctx, AV_LOG_TRACE, + "force_key_frame: n:%f n_forced:%f prev_forced_n:%f t:%f prev_forced_t:%f -> res:%f\n", + kf->expr_const_values[FKF_N], + kf->expr_const_values[FKF_N_FORCED], + kf->expr_const_values[FKF_PREV_FORCED_N], + kf->expr_const_values[FKF_T], + kf->expr_const_values[FKF_PREV_FORCED_T], + res); kf->expr_const_values[FKF_N] += 1; From patchwork Sat Mar 25 19:15:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 40829 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7a30:b0:df:834d:2c1a with SMTP id t48csp225963pzh; Sat, 25 Mar 2023 12:17:43 -0700 (PDT) X-Google-Smtp-Source: AKy350bnjf5riNqZw5097jaY2o7FZAokC0nVqxKI+pmHato+iB3tNTaJQVklVKQDA9hN89UFAA/R X-Received: by 2002:aa7:c94c:0:b0:4fc:eee9:417 with SMTP id h12-20020aa7c94c000000b004fceee90417mr6474872edt.18.1679771863146; Sat, 25 Mar 2023 12:17:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679771863; cv=none; d=google.com; s=arc-20160816; b=dLsx/kP8zYQO7qepPJjrVy9iUnZZx4J/pw6nHQh3gPQTQxrqVfMFw6oFWAJ99qyIrX wG5Ee9p4UHWIgIlCttdnWYZ+oU2Kd2q+6vbUqM4gtaqW0Ku/6MBfwdi/edqLe3pzFokU BFoT2vhhHacDlgoZzWOZIAzmexMTTVBbeYm/cRYLz8ToeNOrsPUxOR0ieCTQLNL3d7Yz 6HtRSL4kWBoggoWNYT6rhZoV4CNQS3cW1OgipAo/BFK3OwZ6sG/UZ+6NQucM5ulSgN++ R/HFepymvkeOjdqHRiPg4aWk7EK0B0D6si1vxe66BcqAlmc/UU3ZXa7lFuXRLuDl5FNm 6LQg== 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:delivered-to; bh=JAes3NwA3lCHW08OG8bPs1siaoPtO1/FSawAamOGXUk=; b=xIu+pHrnWxtKEBrn30/QvWBwhYRX769QR/jZtB70kPzsl34XNk02fgzwpwCKXdz0lZ CiTdiD69ZM85et6GLTnF6OGL0vBXTO+Are70k7h3w1MAttccKEKW3220AuR+154SwDM6 SN0Pg/hiLAsntT3kmlzSyUiPlrMqHEl0FGTtYkBzdc4FZ13bxFbtsYE52VBKTACcY9id iJM7GKL2u4eV7KIHsNZditIAfzJj3D+78GSb8i/CCymc3xe4D6N+cI5PzNGRG+k4SA00 xHE75kuDo+SHaTQfdjIzNXPT8If/KsJj55fTZxDJgoWDaDYvs1mN1GSbjqARttvAjUpQ 9zew== 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id j8-20020a50ed08000000b0050230e4b487si1881466eds.13.2023.03.25.12.17.42; Sat, 25 Mar 2023 12:17:43 -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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 7401E68C9A3; Sat, 25 Mar 2023 21:16:19 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail0.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id D8FB668C810 for ; Sat, 25 Mar 2023 21:16:10 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id 9EB1D2404EE for ; Sat, 25 Mar 2023 20:16:10 +0100 (CET) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id nWPGG_ocLiYs for ; Sat, 25 Mar 2023 20:16:09 +0100 (CET) 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 mail0.khirnov.net (Postfix) with ESMTPS id 493D9240D1A for ; Sat, 25 Mar 2023 20:16:01 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 1DAB23A0786 for ; Sat, 25 Mar 2023 20:15:55 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 25 Mar 2023 20:15:23 +0100 Message-Id: <20230325191529.10578-17-anton@khirnov.net> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230325191529.10578-1-anton@khirnov.net> References: <20230325191529.10578-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 17/23] fftools/ffmpeg: move subtitle encoding to ffmpeg_enc.c 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: vuE7ohcvKLHZ --- fftools/ffmpeg.c | 86 ++------------------------------------------ fftools/ffmpeg.h | 3 ++ fftools/ffmpeg_enc.c | 80 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 84 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 0324e45afa..bc2a9efbc1 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -669,7 +669,7 @@ static void close_output_stream(OutputStream *ost) sq_send(of->sq_encode, ost->sq_idx_encode, SQFRAME(NULL)); } -static int check_recording_time(OutputStream *ost, int64_t ts, AVRational tb) +int check_recording_time(OutputStream *ost, int64_t ts, AVRational tb) { OutputFile *of = output_files[ost->file_index]; @@ -1027,88 +1027,6 @@ static void do_audio_out(OutputFile *of, OutputStream *ost, exit_program(1); } -static void do_subtitle_out(OutputFile *of, - OutputStream *ost, - AVSubtitle *sub) -{ - int subtitle_out_max_size = 1024 * 1024; - int subtitle_out_size, nb, i, ret; - AVCodecContext *enc; - AVPacket *pkt = ost->pkt; - int64_t pts; - - if (sub->pts == AV_NOPTS_VALUE) { - av_log(ost, AV_LOG_ERROR, "Subtitle packets must have a pts\n"); - if (exit_on_error) - exit_program(1); - return; - } - - enc = ost->enc_ctx; - - /* Note: DVB subtitle need one packet to draw them and one other - packet to clear them */ - /* XXX: signal it in the codec context ? */ - if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE) - nb = 2; - else if (enc->codec_id == AV_CODEC_ID_ASS) - nb = FFMAX(sub->num_rects, 1); - else - nb = 1; - - /* shift timestamp to honor -ss and make check_recording_time() work with -t */ - pts = sub->pts; - if (output_files[ost->file_index]->start_time != AV_NOPTS_VALUE) - pts -= output_files[ost->file_index]->start_time; - for (i = 0; i < nb; i++) { - AVSubtitle local_sub = *sub; - - if (!check_recording_time(ost, pts, AV_TIME_BASE_Q)) - return; - - ret = av_new_packet(pkt, subtitle_out_max_size); - if (ret < 0) - report_and_exit(AVERROR(ENOMEM)); - - local_sub.pts = pts; - // start_display_time is required to be 0 - local_sub.pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, AV_TIME_BASE_Q); - local_sub.end_display_time -= sub->start_display_time; - local_sub.start_display_time = 0; - - if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE && i == 1) - local_sub.num_rects = 0; - else if (enc->codec_id == AV_CODEC_ID_ASS && sub->num_rects > 0) { - local_sub.num_rects = 1; - local_sub.rects += i; - } - - ost->frames_encoded++; - - subtitle_out_size = avcodec_encode_subtitle(enc, pkt->data, pkt->size, &local_sub); - if (subtitle_out_size < 0) { - av_log(ost, AV_LOG_FATAL, "Subtitle encoding failed\n"); - exit_program(1); - } - - av_shrink_packet(pkt, subtitle_out_size); - pkt->time_base = ost->mux_timebase; - pkt->pts = av_rescale_q(sub->pts, AV_TIME_BASE_Q, pkt->time_base); - pkt->duration = av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, pkt->time_base); - if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE) { - /* XXX: the pts correction is handled here. Maybe handling - it in the codec would be better */ - if (i == 0) - pkt->pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, pkt->time_base); - else - pkt->pts += av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, pkt->time_base); - } - pkt->dts = pkt->pts; - - of_output_packet(of, pkt, ost, 0); - } -} - /* Convert frame timestamps to the encoder timebase and decide how many times * should this (and possibly previous) frame be repeated in order to conform to * desired target framerate (if any). @@ -2351,7 +2269,7 @@ static int process_subtitle(InputStream *ist, AVSubtitle *subtitle, int *got_out || ost->enc_ctx->codec_type != AVMEDIA_TYPE_SUBTITLE) continue; - do_subtitle_out(output_files[ost->file_index], ost, subtitle); + enc_subtitle(output_files[ost->file_index], ost, subtitle); } out: diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index c1e2bbc300..ffb0ca33ac 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -811,6 +811,9 @@ AVBufferRef *hw_device_for_filter(void); int hwaccel_decode_init(AVCodecContext *avctx); int enc_open(OutputStream *ost, AVFrame *frame); +void enc_subtitle(OutputFile *of, OutputStream *ost, AVSubtitle *sub); + +int check_recording_time(OutputStream *ost, int64_t ts, AVRational tb); /* * Initialize muxing state for the given stream, should be called diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c index a4660051a2..bcc560b9b7 100644 --- a/fftools/ffmpeg_enc.c +++ b/fftools/ffmpeg_enc.c @@ -347,3 +347,83 @@ int enc_open(OutputStream *ost, AVFrame *frame) return 0; } + +void enc_subtitle(OutputFile *of, OutputStream *ost, AVSubtitle *sub) +{ + int subtitle_out_max_size = 1024 * 1024; + int subtitle_out_size, nb, i, ret; + AVCodecContext *enc; + AVPacket *pkt = ost->pkt; + int64_t pts; + + if (sub->pts == AV_NOPTS_VALUE) { + av_log(ost, AV_LOG_ERROR, "Subtitle packets must have a pts\n"); + if (exit_on_error) + exit_program(1); + return; + } + + enc = ost->enc_ctx; + + /* Note: DVB subtitle need one packet to draw them and one other + packet to clear them */ + /* XXX: signal it in the codec context ? */ + if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE) + nb = 2; + else if (enc->codec_id == AV_CODEC_ID_ASS) + nb = FFMAX(sub->num_rects, 1); + else + nb = 1; + + /* shift timestamp to honor -ss and make check_recording_time() work with -t */ + pts = sub->pts; + if (output_files[ost->file_index]->start_time != AV_NOPTS_VALUE) + pts -= output_files[ost->file_index]->start_time; + for (i = 0; i < nb; i++) { + AVSubtitle local_sub = *sub; + + if (!check_recording_time(ost, pts, AV_TIME_BASE_Q)) + return; + + ret = av_new_packet(pkt, subtitle_out_max_size); + if (ret < 0) + report_and_exit(AVERROR(ENOMEM)); + + local_sub.pts = pts; + // start_display_time is required to be 0 + local_sub.pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, AV_TIME_BASE_Q); + local_sub.end_display_time -= sub->start_display_time; + local_sub.start_display_time = 0; + + if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE && i == 1) + local_sub.num_rects = 0; + else if (enc->codec_id == AV_CODEC_ID_ASS && sub->num_rects > 0) { + local_sub.num_rects = 1; + local_sub.rects += i; + } + + ost->frames_encoded++; + + subtitle_out_size = avcodec_encode_subtitle(enc, pkt->data, pkt->size, &local_sub); + if (subtitle_out_size < 0) { + av_log(ost, AV_LOG_FATAL, "Subtitle encoding failed\n"); + exit_program(1); + } + + av_shrink_packet(pkt, subtitle_out_size); + pkt->time_base = ost->mux_timebase; + pkt->pts = av_rescale_q(sub->pts, AV_TIME_BASE_Q, pkt->time_base); + pkt->duration = av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, pkt->time_base); + if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE) { + /* XXX: the pts correction is handled here. Maybe handling + it in the codec would be better */ + if (i == 0) + pkt->pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, pkt->time_base); + else + pkt->pts += av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, pkt->time_base); + } + pkt->dts = pkt->pts; + + of_output_packet(of, pkt, ost, 0); + } +} From patchwork Sat Mar 25 19:15:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 40825 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7a30:b0:df:834d:2c1a with SMTP id t48csp225704pzh; Sat, 25 Mar 2023 12:17:06 -0700 (PDT) X-Google-Smtp-Source: AKy350bU9MnA0uhvPEsMm36xyz8AEAs22J8IRPHF4m4fAWDxmf6Tl49WvJEiuLAE8PvxIV2KozzP X-Received: by 2002:a17:907:6d24:b0:93e:9362:75fa with SMTP id sa36-20020a1709076d2400b0093e936275famr5947030ejc.47.1679771826594; Sat, 25 Mar 2023 12:17:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679771826; cv=none; d=google.com; s=arc-20160816; b=JWDI1sBw0igVPQF6cyxRR0cRp0J9gmC8Ws6x4k1totAQOmONCXBpOVLJPHZU/SeENt i3J6dqTAzUap4rAORl4pLiRNVDaqAE5VIcFe5q14eAmmAVyvN9kAyAfzknogKj0TFMMf ClqHpvYje+4rFZ0U/Tq83w3ZkekUjpSuSHPpkY+rOCI8NnlCZJ0DhUALz6Gy5wIWtpPY cDkffVQ4VmSZOhxOg4mfzDec3Qg+2EUTkgXLSyL86d9/T22z4+hyoTyNxs7HW6ns97BX K9WXJFYnU85qMTQC1vS0LFdOdT9qbh7K2o2jeiHkG6sxtBrRzNg/ryH52lp3vmxy9e6s wlQQ== 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:delivered-to; bh=69QlduMBPRPjPp2wBbHJ9xHa1RAe7ao7Bi5nz8bogmY=; b=R9xVwMt5F6jZfvFLlHb9E6L+Z/sfMJQNe1CJWv+hd6ww7xYR9L3IrXZ/V47LIlRuMB emJMD17SQ5li/7AsjlgUch5BFhc3j7ISGGVr8bp2Ii71I3CUfvba8CRcXAL6c9BkmkiP 7ZG5ENUeJG+c6B6jbeKyQXEanFwHt0IPo0+s+DeAra6o4kxj+MnjgiES2tyK0DiL97iV Wcyi2Hpe5MpQS7UlO606+EGYkKm4IXH1gvsuSN4gRZAHGIAMxDkgf0lhteFfOndCZlp0 +KqqKP32QUQElx3/CPOhSYC1VMSI8WYS4I6St4GIyqJtyPZ64RtqiINfxrT75YhgMsf+ 7blw== 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id vx5-20020a170907a78500b00932bed49028si21028769ejc.809.2023.03.25.12.17.06; Sat, 25 Mar 2023 12:17:06 -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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 86A9268C9A0; Sat, 25 Mar 2023 21:16:15 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail0.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id B3AF968BEC9 for ; Sat, 25 Mar 2023 21:16:08 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id DF1F2240178 for ; Sat, 25 Mar 2023 20:16:07 +0100 (CET) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id 1VmJNE-4Shmh for ; Sat, 25 Mar 2023 20:16:04 +0100 (CET) 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 mail0.khirnov.net (Postfix) with ESMTPS id 16DD02406CB for ; Sat, 25 Mar 2023 20:16:01 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 29CEC3A07C1 for ; Sat, 25 Mar 2023 20:15:55 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 25 Mar 2023 20:15:24 +0100 Message-Id: <20230325191529.10578-18-anton@khirnov.net> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230325191529.10578-1-anton@khirnov.net> References: <20230325191529.10578-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 18/23] fftools/ffmpeg: move audio/video encoding code to ffmpeg_enc.c 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: j06PHSBsLAcW --- fftools/ffmpeg.c | 690 +------------------------------------------ fftools/ffmpeg.h | 31 +- fftools/ffmpeg_enc.c | 660 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 702 insertions(+), 679 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index bc2a9efbc1..7a6b206d11 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -62,7 +62,6 @@ #include "libavutil/time.h" #include "libavutil/thread.h" #include "libavutil/threadmessage.h" -#include "libavcodec/mathops.h" #include "libavcodec/version.h" #include "libavformat/os_support.h" @@ -110,14 +109,7 @@ const char program_name[] = "ffmpeg"; const int program_birth_year = 2000; -static FILE *vstats_file; - -// optionally attached as opaque_ref to decoded AVFrames -typedef struct FrameData { - uint64_t idx; - int64_t pts; - AVRational tb; -} FrameData; +FILE *vstats_file; typedef struct BenchmarkTimeStamps { int64_t real_usec; @@ -125,14 +117,11 @@ typedef struct BenchmarkTimeStamps { int64_t sys_usec; } BenchmarkTimeStamps; -static int trigger_fix_sub_duration_heartbeat(OutputStream *ost, const AVPacket *pkt); static BenchmarkTimeStamps get_benchmark_time_stamps(void); static int64_t getmaxrss(void); -static int ifilter_has_all_input_formats(FilterGraph *fg); -static int64_t nb_frames_dup = 0; -static uint64_t dup_warning = 1000; -static int64_t nb_frames_drop = 0; +int64_t nb_frames_dup = 0; +int64_t nb_frames_drop = 0; static int64_t decode_error_stat[2]; unsigned nb_output_dumped = 0; @@ -582,9 +571,7 @@ static void ffmpeg_cleanup(int ret) ffmpeg_exited = 1; } -/* iterate over all output streams in all output files; - * pass NULL to start iteration */ -static OutputStream *ost_iter(OutputStream *prev) +OutputStream *ost_iter(OutputStream *prev) { int of_idx = prev ? prev->file_index : 0; int ost_idx = prev ? prev->index + 1 : 0; @@ -639,7 +626,7 @@ static void abort_codec_experimental(const AVCodec *c, int encoder) exit_program(1); } -static void update_benchmark(const char *fmt, ...) +void update_benchmark(const char *fmt, ...) { if (do_benchmark_all) { BenchmarkTimeStamps t = get_benchmark_time_stamps(); @@ -660,7 +647,7 @@ static void update_benchmark(const char *fmt, ...) } } -static void close_output_stream(OutputStream *ost) +void close_output_stream(OutputStream *ost) { OutputFile *of = output_files[ost->file_index]; ost->finished |= ENCODER_FINISHED; @@ -669,594 +656,6 @@ static void close_output_stream(OutputStream *ost) sq_send(of->sq_encode, ost->sq_idx_encode, SQFRAME(NULL)); } -int check_recording_time(OutputStream *ost, int64_t ts, AVRational tb) -{ - OutputFile *of = output_files[ost->file_index]; - - if (of->recording_time != INT64_MAX && - av_compare_ts(ts, tb, of->recording_time, AV_TIME_BASE_Q) >= 0) { - close_output_stream(ost); - return 0; - } - return 1; -} - -static double adjust_frame_pts_to_encoder_tb(OutputFile *of, OutputStream *ost, - AVFrame *frame) -{ - double float_pts = AV_NOPTS_VALUE; // this is identical to frame.pts but with higher precision - const int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? - 0 : of->start_time; - - AVCodecContext *const enc = ost->enc_ctx; - - AVRational tb = enc->time_base; - AVRational filter_tb = frame->time_base; - const int extra_bits = av_clip(29 - av_log2(tb.den), 0, 16); - - if (frame->pts == AV_NOPTS_VALUE) - goto early_exit; - - tb.den <<= extra_bits; - float_pts = av_rescale_q(frame->pts, filter_tb, tb) - - av_rescale_q(start_time, AV_TIME_BASE_Q, tb); - float_pts /= 1 << extra_bits; - // avoid exact midoints to reduce the chance of rounding differences, this - // can be removed in case the fps code is changed to work with integers - float_pts += FFSIGN(float_pts) * 1.0 / (1<<17); - - frame->pts = av_rescale_q(frame->pts, filter_tb, enc->time_base) - - av_rescale_q(start_time, AV_TIME_BASE_Q, enc->time_base); - frame->time_base = enc->time_base; - -early_exit: - - if (debug_ts) { - av_log(NULL, AV_LOG_INFO, "filter -> pts:%s pts_time:%s exact:%f time_base:%d/%d\n", - frame ? av_ts2str(frame->pts) : "NULL", - (enc && frame) ? av_ts2timestr(frame->pts, &enc->time_base) : "NULL", - float_pts, - enc ? enc->time_base.num : -1, - enc ? enc->time_base.den : -1); - } - - return float_pts; -} - -static double psnr(double d) -{ - return -10.0 * log10(d); -} - -static void update_video_stats(OutputStream *ost, const AVPacket *pkt, int write_vstats) -{ - const uint8_t *sd = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS, - NULL); - AVCodecContext *enc = ost->enc_ctx; - int64_t frame_number; - double ti1, bitrate, avg_bitrate; - - ost->quality = sd ? AV_RL32(sd) : -1; - ost->pict_type = sd ? sd[4] : AV_PICTURE_TYPE_NONE; - - for (int i = 0; ierror); i++) { - if (sd && i < sd[5]) - ost->error[i] = AV_RL64(sd + 8 + 8*i); - else - ost->error[i] = -1; - } - - if (!write_vstats) - return; - - /* this is executed just the first time update_video_stats is called */ - if (!vstats_file) { - vstats_file = fopen(vstats_filename, "w"); - if (!vstats_file) { - perror("fopen"); - exit_program(1); - } - } - - frame_number = ost->packets_encoded; - if (vstats_version <= 1) { - fprintf(vstats_file, "frame= %5"PRId64" q= %2.1f ", frame_number, - ost->quality / (float)FF_QP2LAMBDA); - } else { - fprintf(vstats_file, "out= %2d st= %2d frame= %5"PRId64" q= %2.1f ", ost->file_index, ost->index, frame_number, - ost->quality / (float)FF_QP2LAMBDA); - } - - if (ost->error[0]>=0 && (enc->flags & AV_CODEC_FLAG_PSNR)) - fprintf(vstats_file, "PSNR= %6.2f ", psnr(ost->error[0] / (enc->width * enc->height * 255.0 * 255.0))); - - fprintf(vstats_file,"f_size= %6d ", pkt->size); - /* compute pts value */ - ti1 = pkt->dts * av_q2d(pkt->time_base); - if (ti1 < 0.01) - ti1 = 0.01; - - bitrate = (pkt->size * 8) / av_q2d(enc->time_base) / 1000.0; - avg_bitrate = (double)(ost->data_size_enc * 8) / ti1 / 1000.0; - fprintf(vstats_file, "s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s ", - (double)ost->data_size_enc / 1024, ti1, bitrate, avg_bitrate); - fprintf(vstats_file, "type= %c\n", av_get_picture_type_char(ost->pict_type)); -} - -void enc_stats_write(OutputStream *ost, EncStats *es, - const AVFrame *frame, const AVPacket *pkt, - uint64_t frame_num) -{ - AVIOContext *io = es->io; - AVRational tb = frame ? frame->time_base : pkt->time_base; - int64_t pts = frame ? frame->pts : pkt->pts; - - AVRational tbi = (AVRational){ 0, 1}; - int64_t ptsi = INT64_MAX; - - const FrameData *fd; - - if ((frame && frame->opaque_ref) || (pkt && pkt->opaque_ref)) { - fd = (const FrameData*)(frame ? frame->opaque_ref->data : pkt->opaque_ref->data); - tbi = fd->tb; - ptsi = fd->pts; - } - - for (size_t i = 0; i < es->nb_components; i++) { - const EncStatsComponent *c = &es->components[i]; - - switch (c->type) { - case ENC_STATS_LITERAL: avio_write (io, c->str, c->str_len); continue; - case ENC_STATS_FILE_IDX: avio_printf(io, "%d", ost->file_index); continue; - case ENC_STATS_STREAM_IDX: avio_printf(io, "%d", ost->index); continue; - case ENC_STATS_TIMEBASE: avio_printf(io, "%d/%d", tb.num, tb.den); continue; - case ENC_STATS_TIMEBASE_IN: avio_printf(io, "%d/%d", tbi.num, tbi.den); continue; - case ENC_STATS_PTS: avio_printf(io, "%"PRId64, pts); continue; - case ENC_STATS_PTS_IN: avio_printf(io, "%"PRId64, ptsi); continue; - case ENC_STATS_PTS_TIME: avio_printf(io, "%g", pts * av_q2d(tb)); continue; - case ENC_STATS_PTS_TIME_IN: avio_printf(io, "%g", ptsi == INT64_MAX ? - INFINITY : ptsi * av_q2d(tbi)); continue; - case ENC_STATS_FRAME_NUM: avio_printf(io, "%"PRIu64, frame_num); continue; - case ENC_STATS_FRAME_NUM_IN: avio_printf(io, "%"PRIu64, fd ? fd->idx : -1); continue; - } - - if (frame) { - switch (c->type) { - case ENC_STATS_SAMPLE_NUM: avio_printf(io, "%"PRIu64, ost->samples_encoded); continue; - case ENC_STATS_NB_SAMPLES: avio_printf(io, "%d", frame->nb_samples); continue; - default: av_assert0(0); - } - } else { - switch (c->type) { - case ENC_STATS_DTS: avio_printf(io, "%"PRId64, pkt->dts); continue; - case ENC_STATS_DTS_TIME: avio_printf(io, "%g", pkt->dts * av_q2d(tb)); continue; - case ENC_STATS_PKT_SIZE: avio_printf(io, "%d", pkt->size); continue; - case ENC_STATS_BITRATE: { - double duration = FFMAX(pkt->duration, 1) * av_q2d(tb); - avio_printf(io, "%g", 8.0 * pkt->size / duration); - continue; - } - case ENC_STATS_AVG_BITRATE: { - double duration = pkt->dts * av_q2d(tb); - avio_printf(io, "%g", duration > 0 ? 8.0 * ost->data_size_enc / duration : -1.); - continue; - } - default: av_assert0(0); - } - } - } - avio_w8(io, '\n'); - avio_flush(io); -} - -static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame) -{ - AVCodecContext *enc = ost->enc_ctx; - AVPacket *pkt = ost->pkt; - const char *type_desc = av_get_media_type_string(enc->codec_type); - const char *action = frame ? "encode" : "flush"; - int ret; - - if (frame) { - if (ost->enc_stats_pre.io) - enc_stats_write(ost, &ost->enc_stats_pre, frame, NULL, - ost->frames_encoded); - - ost->frames_encoded++; - ost->samples_encoded += frame->nb_samples; - - if (debug_ts) { - av_log(ost, AV_LOG_INFO, "encoder <- type:%s " - "frame_pts:%s frame_pts_time:%s time_base:%d/%d\n", - type_desc, - av_ts2str(frame->pts), av_ts2timestr(frame->pts, &enc->time_base), - enc->time_base.num, enc->time_base.den); - } - } - - update_benchmark(NULL); - - ret = avcodec_send_frame(enc, frame); - if (ret < 0 && !(ret == AVERROR_EOF && !frame)) { - av_log(ost, AV_LOG_ERROR, "Error submitting %s frame to the encoder\n", - type_desc); - return ret; - } - - while (1) { - ret = avcodec_receive_packet(enc, pkt); - update_benchmark("%s_%s %d.%d", action, type_desc, - ost->file_index, ost->index); - - pkt->time_base = enc->time_base; - - /* if two pass, output log on success and EOF */ - if ((ret >= 0 || ret == AVERROR_EOF) && ost->logfile && enc->stats_out) - fprintf(ost->logfile, "%s", enc->stats_out); - - if (ret == AVERROR(EAGAIN)) { - av_assert0(frame); // should never happen during flushing - return 0; - } else if (ret == AVERROR_EOF) { - of_output_packet(of, pkt, ost, 1); - return ret; - } else if (ret < 0) { - av_log(ost, AV_LOG_ERROR, "%s encoding failed\n", type_desc); - return ret; - } - - if (enc->codec_type == AVMEDIA_TYPE_VIDEO) - update_video_stats(ost, pkt, !!vstats_filename); - if (ost->enc_stats_post.io) - enc_stats_write(ost, &ost->enc_stats_post, NULL, pkt, - ost->packets_encoded); - - if (debug_ts) { - av_log(ost, AV_LOG_INFO, "encoder -> type:%s " - "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s " - "duration:%s duration_time:%s\n", - type_desc, - av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &enc->time_base), - av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &enc->time_base), - av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &enc->time_base)); - } - - av_packet_rescale_ts(pkt, pkt->time_base, ost->mux_timebase); - pkt->time_base = ost->mux_timebase; - - if (debug_ts) { - av_log(ost, AV_LOG_INFO, "encoder -> type:%s " - "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s " - "duration:%s duration_time:%s\n", - type_desc, - av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &enc->time_base), - av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &enc->time_base), - av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &enc->time_base)); - } - - if ((ret = trigger_fix_sub_duration_heartbeat(ost, pkt)) < 0) { - av_log(NULL, AV_LOG_ERROR, - "Subtitle heartbeat logic failed in %s! (%s)\n", - __func__, av_err2str(ret)); - exit_program(1); - } - - ost->data_size_enc += pkt->size; - - ost->packets_encoded++; - - of_output_packet(of, pkt, ost, 0); - } - - av_assert0(0); -} - -static int submit_encode_frame(OutputFile *of, OutputStream *ost, - AVFrame *frame) -{ - int ret; - - if (ost->sq_idx_encode < 0) - return encode_frame(of, ost, frame); - - if (frame) { - ret = av_frame_ref(ost->sq_frame, frame); - if (ret < 0) - return ret; - frame = ost->sq_frame; - } - - ret = sq_send(of->sq_encode, ost->sq_idx_encode, - SQFRAME(frame)); - if (ret < 0) { - if (frame) - av_frame_unref(frame); - if (ret != AVERROR_EOF) - return ret; - } - - while (1) { - AVFrame *enc_frame = ost->sq_frame; - - ret = sq_receive(of->sq_encode, ost->sq_idx_encode, - SQFRAME(enc_frame)); - if (ret == AVERROR_EOF) { - enc_frame = NULL; - } else if (ret < 0) { - return (ret == AVERROR(EAGAIN)) ? 0 : ret; - } - - ret = encode_frame(of, ost, enc_frame); - if (enc_frame) - av_frame_unref(enc_frame); - if (ret < 0) { - if (ret == AVERROR_EOF) - close_output_stream(ost); - return ret; - } - } -} - -static void do_audio_out(OutputFile *of, OutputStream *ost, - AVFrame *frame) -{ - AVCodecContext *enc = ost->enc_ctx; - int ret; - - ret = enc_open(ost, frame); - if (ret < 0) - exit_program(1); - - if (frame->pts == AV_NOPTS_VALUE) - frame->pts = ost->next_pts; - else { - int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time; - frame->pts = - av_rescale_q(frame->pts, frame->time_base, enc->time_base) - - av_rescale_q(start_time, AV_TIME_BASE_Q, enc->time_base); - } - frame->time_base = enc->time_base; - - if (!check_recording_time(ost, frame->pts, frame->time_base)) - return; - - ost->next_pts = frame->pts + frame->nb_samples; - - ret = submit_encode_frame(of, ost, frame); - if (ret < 0 && ret != AVERROR_EOF) - exit_program(1); -} - -/* Convert frame timestamps to the encoder timebase and decide how many times - * should this (and possibly previous) frame be repeated in order to conform to - * desired target framerate (if any). - */ -static void video_sync_process(OutputFile *of, OutputStream *ost, - AVFrame *next_picture, double duration, - int64_t *nb_frames, int64_t *nb_frames_prev) -{ - double delta0, delta; - - double sync_ipts = adjust_frame_pts_to_encoder_tb(of, ost, next_picture); - /* delta0 is the "drift" between the input frame (next_picture) and - * where it would fall in the output. */ - delta0 = sync_ipts - ost->next_pts; - delta = delta0 + duration; - - // tracks the number of times the PREVIOUS frame should be duplicated, - // mostly for variable framerate (VFR) - *nb_frames_prev = 0; - /* by default, we output a single frame */ - *nb_frames = 1; - - if (delta0 < 0 && - delta > 0 && - ost->vsync_method != VSYNC_PASSTHROUGH && - ost->vsync_method != VSYNC_DROP) { - if (delta0 < -0.6) { - av_log(ost, AV_LOG_VERBOSE, "Past duration %f too large\n", -delta0); - } else - av_log(ost, AV_LOG_DEBUG, "Clipping frame in rate conversion by %f\n", -delta0); - sync_ipts = ost->next_pts; - duration += delta0; - delta0 = 0; - } - - switch (ost->vsync_method) { - case VSYNC_VSCFR: - if (ost->vsync_frame_number == 0 && delta0 >= 0.5) { - av_log(ost, AV_LOG_DEBUG, "Not duplicating %d initial frames\n", (int)lrintf(delta0)); - delta = duration; - delta0 = 0; - ost->next_pts = llrint(sync_ipts); - } - case VSYNC_CFR: - // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c - if (frame_drop_threshold && delta < frame_drop_threshold && ost->vsync_frame_number) { - *nb_frames = 0; - } else if (delta < -1.1) - *nb_frames = 0; - else if (delta > 1.1) { - *nb_frames = llrintf(delta); - if (delta0 > 1.1) - *nb_frames_prev = llrintf(delta0 - 0.6); - } - next_picture->duration = 1; - break; - case VSYNC_VFR: - if (delta <= -0.6) - *nb_frames = 0; - else if (delta > 0.6) - ost->next_pts = llrint(sync_ipts); - next_picture->duration = duration; - break; - case VSYNC_DROP: - case VSYNC_PASSTHROUGH: - next_picture->duration = duration; - ost->next_pts = llrint(sync_ipts); - break; - default: - av_assert0(0); - } -} - -static enum AVPictureType forced_kf_apply(void *logctx, KeyframeForceCtx *kf, - AVRational tb, const AVFrame *in_picture, - int dup_idx) -{ - double pts_time; - - if (kf->ref_pts == AV_NOPTS_VALUE) - kf->ref_pts = in_picture->pts; - - pts_time = (in_picture->pts - kf->ref_pts) * av_q2d(tb); - if (kf->index < kf->nb_pts && - av_compare_ts(in_picture->pts, tb, kf->pts[kf->index], AV_TIME_BASE_Q) >= 0) { - kf->index++; - goto force_keyframe; - } else if (kf->pexpr) { - double res; - kf->expr_const_values[FKF_T] = pts_time; - res = av_expr_eval(kf->pexpr, - kf->expr_const_values, NULL); - av_log(logctx, AV_LOG_TRACE, - "force_key_frame: n:%f n_forced:%f prev_forced_n:%f t:%f prev_forced_t:%f -> res:%f\n", - kf->expr_const_values[FKF_N], - kf->expr_const_values[FKF_N_FORCED], - kf->expr_const_values[FKF_PREV_FORCED_N], - kf->expr_const_values[FKF_T], - kf->expr_const_values[FKF_PREV_FORCED_T], - res); - - kf->expr_const_values[FKF_N] += 1; - - if (res) { - kf->expr_const_values[FKF_PREV_FORCED_N] = kf->expr_const_values[FKF_N] - 1; - kf->expr_const_values[FKF_PREV_FORCED_T] = kf->expr_const_values[FKF_T]; - kf->expr_const_values[FKF_N_FORCED] += 1; - goto force_keyframe; - } - } else if (kf->type == KF_FORCE_SOURCE && - in_picture->key_frame == 1 && !dup_idx) { - goto force_keyframe; - } else if (kf->type == KF_FORCE_SOURCE_NO_DROP && !dup_idx) { - kf->dropped_keyframe = 0; - if ((in_picture->key_frame == 1) || kf->dropped_keyframe) - goto force_keyframe; - } - - return AV_PICTURE_TYPE_NONE; - -force_keyframe: - av_log(logctx, AV_LOG_DEBUG, "Forced keyframe at time %f\n", pts_time); - return AV_PICTURE_TYPE_I; -} - -/* May modify/reset next_picture */ -static void do_video_out(OutputFile *of, - OutputStream *ost, - AVFrame *next_picture) -{ - int ret; - AVCodecContext *enc = ost->enc_ctx; - AVRational frame_rate; - int64_t nb_frames, nb_frames_prev, i; - double duration = 0; - InputStream *ist = ost->ist; - AVFilterContext *filter = ost->filter->filter; - - ret = enc_open(ost, next_picture); - if (ret < 0) - exit_program(1); - - frame_rate = av_buffersink_get_frame_rate(filter); - if (frame_rate.num > 0 && frame_rate.den > 0) - duration = 1/(av_q2d(frame_rate) * av_q2d(enc->time_base)); - - if(ist && ist->st->start_time != AV_NOPTS_VALUE && ist->first_dts != AV_NOPTS_VALUE && ost->frame_rate.num) - duration = FFMIN(duration, 1/(av_q2d(ost->frame_rate) * av_q2d(enc->time_base))); - - if (!ost->filters_script && - !ost->filters && - (nb_filtergraphs == 0 || !filtergraphs[0]->graph_desc) && - next_picture && - ist && - lrintf(next_picture->duration * av_q2d(ist->st->time_base) / av_q2d(enc->time_base)) > 0) { - duration = lrintf(next_picture->duration * av_q2d(ist->st->time_base) / av_q2d(enc->time_base)); - } - - if (!next_picture) { - //end, flushing - nb_frames_prev = nb_frames = mid_pred(ost->last_nb0_frames[0], - ost->last_nb0_frames[1], - ost->last_nb0_frames[2]); - } else { - video_sync_process(of, ost, next_picture, duration, - &nb_frames, &nb_frames_prev); - } - - memmove(ost->last_nb0_frames + 1, - ost->last_nb0_frames, - sizeof(ost->last_nb0_frames[0]) * (FF_ARRAY_ELEMS(ost->last_nb0_frames) - 1)); - ost->last_nb0_frames[0] = nb_frames_prev; - - if (nb_frames_prev == 0 && ost->last_dropped) { - nb_frames_drop++; - av_log(ost, AV_LOG_VERBOSE, - "*** dropping frame %"PRId64" at ts %"PRId64"\n", - ost->vsync_frame_number, ost->last_frame->pts); - } - if (nb_frames > (nb_frames_prev && ost->last_dropped) + (nb_frames > nb_frames_prev)) { - if (nb_frames > dts_error_threshold * 30) { - av_log(ost, AV_LOG_ERROR, "%"PRId64" frame duplication too large, skipping\n", nb_frames - 1); - nb_frames_drop++; - return; - } - nb_frames_dup += nb_frames - (nb_frames_prev && ost->last_dropped) - (nb_frames > nb_frames_prev); - av_log(ost, AV_LOG_VERBOSE, "*** %"PRId64" dup!\n", nb_frames - 1); - if (nb_frames_dup > dup_warning) { - av_log(ost, AV_LOG_WARNING, "More than %"PRIu64" frames duplicated\n", dup_warning); - dup_warning *= 10; - } - } - ost->last_dropped = nb_frames == nb_frames_prev && next_picture; - ost->kf.dropped_keyframe = ost->last_dropped && next_picture && next_picture->key_frame; - - /* duplicates frame if needed */ - for (i = 0; i < nb_frames; i++) { - AVFrame *in_picture; - - if (i < nb_frames_prev && ost->last_frame->buf[0]) { - in_picture = ost->last_frame; - } else - in_picture = next_picture; - - if (!in_picture) - return; - - in_picture->pts = ost->next_pts; - - if (!check_recording_time(ost, in_picture->pts, ost->enc_ctx->time_base)) - return; - - in_picture->quality = enc->global_quality; - in_picture->pict_type = forced_kf_apply(ost, &ost->kf, enc->time_base, in_picture, i); - - ret = submit_encode_frame(of, ost, in_picture); - if (ret == AVERROR_EOF) - break; - else if (ret < 0) - exit_program(1); - - ost->next_pts++; - ost->vsync_frame_number++; - } - - av_frame_unref(ost->last_frame); - if (next_picture) - av_frame_move_ref(ost->last_frame, next_picture); -} - /** * Get and encode new output from any of the filtergraphs, without causing * activity. @@ -1269,7 +668,6 @@ static int reap_filters(int flush) /* Reap all buffers present in the buffer sinks */ for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) { - OutputFile *of = output_files[ost->file_index]; AVFilterContext *filter; AVCodecContext *enc = ost->enc_ctx; int ret = 0; @@ -1289,7 +687,7 @@ static int reap_filters(int flush) "Error in av_buffersink_get_frame_flags(): %s\n", av_err2str(ret)); } else if (flush && ret == AVERROR_EOF) { if (av_buffersink_get_type(filter) == AVMEDIA_TYPE_VIDEO) - do_video_out(of, ost, NULL); + enc_frame(ost, NULL); } break; } @@ -1316,7 +714,7 @@ static int reap_filters(int flush) if (!ost->frame_aspect_ratio.num) enc->sample_aspect_ratio = filtered_frame->sample_aspect_ratio; - do_video_out(of, ost, filtered_frame); + enc_frame(ost, filtered_frame); break; case AVMEDIA_TYPE_AUDIO: if (!(enc->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE) && @@ -1326,7 +724,7 @@ static int reap_filters(int flush) "Audio filter graph output is not normalized and encoder does not support parameter changes\n"); break; } - do_audio_out(of, ost, filtered_frame); + enc_frame(ost, filtered_frame); break; default: // TODO support subtitle filters @@ -1657,7 +1055,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti print_final_stats(total_size); } -static int ifilter_parameters_from_codecpar(InputFilter *ifilter, AVCodecParameters *par) +int ifilter_parameters_from_codecpar(InputFilter *ifilter, AVCodecParameters *par) { int ret; @@ -1675,68 +1073,6 @@ static int ifilter_parameters_from_codecpar(InputFilter *ifilter, AVCodecParamet return 0; } -static void flush_encoders(void) -{ - int ret; - - for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) { - OutputFile *of = output_files[ost->file_index]; - if (ost->sq_idx_encode >= 0) - sq_send(of->sq_encode, ost->sq_idx_encode, SQFRAME(NULL)); - } - - for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) { - AVCodecContext *enc = ost->enc_ctx; - OutputFile *of = output_files[ost->file_index]; - - if (!enc) - continue; - - // Try to enable encoding with no input frames. - // Maybe we should just let encoding fail instead. - if (!ost->initialized) { - FilterGraph *fg = ost->filter->graph; - - av_log(ost, AV_LOG_WARNING, - "Finishing stream without any data written to it.\n"); - - if (ost->filter && !fg->graph) { - int x; - for (x = 0; x < fg->nb_inputs; x++) { - InputFilter *ifilter = fg->inputs[x]; - if (ifilter->format < 0 && - ifilter_parameters_from_codecpar(ifilter, ifilter->ist->par) < 0) { - av_log(ost, AV_LOG_ERROR, "Error copying paramerets from input stream\n"); - exit_program(1); - } - } - - if (!ifilter_has_all_input_formats(fg)) - continue; - - ret = configure_filtergraph(fg); - if (ret < 0) { - av_log(ost, AV_LOG_ERROR, "Error configuring filter graph\n"); - exit_program(1); - } - - of_output_packet(of, ost->pkt, ost, 1); - } - - ret = enc_open(ost, NULL); - if (ret < 0) - exit_program(1); - } - - if (enc->codec_type != AVMEDIA_TYPE_VIDEO && enc->codec_type != AVMEDIA_TYPE_AUDIO) - continue; - - ret = submit_encode_frame(of, ost, NULL); - if (ret != AVERROR_EOF) - exit_program(1); - } -} - /* * Check whether a packet from ist should be written into ost at this time */ @@ -1859,7 +1195,7 @@ static void check_decode_result(InputStream *ist, int *got_output, int ret) } // Filters can be configured only if the formats of all inputs are known. -static int ifilter_has_all_input_formats(FilterGraph *fg) +int ifilter_has_all_input_formats(FilterGraph *fg) { int i; for (i = 0; i < fg->nb_inputs; i++) { @@ -2377,7 +1713,7 @@ static int fix_sub_duration_heartbeat(InputStream *ist, int64_t signal_pts) return process_subtitle(ist, &subtitle, &got_output); } -static int trigger_fix_sub_duration_heartbeat(OutputStream *ost, const AVPacket *pkt) +int trigger_fix_sub_duration_heartbeat(OutputStream *ost, const AVPacket *pkt) { OutputFile *of = output_files[ost->file_index]; int64_t signal_pts = av_rescale_q(pkt->pts, pkt->time_base, @@ -3607,7 +2943,7 @@ static int transcode(void) process_input_packet(ist, NULL, 0); } } - flush_encoders(); + enc_flush(); term_exit(); diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index ffb0ca33ac..c30659176e 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -707,6 +707,13 @@ typedef struct OutputFile { int bitexact; } OutputFile; +// optionally attached as opaque_ref to decoded AVFrames +typedef struct FrameData { + uint64_t idx; + int64_t pts; + AVRational tb; +} FrameData; + extern InputFile **input_files; extern int nb_input_files; @@ -760,6 +767,11 @@ extern int copy_unknown_streams; extern int recast_media; +extern FILE *vstats_file; + +extern int64_t nb_frames_dup; +extern int64_t nb_frames_drop; + #if FFMPEG_OPT_PSNR extern int do_psnr; #endif @@ -788,6 +800,8 @@ int init_complex_filtergraph(FilterGraph *fg); void sub2video_update(InputStream *ist, int64_t heartbeat_pts, AVSubtitle *sub); int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame); +int ifilter_parameters_from_codecpar(InputFilter *ifilter, AVCodecParameters *par); +int ifilter_has_all_input_formats(FilterGraph *fg); int ffmpeg_parse_options(int argc, char **argv); @@ -812,8 +826,8 @@ int hwaccel_decode_init(AVCodecContext *avctx); int enc_open(OutputStream *ost, AVFrame *frame); void enc_subtitle(OutputFile *of, OutputStream *ost, AVSubtitle *sub); - -int check_recording_time(OutputStream *ost, int64_t ts, AVRational tb); +void enc_frame(OutputStream *ost, AVFrame *frame); +void enc_flush(void); /* * Initialize muxing state for the given stream, should be called @@ -861,6 +875,19 @@ int ifile_get_packet(InputFile *f, AVPacket **pkt); * pass NULL to start iteration */ InputStream *ist_iter(InputStream *prev); +/* iterate over all output streams in all output files; + * pass NULL to start iteration */ +OutputStream *ost_iter(OutputStream *prev); + +static inline double psnr(double d) +{ + return -10.0 * log10(d); +} + +void close_output_stream(OutputStream *ost); +int trigger_fix_sub_duration_heartbeat(OutputStream *ost, const AVPacket *pkt); +void update_benchmark(const char *fmt, ...); + #define SPECIFIER_OPT_FMT_str "%s" #define SPECIFIER_OPT_FMT_i "%i" #define SPECIFIER_OPT_FMT_i64 "%"PRId64 diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c index bcc560b9b7..c0e3eaa1e8 100644 --- a/fftools/ffmpeg_enc.c +++ b/fftools/ffmpeg_enc.c @@ -28,16 +28,23 @@ #include "libavutil/display.h" #include "libavutil/eval.h" #include "libavutil/frame.h" +#include "libavutil/intreadwrite.h" #include "libavutil/log.h" #include "libavutil/pixdesc.h" #include "libavutil/rational.h" +#include "libavutil/timestamp.h" #include "libavfilter/buffersink.h" #include "libavcodec/avcodec.h" +// FIXME private header, used for mid_pred() +#include "libavcodec/mathops.h" + #include "libavformat/avformat.h" +static uint64_t dup_warning = 1000; + static void set_encoder_id(OutputFile *of, OutputStream *ost) { const char *cname = ost->enc_ctx->codec->name; @@ -348,6 +355,18 @@ int enc_open(OutputStream *ost, AVFrame *frame) return 0; } +static int check_recording_time(OutputStream *ost, int64_t ts, AVRational tb) +{ + OutputFile *of = output_files[ost->file_index]; + + if (of->recording_time != INT64_MAX && + av_compare_ts(ts, tb, of->recording_time, AV_TIME_BASE_Q) >= 0) { + close_output_stream(ost); + return 0; + } + return 1; +} + void enc_subtitle(OutputFile *of, OutputStream *ost, AVSubtitle *sub) { int subtitle_out_max_size = 1024 * 1024; @@ -427,3 +446,644 @@ void enc_subtitle(OutputFile *of, OutputStream *ost, AVSubtitle *sub) of_output_packet(of, pkt, ost, 0); } } + +void enc_stats_write(OutputStream *ost, EncStats *es, + const AVFrame *frame, const AVPacket *pkt, + uint64_t frame_num) +{ + AVIOContext *io = es->io; + AVRational tb = frame ? frame->time_base : pkt->time_base; + int64_t pts = frame ? frame->pts : pkt->pts; + + AVRational tbi = (AVRational){ 0, 1}; + int64_t ptsi = INT64_MAX; + + const FrameData *fd; + + if ((frame && frame->opaque_ref) || (pkt && pkt->opaque_ref)) { + fd = (const FrameData*)(frame ? frame->opaque_ref->data : pkt->opaque_ref->data); + tbi = fd->tb; + ptsi = fd->pts; + } + + for (size_t i = 0; i < es->nb_components; i++) { + const EncStatsComponent *c = &es->components[i]; + + switch (c->type) { + case ENC_STATS_LITERAL: avio_write (io, c->str, c->str_len); continue; + case ENC_STATS_FILE_IDX: avio_printf(io, "%d", ost->file_index); continue; + case ENC_STATS_STREAM_IDX: avio_printf(io, "%d", ost->index); continue; + case ENC_STATS_TIMEBASE: avio_printf(io, "%d/%d", tb.num, tb.den); continue; + case ENC_STATS_TIMEBASE_IN: avio_printf(io, "%d/%d", tbi.num, tbi.den); continue; + case ENC_STATS_PTS: avio_printf(io, "%"PRId64, pts); continue; + case ENC_STATS_PTS_IN: avio_printf(io, "%"PRId64, ptsi); continue; + case ENC_STATS_PTS_TIME: avio_printf(io, "%g", pts * av_q2d(tb)); continue; + case ENC_STATS_PTS_TIME_IN: avio_printf(io, "%g", ptsi == INT64_MAX ? + INFINITY : ptsi * av_q2d(tbi)); continue; + case ENC_STATS_FRAME_NUM: avio_printf(io, "%"PRIu64, frame_num); continue; + case ENC_STATS_FRAME_NUM_IN: avio_printf(io, "%"PRIu64, fd ? fd->idx : -1); continue; + } + + if (frame) { + switch (c->type) { + case ENC_STATS_SAMPLE_NUM: avio_printf(io, "%"PRIu64, ost->samples_encoded); continue; + case ENC_STATS_NB_SAMPLES: avio_printf(io, "%d", frame->nb_samples); continue; + default: av_assert0(0); + } + } else { + switch (c->type) { + case ENC_STATS_DTS: avio_printf(io, "%"PRId64, pkt->dts); continue; + case ENC_STATS_DTS_TIME: avio_printf(io, "%g", pkt->dts * av_q2d(tb)); continue; + case ENC_STATS_PKT_SIZE: avio_printf(io, "%d", pkt->size); continue; + case ENC_STATS_BITRATE: { + double duration = FFMAX(pkt->duration, 1) * av_q2d(tb); + avio_printf(io, "%g", 8.0 * pkt->size / duration); + continue; + } + case ENC_STATS_AVG_BITRATE: { + double duration = pkt->dts * av_q2d(tb); + avio_printf(io, "%g", duration > 0 ? 8.0 * ost->data_size_enc / duration : -1.); + continue; + } + default: av_assert0(0); + } + } + } + avio_w8(io, '\n'); + avio_flush(io); +} + +static void update_video_stats(OutputStream *ost, const AVPacket *pkt, int write_vstats) +{ + const uint8_t *sd = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS, + NULL); + AVCodecContext *enc = ost->enc_ctx; + int64_t frame_number; + double ti1, bitrate, avg_bitrate; + + ost->quality = sd ? AV_RL32(sd) : -1; + ost->pict_type = sd ? sd[4] : AV_PICTURE_TYPE_NONE; + + for (int i = 0; ierror); i++) { + if (sd && i < sd[5]) + ost->error[i] = AV_RL64(sd + 8 + 8*i); + else + ost->error[i] = -1; + } + + if (!write_vstats) + return; + + /* this is executed just the first time update_video_stats is called */ + if (!vstats_file) { + vstats_file = fopen(vstats_filename, "w"); + if (!vstats_file) { + perror("fopen"); + exit_program(1); + } + } + + frame_number = ost->packets_encoded; + if (vstats_version <= 1) { + fprintf(vstats_file, "frame= %5"PRId64" q= %2.1f ", frame_number, + ost->quality / (float)FF_QP2LAMBDA); + } else { + fprintf(vstats_file, "out= %2d st= %2d frame= %5"PRId64" q= %2.1f ", ost->file_index, ost->index, frame_number, + ost->quality / (float)FF_QP2LAMBDA); + } + + if (ost->error[0]>=0 && (enc->flags & AV_CODEC_FLAG_PSNR)) + fprintf(vstats_file, "PSNR= %6.2f ", psnr(ost->error[0] / (enc->width * enc->height * 255.0 * 255.0))); + + fprintf(vstats_file,"f_size= %6d ", pkt->size); + /* compute pts value */ + ti1 = pkt->dts * av_q2d(pkt->time_base); + if (ti1 < 0.01) + ti1 = 0.01; + + bitrate = (pkt->size * 8) / av_q2d(enc->time_base) / 1000.0; + avg_bitrate = (double)(ost->data_size_enc * 8) / ti1 / 1000.0; + fprintf(vstats_file, "s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s ", + (double)ost->data_size_enc / 1024, ti1, bitrate, avg_bitrate); + fprintf(vstats_file, "type= %c\n", av_get_picture_type_char(ost->pict_type)); +} + +static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame) +{ + AVCodecContext *enc = ost->enc_ctx; + AVPacket *pkt = ost->pkt; + const char *type_desc = av_get_media_type_string(enc->codec_type); + const char *action = frame ? "encode" : "flush"; + int ret; + + if (frame) { + if (ost->enc_stats_pre.io) + enc_stats_write(ost, &ost->enc_stats_pre, frame, NULL, + ost->frames_encoded); + + ost->frames_encoded++; + ost->samples_encoded += frame->nb_samples; + + if (debug_ts) { + av_log(ost, AV_LOG_INFO, "encoder <- type:%s " + "frame_pts:%s frame_pts_time:%s time_base:%d/%d\n", + type_desc, + av_ts2str(frame->pts), av_ts2timestr(frame->pts, &enc->time_base), + enc->time_base.num, enc->time_base.den); + } + } + + update_benchmark(NULL); + + ret = avcodec_send_frame(enc, frame); + if (ret < 0 && !(ret == AVERROR_EOF && !frame)) { + av_log(ost, AV_LOG_ERROR, "Error submitting %s frame to the encoder\n", + type_desc); + return ret; + } + + while (1) { + ret = avcodec_receive_packet(enc, pkt); + update_benchmark("%s_%s %d.%d", action, type_desc, + ost->file_index, ost->index); + + pkt->time_base = enc->time_base; + + /* if two pass, output log on success and EOF */ + if ((ret >= 0 || ret == AVERROR_EOF) && ost->logfile && enc->stats_out) + fprintf(ost->logfile, "%s", enc->stats_out); + + if (ret == AVERROR(EAGAIN)) { + av_assert0(frame); // should never happen during flushing + return 0; + } else if (ret == AVERROR_EOF) { + of_output_packet(of, pkt, ost, 1); + return ret; + } else if (ret < 0) { + av_log(ost, AV_LOG_ERROR, "%s encoding failed\n", type_desc); + return ret; + } + + if (enc->codec_type == AVMEDIA_TYPE_VIDEO) + update_video_stats(ost, pkt, !!vstats_filename); + if (ost->enc_stats_post.io) + enc_stats_write(ost, &ost->enc_stats_post, NULL, pkt, + ost->packets_encoded); + + if (debug_ts) { + av_log(ost, AV_LOG_INFO, "encoder -> type:%s " + "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s " + "duration:%s duration_time:%s\n", + type_desc, + av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &enc->time_base), + av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &enc->time_base), + av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &enc->time_base)); + } + + av_packet_rescale_ts(pkt, pkt->time_base, ost->mux_timebase); + pkt->time_base = ost->mux_timebase; + + if (debug_ts) { + av_log(ost, AV_LOG_INFO, "encoder -> type:%s " + "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s " + "duration:%s duration_time:%s\n", + type_desc, + av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &enc->time_base), + av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &enc->time_base), + av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &enc->time_base)); + } + + if ((ret = trigger_fix_sub_duration_heartbeat(ost, pkt)) < 0) { + av_log(NULL, AV_LOG_ERROR, + "Subtitle heartbeat logic failed in %s! (%s)\n", + __func__, av_err2str(ret)); + exit_program(1); + } + + ost->data_size_enc += pkt->size; + + ost->packets_encoded++; + + of_output_packet(of, pkt, ost, 0); + } + + av_assert0(0); +} + +static int submit_encode_frame(OutputFile *of, OutputStream *ost, + AVFrame *frame) +{ + int ret; + + if (ost->sq_idx_encode < 0) + return encode_frame(of, ost, frame); + + if (frame) { + ret = av_frame_ref(ost->sq_frame, frame); + if (ret < 0) + return ret; + frame = ost->sq_frame; + } + + ret = sq_send(of->sq_encode, ost->sq_idx_encode, + SQFRAME(frame)); + if (ret < 0) { + if (frame) + av_frame_unref(frame); + if (ret != AVERROR_EOF) + return ret; + } + + while (1) { + AVFrame *enc_frame = ost->sq_frame; + + ret = sq_receive(of->sq_encode, ost->sq_idx_encode, + SQFRAME(enc_frame)); + if (ret == AVERROR_EOF) { + enc_frame = NULL; + } else if (ret < 0) { + return (ret == AVERROR(EAGAIN)) ? 0 : ret; + } + + ret = encode_frame(of, ost, enc_frame); + if (enc_frame) + av_frame_unref(enc_frame); + if (ret < 0) { + if (ret == AVERROR_EOF) + close_output_stream(ost); + return ret; + } + } +} + +static void do_audio_out(OutputFile *of, OutputStream *ost, + AVFrame *frame) +{ + AVCodecContext *enc = ost->enc_ctx; + int ret; + + ret = enc_open(ost, frame); + if (ret < 0) + exit_program(1); + + if (frame->pts == AV_NOPTS_VALUE) + frame->pts = ost->next_pts; + else { + int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? 0 : of->start_time; + frame->pts = + av_rescale_q(frame->pts, frame->time_base, enc->time_base) - + av_rescale_q(start_time, AV_TIME_BASE_Q, enc->time_base); + } + frame->time_base = enc->time_base; + + if (!check_recording_time(ost, frame->pts, frame->time_base)) + return; + + ost->next_pts = frame->pts + frame->nb_samples; + + ret = submit_encode_frame(of, ost, frame); + if (ret < 0 && ret != AVERROR_EOF) + exit_program(1); +} + +static double adjust_frame_pts_to_encoder_tb(OutputFile *of, OutputStream *ost, + AVFrame *frame) +{ + double float_pts = AV_NOPTS_VALUE; // this is identical to frame.pts but with higher precision + const int64_t start_time = (of->start_time == AV_NOPTS_VALUE) ? + 0 : of->start_time; + + AVCodecContext *const enc = ost->enc_ctx; + + AVRational tb = enc->time_base; + AVRational filter_tb = frame->time_base; + const int extra_bits = av_clip(29 - av_log2(tb.den), 0, 16); + + if (frame->pts == AV_NOPTS_VALUE) + goto early_exit; + + tb.den <<= extra_bits; + float_pts = av_rescale_q(frame->pts, filter_tb, tb) - + av_rescale_q(start_time, AV_TIME_BASE_Q, tb); + float_pts /= 1 << extra_bits; + // avoid exact midoints to reduce the chance of rounding differences, this + // can be removed in case the fps code is changed to work with integers + float_pts += FFSIGN(float_pts) * 1.0 / (1<<17); + + frame->pts = av_rescale_q(frame->pts, filter_tb, enc->time_base) - + av_rescale_q(start_time, AV_TIME_BASE_Q, enc->time_base); + frame->time_base = enc->time_base; + +early_exit: + + if (debug_ts) { + av_log(NULL, AV_LOG_INFO, "filter -> pts:%s pts_time:%s exact:%f time_base:%d/%d\n", + frame ? av_ts2str(frame->pts) : "NULL", + (enc && frame) ? av_ts2timestr(frame->pts, &enc->time_base) : "NULL", + float_pts, + enc ? enc->time_base.num : -1, + enc ? enc->time_base.den : -1); + } + + return float_pts; +} + +/* Convert frame timestamps to the encoder timebase and decide how many times + * should this (and possibly previous) frame be repeated in order to conform to + * desired target framerate (if any). + */ +static void video_sync_process(OutputFile *of, OutputStream *ost, + AVFrame *next_picture, double duration, + int64_t *nb_frames, int64_t *nb_frames_prev) +{ + double delta0, delta; + + double sync_ipts = adjust_frame_pts_to_encoder_tb(of, ost, next_picture); + /* delta0 is the "drift" between the input frame (next_picture) and + * where it would fall in the output. */ + delta0 = sync_ipts - ost->next_pts; + delta = delta0 + duration; + + // tracks the number of times the PREVIOUS frame should be duplicated, + // mostly for variable framerate (VFR) + *nb_frames_prev = 0; + /* by default, we output a single frame */ + *nb_frames = 1; + + if (delta0 < 0 && + delta > 0 && + ost->vsync_method != VSYNC_PASSTHROUGH && + ost->vsync_method != VSYNC_DROP) { + if (delta0 < -0.6) { + av_log(ost, AV_LOG_VERBOSE, "Past duration %f too large\n", -delta0); + } else + av_log(ost, AV_LOG_DEBUG, "Clipping frame in rate conversion by %f\n", -delta0); + sync_ipts = ost->next_pts; + duration += delta0; + delta0 = 0; + } + + switch (ost->vsync_method) { + case VSYNC_VSCFR: + if (ost->vsync_frame_number == 0 && delta0 >= 0.5) { + av_log(ost, AV_LOG_DEBUG, "Not duplicating %d initial frames\n", (int)lrintf(delta0)); + delta = duration; + delta0 = 0; + ost->next_pts = llrint(sync_ipts); + } + case VSYNC_CFR: + // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c + if (frame_drop_threshold && delta < frame_drop_threshold && ost->vsync_frame_number) { + *nb_frames = 0; + } else if (delta < -1.1) + *nb_frames = 0; + else if (delta > 1.1) { + *nb_frames = llrintf(delta); + if (delta0 > 1.1) + *nb_frames_prev = llrintf(delta0 - 0.6); + } + next_picture->duration = 1; + break; + case VSYNC_VFR: + if (delta <= -0.6) + *nb_frames = 0; + else if (delta > 0.6) + ost->next_pts = llrint(sync_ipts); + next_picture->duration = duration; + break; + case VSYNC_DROP: + case VSYNC_PASSTHROUGH: + next_picture->duration = duration; + ost->next_pts = llrint(sync_ipts); + break; + default: + av_assert0(0); + } +} + +static enum AVPictureType forced_kf_apply(void *logctx, KeyframeForceCtx *kf, + AVRational tb, const AVFrame *in_picture, + int dup_idx) +{ + double pts_time; + + if (kf->ref_pts == AV_NOPTS_VALUE) + kf->ref_pts = in_picture->pts; + + pts_time = (in_picture->pts - kf->ref_pts) * av_q2d(tb); + if (kf->index < kf->nb_pts && + av_compare_ts(in_picture->pts, tb, kf->pts[kf->index], AV_TIME_BASE_Q) >= 0) { + kf->index++; + goto force_keyframe; + } else if (kf->pexpr) { + double res; + kf->expr_const_values[FKF_T] = pts_time; + res = av_expr_eval(kf->pexpr, + kf->expr_const_values, NULL); + av_log(logctx, AV_LOG_TRACE, + "force_key_frame: n:%f n_forced:%f prev_forced_n:%f t:%f prev_forced_t:%f -> res:%f\n", + kf->expr_const_values[FKF_N], + kf->expr_const_values[FKF_N_FORCED], + kf->expr_const_values[FKF_PREV_FORCED_N], + kf->expr_const_values[FKF_T], + kf->expr_const_values[FKF_PREV_FORCED_T], + res); + + kf->expr_const_values[FKF_N] += 1; + + if (res) { + kf->expr_const_values[FKF_PREV_FORCED_N] = kf->expr_const_values[FKF_N] - 1; + kf->expr_const_values[FKF_PREV_FORCED_T] = kf->expr_const_values[FKF_T]; + kf->expr_const_values[FKF_N_FORCED] += 1; + goto force_keyframe; + } + } else if (kf->type == KF_FORCE_SOURCE && + in_picture->key_frame == 1 && !dup_idx) { + goto force_keyframe; + } else if (kf->type == KF_FORCE_SOURCE_NO_DROP && !dup_idx) { + kf->dropped_keyframe = 0; + if ((in_picture->key_frame == 1) || kf->dropped_keyframe) + goto force_keyframe; + } + + return AV_PICTURE_TYPE_NONE; + +force_keyframe: + av_log(logctx, AV_LOG_DEBUG, "Forced keyframe at time %f\n", pts_time); + return AV_PICTURE_TYPE_I; +} + +/* May modify/reset next_picture */ +static void do_video_out(OutputFile *of, + OutputStream *ost, + AVFrame *next_picture) +{ + int ret; + AVCodecContext *enc = ost->enc_ctx; + AVRational frame_rate; + int64_t nb_frames, nb_frames_prev, i; + double duration = 0; + InputStream *ist = ost->ist; + AVFilterContext *filter = ost->filter->filter; + + ret = enc_open(ost, next_picture); + if (ret < 0) + exit_program(1); + + frame_rate = av_buffersink_get_frame_rate(filter); + if (frame_rate.num > 0 && frame_rate.den > 0) + duration = 1/(av_q2d(frame_rate) * av_q2d(enc->time_base)); + + if(ist && ist->st->start_time != AV_NOPTS_VALUE && ist->first_dts != AV_NOPTS_VALUE && ost->frame_rate.num) + duration = FFMIN(duration, 1/(av_q2d(ost->frame_rate) * av_q2d(enc->time_base))); + + if (!ost->filters_script && + !ost->filters && + (nb_filtergraphs == 0 || !filtergraphs[0]->graph_desc) && + next_picture && + ist && + lrintf(next_picture->duration * av_q2d(ist->st->time_base) / av_q2d(enc->time_base)) > 0) { + duration = lrintf(next_picture->duration * av_q2d(ist->st->time_base) / av_q2d(enc->time_base)); + } + + if (!next_picture) { + //end, flushing + nb_frames_prev = nb_frames = mid_pred(ost->last_nb0_frames[0], + ost->last_nb0_frames[1], + ost->last_nb0_frames[2]); + } else { + video_sync_process(of, ost, next_picture, duration, + &nb_frames, &nb_frames_prev); + } + + memmove(ost->last_nb0_frames + 1, + ost->last_nb0_frames, + sizeof(ost->last_nb0_frames[0]) * (FF_ARRAY_ELEMS(ost->last_nb0_frames) - 1)); + ost->last_nb0_frames[0] = nb_frames_prev; + + if (nb_frames_prev == 0 && ost->last_dropped) { + nb_frames_drop++; + av_log(ost, AV_LOG_VERBOSE, + "*** dropping frame %"PRId64" at ts %"PRId64"\n", + ost->vsync_frame_number, ost->last_frame->pts); + } + if (nb_frames > (nb_frames_prev && ost->last_dropped) + (nb_frames > nb_frames_prev)) { + if (nb_frames > dts_error_threshold * 30) { + av_log(ost, AV_LOG_ERROR, "%"PRId64" frame duplication too large, skipping\n", nb_frames - 1); + nb_frames_drop++; + return; + } + nb_frames_dup += nb_frames - (nb_frames_prev && ost->last_dropped) - (nb_frames > nb_frames_prev); + av_log(ost, AV_LOG_VERBOSE, "*** %"PRId64" dup!\n", nb_frames - 1); + if (nb_frames_dup > dup_warning) { + av_log(ost, AV_LOG_WARNING, "More than %"PRIu64" frames duplicated\n", dup_warning); + dup_warning *= 10; + } + } + ost->last_dropped = nb_frames == nb_frames_prev && next_picture; + ost->kf.dropped_keyframe = ost->last_dropped && next_picture && next_picture->key_frame; + + /* duplicates frame if needed */ + for (i = 0; i < nb_frames; i++) { + AVFrame *in_picture; + + if (i < nb_frames_prev && ost->last_frame->buf[0]) { + in_picture = ost->last_frame; + } else + in_picture = next_picture; + + if (!in_picture) + return; + + in_picture->pts = ost->next_pts; + + if (!check_recording_time(ost, in_picture->pts, ost->enc_ctx->time_base)) + return; + + in_picture->quality = enc->global_quality; + in_picture->pict_type = forced_kf_apply(ost, &ost->kf, enc->time_base, in_picture, i); + + ret = submit_encode_frame(of, ost, in_picture); + if (ret == AVERROR_EOF) + break; + else if (ret < 0) + exit_program(1); + + ost->next_pts++; + ost->vsync_frame_number++; + } + + av_frame_unref(ost->last_frame); + if (next_picture) + av_frame_move_ref(ost->last_frame, next_picture); +} + +void enc_frame(OutputStream *ost, AVFrame *frame) +{ + OutputFile *of = output_files[ost->file_index]; + + if (ost->enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO) do_video_out(of, ost, frame); + else do_audio_out(of, ost, frame); +} + +void enc_flush(void) +{ + int ret; + + for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) { + OutputFile *of = output_files[ost->file_index]; + if (ost->sq_idx_encode >= 0) + sq_send(of->sq_encode, ost->sq_idx_encode, SQFRAME(NULL)); + } + + for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) { + AVCodecContext *enc = ost->enc_ctx; + OutputFile *of = output_files[ost->file_index]; + + if (!enc) + continue; + + // Try to enable encoding with no input frames. + // Maybe we should just let encoding fail instead. + if (!ost->initialized) { + FilterGraph *fg = ost->filter->graph; + + av_log(ost, AV_LOG_WARNING, + "Finishing stream without any data written to it.\n"); + + if (ost->filter && !fg->graph) { + int x; + for (x = 0; x < fg->nb_inputs; x++) { + InputFilter *ifilter = fg->inputs[x]; + if (ifilter->format < 0 && + ifilter_parameters_from_codecpar(ifilter, ifilter->ist->par) < 0) { + av_log(ost, AV_LOG_ERROR, "Error copying paramerets from input stream\n"); + exit_program(1); + } + } + + if (!ifilter_has_all_input_formats(fg)) + continue; + + ret = configure_filtergraph(fg); + if (ret < 0) { + av_log(ost, AV_LOG_ERROR, "Error configuring filter graph\n"); + exit_program(1); + } + + of_output_packet(of, ost->pkt, ost, 1); + } + + ret = enc_open(ost, NULL); + if (ret < 0) + exit_program(1); + } + + if (enc->codec_type != AVMEDIA_TYPE_VIDEO && enc->codec_type != AVMEDIA_TYPE_AUDIO) + continue; + + ret = submit_encode_frame(of, ost, NULL); + if (ret != AVERROR_EOF) + exit_program(1); + } +} From patchwork Sat Mar 25 19:15:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 40824 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7a30:b0:df:834d:2c1a with SMTP id t48csp225599pzh; Sat, 25 Mar 2023 12:16:57 -0700 (PDT) X-Google-Smtp-Source: AKy350a5YqDCWwggv44rUZ86KJlD7PsgvhiRnScpEHHetY3uNFSgZWMpg8zzwi/mZ745zNM1otZp X-Received: by 2002:a17:906:9c84:b0:932:3ca:e228 with SMTP id fj4-20020a1709069c8400b0093203cae228mr8492738ejc.0.1679771816997; Sat, 25 Mar 2023 12:16:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679771816; cv=none; d=google.com; s=arc-20160816; b=Ysnk9xLJZIFgt3L5z/lHdNZipvuFqbFVVwUx6JmFnYrTnmhiIChKnD4WqGK2qJkoEM JZuHC6MnIfqwbEqobgKnmnACDnxEeR6Aylz33r65EKnJ4keWF1EwF3xtuRN6b+Fan20H i69PiRlIm/iXmjw1Cq9BEYSWcLpHjoVpkVippqbdl4lW9rt/tVCKEBC60VSezq8u0sAx yFfkY6jgAJ69azG8eo9pE+V8X7Km9v6WH4CPcPNZqVYU20Rb05Ye5lHvfnJ3DE5q5QOB IgBueG+hZGJ4rFHt25+JHdpIJjBfuCaDRpNyN9uez7YvS+0kBn5b+w8AnxtHUwotEvH5 bkoA== 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:delivered-to; bh=+XK/mKI9UiXl59M59qV7KF2zx4+MKkK/4kDE471ByOw=; b=XIjpyLYMXlmJFs04/2rSJ21ig0Htxs8tf3BCWdyXVpu6bKA/vK/W4E/BvVAmz9JJCT dAukvMHgzQfmwXiMOU+Ifao+tlZF4D2YmZQF7HlRa12AsH3FvGlmk0qmogT1QrfsELOz P4gdV1/IFv8fj7/Qt9spdls3Vlywgk8dBwb2q2HiznsqMhc8bcM2tny6hBYe4A4L2Vj9 sI0rgfHhbvikSmkTAuBCKgS++hQ9/0W1/yCxq+YCxq8RR7s4bFQ2vEzuh8DpnNvGUc+n FT3u2JhaJfJP1i3doxQOXwAGGWOnyRJkOQVdZx7bYc5NnnSy6Z/Iowl+oe9PGXTuC+wB Hjmw== 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id f8-20020a05640214c800b00501d4f93130si15819278edx.646.2023.03.25.12.16.56; Sat, 25 Mar 2023 12:16:56 -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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 7FE2368C95C; Sat, 25 Mar 2023 21:16:14 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail0.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id BD3B868C937 for ; Sat, 25 Mar 2023 21:16:08 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id 7D1642404EE for ; Sat, 25 Mar 2023 20:16:08 +0100 (CET) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id T2tUlA2_OhLD for ; Sat, 25 Mar 2023 20:16:07 +0100 (CET) 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 mail0.khirnov.net (Postfix) with ESMTPS id 2D3A22406CE for ; Sat, 25 Mar 2023 20:16:01 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 437C73A07D9 for ; Sat, 25 Mar 2023 20:15:55 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 25 Mar 2023 20:15:26 +0100 Message-Id: <20230325191529.10578-20-anton@khirnov.net> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230325191529.10578-1-anton@khirnov.net> References: <20230325191529.10578-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 20/23] fftools/ffmpeg: stop including os_support.h 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: EM4vlrxQj2I6 It was added for usleep(), which - is not used in ffmpeg - is not handled in os_support.h anymore --- fftools/ffmpeg.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 7a6b206d11..63dd97a130 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -63,7 +63,6 @@ #include "libavutil/thread.h" #include "libavutil/threadmessage.h" #include "libavcodec/version.h" -#include "libavformat/os_support.h" # include "libavfilter/avfilter.h" # include "libavfilter/buffersrc.h" From patchwork Sat Mar 25 19:15:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 40831 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:7a30:b0:df:834d:2c1a with SMTP id t48csp226052pzh; Sat, 25 Mar 2023 12:18:00 -0700 (PDT) X-Google-Smtp-Source: AKy350bm84JFV7UfQpzu/8XKa0aNzm+avB8DZINTs931gamtYdm0d7KPLiTgybgejhn+efKRUEMj X-Received: by 2002:a17:906:5785:b0:93d:1c2b:bd23 with SMTP id k5-20020a170906578500b0093d1c2bbd23mr8224936ejq.39.1679771880094; Sat, 25 Mar 2023 12:18:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679771880; cv=none; d=google.com; s=arc-20160816; b=QMlnNHjF+qN2tXqoCaRbsJq+gMeTAYEnEXgFy+NA9S5fd8sUM/8p+SiohkT7DHW0sE LhF4F1QkTqCZFXj5TJTH9NCCacEgySX/Q5qRwP/6szULPV/R201RSY1ZNXcZTo1GmdDV WmcZr66fyDbE7yaAug58g+3ycycZ9EBp+65J7eAbovYQvqF+rAHkEkP1XKAZm9AeiGn9 kUN0+cjMIkzudpFGU6OxBd8BEWKYFvIFrYJWPKDYEoHMWvP5gyxbn4xQbcAkOVxuVt4H D+k9dC4WWpu2xrZ7b7wAoJDWTI86tFqgmNe1NlJrTTU1MEI/2kRvl7ebgRmDL4EAsmmV 5G0Q== 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:delivered-to; bh=cYLvfIQggg4fkfroXZwfWT+1W7P0Xel8RQuaM+weQgQ=; b=H5MEnn9BpfEp8lmETOmeO3Qyakmm8ZU9+ZNT6rFmm59P1j/liogQMNLvDaUX9Um4jG J6md3jSDv6UjK3fuyWo8RQlVeuvP8UOnrX6fxLlWNFf5ng8/+nHZkfBD1kg5cC79xalK c3slPoqepdUi9fmUF78hqGdDzpR7BFrhtN2IvT5kJyFoTRfQEkC9uiAhtprof2oTa+Bl nUdk36zP+EETq2k/zNDtA+NGsRDz5WuMH8DkxB0sj3WZXWzK67bL7HDufHmuBhq1EGgF gbRNJL3IZ/ZDfQaNi5Fyyeup5ADUPEG83P+0WLYdbG6ZSZjDRsAFdzlwA+Uztl/jdJW2 vxqg== 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id r9-20020aa7d149000000b004acbeceab83si24692546edo.448.2023.03.25.12.17.59; Sat, 25 Mar 2023 12:18:00 -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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 5D64968C9DF; Sat, 25 Mar 2023 21:16:21 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail0.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 186BB68C904 for ; Sat, 25 Mar 2023 21:16:12 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id C47792404EE for ; Sat, 25 Mar 2023 20:16:11 +0100 (CET) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id huVVA4MRpKZV for ; Sat, 25 Mar 2023 20:16:10 +0100 (CET) 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 mail0.khirnov.net (Postfix) with ESMTPS id 4FD42240D1B for ; Sat, 25 Mar 2023 20:16:01 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 5A1DE3A07F4 for ; Sat, 25 Mar 2023 20:15:55 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Sat, 25 Mar 2023 20:15:28 +0100 Message-Id: <20230325191529.10578-22-anton@khirnov.net> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230325191529.10578-1-anton@khirnov.net> References: <20230325191529.10578-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 22/23] fftools/ffmpeg: clean up local includes 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: 2/+TXuWxB3Dj Group them by the library, sort alphabetically. --- fftools/ffmpeg.c | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index eedd51d407..ae69d29ab7 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -68,40 +68,43 @@ #include #endif -#include "libavformat/avformat.h" -#include "libavdevice/avdevice.h" -#include "libswresample/swresample.h" -#include "libavutil/opt.h" +#include "libavutil/avassert.h" +#include "libavutil/avstring.h" +#include "libavutil/bprint.h" #include "libavutil/channel_layout.h" -#include "libavutil/parseutils.h" -#include "libavutil/samplefmt.h" +#include "libavutil/dict.h" +#include "libavutil/display.h" #include "libavutil/fifo.h" #include "libavutil/hwcontext.h" +#include "libavutil/imgutils.h" #include "libavutil/intreadwrite.h" -#include "libavutil/dict.h" -#include "libavutil/display.h" +#include "libavutil/libm.h" #include "libavutil/mathematics.h" +#include "libavutil/opt.h" +#include "libavutil/parseutils.h" #include "libavutil/pixdesc.h" -#include "libavutil/avstring.h" -#include "libavutil/libm.h" -#include "libavutil/imgutils.h" -#include "libavutil/timestamp.h" -#include "libavutil/bprint.h" -#include "libavutil/time.h" +#include "libavutil/samplefmt.h" #include "libavutil/thread.h" #include "libavutil/threadmessage.h" +#include "libavutil/time.h" +#include "libavutil/timestamp.h" + #include "libavcodec/version.h" -# include "libavfilter/avfilter.h" -# include "libavfilter/buffersrc.h" -# include "libavfilter/buffersink.h" +#include "libavformat/avformat.h" + +#include "libavdevice/avdevice.h" + +#include "libswresample/swresample.h" + +#include "libavfilter/avfilter.h" +#include "libavfilter/buffersrc.h" +#include "libavfilter/buffersink.h" -#include "ffmpeg.h" #include "cmdutils.h" +#include "ffmpeg.h" #include "sync_queue.h" -#include "libavutil/avassert.h" - const char program_name[] = "ffmpeg"; const int program_birth_year = 2000;