Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH 1/2] fftools/ffmpeg: store output packet timebases in the packet
@ 2023-02-07  9:33 Anton Khirnov
  2023-02-07  9:33 ` [FFmpeg-devel] [PATCH 2/2] fftools/ffmpeg: add an option for writing pre-muxing stats Anton Khirnov
  0 siblings, 1 reply; 8+ messages in thread
From: Anton Khirnov @ 2023-02-07  9:33 UTC (permalink / raw)
  To: ffmpeg-devel

Useful to keep track of what timebase the packet's timestamps are in.
---
 fftools/ffmpeg.c     | 33 ++++++++++++++++++++-------------
 fftools/ffmpeg_mux.c |  7 ++++---
 2 files changed, 24 insertions(+), 16 deletions(-)

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 743bc0c6b6..32e0c3febd 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -797,7 +797,7 @@ static void update_video_stats(OutputStream *ost, const AVPacket *pkt, int write
 
     fprintf(vstats_file,"f_size= %6d ", pkt->size);
     /* compute pts value */
-    ti1 = pkt->dts * av_q2d(ost->mux_timebase);
+    ti1 = pkt->dts * av_q2d(pkt->time_base);
     if (ti1 < 0.01)
         ti1 = 0.01;
 
@@ -812,7 +812,7 @@ static void enc_stats_write(OutputStream *ost, EncStats *es,
                             const AVFrame *frame, const AVPacket *pkt)
 {
     AVIOContext *io = es->io;
-    AVRational   tb = ost->enc_ctx->time_base;
+    AVRational   tb = frame ? frame->time_base : pkt->time_base;
     int64_t     pts = frame ? frame->pts : pkt->pts;
 
     AVRational  tbi = (AVRational){ 0, 1};
@@ -912,6 +912,8 @@ static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame)
         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);
@@ -942,7 +944,8 @@ static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame)
                    av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &enc->time_base));
         }
 
-        av_packet_rescale_ts(pkt, enc->time_base, ost->mux_timebase);
+        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 "
@@ -1103,17 +1106,19 @@ static void do_subtitle_out(OutputFile *of,
         }
 
         av_shrink_packet(pkt, subtitle_out_size);
-        pkt->pts  = av_rescale_q(sub->pts, AV_TIME_BASE_Q, ost->mux_timebase);
-        pkt->duration = av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, ost->mux_timebase);
+        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 }, ost->mux_timebase);
+                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 }, ost->mux_timebase);
+                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);
     }
 }
@@ -1900,25 +1905,27 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
     if (av_packet_ref(opkt, pkt) < 0)
         exit_program(1);
 
+    opkt->time_base = ost->mux_timebase;
+
     if (pkt->pts != AV_NOPTS_VALUE)
-        opkt->pts = av_rescale_q(pkt->pts, ist->st->time_base, ost->mux_timebase) - ost_tb_start_time;
+        opkt->pts = av_rescale_q(pkt->pts, ist->st->time_base, opkt->time_base) - ost_tb_start_time;
 
     if (pkt->dts == AV_NOPTS_VALUE) {
-        opkt->dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q, ost->mux_timebase);
+        opkt->dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q, opkt->time_base);
     } else if (ost->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
         int duration = av_get_audio_frame_duration2(ist->par, pkt->size);
         if(!duration)
             duration = ist->par->frame_size;
         opkt->dts = av_rescale_delta(ist->st->time_base, pkt->dts,
                                     (AVRational){1, ist->par->sample_rate}, duration,
-                                    &ist->filter_in_rescale_delta_last, ost->mux_timebase);
+                                    &ist->filter_in_rescale_delta_last, opkt->time_base);
         /* dts will be set immediately afterwards to what pts is now */
         opkt->pts = opkt->dts - ost_tb_start_time;
     } else
-        opkt->dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->mux_timebase);
+        opkt->dts = av_rescale_q(pkt->dts, ist->st->time_base, opkt->time_base);
     opkt->dts -= ost_tb_start_time;
 
-    opkt->duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->mux_timebase);
+    opkt->duration = av_rescale_q(pkt->duration, ist->st->time_base, opkt->time_base);
 
     {
         int ret = trigger_fix_sub_duration_heartbeat(ost, pkt);
@@ -2475,7 +2482,7 @@ static int fix_sub_duration_heartbeat(InputStream *ist, int64_t signal_pts)
 static 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, ost->mux_timebase,
+    int64_t signal_pts = av_rescale_q(pkt->pts, pkt->time_base,
                                       AV_TIME_BASE_Q);
 
     if (!ost->fix_sub_duration_heartbeat || !(pkt->flags & AV_PKT_FLAG_KEY))
diff --git a/fftools/ffmpeg_mux.c b/fftools/ffmpeg_mux.c
index 5d427b44ea..30764e22d1 100644
--- a/fftools/ffmpeg_mux.c
+++ b/fftools/ffmpeg_mux.c
@@ -81,11 +81,12 @@ static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
             if (pkt->duration > 0)
                 av_log(ost, AV_LOG_WARNING, "Overriding packet duration by frame rate, this should not happen\n");
             pkt->duration = av_rescale_q(1, av_inv_q(ost->frame_rate),
-                                         ost->mux_timebase);
+                                         pkt->time_base);
         }
     }
 
-    av_packet_rescale_ts(pkt, ost->mux_timebase, ost->st->time_base);
+    av_packet_rescale_ts(pkt, pkt->time_base, ost->st->time_base);
+    pkt->time_base = ost->st->time_base;
 
     if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) {
         if (pkt->dts != AV_NOPTS_VALUE &&
@@ -325,7 +326,7 @@ void of_output_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int eof)
     int ret = 0;
 
     if (!eof && pkt->dts != AV_NOPTS_VALUE)
-        ost->last_mux_dts = av_rescale_q(pkt->dts, ost->mux_timebase, AV_TIME_BASE_Q);
+        ost->last_mux_dts = av_rescale_q(pkt->dts, pkt->time_base, AV_TIME_BASE_Q);
 
     /* apply the output bitstream filters */
     if (ms->bsf_ctx) {
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [FFmpeg-devel] [PATCH 2/2] fftools/ffmpeg: add an option for writing pre-muxing stats
  2023-02-07  9:33 [FFmpeg-devel] [PATCH 1/2] fftools/ffmpeg: store output packet timebases in the packet Anton Khirnov
@ 2023-02-07  9:33 ` Anton Khirnov
  2023-02-07  9:41   ` Anton Khirnov
  0 siblings, 1 reply; 8+ messages in thread
From: Anton Khirnov @ 2023-02-07  9:33 UTC (permalink / raw)
  To: ffmpeg-devel

Analogous to -enc_stats*, but happens right before muxing. Useful
because bitstream filters and the sync queue can modify packets after
encoding and before muxing. Also has access to the muxing timebase.
---
 Changelog                 |  3 ++-
 doc/ffmpeg.texi           | 13 +++++++++----
 fftools/ffmpeg.c          | 14 ++++++++------
 fftools/ffmpeg.h          |  8 ++++++++
 fftools/ffmpeg_mux.c      | 10 +++++++++-
 fftools/ffmpeg_mux.h      |  2 ++
 fftools/ffmpeg_mux_init.c | 23 ++++++++++++++++++-----
 fftools/ffmpeg_opt.c      |  4 ++++
 8 files changed, 60 insertions(+), 17 deletions(-)

diff --git a/Changelog b/Changelog
index df9cd69da2..3738df2827 100644
--- a/Changelog
+++ b/Changelog
@@ -32,7 +32,8 @@ version <next>:
 - WADY DPCM decoder and demuxer
 - CBD2 DPCM decoder
 - ssim360 video filter
-- ffmpeg CLI new options: -enc_stats_pre[_fmt], -enc_stats_post[_fmt]
+- ffmpeg CLI new options: -enc_stats_pre[_fmt], -enc_stats_post[_fmt],
+  -mux_stats[_fmt]
 - hstack_vaapi, vstack_vaapi and xstack_vaapi filters
 - XMD ADPCM decoder and demuxer
 - media100 to mjpegb bsf
diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index 592c4b4393..aa7e1cc1e8 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -2063,14 +2063,17 @@ or invalid output files.
 
 @item -enc_stats_pre[:@var{stream_specifier}] @var{path} (@emph{output,per-stream})
 @item -enc_stats_post[:@var{stream_specifier}] @var{path} (@emph{output,per-stream})
+@item -mux_stats[:@var{stream_specifier}] @var{path} (@emph{output,per-stream})
 Write per-frame encoding information about the matching streams into the file
 given by @var{path}.
 
 @option{-enc_stats_pre} writes information about raw video or audio frames right
 before they are sent for encoding, while @option{-enc_stats_post} writes
-information about encoded packets as they are received from the encoder. Every
-frame or packet produces one line in the specified file. The format of this line
-is controlled by @option{-enc_stats_pre_fmt} / @option{-enc_stats_post_fmt}.
+information about encoded packets as they are received from the encoder.
+@option{-mux_stats} writes information about packets just as they are about to
+be sent to the muxer. Every frame or packet produces one line in the specified
+file. The format of this line is controlled by @option{-enc_stats_pre_fmt} /
+@option{-enc_stats_post_fmt} / @option{-mux_stats_fmt}.
 
 When stats for multiple streams are written into a single file, the lines
 corresponding to different streams will be interleaved. The precise order of
@@ -2079,8 +2082,9 @@ different invocations of the program, even with the same options.
 
 @item -enc_stats_pre_fmt[:@var{stream_specifier}] @var{format_spec} (@emph{output,per-stream})
 @item -enc_stats_post_fmt[:@var{stream_specifier}] @var{format_spec} (@emph{output,per-stream})
+@item -mux_stats_fmt[:@var{stream_specifier}] @var{format_spec} (@emph{output,per-stream})
 Specify the format for the lines written with @option{-enc_stats_pre} /
-@option{-enc_stats_post}.
+@option{-enc_stats_post} / @option{-mux_stats}.
 
 @var{format_spec} is a string that may contain directives of the form
 @var{@{fmt@}}. @var{format_spec} is backslash-escaped --- use \@{, \@}, and \\
@@ -2097,6 +2101,7 @@ Index of the output stream in the file.
 @item n
 Frame number. Pre-encoding: number of frames sent to the encoder so far.
 Post-encoding: number of packets received from the encoder so far.
+Muxing: number of packets submitted to the muxer for this stream so far.
 
 @item ni
 Input frame number. Index of the input frame (i.e. output by a decoder) that
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 32e0c3febd..aac393c714 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -808,8 +808,9 @@ static void update_video_stats(OutputStream *ost, const AVPacket *pkt, int write
     fprintf(vstats_file, "type= %c\n", av_get_picture_type_char(ost->pict_type));
 }
 
-static void enc_stats_write(OutputStream *ost, EncStats *es,
-                            const AVFrame *frame, const AVPacket *pkt)
+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;
@@ -840,12 +841,12 @@ static void enc_stats_write(OutputStream *ost, EncStats *es,
         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_FRAME_NUM:   avio_printf(io, "%"PRIu64,  ost->frames_encoded);           continue;
             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);
@@ -855,7 +856,6 @@ static void enc_stats_write(OutputStream *ost, EncStats *es,
             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_FRAME_NUM:   avio_printf(io, "%"PRIu64,  ost->packets_encoded);          continue;
             case ENC_STATS_BITRATE: {
                 double duration = FFMAX(pkt->duration, 1) * av_q2d(tb);
                 avio_printf(io, "%g",  8.0 * pkt->size / duration);
@@ -884,7 +884,8 @@ static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame)
 
     if (frame) {
         if (ost->enc_stats_pre.io)
-            enc_stats_write(ost, &ost->enc_stats_pre, frame, NULL);
+            enc_stats_write(ost, &ost->enc_stats_pre, frame, NULL,
+                            ost->frames_encoded);
 
         ost->frames_encoded++;
         ost->samples_encoded += frame->nb_samples;
@@ -932,7 +933,8 @@ static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame)
         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);
+            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 "
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 933312dba7..f1412f6446 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -258,10 +258,14 @@ typedef struct OptionsContext {
     int        nb_enc_stats_pre;
     SpecifierOpt *enc_stats_post;
     int        nb_enc_stats_post;
+    SpecifierOpt *mux_stats;
+    int        nb_mux_stats;
     SpecifierOpt *enc_stats_pre_fmt;
     int        nb_enc_stats_pre_fmt;
     SpecifierOpt *enc_stats_post_fmt;
     int        nb_enc_stats_post_fmt;
+    SpecifierOpt *mux_stats_fmt;
+    int        nb_mux_stats_fmt;
 } OptionsContext;
 
 typedef struct InputFilter {
@@ -789,6 +793,10 @@ int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame);
 
 int ffmpeg_parse_options(int argc, char **argv);
 
+void enc_stats_write(OutputStream *ost, EncStats *es,
+                     const AVFrame *frame, const AVPacket *pkt,
+                     uint64_t frame_num);
+
 HWDevice *hw_device_get_by_name(const char *name);
 int hw_device_init_from_string(const char *arg, HWDevice **dev);
 void hw_device_free_all(void);
diff --git a/fftools/ffmpeg_mux.c b/fftools/ffmpeg_mux.c
index 30764e22d1..dffc1410c8 100644
--- a/fftools/ffmpeg_mux.c
+++ b/fftools/ffmpeg_mux.c
@@ -64,6 +64,7 @@ static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
     AVFormatContext *s = mux->fc;
     AVStream *st = ost->st;
     int64_t fs;
+    uint64_t frame_num;
     int ret;
 
     fs = filesize(s->pb);
@@ -128,7 +129,7 @@ static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
     ms->last_mux_dts = pkt->dts;
 
     ost->data_size_mux += pkt->size;
-    atomic_fetch_add(&ost->packets_written, 1);
+    frame_num = atomic_fetch_add(&ost->packets_written, 1);
 
     pkt->stream_index = ost->index;
 
@@ -143,6 +144,9 @@ static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
               );
     }
 
+    if (ms->stats.io)
+        enc_stats_write(ost, &ms->stats, NULL, pkt, frame_num);
+
     ret = av_interleaved_write_frame(s, pkt);
     if (ret < 0) {
         print_error("av_interleaved_write_frame()", ret);
@@ -688,6 +692,10 @@ static void ost_free(OutputStream **post)
         av_freep(&ost->enc_stats_post.components[i].str);
     av_freep(&ost->enc_stats_post.components);
 
+    for (int i = 0; i < ms->stats.nb_components; i++)
+        av_freep(&ms->stats.components[i].str);
+    av_freep(&ms->stats.components);
+
     av_freep(post);
 }
 
diff --git a/fftools/ffmpeg_mux.h b/fftools/ffmpeg_mux.h
index 1487d86ae1..c76dc2e524 100644
--- a/fftools/ffmpeg_mux.h
+++ b/fftools/ffmpeg_mux.h
@@ -45,6 +45,8 @@ typedef struct MuxStream {
 
     AVBSFContext *bsf_ctx;
 
+    EncStats stats;
+
     int64_t max_frames;
 
     /*
diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c
index 834cdbcc9f..f4ef83f6af 100644
--- a/fftools/ffmpeg_mux_init.c
+++ b/fftools/ffmpeg_mux_init.c
@@ -57,8 +57,10 @@ static const char *const opt_name_disposition[]               = {"disposition",
 static const char *const opt_name_enc_time_bases[]            = {"enc_time_base", NULL};
 static const char *const opt_name_enc_stats_pre[]             = {"enc_stats_pre", NULL};
 static const char *const opt_name_enc_stats_post[]            = {"enc_stats_post", NULL};
+static const char *const opt_name_mux_stats[]                 = {"mux_stats", NULL};
 static const char *const opt_name_enc_stats_pre_fmt[]         = {"enc_stats_pre_fmt", NULL};
 static const char *const opt_name_enc_stats_post_fmt[]        = {"enc_stats_post_fmt", NULL};
+static const char *const opt_name_mux_stats_fmt[]             = {"mux_stats_fmt", NULL};
 static const char *const opt_name_filters[]                   = {"filter", "af", "vf", NULL};
 static const char *const opt_name_filter_scripts[]            = {"filter_script", NULL};
 static const char *const opt_name_fix_sub_duration_heartbeat[] = {"fix_sub_duration_heartbeat", NULL};
@@ -262,7 +264,7 @@ static int unescape(char **pdst, size_t *dst_len,
     return 0;
 }
 
-static int enc_stats_init(OutputStream *ost, int pre,
+static int enc_stats_init(OutputStream *ost, EncStats *es, int pre,
                           const char *path, const char *fmt_spec)
 {
     static const struct {
@@ -290,7 +292,6 @@ static int enc_stats_init(OutputStream *ost, int pre,
         { ENC_STATS_BITRATE,        "br",       0, 1            },
         { ENC_STATS_AVG_BITRATE,    "abr",      0, 1            },
     };
-    EncStats *es = pre ? &ost->enc_stats_pre : &ost->enc_stats_post;
     const char *next = fmt_spec;
 
     int ret;
@@ -479,7 +480,7 @@ static OutputStream *new_output_stream(Muxer *mux, const OptionsContext *o,
         AVCodecContext *enc = ost->enc_ctx;
         AVIOContext *s = NULL;
         char *buf = NULL, *arg = NULL, *preset = NULL;
-        const char *enc_stats_pre = NULL, *enc_stats_post = NULL;
+        const char *enc_stats_pre = NULL, *enc_stats_post = NULL, *mux_stats = NULL;
 
         ost->encoder_opts = filter_codec_opts(o->g->codec_opts, enc->codec_id,
                                               oc, st, enc->codec);
@@ -518,7 +519,7 @@ static OutputStream *new_output_stream(Muxer *mux, const OptionsContext *o,
 
             MATCH_PER_STREAM_OPT(enc_stats_pre_fmt, str, format, oc, st);
 
-            ret = enc_stats_init(ost, 1, enc_stats_pre, format);
+            ret = enc_stats_init(ost, &ost->enc_stats_pre, 1, enc_stats_pre, format);
             if (ret < 0)
                 exit_program(1);
         }
@@ -530,7 +531,19 @@ static OutputStream *new_output_stream(Muxer *mux, const OptionsContext *o,
 
             MATCH_PER_STREAM_OPT(enc_stats_post_fmt, str, format, oc, st);
 
-            ret = enc_stats_init(ost, 0, enc_stats_post, format);
+            ret = enc_stats_init(ost, &ost->enc_stats_post, 0, enc_stats_post, format);
+            if (ret < 0)
+                exit_program(1);
+        }
+
+        MATCH_PER_STREAM_OPT(mux_stats, str, mux_stats, oc, st);
+        if (mux_stats &&
+            (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)) {
+            const char *format = "{fidx} {sidx} {n} {t}";
+
+            MATCH_PER_STREAM_OPT(mux_stats_fmt, str, format, oc, st);
+
+            ret = enc_stats_init(ost, &ms->stats, 0, mux_stats, format);
             if (ret < 0)
                 exit_program(1);
         }
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index 204be38c94..93fd9509ce 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -1548,10 +1548,14 @@ const OptionDef options[] = {
         "write encoding stats before encoding" },
     { "enc_stats_post",     HAS_ARG | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT | OPT_STRING, { .off = OFFSET(enc_stats_post)     },
         "write encoding stats after encoding" },
+    { "mux_stats",          HAS_ARG | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT | OPT_STRING, { .off = OFFSET(mux_stats)          },
+        "write packets stats before muxing" },
     { "enc_stats_pre_fmt",  HAS_ARG | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT | OPT_STRING, { .off = OFFSET(enc_stats_pre_fmt)  },
         "format of the stats written with -enc_stats_pre" },
     { "enc_stats_post_fmt", HAS_ARG | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT | OPT_STRING, { .off = OFFSET(enc_stats_post_fmt) },
         "format of the stats written with -enc_stats_post" },
+    { "mux_stats_fmt",      HAS_ARG | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT | OPT_STRING, { .off = OFFSET(mux_stats_fmt)      },
+        "format of the stats written with -mux_stats" },
 
     /* video options */
     { "vframes",      OPT_VIDEO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .func_arg = opt_video_frames },
-- 
2.35.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [FFmpeg-devel] [PATCH 2/2] fftools/ffmpeg: add an option for writing pre-muxing stats
  2023-02-07  9:33 ` [FFmpeg-devel] [PATCH 2/2] fftools/ffmpeg: add an option for writing pre-muxing stats Anton Khirnov
