oggstream: only use information from skeleton if we have nothing better
authorVincent Penquerc'h <vincent.penquerch@collabora.co.uk>
Thu, 13 Jan 2011 15:35:30 +0000 (15:35 +0000)
committerTim-Philipp Müller <tim.muller@collabora.co.uk>
Mon, 19 Sep 2011 22:21:23 +0000 (23:21 +0100)
The codec setup headers are a lot more likely to have correct information,
especially as it's easy to remux a skeleton in a file where streams don't
have the same parameters (I've even seen a file with two skeletons).

Still, this is useful in the case we have a codec we can't decode, so we
can at least (theoretically) convert granpos to time, so we discard this
information if the codec setup has already provided it.

This fixes playback on (at lesat) the original archive.org encoding of
"The Night of the Living Dead" (now replaced by another encoding).

https://bugzilla.gnome.org/show_bug.cgi?id=612443

ext/ogg/gstoggdemux.c
ext/ogg/gstoggstream.c

index 58a1a7c..c883d12 100644 (file)
@@ -189,6 +189,10 @@ gst_ogg_pad_init (GstOggPad * pad)
   pad->continued = NULL;
   pad->map.headers = NULL;
   pad->map.queued = NULL;
+
+  pad->map.granulerate_n = 0;
+  pad->map.granulerate_d = 0;
+  pad->map.granuleshift = -1;
 }
 
 static void
index c58daea..a26791d 100644 (file)
@@ -1160,13 +1160,23 @@ gst_ogg_map_add_fisbone (GstOggStream * pad, GstOggStream * skel_pad,
 
   pad->have_fisbone = TRUE;
 
-  /* we just overwrite whatever was set before by the format-specific setup */
-  pad->granulerate_n = GST_READ_UINT64_LE (data);
-  pad->granulerate_d = GST_READ_UINT64_LE (data + 8);
+  /* We don't overwrite whatever was set before by the format-specific
+     setup: skeleton contains wrong information sometimes, and the codec
+     headers are authoritative.
+     So we only gather information that was not already filled out by
+     the mapper setup. This should hopefully allow handling unknown
+     streams a bit better, while not trashing correct setup from bad
+     skeleton data. */
+  if (pad->granulerate_n == 0 || pad->granulerate_d == 0) {
+    pad->granulerate_n = GST_READ_UINT64_LE (data);
+    pad->granulerate_d = GST_READ_UINT64_LE (data + 8);
+  }
+  if (pad->granuleshift < 0) {
+    pad->granuleshift = GST_READ_UINT8 (data + 28);
+  }
 
   start_granule = GST_READ_UINT64_LE (data + 16);
   pad->preroll = GST_READ_UINT32_LE (data + 24);
-  pad->granuleshift = GST_READ_UINT8 (data + 28);
 
   start_time = granulepos_to_granule_default (pad, start_granule);