[0.11] gst-plugins-bad: mpegpsdemux: limit the amount of scanning done on duration queries

Sebastian Dröge slomo at kemper.freedesktop.org
Wed Jan 25 04:24:03 PST 2012


Module: gst-plugins-bad
Branch: 0.11
Commit: 8fb0beaf00aeae2ef6081d08f0d74d6e655a53da
URL:    http://cgit.freedesktop.org/gstreamer/gst-plugins-bad/commit/?id=8fb0beaf00aeae2ef6081d08f0d74d6e655a53da

Author: Alessandro Decina <alessandro.d at gmail.com>
Date:   Wed Jan 18 12:04:52 2012 +0100

mpegpsdemux: limit the amount of scanning done on duration queries

Limit the amount of data scanned when looking for PTSes in duration queries as a
failsafe for kinda broken, potentially large files with sparse or no PTSes.

---

 gst/mpegdemux/gstmpegdemux.c |   40 +++++++++++++++++++++++++++-------------
 1 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/gst/mpegdemux/gstmpegdemux.c b/gst/mpegdemux/gstmpegdemux.c
index ec9b613..ef29208 100644
--- a/gst/mpegdemux/gstmpegdemux.c
+++ b/gst/mpegdemux/gstmpegdemux.c
@@ -60,6 +60,8 @@
 #define SEGMENT_THRESHOLD (300*GST_MSECOND)
 #define VIDEO_SEGMENT_THRESHOLD (500*GST_MSECOND)
 
+#define DURATION_SCAN_LIMIT         4 * 1024 * 1024
+
 typedef enum
 {
   SCAN_SCR,
@@ -154,9 +156,9 @@ static GstStateChangeReturn gst_flups_demux_change_state (GstElement * element,
     GstStateChange transition);
 
 static inline gboolean gst_flups_demux_scan_forward_ts (GstFluPSDemux * demux,
-    guint64 * pos, SCAN_MODE mode, guint64 * rts);
+    guint64 * pos, SCAN_MODE mode, guint64 * rts, gint limit);
 static inline gboolean gst_flups_demux_scan_backward_ts (GstFluPSDemux * demux,
-    guint64 * pos, SCAN_MODE mode, guint64 * rts);
+    guint64 * pos, SCAN_MODE mode, guint64 * rts, gint limit);
 
 static inline void gst_flups_demux_send_segment_updates (GstFluPSDemux * demux,
     GstClockTime new_time);
@@ -1051,19 +1053,22 @@ gst_flups_demux_do_seek (GstFluPSDemux * demux, GstSegment * seeksegment)
       MIN (gst_util_uint64_scale (scr - demux->first_scr, scr_rate_n,
           scr_rate_d), demux->sink_segment.stop);
 