@ 2023-02-07  9:41   ` Anton Khirnov
  2023-02-07 10:50     ` Thilo Borgmann
  0 siblings, 1 reply; 8+ messages in thread
From: Anton Khirnov @ 2023-02-07  9:41 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

Also, I'm wondering if we shouldn't rename the options to
 -stats_{mux,enc_pre,enc_post}[_fmt] for consistency.
They were added just recently, so it should be fine if done before the
release.

Opinions?

-- 
Anton Khirnov
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [FFmpeg-devel] [PATCH 2/2] fftools/ffmpeg: add an option for writing pre-muxing stats
  2023-02-07  9:41   ` Anton Khirnov
@ 2023-02-07 10:50     ` Thilo Borgmann
  2023-02-07 17:19       ` Tim Harris
  2023-02-08 13:53       ` Anton Khirnov
  0 siblings, 2 replies; 8+ messages in thread
From: Thilo Borgmann @ 2023-02-07 10:50 UTC (permalink / raw)
  To: ffmpeg-devel

Am 07.02.23 um 10:41 schrieb Anton Khirnov:
> Also, I'm wondering if we shouldn't rename the options to
>   -stats_{mux,enc_pre,enc_post}[_fmt] for consistency.
> They were added just recently, so it should be fine if done before the
> release.
> 
> Opinions?

