typefinding: fix detection of fLaC id packet in broken flac-in-ogg
authorTim-Philipp Müller <tim.muller@collabora.co.uk>
Sat, 1 Aug 2009 16:26:23 +0000 (17:26 +0100)
committerTim-Philipp Müller <tim.muller@collabora.co.uk>
Sat, 1 Aug 2009 18:01:39 +0000 (19:01 +0100)
There are flac-in-ogg files without the usual flac packet framing
and these files just have a 4-byte fLaC ID packet as first packet.
We need to recognise the type just from these four bytes if we
want oggdemux to recognise these streams correctly.

gst/typefind/gsttypefindfunctions.c
tests/check/gst/typefindfunctions.c

index 5600c53..be7371a 100644 (file)
@@ -554,15 +554,19 @@ flac_type_find (GstTypeFind * tf, gpointer unused)
 {
   DataScanCtx c = { 0, NULL, 0 };
 
-  if (G_UNLIKELY (!data_scan_ctx_ensure_data (tf, &c, 6)))
+  if (G_UNLIKELY (!data_scan_ctx_ensure_data (tf, &c, 4)))
     return;
 
-  /* standard flac */
+  /* standard flac (also old/broken flac-in-ogg with an initial 4-byte marker
+   * packet and without the usual packet framing) */
   if (memcmp (c.data, "fLaC", 4) == 0) {
     gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, FLAC_CAPS);
     return;
   }
 
+  if (G_UNLIKELY (!data_scan_ctx_ensure_data (tf, &c, 6)))
+    return;
+
   /* flac-in-ogg, see http://flac.sourceforge.net/ogg_mapping.html */
   if (memcmp (c.data, "\177FLAC\001", 6) == 0) {
     gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, FLAC_CAPS);
index e74aaf3..08d3f1b 100644 (file)
@@ -80,6 +80,34 @@ GST_START_TEST (test_quicktime_mpeg4video)
 
 GST_END_TEST;
 
+GST_START_TEST (test_broken_flac_in_ogg)
+{
+  const guint8 flac_id_packet[4] = { 'f', 'L', 'a', 'C' };
+  GstTypeFindProbability prob;
+  const gchar *type;
+  GstBuffer *buf;
+  GstCaps *caps = NULL;
+
+  buf = gst_buffer_new ();
+  GST_BUFFER_DATA (buf) = (guint8 *) flac_id_packet;
+  GST_BUFFER_SIZE (buf) = sizeof (flac_id_packet);
+  GST_BUFFER_OFFSET (buf) = 0;
+
+  caps = gst_type_find_helper_for_buffer (NULL, buf, &prob);
+  fail_unless (caps != NULL);
+  GST_LOG ("Found type: %" GST_PTR_FORMAT, caps);
+
+  type = gst_structure_get_name (gst_caps_get_structure (caps, 0));
+  fail_unless_equals_string (type, "audio/x-flac");
+  fail_unless (prob > GST_TYPE_FIND_MINIMUM && prob <= GST_TYPE_FIND_MAXIMUM);
+
+  gst_buffer_unref (buf);
+  gst_caps_unref (caps);
+
+}
+
+GST_END_TEST;
+
 static Suite *
 typefindfunctions_suite (void)
 {
@@ -89,6 +117,7 @@ typefindfunctions_suite (void)
   suite_add_tcase (s, tc_chain);
 
   tcase_add_test (tc_chain, test_quicktime_mpeg4video);
+  tcase_add_test (tc_chain, test_broken_flac_in_ogg);
 
   return s;
 }