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.
This commit is contained in:
Ronald S. Bultje 2004-05-09 15:49:25 +00:00
parent 23c774e5a3
commit 3ce13c7d99
3 changed files with 46 additions and 0 deletions

View file

@ -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> 2004-05-09 Edward Hervey <bilboed@bilboed.com>
reviewed by Benjamin Otte <otte@gnome.org> reviewed by Benjamin Otte <otte@gnome.org>

View file

@ -323,6 +323,7 @@ GstCaps *
gst_riff_create_audio_caps (guint16 codec_id, gst_riff_create_audio_caps (guint16 codec_id,
gst_riff_strh * strh, gst_riff_strf_auds * strf, char **codec_name) gst_riff_strh * strh, gst_riff_strf_auds * strf, char **codec_name)
{ {
gboolean block_align = FALSE;
GstCaps *caps = NULL; GstCaps *caps = NULL;
switch (codec_id) { switch (codec_id) {
@ -365,6 +366,15 @@ gst_riff_create_audio_caps (guint16 codec_id,
"layout", G_TYPE_STRING, "microsoft", NULL); "layout", G_TYPE_STRING, "microsoft", NULL);
if (codec_name) if (codec_name)
*codec_name = g_strdup ("ADPCM audio"); *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; break;
case GST_RIFF_WAVE_FORMAT_MULAW: case GST_RIFF_WAVE_FORMAT_MULAW:
@ -413,10 +423,16 @@ gst_riff_create_audio_caps (guint16 codec_id,
gst_caps_set_simple (caps, gst_caps_set_simple (caps,
"rate", G_TYPE_INT, strf->rate, "rate", G_TYPE_INT, strf->rate,
"channels", G_TYPE_INT, strf->channels, NULL); "channels", G_TYPE_INT, strf->channels, NULL);
if (block_align)
gst_caps_set_simple (caps,
"block_align", G_TYPE_INT, strf->blockalign, NULL);
} else { } else {
gst_caps_set_simple (caps, gst_caps_set_simple (caps,
"rate", GST_TYPE_INT_RANGE, 8000, 96000, "rate", GST_TYPE_INT_RANGE, 8000, 96000,
"channels", GST_TYPE_INT_RANGE, 1, 2, NULL); "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; return caps;
@ -501,6 +517,7 @@ gst_riff_create_audio_template_caps (void)
GST_RIFF_WAVE_FORMAT_ALAW, GST_RIFF_WAVE_FORMAT_ALAW,
GST_RIFF_WAVE_FORMAT_MULAW, GST_RIFF_WAVE_FORMAT_MULAW,
GST_RIFF_WAVE_FORMAT_ADPCM, GST_RIFF_WAVE_FORMAT_ADPCM,
GST_RIFF_WAVE_FORMAT_DVI_ADPCM,
/* FILL ME */ /* FILL ME */
0 0
}; };

View file

@ -154,8 +154,24 @@ gboolean
gst_riff_peek_head (GstRiffRead * riff, gst_riff_peek_head (GstRiffRead * riff,
guint32 * tag, guint32 * length, guint * level_up) guint32 * tag, guint32 * length, guint * level_up)
{ {
GList *last;
guint8 *data; 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 */ /* read */
while (gst_bytestream_peek_bytes (riff->bs, &data, 8) != 8) { while (gst_bytestream_peek_bytes (riff->bs, &data, 8) != 8) {
GstEvent *event = NULL; GstEvent *event = NULL;