From patchwork Tue Jan 11 09:58:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 33220 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a6b:cd86:0:0:0:0:0 with SMTP id d128csp3546807iog; Tue, 11 Jan 2022 02:02:07 -0800 (PST) X-Google-Smtp-Source: ABdhPJzDrsOdYvM+TXlpVYYMitK3AWN3PYGh5ntflP88Imq6M3Xvl8WXty78uFWhCG+vgqScuoDm X-Received: by 2002:a05:6402:180d:: with SMTP id g13mr3537096edy.187.1641895327242; Tue, 11 Jan 2022 02:02:07 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1641895327; cv=none; d=google.com; s=arc-20160816; b=CEnG4kZvmggNFl74MOJfwemPxiIRPstXqu2CZCMVZIkBYT8IoDeeTuGJUJ8LfrQrXF CxoagkYnlD4KUeBeAjkTDADhBqPCO2t+HWiFh0o8/OFRot34t1W5p38KJO/vtVHe9EAb 9WGImIWsw9kucLedY92mqeHkz3ManF1hWI7uIqNPTYTQt8A4YjoBsmGQmUFhUTREDM3l HW8XLOqq7Sw6uXfWKSAYjBwszKpIE9ZA61P5fkHVJhnz4EdH/POcsD8jQS2p8UJa2Cvb zOdWoEn+3N0PCaVIYjotJmwd4oVHyqLeAGQb5Nb+C/3XZXVjEJ6vPk8gsxmLoHkWFD+v /Dvw== 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=3FZkbtVnL/hLBx88gOa+6uHbaLmuEACpxasuszG7mrc=; b=kdoqUswO1Is2LBVrTpKWgPv0DOuDI57t7kRdbG0TPYJfLYkXHAPKGB3IKNq/aUlwCq WUYotK2CNTzi4WZrlNx1qL+iHY7ZA0VQQPGZA+Odw9yQVMOW4AGZqni+P2tfdylafHJq zd2lWm9tlVjNILq2IZg6z/VwAZPzqOtD+IfvLxmp9ZMaFwZ30gfePLBeMCRBhPeR7ZMR pyI3nXng3YLNB/h7+hpk9UlfU5fA2v5OZsATKGMb8rJqkg9/EcdIAfjq+p+EHv+cVWcN bnU2Rx113LTcT634NmmzppPG4FsF60Z/RUJjaepZti3Q7NtlRD2dE6DZjRkGQLTyE0Mr p5Xw== 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 bm12si4527119ejb.245.2022.01.11.02.02.02; Tue, 11 Jan 2022 02:02:07 -0800 (PST) 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 BC4E468AFDF; Tue, 11 Jan 2022 11:59:26 +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 AE58C68AF51 for ; Tue, 11 Jan 2022 11:59:14 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id CCBEC24062A for ; Tue, 11 Jan 2022 10:59:12 +0100 (CET) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id LKaC2hQRxZYd for ; Tue, 11 Jan 2022 10:59:12 +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 EC80924068C for ; Tue, 11 Jan 2022 10:59:02 +0100 (CET) Received: by libav.khirnov.net (Postfix, from userid 1000) id 378A83A0C80; Tue, 11 Jan 2022 10:59:02 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Tue, 11 Jan 2022 10:58:25 +0100 Message-Id: <20220111095830.31542-23-anton@khirnov.net> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20220111095830.31542-1-anton@khirnov.net> References: <20220111095830.31542-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 23/28] ffmpeg: move processing video stats to ffmpeg_mux 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: Aj0i2C+URXnF Currently it is called from - do_video_out(), at the end of each encode loop iteration - from flush_encoders(), after muxing each packet Since this function processes the data from the last encoded packet, neither of the above is fully correct, because - an encoder can in principle produce multiple packets per one submitted frame - bitstream filters may modify the number of encoded packets or their properties. It thus makes most sense to call this function right before sending the packet to the muxer. --- fftools/ffmpeg.c | 61 +------------------------------------------- fftools/ffmpeg.h | 5 ++++ fftools/ffmpeg_mux.c | 47 ++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 60 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index f39b1b9375..c89a95937e 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -109,7 +109,7 @@ const char program_name[] = "ffmpeg"; const int program_birth_year = 2000; -static FILE *vstats_file; +FILE *vstats_file; const char *const forced_keyframes_const_names[] = { "n", @@ -126,7 +126,6 @@ typedef struct BenchmarkTimeStamps { int64_t sys_usec; } BenchmarkTimeStamps; -static void do_video_stats(OutputStream *ost, int frame_size); static BenchmarkTimeStamps get_benchmark_time_stamps(void); static int64_t getmaxrss(void); static int ifilter_has_all_input_formats(FilterGraph *fg); @@ -977,7 +976,6 @@ static void do_video_out(OutputFile *of, double delta, delta0; double duration = 0; double sync_ipts = AV_NOPTS_VALUE; - int frame_size = 0; InputStream *ist = NULL; AVFilterContext *filter = ost->filter->filter; @@ -1213,7 +1211,6 @@ static void do_video_out(OutputFile *of, av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ost->mux_timebase)); } - frame_size = pkt->size; output_packet(of, pkt, ost, 0); /* if two pass, output log */ @@ -1223,9 +1220,6 @@ static void do_video_out(OutputFile *of, } ost->sync_opts++; ost->frame_number++; - - if (vstats_filename && frame_size) - do_video_stats(ost, frame_size); } av_frame_unref(ost->last_frame); @@ -1238,54 +1232,6 @@ error: exit_program(1); } -static double psnr(double d) -{ - return -10.0 * log10(d); -} - -static void do_video_stats(OutputStream *ost, int frame_size) -{ - AVCodecContext *enc; - int frame_number; - double ti1, bitrate, avg_bitrate; - - /* this is executed just the first time do_video_stats is called */ - if (!vstats_file) { - vstats_file = fopen(vstats_filename, "w"); - if (!vstats_file) { - perror("fopen"); - exit_program(1); - } - } - - enc = ost->enc_ctx; - if (enc->codec_type == AVMEDIA_TYPE_VIDEO) { - frame_number = ost->st->nb_frames; - if (vstats_version <= 1) { - fprintf(vstats_file, "frame= %5d q= %2.1f ", frame_number, - ost->quality / (float)FF_QP2LAMBDA); - } else { - fprintf(vstats_file, "out= %2d st= %2d frame= %5d 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 ", frame_size); - /* compute pts value */ - ti1 = av_stream_get_end_pts(ost->st) * av_q2d(ost->st->time_base); - if (ti1 < 0.01) - ti1 = 0.01; - - bitrate = (frame_size * 8) / av_q2d(enc->time_base) / 1000.0; - avg_bitrate = (double)(ost->data_size * 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 / 1024, ti1, bitrate, avg_bitrate); - fprintf(vstats_file, "type= %c\n", av_get_picture_type_char(ost->pict_type)); - } -} - static void finish_output_stream(OutputStream *ost) { OutputFile *of = output_files[ost->file_index]; @@ -1764,7 +1710,6 @@ static void flush_encoders(void) for (;;) { const char *desc = NULL; AVPacket *pkt = ost->pkt; - int pkt_size; switch (enc->codec_type) { case AVMEDIA_TYPE_AUDIO: @@ -1808,11 +1753,7 @@ static void flush_encoders(void) continue; } av_packet_rescale_ts(pkt, enc->time_base, ost->mux_timebase); - pkt_size = pkt->size; output_packet(of, pkt, ost, 0); - if (ost->enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO && vstats_filename) { - do_video_stats(ost, pkt_size); - } } } } diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index d9f997bf7a..908dc2eb38 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -624,6 +624,7 @@ extern int stdin_interaction; extern int frame_bits_per_raw_sample; extern AVIOContext *progress_avio; extern float max_error_rate; +extern FILE *vstats_file; extern char *filter_nbthreads; extern int filter_complex_nbthreads; @@ -641,6 +642,10 @@ extern HWDevice *filter_hw_device; extern unsigned nb_output_dumped; extern int main_return_code; +static inline double psnr(double d) +{ + return -10.0 * log10(d); +} void term_init(void); void term_exit(void); diff --git a/fftools/ffmpeg_mux.c b/fftools/ffmpeg_mux.c index 729cc1a7d8..76d9d4b9c4 100644 --- a/fftools/ffmpeg_mux.c +++ b/fftools/ffmpeg_mux.c @@ -56,6 +56,49 @@ struct Muxer { static int want_sdp = 1; +static void do_video_stats(OutputStream *ost, int frame_size) +{ + AVCodecContext *enc; + int frame_number; + double ti1, bitrate, avg_bitrate; + + /* this is executed just the first time do_video_stats is called */ + if (!vstats_file) { + vstats_file = fopen(vstats_filename, "w"); + if (!vstats_file) { + perror("fopen"); + exit_program(1); + } + } + + enc = ost->enc_ctx; + if (enc->codec_type == AVMEDIA_TYPE_VIDEO) { + frame_number = ost->st->nb_frames; + if (vstats_version <= 1) { + fprintf(vstats_file, "frame= %5d q= %2.1f ", frame_number, + ost->quality / (float)FF_QP2LAMBDA); + } else { + fprintf(vstats_file, "out= %2d st= %2d frame= %5d 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 ", frame_size); + /* compute pts value */ + ti1 = av_stream_get_end_pts(ost->st) * av_q2d(ost->st->time_base); + if (ti1 < 0.01) + ti1 = 0.01; + + bitrate = (frame_size * 8) / av_q2d(enc->time_base) / 1000.0; + avg_bitrate = (double)(ost->data_size * 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 / 1024, ti1, bitrate, avg_bitrate); + fprintf(vstats_file, "type= %c\n", av_get_picture_type_char(ost->pict_type)); + } +} + static void close_all_output_streams(OutputStream *ost, OSTFinished this_stream, OSTFinished others) { int i; @@ -180,6 +223,10 @@ static void write_packet(OutputFile *of, OutputStream *ost, AVPacket *pkt) ost->data_size += pkt->size; ost->packets_written++; + if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && + ost->encoding_needed && vstats_filename) + do_video_stats(ost, pkt->size); + pkt->stream_index = ost->index; if (debug_ts) {