gst-libs/gst/riff/: Fix for unaligned RIFF files (i.e. where all the chunks together...
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>
Sun, 9 May 2004 15:49:25 +0000 (15:49 +0000)
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>
Sun, 9 May 2004 15:49:25 +0000 (15:49 +0000)
Original commit message from CVS:
* gst-libs/gst/riff/riff-media.c:
(gst_riff_create_video_caps_with_data),
(gst_riff_create_audio_caps),
(gst_riff_create_audio_template_caps):
* gst-libs/gst/riff/riff-read.c: (gst_riff_peek_head):
Fix for unaligned RIFF files (i.e. where all the chunks together
in a LIST chunk are not of the same size as the size given in
the LIST chunk header). Fixes several odd WAVE files. Also fix
ADPCM (block_align property) in audio, so that wavparse based
on this works now as it used to stand-alone.

ChangeLog
gst-libs/gst/riff/riff-media.c
gst-libs/gst/riff/riff-read.c

index 9dd2a1a6a0de1223fa50eff00b3026159408b0b2..0f73f4c69aa24f80860f5f3de54cfce9b9e7dd35 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2004-05-09  Ronald Bultje  <rbultje@ronald.bitfreak.net>
+
+       * gst-libs/gst/riff/riff-media.c:
+       (gst_riff_create_video_caps_with_data),
+       (gst_riff_create_audio_caps),
+       (gst_riff_create_audio_template_caps):
+       * gst-libs/gst/riff/riff-read.c: (gst_riff_peek_head):
+         Fix for unaligned RIFF files (i.e. where all the chunks together
+         in a LIST chunk are not of the same size as the size given in
+         the LIST chunk header). Fixes several odd WAVE files. Also fix
+         ADPCM (block_align property) in audio, so that wavparse based
+         on this works now as it used to stand-alone.
+
 2004-05-09  Edward Hervey  <bilboed@bilboed.com>
 
        reviewed by Benjamin Otte  <otte@gnome.org>
index 2a7529a91c09ffcbe36ce06bf13c12a3b81662fe..c4636834de9b65930af7a217970d2369bc620886 100644 (file)
@@ -323,6 +323,7 @@ GstCaps *
 gst_riff_create_audio_caps (guint16 codec_id,
     gst_riff_strh * strh, gst_riff_strf_auds * strf, char **codec_name)
 {
+  gboolean block_align = FALSE;
   GstCaps *caps = NULL;
 
   switch (codec_id) {
@@ -365,6 +366,15 @@ gst_riff_create_audio_caps (guint16 codec_id,
           "layout", G_TYPE_STRING, "microsoft", NULL);
       if (codec_name)
         *codec_name = g_strdup ("ADPCM audio");
+      block_align = TRUE;
+      break;
+
+    case GST_RIFF_WAVE_FORMAT_DVI_ADPCM:
+      caps = gst_caps_new_simple ("audio/x-adpcm",
+          "layout", G_TYPE_STRING, "dvi", NULL);
+      if (codec_name)
+        *codec_name = g_strdup ("DVI ADPCM audio");
+      block_align = TRUE;
       break;
 
     case GST_RIFF_WAVE_FORMAT_MULAW:
@@ -413,10 +423,16 @@ gst_riff_create_audio_caps (guint16 codec_id,
     gst_caps_set_simple (caps,
         "rate", G_TYPE_INT, strf->rate,
         "channels", G_TYPE_INT, strf->channels, NULL);
+    if (block_align)
+      gst_caps_set_simple (caps,
+          "block_align", G_TYPE_INT, strf->blockalign, NULL);
   } else {
     gst_caps_set_simple (caps,
         "rate", GST_TYPE_INT_RANGE, 8000, 96000,
         "channels", GST_TYPE_INT_RANGE, 1, 2, NULL);
+    if (block_align)
+      gst_caps_set_simple (caps,
+          "block_align", GST_TYPE_INT_RANGE, 1, 8192, NULL);
   }
 
   return caps;
@@ -501,6 +517,7 @@ gst_riff_create_audio_template_caps (void)
     GST_RIFF_WAVE_FORMAT_ALAW,
     GST_RIFF_WAVE_FORMAT_MULAW,
     GST_RIFF_WAVE_FORMAT_ADPCM,
+    GST_RIFF_WAVE_FORMAT_DVI_ADPCM,
     /* FILL ME */
     0
   };
index 388ea7539ff4a7a277afe61dfb5bfa3443aa6546..fc47f2c83e67def961be746f1822b623729b465b 100644 (file)
@@ -154,8 +154,24 @@ gboolean
 gst_riff_peek_head (GstRiffRead * riff,
     guint32 * tag, guint32 * length, guint * level_up)
 {
+  GList *last;
   guint8 *data;
 
+  /* if we're at the end of a chunk, but unaligned, then re-align.
+   * Those are essentially broken files, but unfortunately they
+   * exist. */
+  if ((last = g_list_last (riff->level)) != NULL) {
+    GstRiffLevel *level = last->data;
+    guint64 pos = gst_bytestream_tell (riff->bs);
+
+    if (level->start + level->length - pos < 8) {
+      if (!gst_bytestream_flush (riff->bs, level->start + level->length - pos)) {
+        GST_ELEMENT_ERROR (riff, RESOURCE, READ, (NULL), (NULL));
+        return FALSE;
+      }
+    }
+  }
+
   /* read */
   while (gst_bytestream_peek_bytes (riff->bs, &data, 8) != 8) {
     GstEvent *event = NULL;