[FFmpeg-devel] ffmpeg print_report for rtmp streams

Tom Marecek tom.marecek at accretivetg.com
Fri Nov 6 23:16:51 CET 2015


Hello, I have no experience with submitting patches to ffmpeg yet and so I am sorry if I am going about this the wrong way but I wanted to discuss a change that I made to print_report which is related to this bug:  https://trac.ffmpeg.org/ticket/1446

We are using stdout from ffmpeg to monitor rtmp streams. Currently the FPS and bitrate numbers which print_report outputs are calculated as a running average - the total number of frames divided by the elapsed time and the total size in bits divided by elapsed time.

This might make sense for files but for live streams it is not very useful since over time the changes in the streams are reflected less and less.
My change is to output the actual frame rate and bit rate each time print_report is called (every half a second or so). Also instead of using the file size to calculate the bit rate, I use the sum of the data sizes written to each stream which is giving me more consistent numbers..

Here is the diff, thank you for your feedback..


diff --git a/ffmpeg.c b/ffmpeg.c
index d3b8c4d..0c5afc9 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -1521,13 +1521,18 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
     char buf[1024];
     AVBPrint buf_script;
     OutputStream *ost;
-    AVFormatContext *oc;
-    int64_t total_size;
+    int64_t total_size = 0;
     AVCodecContext *enc;
     int frame_number, vid, i;
-    double bitrate;
+    double bitrate = -1;
     int64_t pts = INT64_MIN + 1;
+    static int last_frame_number = 0;
     static int64_t last_time = -1;
+    static int64_t last_frame_time = -1;
+    static int64_t last_file_size = 0;
+    static int64_t last_file_time = -1;
+    static float last_fps = -1;
+    static double last_bitrate = -1;
     static int qp_histogram[52];
     int hours, mins, secs, us;
@@ -1544,13 +1549,6 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
         last_time = cur_time;
     }
-
-    oc = output_files[0]->ctx;
-
-    total_size = avio_size(oc->pb);
-    if (total_size <= 0) // FIXME improve avio_size() so it works with non seekable output too
-        total_size = avio_tell(oc->pb);
-
     buf[0] = '\0';
     vid = 0;
     av_bprint_init(&buf_script, 0, 1);
@@ -1558,6 +1556,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
         float q = -1;
         ost = output_streams[i];
         enc = ost->enc_ctx;
+        total_size += ost->data_size;
         if (!ost->stream_copy)
             q = ost->quality / (float) FF_QP2LAMBDA;
@@ -1567,16 +1566,20 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
                        ost->file_index, ost->index, q);
         }
         if (!vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {
-            float fps, t = (cur_time-timer_start) / 1000000.0;
-
-            frame_number = ost->frame_number;
-            fps = t > 1 ? frame_number / t : 0;
+            int frame_number = ost->frame_number;
+            float frame_time_change = last_frame_time > 0 && cur_time > last_frame_time ? (cur_time - last_frame_time) / 1000000.0 : 0;
+            float fps = frame_time_change > 0 ? (frame_number - last_frame_number) / frame_time_change : 0;
+
             snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "frame=%5d fps=%3.*f q=%3.1f ",
                      frame_number, fps < 9.95, fps, q);
             av_bprintf(&buf_script, "frame=%d\n", frame_number);
             av_bprintf(&buf_script, "fps=%.1f\n", fps);
             av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
                        ost->file_index, ost->index, q);
+
+            last_frame_number = frame_number;
+            last_frame_time = cur_time;
+
             if (is_last_report)
                 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "L");
             if (qp_hist) {
@@ -1633,8 +1636,11 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
     secs %= 60;
     hours = mins / 60;
     mins %= 60;
+
+    float file_time_change = (last_file_time >= 0 && cur_time > last_file_time) ? (cur_time -last_file_time) / 1000000.0 : 0;
+    int64_t file_size_change = total_size > last_file_size ? total_size - last_file_size : 0;
-    bitrate = pts && total_size >= 0 ? total_size * 8 / (pts / 1000.0) : -1;
+    bitrate = file_time_change > 0 ? (file_size_change * 8) / (file_time_change * 1000.0) : -1;

     if (total_size < 0) snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
                                  "size=N/A time=");
@@ -1690,6 +1696,9 @@ 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);
+
+    last_file_time = cur_time;
+    last_file_size = total_size;
 }
 static void flush_encoders(void)





More information about the ffmpeg-devel mailing list