[FFmpeg-devel] [PATCH 2/3] ffmpeg.c: Continuously log current kbps and kBytes total for each non-seekable (aka live) output stream.

Michael Smithng michael at transparentpixel.com
Tue Aug 14 04:16:55 CEST 2012


in write_frame():
	if return value is not negative, add size of data written (see above) to ost->actual_bytes_written.

in print_report():
	+ static int64_t  print_timebase = 1000000;   (set timebase of logged stats to 1 second)
	+ static int64_t  last_last_time = -1;
	+ double  elapsed_time;
	+ double  actual_time;
	+ double  actual_kBytes;
	+ double  actual_kbps;

when last_time is initialized, also initialize last_last_time.

when (cur_time - last_time) >= print_timebase,
set last_last_time to last_time
add print_timebase to last_time (this moves our timer forward by exact intervals)

if last_time still lags behind cur_time by more than print_timebase,
set it to cur_time - print_timebase to catch it up rapidly.

then  elapsed_time = (double)(last_time - last_last_time) / 1000000.0;  (regularized time interval)

now for each output stream,
calculate actual_kBytes = accumulated  actual_bytes_written / 1000.
calculate actual_kbps = 8 * (actual_kBytes - (actual_prev_bytes / 1000.)) divided by elapsed_time.
set actual_prev_bytes = actual_bytes_written.

print  kB= and kbps= (actual_kBytes and actual_kbps)  along with normal printed output.

Allow printing of this data for audio_only streams in addition to video.

in transcode_init():
for each output stream:
initialize ost->actual_bytes_written = 0.
initialize ost->actual_prev_b
---
 ffmpeg.c | 45 ++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 40 insertions(+), 5 deletions(-)

diff --git a/ffmpeg.c b/ffmpeg.c
index 411cad1..90e8b71 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -566,6 +566,12 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
         print_error("av_interleaved_write_frame()", ret);
         exit_program(1);
     }
+    else if (ret > 0) {
+        ost->actual_bytes_written += ret;         // CK: if av_interleaved_write_frame() returns the size of the packet, add it to actual_bytes_written
+    }
+    else {
+        ost->actual_bytes_written += pkt->size;   // CK: otherwise add the packet size to actual_bytes_written (which doesn't include network packaging)
+    }
 }
 
 static int check_recording_time(OutputStream *ost)
@@ -1064,19 +1070,31 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
     static int qp_histogram[52];
     int hours, mins, secs, us;
 
+    static int64_t print_timebase = 1000000;    // CK: adjust timebase to 1 second (in microseconds)
+    static int64_t last_last_time = -1;         // CK: for capturing accurate time interval
+    double elapsed_time;
+    double actual_time;                         // CK: actual kBytes and kbps
+    double actual_kBytes;
+    double actual_kbps;
+
+
     if (!print_stats && !is_last_report && !progress_avio)
         return;
 
     if (!is_last_report) {
         if (last_time == -1) {
             last_time = cur_time;
+            last_last_time = cur_time; //CK: initialize last_last_time
             return;
         }
-        if ((cur_time - last_time) < 500000)
+        if ((cur_time - last_time) < print_timebase)
             return;
-        last_time = cur_time;
+        last_last_time = last_time;
+        last_time += print_timebase;                  // CK: make the intervals more regular
+        if (last_time < (cur_time - print_timebase))
+                last_time = cur_time - print_timebase;
     }
-
+    elapsed_time = (double)(last_time - last_last_time) / 1000000.0;    // CK: regularized interval
 
     oc = output_files[0]->ctx;
 
@@ -1094,6 +1112,16 @@ 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->st->codec;
+
+        // CK: calculate actual kBytes and kbps
+        actual_kBytes = 0.0;
+        actual_kbps = 0.0;
+        if ((elapsed_time > 0.0) && !is_last_report) {
+                actual_kBytes = (double)ost->actual_bytes_written / 1000.0;
+                actual_kbps = (8.0 * (actual_kBytes - ((double)ost->actual_prev_bytes / 1000.0))) / elapsed_time;
+                ost->actual_prev_bytes = ost->actual_bytes_written;
+        }
+
         if (!ost->stream_copy && enc->coded_frame)
             q = enc->coded_frame->quality / (float)FF_QP2LAMBDA;
         if (vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {
@@ -1101,13 +1129,16 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
             av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
                        ost->file_index, ost->index, q);
         }
-        if (!vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {
+        // CK: print details for audio-only primary streams too (if ost->index > 0, it's a secondary stream)
+        if (!vid && ((enc->codec_type == AVMEDIA_TYPE_VIDEO) || ((enc->codec_type == AVMEDIA_TYPE_AUDIO) && (ost->index == 0)))) {
             float fps, t = (cur_time-timer_start) / 1000000.0;
 
             frame_number = ost->frame_number;
             fps = t > 1 ? frame_number / t : 0;
             snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "frame=%5d fps=%3.*f q=%3.1f ",
                      frame_number, fps < 9.95, fps, q);
+            // CK: print actual kBytes and kbps
+            snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "kB=%8.1f kbps=%6.1f ", actual_kBytes, actual_kbps);
             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",
@@ -1151,7 +1182,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
                 av_bprintf(&buf_script, "stream_%d_%d_psnr_all=%2.2f\n",
                            ost->file_index, ost->index, p);
             }
-            vid = 1;
+            // vid = 1;     // CK: print full report for each stream
         }
         /* compute min output value */
         pts = FFMIN(pts, av_rescale_q(ost->st->pts.val,
@@ -1957,6 +1988,10 @@ static int transcode_init(void)
         oc  = output_files[ost->file_index]->ctx;
         ist = get_input_stream(ost);
 
+        // CK: initialize actual_bytes_written and history
+        ost->actual_bytes_written = 0;
+        ost->actual_prev_bytes = 0;
+
         if (ost->attachment_filename)
             continue;
 
-- 
1.7.11.3



More information about the ffmpeg-devel mailing list