[FFmpeg-devel] [PATCH 2/2] fftools/ffmpeg.c: Add an option "multiple_output_final_stats"
Wang Cao
doubleecao at gmail.com
Sat Jun 27 00:28:30 EEST 2020
From: Wang Cao <doubleecao at gmail.com>
* "multiple_output_final_stats" is used to display stats for each output when ffmpeg completes processing.
* Also refactor to add a new function to print verbose stats for input/output so that the behavior is same as before by default.
Signed-off-by: Wang Cao <doubleecao at gmail.com>
---
doc/ffmpeg.texi | 6 +++++
fftools/ffmpeg.c | 53 +++++++++++++++++++++++++++++---------------
fftools/ffmpeg.h | 1 +
fftools/ffmpeg_opt.c | 3 +++
4 files changed, 45 insertions(+), 18 deletions(-)
diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index 70b8965d7f..6c88c97c60 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -734,6 +734,12 @@ ffmpeg -dump_attachment:t "" -i INPUT
Technical note -- attachments are implemented as codec extradata, so this
option can actually be used to extract extradata from any stream, not just
attachments.
+
+ at item -multiple_output_final_stats (@emph{global})
+Print final stats for each output when processing completes.
+ at example
+ffmpeg -i INPUT -multiple_output_final_stats out0.mkv out1.mkv
+ at end example
@end table
@section Video Options
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 07396204b6..1757899d7f 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -1514,8 +1514,9 @@ static int reap_filters(int flush)
return 0;
}
-static void print_final_stats(int64_t total_size)
+static void print_final_stats(int64_t total_size, int output_file_index)
{
+ OutputFile *of;
AVFormatContext *oc;
uint64_t video_size = 0, audio_size = 0, extra_size = 0, other_size = 0;
uint64_t subtitle_size = 0;
@@ -1524,10 +1525,11 @@ static void print_final_stats(int64_t total_size)
int i, j;
int pass1_used = 1;
- oc = output_files[0]->ctx;
+ of = output_files[output_file_index];
+ oc = of->ctx;
for (i = 0; i < oc->nb_streams; i++) {
- OutputStream *ost = output_streams[i];
+ OutputStream *ost = output_streams[of->ost_index + i];
switch (ost->enc_ctx->codec_type) {
case AVMEDIA_TYPE_VIDEO: video_size += ost->data_size; break;
case AVMEDIA_TYPE_AUDIO: audio_size += ost->data_size; break;
@@ -1555,6 +1557,18 @@ static void print_final_stats(int64_t total_size)
else
av_log(NULL, AV_LOG_INFO, "unknown");
av_log(NULL, AV_LOG_INFO, "\n");
+ if (video_size + data_size + audio_size + subtitle_size + extra_size == 0){
+ av_log(NULL, AV_LOG_WARNING, "Output file is empty, nothing was encoded ");
+ if (pass1_used) {
+ av_log(NULL, AV_LOG_WARNING, "\n");
+ } else {
+ av_log(NULL, AV_LOG_WARNING, "(check -ss / -t / -frames parameters if used)\n");
+ }
+ }
+}
+
+static void print_verbose_input_output_stats() {
+ int i, j;
/* print verbose per-stream stats */
for (i = 0; i < nb_input_files; i++) {
@@ -1624,20 +1638,14 @@ static void print_final_stats(int64_t total_size)
av_log(NULL, AV_LOG_VERBOSE, " Total: %"PRIu64" packets (%"PRIu64" bytes) muxed\n",
total_packets, total_size);
}
- if(video_size + data_size + audio_size + subtitle_size + extra_size == 0){
- av_log(NULL, AV_LOG_WARNING, "Output file is empty, nothing was encoded ");
- if (pass1_used) {
- av_log(NULL, AV_LOG_WARNING, "\n");
- } else {
- av_log(NULL, AV_LOG_WARNING, "(check -ss / -t / -frames parameters if used)\n");
- }
- }
}
-static void print_report(int is_last_report, int64_t timer_start, int64_t cur_time)
+static void print_report(int is_last_report, int output_file_index,
+ int64_t timer_start, int64_t cur_time)
{
AVBPrint buf, buf_script;
OutputStream *ost;
+ OutputFile *of;
AVFormatContext *oc;
int64_t total_size;
AVCodecContext *enc;
@@ -1668,7 +1676,8 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
t = (cur_time-timer_start) / 1000000.0;
- oc = output_files[0]->ctx;
+ of = output_files[output_file_index];
+ oc = of->ctx;
total_size = avio_size(oc->pb);
if (total_size <= 0) // FIXME improve avio_size() so it works with non seekable output too
@@ -1679,7 +1688,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
av_bprint_init(&buf_script, 0, AV_BPRINT_SIZE_AUTOMATIC);
for (i = 0; i < oc->nb_streams; i++) {
float q = -1;
- ost = output_streams[i];
+ ost = output_streams[of->ost_index + i];
enc = ost->enc_ctx;
if (!ost->stream_copy)
q = ost->quality / (float) FF_QP2LAMBDA;
@@ -1830,7 +1839,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
}
if (is_last_report)
- print_final_stats(total_size);
+ print_final_stats(total_size, output_file_index);
}
static void ifilter_parameters_from_codecpar(InputFilter *ifilter, AVCodecParameters *par)
@@ -4672,7 +4681,7 @@ static int transcode(void)
}
/* dump report by using the output first video and audio streams */
- print_report(0, timer_start, cur_time);
+ print_report(0, 0, timer_start, cur_time);
}
#if HAVE_THREADS
free_input_threads();
@@ -4706,8 +4715,16 @@ static int transcode(void)
}
}
- /* dump report by using the first video and audio streams */
- print_report(1, timer_start, av_gettime_relative());
+ /* dump report for each output */
+ if (multiple_output_final_stats) {
+ for (i = 0; i < nb_output_files; i++) {
+ print_report(1, i, timer_start, av_gettime_relative());
+ }
+ } else {
+ /* dump report by using the first video and audio streams */
+ print_report(1, 0, timer_start, av_gettime_relative());
+ }
+ print_verbose_input_output_stats();
/* close each encoder */
for (i = 0; i < nb_output_streams; i++) {
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 6e3f2545c7..44414746e0 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -609,6 +609,7 @@ extern int frame_bits_per_raw_sample;
extern AVIOContext *progress_avio;
extern float max_error_rate;
extern char *videotoolbox_pixfmt;
+extern int multiple_output_final_stats;
extern int filter_nbthreads;
extern int filter_complex_nbthreads;
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index 9d1489ce01..2154a79aeb 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -172,6 +172,7 @@ float max_error_rate = 2.0/3;
int filter_nbthreads = 0;
int filter_complex_nbthreads = 0;
int vstats_version = 2;
+int multiple_output_final_stats = 0;
static int intra_only = 0;
@@ -3569,6 +3570,8 @@ const OptionDef options[] = {
"set the maximum number of queued packets from the demuxer" },
{ "find_stream_info", OPT_BOOL | OPT_PERFILE | OPT_INPUT | OPT_EXPERT, { &find_stream_info },
"read and decode the streams to fill missing information with heuristics" },
+ { "multiple_output_final_stats", OPT_BOOL | OPT_EXPERT, { &multiple_output_final_stats },
+ "display the encoding stats for first stream of each output." },
/* video options */
{ "vframes", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_video_frames },
--
2.27.0.212.ge8ba1cc988-goog
More information about the ffmpeg-devel
mailing list