oggdemux: Implement correct parsing of Skeleton 4.0 index packets
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Tue, 8 Jun 2010 11:11:05 +0000 (13:11 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Tue, 8 Jun 2010 11:11:05 +0000 (13:11 +0200)
ext/ogg/gstoggstream.c

index d07a221c00a6176917f0ad249cc97a2ac0e0afd5..9c99e5b7861c23e39d6e68032e930312310f8a67 100644 (file)
@@ -1000,7 +1000,7 @@ static gboolean
 read_vlc (const guint8 ** data, guint * size, guint64 * result)
 {
   gint shift = 0;
-  gint64 byte;
+  guint8 byte;
 
   *result = 0;
 
@@ -1032,7 +1032,8 @@ gst_ogg_map_add_index (GstOggStream * pad, GstOggStream * skel_pad,
     return TRUE;
   }
 
-  if (size < 26) {
+  if ((skel_pad->skeleton_major == 3 && size < 26) ||
+      (skel_pad->skeleton_major == 4 && size < 62)) {
     GST_WARNING ("small index packet of size %u, ignoring", size);
     return FALSE;
   }
@@ -1043,30 +1044,51 @@ gst_ogg_map_add_index (GstOggStream * pad, GstOggStream * skel_pad,
 
   n_keypoints = GST_READ_UINT64_LE (data);
 
-  pad->kp_denom = GST_READ_UINT64_LE (data + 8);
-  if (pad->kp_denom == 0)
-    pad->kp_denom = 1;
+  data += 8;
+  size -= 8;
+
+  if (skel_pad->skeleton_major == 3) {
+    pad->kp_denom = GST_READ_UINT64_LE (data);
+    if (pad->kp_denom == 0)
+      pad->kp_denom = 1;
 
-  data += 16;
-  size -= 16;
+    data += 8;
+    size -= 8;
+  } else if (skel_pad->skeleton_major == 4) {
+    gint64 firstsampletime_n, firstsampletime_d;
+    gint64 lastsampletime_n, lastsampletime_d;
+    gint64 firstsampletime, lastsampletime;
 
-  if (skel_pad->skeleton_major == 4) {
-    guint64 firstsampletime_n, lastsampletime_n;
-    guint64 firstsampletime, lastsampletime;
+    firstsampletime_n = GST_READ_UINT64_LE (data + 0);
+    firstsampletime_d = GST_READ_UINT64_LE (data + 8);
+    lastsampletime_n = GST_READ_UINT64_LE (data + 16);
+    lastsampletime_d = GST_READ_UINT64_LE (data + 24);
 
-    firstsampletime_n = GST_READ_UINT64_LE (data);
-    lastsampletime_n = GST_READ_UINT64_LE (data + 8);
+    /* FIXME: What's in this gap? Also http://github.com/cpearce/OggIndex
+     * and http://wiki.xiph.org/Ogg_Skeleton_4 disagree on the content
+     * and format of the index pages. This implements the former because
+     * files using this actually exist... */
+
+    pad->kp_denom = GST_READ_UINT64_LE (data + 36);
+    if (pad->kp_denom == 0)
+      pad->kp_denom = 1;
 
     GST_INFO ("firstsampletime %" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT,
-        firstsampletime_n, pad->kp_denom);
+        firstsampletime_n, firstsampletime_d);
     GST_INFO ("lastsampletime %" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT,
-        lastsampletime_n, pad->kp_denom);
+        lastsampletime_n, lastsampletime_d);
 
-    firstsampletime = gst_util_uint64_scale (GST_SECOND,
-        firstsampletime_n, pad->kp_denom);
+    if (firstsampletime_d > 0)
+      firstsampletime = gst_util_uint64_scale (GST_SECOND,
+          firstsampletime_n, firstsampletime_d);
+    else
+      firstsampletime = 0;
 
-    lastsampletime = gst_util_uint64_scale (GST_SECOND,
-        lastsampletime_n, pad->kp_denom);
+    if (lastsampletime_d > 0)
+      lastsampletime = gst_util_uint64_scale (GST_SECOND,
+          lastsampletime_n, lastsampletime_d);
+    else
+      lastsampletime = 0;
 
     if (lastsampletime > firstsampletime)
       pad->total_time = lastsampletime - firstsampletime;
@@ -1076,8 +1098,8 @@ gst_ogg_map_add_index (GstOggStream * pad, GstOggStream * skel_pad,
     GST_INFO ("skeleton index parsed total: %" GST_TIME_FORMAT,
         GST_TIME_ARGS (pad->total_time));
 
-    data += 16;
-    size -= 16;
+    data += 44;
+    size -= 44;
   }
 
   GST_INFO ("skeleton index has %" G_GUINT64_FORMAT " keypoints, denom: %"