flacparse: detect when a file lies about fixed block size
authorVincent Penquerc'h <vincent.penquerch@collabora.co.uk>
Mon, 14 Nov 2011 15:34:57 +0000 (15:34 +0000)
committerVincent Penquerc'h <vincent.penquerch@collabora.co.uk>
Mon, 14 Nov 2011 15:53:36 +0000 (15:53 +0000)
If the sample/block number happens to be the same as the block
size, we assume variable block size, and thus counters in samples
in the headers. This can only get us a false positive for a block
size of 1, which is invalid. We can get false negatives more
often though (eg, if not starting at the start of the stream),
but then that's already GIGO.

gst/audioparsers/gstflacparse.c
gst/audioparsers/gstflacparse.h

index 05bfd0e..637319f 100644 (file)
@@ -399,6 +399,8 @@ gst_flac_parse_frame_header_is_valid (GstFlacParse * flacparse,
 
   /* 0 == fixed block size, 1 == variable block size */
   blocking_strategy = gst_bit_reader_get_bits_uint8_unchecked (&reader, 1);
+  if (flacparse->force_variable_block_size)
+    blocking_strategy = 1;
 
   /* block size index, calculation of the real blocksize below */
   block_size = gst_bit_reader_get_bits_uint16_unchecked (&reader, 4);
@@ -532,6 +534,16 @@ gst_flac_parse_frame_header_is_valid (GstFlacParse * flacparse,
   if (actual_crc != expected_crc)
     goto error;
 
+  /* Sanity check sample number against blocking strategy, as it seems
+     some files claim fixed block size but supply sample numbers,
+     rather than block numbers. */
+  if (set && blocking_strategy == 0 && block_size == sample_number) {
+    GST_WARNING_OBJECT (flacparse, "This file claims fixed block size, "
+        "but seems to be lying: assuming variable block size");
+    flacparse->force_variable_block_size = TRUE;
+    blocking_strategy = 1;
+  }
+
   /* 
      The FLAC format documentation says:
      The "blocking strategy" bit determines how to calculate the sample number
index 1c6db0e..2827552 100644 (file)
@@ -79,6 +79,8 @@ struct _GstFlacParse {
 
   GList *headers;
   GstBuffer *seektable;
+
+  gboolean force_variable_block_size;
 };
 
 struct _GstFlacParseClass {