+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>
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) {
"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:
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;
GST_RIFF_WAVE_FORMAT_ALAW,
GST_RIFF_WAVE_FORMAT_MULAW,
GST_RIFF_WAVE_FORMAT_ADPCM,
+ GST_RIFF_WAVE_FORMAT_DVI_ADPCM,
/* FILL ME */
0
};
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;