oggdemux: guard against wrong granulepos
authorWim Taymans <wim.taymans@collabora.co.uk>
Fri, 4 Dec 2009 12:14:57 +0000 (13:14 +0100)
committerWim Taymans <wim.taymans@collabora.co.uk>
Fri, 4 Dec 2009 12:14:57 +0000 (13:14 +0100)
Clamp the initial granulepos to 0 instead of going negative for some badly muxed
ogg files.

ext/ogg/gstoggdemux.c
ext/ogg/gstoggdemux.h

index 08abc04..a5b047c 100644 (file)
@@ -513,6 +513,8 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet)
 
   duration = gst_ogg_stream_get_packet_duration (&pad->map, packet);
 
+  GST_DEBUG_OBJECT (ogg, "duration %" G_GUINT64_FORMAT, duration);
+
   if (packet->b_o_s) {
     GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
     GST_BUFFER_DURATION (buf) = GST_CLOCK_TIME_NONE;
@@ -527,16 +529,29 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet)
           gst_ogg_stream_granulepos_to_key_granule (&pad->map,
           packet->granulepos);
     }
+    GST_DEBUG_OBJECT (ogg, "current granule %" G_GUINT64_FORMAT,
+        pad->current_granule);
+
     if (pad->map.is_ogm) {
       GST_BUFFER_TIMESTAMP (buf) = gst_ogg_stream_granule_to_time (&pad->map,
           pad->current_granule);
       GST_BUFFER_DURATION (buf) = gst_util_uint64_scale (duration,
           GST_SECOND * pad->map.granulerate_d, pad->map.granulerate_n);
     } else {
+      guint64 endtime;
+
       GST_BUFFER_TIMESTAMP (buf) = gst_ogg_stream_granule_to_time (&pad->map,
           pad->current_granule - duration);
-      GST_BUFFER_DURATION (buf) = gst_ogg_stream_granule_to_time (&pad->map,
-          pad->current_granule) - GST_BUFFER_TIMESTAMP (buf);
+      GST_DEBUG_OBJECT (ogg, "current granule time %" GST_TIME_FORMAT,
+          GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
+      endtime =
+          gst_ogg_stream_granule_to_time (&pad->map, pad->current_granule);
+      GST_DEBUG_OBJECT (ogg, "current granule end time %" GST_TIME_FORMAT,
+          GST_TIME_ARGS (endtime));
+
+      GST_BUFFER_DURATION (buf) = endtime - GST_BUFFER_TIMESTAMP (buf);
+      GST_DEBUG_OBJECT (ogg, "current duration %" GST_TIME_FORMAT,
+          GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
     }
     GST_BUFFER_OFFSET_END (buf) =
         gst_ogg_stream_granule_to_granulepos (&pad->map, pad->current_granule,
@@ -657,16 +672,24 @@ gst_ogg_pad_submit_packet (GstOggPad * pad, ogg_packet * packet)
   if (!packet->b_o_s) {
     if (pad->start_time == GST_CLOCK_TIME_NONE) {
       gint64 duration = gst_ogg_stream_get_packet_duration (&pad->map, packet);
+      GST_DEBUG ("duration %" G_GINT64_FORMAT, duration);
       if (duration != -1) {
         pad->map.accumulated_granule += duration;
+        GST_DEBUG ("accumulated granule %" G_GINT64_FORMAT,
+            pad->map.accumulated_granule);
       }
 
       if (packet->granulepos != -1) {
         ogg_int64_t start_granule;
+        gint64 granule;
+
+        granule = gst_ogg_stream_granulepos_to_granule (&pad->map,
+            packet->granulepos);
 
-        start_granule =
-            gst_ogg_stream_granulepos_to_granule (&pad->map,
-            packet->granulepos) - pad->map.accumulated_granule;
+        if (granule > pad->map.accumulated_granule)
+          start_granule = granule - pad->map.accumulated_granule;
+        else
+          start_granule = 0;
 
         pad->start_time = gst_ogg_stream_granule_to_time (&pad->map,
             start_granule);
index 2c058d2..ef8b23d 100644 (file)
@@ -89,32 +89,11 @@ struct _GstOggPad
   gboolean have_type;
   GstOggPadMode mode;
 
-#if 0
-  GstPad *elem_pad;             /* sinkpad of internal element */
-  GstElement *element;          /* internal element */
-  GstPad *elem_out;             /* our sinkpad to receive buffers form the internal element */
-#endif
-
   GstOggChain *chain;           /* the chain we are part of */
   GstOggDemux *ogg;             /* the ogg demuxer we are part of */
 
-  //GList *headers;
   GstOggStream map;
-#if 0
-  gint map;
-  gboolean is_skeleton;
-  gboolean have_fisbone;
-  gint granulerate_n;
-  gint granulerate_d;
-  guint32 preroll;
-  guint granuleshift;
-  gint n_header_packets;
-  gint n_header_packets_seen;
-  gint64 accumulated_granule;
-  gint frame_size;
-#endif
-
-  //gint serialno;
+
   gint64 packetno;
   gint64 current_granule;
   gint64 keyframe_granule;