I'd like that. Can't comment on the code itself, though.

-Thilo

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [FFmpeg-devel] [PATCH 2/2] fftools/ffmpeg: add an option for writing pre-muxing stats
  2023-02-07 10:50     ` Thilo Borgmann
@ 2023-02-07 17:19       ` Tim Harris
  2023-02-08 13:53       ` Anton Khirnov
  1 sibling, 0 replies; 8+ messages in thread
From: Tim Harris @ 2023-02-07 17:19 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

> > Am 07.02.23 um 10:41 schrieb Anton Khirnov:
> > Also, I'm wondering if we shouldn't rename the options to
> >   -stats_{mux,enc_pre,enc_post}[_fmt] for consistency.
> > They were added just recently, so it should be fine if done before the
> > release.
> >
> > Opinions?
>
> I'd like that. Can't comment on the code itself, though.
>

-stats_mux_pre (in case we want to report stats post muxing in the future?)

-Tim
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel<https://ffmpeg.org/mailman/listinfo/ffmpeg-devel>

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [FFmpeg-devel] [PATCH 2/2] fftools/ffmpeg: add an option for writing pre-muxing stats
  2023-02-07 10:50     ` Thilo Borgmann
  2023-02-07 17:19       ` Tim Harris
@ 2023-02-08 13:53       ` Anton Khirnov
  2023-02-08 15:59         ` Devin Heitmueller
  1 sibling, 1 reply; 8+ messages in thread
From: Anton Khirnov @ 2023-02-08 13:53 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

Quoting Tim Harris (2023-02-07 18:19:48)
> > > Am 07.02.23 um 10:41 schrieb Anton Khirnov:
> > > Also, I'm wondering if we shouldn't rename the options to
> > >   -stats_{mux,enc_pre,enc_post}[_fmt] for consistency.
> > > They were added just recently, so it should be fine if done before the
> > > release.
> > >
> > > Opinions?
> >
> > I'd like that. Can't comment on the code itself, though.
> >
> 
> -stats_mux_pre (in case we want to report stats post muxing in the future?)

Muxers are fundamentally consume-only, I don't see what stats could
possibly be printed after muxing, even conceptually.

-- 
Anton Khirnov
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [FFmpeg-devel] [PATCH 2/2] fftools/ffmpeg: add an option for writing pre-muxing stats
  2023-02-08 13:53       ` Anton Khirnov
