From 3ce13c7d9989d5376f738c0ef057c206dec29bdf Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sun, 9 May 2004 15:49:25 +0000 Subject: [PATCH] gst-libs/gst/riff/: Fix for unaligned RIFF files (i.e. where all the chunks together in a LIST chunk are not of the s... 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 | 13 +++++++++++++ gst-libs/gst/riff/riff-media.c | 17 +++++++++++++++++ gst-libs/gst/riff/riff-read.c | 16 ++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/ChangeLog b/ChangeLog index 9dd2a1a6a0..0f73f4c69a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2004-05-09 Ronald Bultje + + * 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 reviewed by Benjamin Otte diff --git a/gst-libs/gst/riff/riff-media.c b/gst-libs/gst/riff/riff-media.c index 2a7529a91c..c4636834de 100644 --- a/gst-libs/gst/riff/riff-media.c +++ b/gst-libs/gst/riff/riff-media.c @@ -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 }; diff --git a/gst-libs/gst/riff/riff-read.c b/gst-libs/gst/riff/riff-read.c index 388ea7539f..fc47f2c83e 100644 --- a/gst-libs/gst/riff/riff-read.c +++ b/gst-libs/gst/riff/riff-read.c @@ -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;