[FFmpeg-devel] [PATCH 2/3] lavf/webm_dash: Fix incorrect bandwidth computation

Vignesh Venkatasubramanian vigneshv at google.com
Wed Oct 1 19:13:31 CEST 2014


Fix incorrect bandwidth computation in some cases. When the cue end
descriptor is null (i.e.) start_time_ns == -1, existing bandwidth
computed (if any) should be returned rather than returning 0.

Signed-off-by: Vignesh Venkatasubramanian <vigneshv at google.com>
---
 libavformat/matroskadec.c | 96 ++++++++++++++++++++++++-----------------------
 1 file changed, 49 insertions(+), 47 deletions(-)

diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index d856fcc..0e405c7 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -3188,55 +3188,57 @@ static int64_t webm_dash_manifest_compute_bandwidth(AVFormatContext *s, int64_t
         }
         if (desc_end.start_time_ns == -1) {
             // The prebuffer is larger than the duration.
-            return (matroska->duration * matroska->time_scale >= prebuffered_ns) ? -1 : 0;
-        }
-
-        // The prebuffer ends in the last Cue. Estimate how much data was
-        // prebuffered.
-        pre_bytes = desc_end.end_offset - desc_end.start_offset;
-        pre_ns = desc_end.end_time_ns - desc_end.start_time_ns;
-        pre_sec = pre_ns / nano_seconds_per_second;
-        prebuffer_bytes +=
-            pre_bytes * ((temp_prebuffer_ns / nano_seconds_per_second) / pre_sec);
-
-        prebuffer = prebuffer_ns / nano_seconds_per_second;
-
-        // Set this to 0.0 in case our prebuffer buffers the entire video.
-        bits_per_second = 0.0;
-        do {
-            int64_t desc_bytes = desc_end.end_offset - desc_beg.start_offset;
-            int64_t desc_ns = desc_end.end_time_ns - desc_beg.start_time_ns;
-            double desc_sec = desc_ns / nano_seconds_per_second;
-            double calc_bits_per_second = (desc_bytes * 8) / desc_sec;
-
-            // Drop the bps by the percentage of bytes buffered.
-            double percent = (desc_bytes - prebuffer_bytes) / desc_bytes;
-            double mod_bits_per_second = calc_bits_per_second * percent;
-
-            if (prebuffer < desc_sec) {
-                double search_sec =
-                    (double)(matroska->duration * matroska->time_scale) / nano_seconds_per_second;
-
-                // Add 1 so the bits per second should be a little bit greater than file
-                // datarate.
-                int64_t bps = (int64_t)(mod_bits_per_second) + 1;
-                const double min_buffer = 0.0;
-                double buffer = prebuffer;
-                double sec_to_download = 0.0;
-
-                int rv = buffer_size_after_time_downloaded(prebuffered_ns, search_sec, bps,
-                                                           min_buffer, &buffer, &sec_to_download,
-                                                           s, cues_start);
-                if (rv < 0) {
-                    return -1;
-                } else if (rv == 0) {
-                    bits_per_second = (double)(bps);
-                    break;
+            if (matroska->duration * matroska->time_scale >= prebuffered_ns)
+              return -1;
+            bits_per_second = 0.0;
+        } else {
+            // The prebuffer ends in the last Cue. Estimate how much data was
+            // prebuffered.
+            pre_bytes = desc_end.end_offset - desc_end.start_offset;
+            pre_ns = desc_end.end_time_ns - desc_end.start_time_ns;
+            pre_sec = pre_ns / nano_seconds_per_second;
+            prebuffer_bytes +=
+                pre_bytes * ((temp_prebuffer_ns / nano_seconds_per_second) / pre_sec);
+
+            prebuffer = prebuffer_ns / nano_seconds_per_second;
+
+            // Set this to 0.0 in case our prebuffer buffers the entire video.
+            bits_per_second = 0.0;
+            do {
+                int64_t desc_bytes = desc_end.end_offset - desc_beg.start_offset;
+                int64_t desc_ns = desc_end.end_time_ns - desc_beg.start_time_ns;
+                double desc_sec = desc_ns / nano_seconds_per_second;
+                double calc_bits_per_second = (desc_bytes * 8) / desc_sec;
+
+                // Drop the bps by the percentage of bytes buffered.
+                double percent = (desc_bytes - prebuffer_bytes) / desc_bytes;
+                double mod_bits_per_second = calc_bits_per_second * percent;
+
+                if (prebuffer < desc_sec) {
+                    double search_sec =
+                        (double)(matroska->duration * matroska->time_scale) / nano_seconds_per_second;
+
+                    // Add 1 so the bits per second should be a little bit greater than file
+                    // datarate.
+                    int64_t bps = (int64_t)(mod_bits_per_second) + 1;
+                    const double min_buffer = 0.0;
+                    double buffer = prebuffer;
+                    double sec_to_download = 0.0;
+
+                    int rv = buffer_size_after_time_downloaded(prebuffered_ns, search_sec, bps,
+                                                               min_buffer, &buffer, &sec_to_download,
+                                                               s, cues_start);
+                    if (rv < 0) {
+                        return -1;
+                    } else if (rv == 0) {
+                        bits_per_second = (double)(bps);
+                        break;
+                    }
                 }
-            }
 
-            desc_end = get_cue_desc(s, desc_end.end_time_ns, cues_start);
-        } while (desc_end.start_time_ns != -1);
+                desc_end = get_cue_desc(s, desc_end.end_time_ns, cues_start);
+            } while (desc_end.start_time_ns != -1);
+        }
         if (bandwidth < bits_per_second) bandwidth = bits_per_second;
     }
     return (int64_t)bandwidth;
-- 
2.1.0.rc2.206.gedb03e5



More information about the ffmpeg-devel mailing list