@ 2023-02-08 15:59         ` Devin Heitmueller
  2023-02-08 16:10           ` Anton Khirnov
  0 siblings, 1 reply; 8+ messages in thread
From: Devin Heitmueller @ 2023-02-08 15:59 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

On Wed, Feb 8, 2023 at 8:54 AM Anton Khirnov <anton@khirnov.net> wrote:
> Muxers are fundamentally consume-only, I don't see what stats could
> possibly be printed after muxing, even conceptually.

I can offer some examples, in particular because I generate lots of
such statistics after muxing in my private tree.

- Decklink output statistics - late arrival and drop counts for audio
and video packets, pipeline latency (time between submission to the
hardware and the callback indicating frame was played out), FIFO
levels within the module, video frames actually played out in last
second, audio samples played out in last second.

- SRT output - various SRT related statistics (lost packets,
retransmits, connection RTT, etc)

- HLS output - counters for various HTTP recoverable events (HTTP
redirects, resends, etc), packets written

Devin

-- 
Devin Heitmueller, Senior Software Engineer
LTN Global Communications
o: +1 (301) 363-1001
w: https://ltnglobal.com  e: devin.heitmueller@ltnglobal.com
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [FFmpeg-devel] [PATCH 2/2] fftools/ffmpeg: add an option for writing pre-muxing stats
  2023-02-08 15:59         ` Devin Heitmueller
@ 2023-02-08 16:10           ` Anton Khirnov
  0 siblings, 0 replies; 8+ messages in thread