-  found = gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_SCR, &fscr);
+  found = gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_SCR, &fscr, 0);
   if (!found) {
-    found = gst_flups_demux_scan_backward_ts (demux, &offset, SCAN_SCR, &fscr);
+    found =
+        gst_flups_demux_scan_backward_ts (demux, &offset, SCAN_SCR, &fscr, 0);
   }
 
   while (found && fscr < scr) {
     offset++;
-    found = gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_SCR, &fscr);
+    found =
+        gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_SCR, &fscr, 0);
   }
 
   while (found && fscr > scr && offset > 0) {
     offset--;
-    found = gst_flups_demux_scan_backward_ts (demux, &offset, SCAN_SCR, &fscr);
+    found =
+        gst_flups_demux_scan_backward_ts (demux, &offset, SCAN_SCR, &fscr, 0);
   }
 
   GST_INFO_OBJECT (demux, "doing seek at offset %" G_GUINT64_FORMAT
@@ -2382,7 +2387,7 @@ beach:
 
 static inline gboolean
 gst_flups_demux_scan_forward_ts (GstFluPSDemux * demux, guint64 * pos,
-    SCAN_MODE mode, guint64 * rts)
+    SCAN_MODE mode, guint64 * rts, gint limit)
 {
   GstFlowReturn ret = GST_FLOW_OK;
   GstBuffer *buffer = NULL;
@@ -2398,6 +2403,9 @@ gst_flups_demux_scan_forward_ts (GstFluPSDemux * demux, guint64 * pos,
     if (offset + scan_sz > demux->sink_segment.stop)
       return FALSE;
 
+    if (limit && offset > *pos + limit)
+      return FALSE;
+
     if (offset + to_read > demux->sink_segment.stop)
       to_read = demux->sink_segment.stop - offset;
 
@@ -2435,7 +2443,7 @@ gst_flups_demux_scan_forward_ts (GstFluPSDemux * demux, guint64 * pos,
 
 static inline gboolean
 gst_flups_demux_scan_backward_ts (GstFluPSDemux * demux, guint64 * pos,
-    SCAN_MODE mode, guint64 * rts)
+    SCAN_MODE mode, guint64 * rts, gint limit)
 {
   GstFlowReturn ret = GST_FLOW_OK;
   GstBuffer *buffer = NULL;
@@ -2451,6 +2459,9 @@ gst_flups_demux_scan_backward_ts (GstFluPSDemux * demux, guint64 * pos,
     if (offset < scan_sz - 1)
       return FALSE;
 
+    if (limit && offset < *pos - limit)
+      return FALSE;
+
     if (offset > BLOCK_SZ)
       offset -= BLOCK_SZ;
     else {
@@ -2522,7 +2533,8 @@ gst_flups_sink_get_duration (GstFluPSDemux * demux)
   /* Scan for notorious SCR and PTS to calculate the duration */
   /* scan for first SCR in the stream */
   offset = demux->sink_segment.start;
-  gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_SCR, &demux->first_scr);
+  gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_SCR, &demux->first_scr,
+      DURATION_SCAN_LIMIT);
   GST_DEBUG_OBJECT (demux, "First SCR: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
       " in packet starting at %" G_GUINT64_FORMAT,
       demux->first_scr, GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->first_scr)),
@@ -2530,7 +2542,8 @@ gst_flups_sink_get_duration (GstFluPSDemux * demux)
   demux->first_scr_offset = offset;
   /* scan for last SCR in the stream */
   offset = demux->sink_segment.stop;
-  gst_flups_demux_scan_backward_ts (demux, &offset, SCAN_SCR, &demux->last_scr);
+  gst_flups_demux_scan_backward_ts (demux, &offset, SCAN_SCR,
+      &demux->last_scr, 0);
   GST_DEBUG_OBJECT (demux, "Last SCR: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
       " in packet starting at %" G_GUINT64_FORMAT,
       demux->last_scr, GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->last_scr)),
@@ -2538,7 +2551,8 @@ gst_flups_sink_get_duration (GstFluPSDemux * demux)
   demux->last_scr_offset = offset;
   /* scan for first PTS in the stream */
   offset = demux->sink_segment.start;
-  gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_PTS, &demux->first_pts);
+  gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_PTS, &demux->first_pts,
+      DURATION_SCAN_LIMIT);
   GST_DEBUG_OBJECT (demux, "First PTS: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
       " in packet starting at %" G_GUINT64_FORMAT,
       demux->first_pts, GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->first_pts)),
@@ -2547,7 +2561,7 @@ gst_flups_sink_get_duration (GstFluPSDemux * demux)
     /* scan for last PTS in the stream */
     offset = demux->sink_segment.stop;
     gst_flups_demux_scan_backward_ts (demux, &offset, SCAN_PTS,
-        &demux->last_pts);
+        &demux->last_pts, DURATION_SCAN_LIMIT);
     GST_DEBUG_OBJECT (demux,
         "Last PTS: %" G_GINT64_FORMAT " %" GST_TIME_FORMAT
         " in packet starting at %" G_GUINT64_FORMAT, demux->last_pts,
@@ -2560,7 +2574,7 @@ gst_flups_sink_get_duration (GstFluPSDemux * demux)
     offset = demux->first_scr_offset;
     for (i = 0; i < 10; i++) {
       offset++;
-      gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_SCR, &scr);
+      gst_flups_demux_scan_forward_ts (demux, &offset, SCAN_SCR, &scr, 0);
       if (scr < demux->last_scr) {
         demux->first_scr = scr;
         demux->first_scr_offset = offset;



More information about the gstreamer-commits mailing list