avidemux: add workaround for buggy list size
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Tue, 26 Oct 2010 09:15:49 +0000 (11:15 +0200)
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Fri, 3 Dec 2010 14:50:30 +0000 (15:50 +0100)
Fixes truncated extra-data in hdrl/strl/strf due to buggy containing
list size not accounting for padding in contained chunks.

gst/avi/gstavidemux.c

index e052376..5e4c1be 100644 (file)
@@ -1869,6 +1869,24 @@ gst_avi_demux_expose_streams (GstAviDemux * avi, gboolean force)
   }
 }
 
+/* buf contains LIST chunk data, and will be padded to even size,
+ * since some buggy files do not account for the padding of chunks
+ * within a LIST in the size of the LIST */
+static inline void
+gst_avi_demux_roundup_list (GstAviDemux * avi, GstBuffer ** buf)
+{
+  if (G_UNLIKELY (GST_BUFFER_SIZE (*buf) & 1)) {
+    GstBuffer *obuf;
+
+    GST_DEBUG_OBJECT (avi, "rounding up dubious list size %d",
+        GST_BUFFER_SIZE (*buf));
+    obuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (*buf) + 1);
+    memcpy (GST_BUFFER_DATA (obuf), GST_BUFFER_DATA (*buf),
+        GST_BUFFER_SIZE (*buf));
+    gst_buffer_replace (buf, obuf);
+  }
+}
+
 /*
  * gst_avi_demux_parse_stream:
  * @avi: calling element (used for debugging/errors).
@@ -1903,6 +1921,8 @@ gst_avi_demux_parse_stream (GstAviDemux * avi, GstBuffer * buf)
 
   GST_DEBUG_OBJECT (avi, "Parsing stream");
 
+  gst_avi_demux_roundup_list (avi, &buf);
+
   if (avi->num_streams >= GST_AVI_DEMUX_MAX_STREAMS) {
     GST_WARNING_OBJECT (avi,
         "maximum no of streams (%d) exceeded, ignoring stream",
@@ -3140,6 +3160,8 @@ gst_avi_demux_stream_header_push (GstAviDemux * avi)
 
         GST_DEBUG ("'hdrl' LIST tag found. Parsing next chunk");
 
+        gst_avi_demux_roundup_list (avi, &buf);
+
         /* the hdrl starts with a 'avih' header */
         if (!gst_riff_parse_chunk (GST_ELEMENT_CAST (avi), buf, &offset, &tag,
                 &sub))
@@ -3581,6 +3603,8 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
 
   GST_DEBUG_OBJECT (avi, "hdrl LIST tag found");
 
+  gst_avi_demux_roundup_list (avi, &buf);
+
   /* the hdrl starts with a 'avih' header */
   if (!gst_riff_parse_chunk (element, buf, &offset, &tag, &sub))
     goto no_avih;