From: Anton Khirnov @ 2023-02-08 16:10 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

Quoting Devin Heitmueller (2023-02-08 16:59:43)
> On Wed, Feb 8, 2023 at 8:54 AM Anton Khirnov <anton@khirnov.net> wrote:
> > Muxers are fundamentally consume-only, I don't see what stats could
> > possibly be printed after muxing, even conceptually.
> 
> I can offer some examples, in particular because I generate lots of
> such statistics after muxing in my private tree.
> 
> - Decklink output statistics - late arrival and drop counts for audio
> and video packets, pipeline latency (time between submission to the
> hardware and the callback indicating frame was played out), FIFO
> levels within the module, video frames actually played out in last
> second, audio samples played out in last second.
> 
> - SRT output - various SRT related statistics (lost packets,
> retransmits, connection RTT, etc)
> 
> - HLS output - counters for various HTTP recoverable events (HTTP
> redirects, resends, etc), packets written

Hmm, I have not considered it but you're right that this information
could be exported via AVOptions and printed by ffmpeg CLI.

I'll send a patch with the renames then.

-- 
Anton Khirnov
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2023-02-08 16:11 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-07  9:33 [FFmpeg-devel] [PATCH 1/2] fftools/ffmpeg: store output packet timebases in the packet Anton Khirnov
2023-02-07  9:33 ` [FFmpeg-devel] [PATCH 2/2] fftools/ffmpeg: add an option for writing pre-muxing stats Anton Khirnov
2023-02-07  9:41   ` Anton Khirnov
2023-02-07 10:50     ` Thilo Borgmann
2023-02-07 17:19       ` Tim Harris
2023-02-08 13:53       ` Anton Khirnov
2023-02-08 15:59         ` Devin Heitmueller
2023-02-08 16:10           ` Anton Khirnov

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git