mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 01:30:38 +00:00
gst-libs/gst/riff/riff-media.c: Correctly support 4, 6 and 8 channels with normal PCM and float wav files.
Original commit message from CVS: * gst-libs/gst/riff/riff-media.c: (gst_riff_create_audio_caps): Correctly support 4, 6 and 8 channels with normal PCM and float wav files. Fix the depth and signedness calculation in extensible wav files and also handle 1, 2, 4, 6, 8 channels here when a file without channel mask is found. Add support for float, alaw and mulaw in extensible wav files. This allows correct playback of all but 5 files from http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Samples.html (gst_riff_create_audio_template_caps): Add voxware and float formats to the template caps.
This commit is contained in:
parent
0138ad7e09
commit
3effb4d23e
2 changed files with 149 additions and 8 deletions
18
ChangeLog
18
ChangeLog
|
@ -1,3 +1,21 @@
|
||||||
|
2007-04-17 Sebastian Dröge <slomo@circular-chaos.org>
|
||||||
|
|
||||||
|
* gst-libs/gst/riff/riff-media.c: (gst_riff_create_audio_caps):
|
||||||
|
Correctly support 4, 6 and 8 channels with normal PCM and float
|
||||||
|
wav files.
|
||||||
|
|
||||||
|
Fix the depth and signedness calculation in extensible wav files and
|
||||||
|
also handle 1, 2, 4, 6, 8 channels here when a file without channel
|
||||||
|
mask is found.
|
||||||
|
|
||||||
|
Add support for float, alaw and mulaw in extensible wav files.
|
||||||
|
|
||||||
|
This allows correct playback of all but 5 files from
|
||||||
|
http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Samples.html
|
||||||
|
|
||||||
|
(gst_riff_create_audio_template_caps):
|
||||||
|
Add voxware and float formats to the template caps.
|
||||||
|
|
||||||
2007-04-17 Sebastian Dröge <slomo@circular-chaos.org>
|
2007-04-17 Sebastian Dröge <slomo@circular-chaos.org>
|
||||||
|
|
||||||
Patch by: Vincent Torri <vtorri at univ-evry dot fr>
|
Patch by: Vincent Torri <vtorri at univ-evry dot fr>
|
||||||
|
|
|
@ -759,6 +759,8 @@ gst_riff_create_audio_caps (guint16 codec_id,
|
||||||
gint wd = ba * 8 / ch;
|
gint wd = ba * 8 / ch;
|
||||||
gint ws;
|
gint ws;
|
||||||
|
|
||||||
|
channels_max = 8;
|
||||||
|
|
||||||
if (strf->size > 32) {
|
if (strf->size > 32) {
|
||||||
GST_WARNING ("invalid depth (%d) of pcm audio, overwriting.",
|
GST_WARNING ("invalid depth (%d) of pcm audio, overwriting.",
|
||||||
strf->size);
|
strf->size);
|
||||||
|
@ -787,6 +789,9 @@ gst_riff_create_audio_caps (guint16 codec_id,
|
||||||
case 6:
|
case 6:
|
||||||
channel_mask = 0x3f;
|
channel_mask = 0x3f;
|
||||||
break;
|
break;
|
||||||
|
case 8:
|
||||||
|
channel_mask = 0xff;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
GST_WARNING ("don't know default layout for %d channels", ch);
|
GST_WARNING ("don't know default layout for %d channels", ch);
|
||||||
channel_mask = 0;
|
channel_mask = 0;
|
||||||
|
@ -827,6 +832,8 @@ gst_riff_create_audio_caps (guint16 codec_id,
|
||||||
gint ch = strf->channels;
|
gint ch = strf->channels;
|
||||||
gint wd = ba * 8 / ch;
|
gint wd = ba * 8 / ch;
|
||||||
|
|
||||||
|
channels_max = 8;
|
||||||
|
|
||||||
caps = gst_caps_new_simple ("audio/x-raw-float",
|
caps = gst_caps_new_simple ("audio/x-raw-float",
|
||||||
"endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
|
"endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
|
||||||
"channels", G_TYPE_INT, ch, "width", G_TYPE_INT, wd, NULL);
|
"channels", G_TYPE_INT, ch, "width", G_TYPE_INT, wd, NULL);
|
||||||
|
@ -846,6 +853,9 @@ gst_riff_create_audio_caps (guint16 codec_id,
|
||||||
case 6:
|
case 6:
|
||||||
channel_mask = 0x3f;
|
channel_mask = 0x3f;
|
||||||
break;
|
break;
|
||||||
|
case 8:
|
||||||
|
channel_mask = 0xff;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
GST_WARNING ("don't know default layout for %d channels", ch);
|
GST_WARNING ("don't know default layout for %d channels", ch);
|
||||||
channel_mask = 0;
|
channel_mask = 0;
|
||||||
|
@ -1043,6 +1053,8 @@ gst_riff_create_audio_caps (guint16 codec_id,
|
||||||
guint32 subformat_guid[4];
|
guint32 subformat_guid[4];
|
||||||
const guint8 *data;
|
const guint8 *data;
|
||||||
|
|
||||||
|
channels_max = 8;
|
||||||
|
|
||||||
/* should be at least 22 bytes */
|
/* should be at least 22 bytes */
|
||||||
if (strf_data == NULL || GST_BUFFER_SIZE (strf_data) < 22) {
|
if (strf_data == NULL || GST_BUFFER_SIZE (strf_data) < 22) {
|
||||||
GST_WARNING ("WAVE_FORMAT_EXTENSIBLE data size is %d (expected: 22)",
|
GST_WARNING ("WAVE_FORMAT_EXTENSIBLE data size is %d (expected: 22)",
|
||||||
|
@ -1071,20 +1083,39 @@ gst_riff_create_audio_caps (guint16 codec_id,
|
||||||
if (strf != NULL) {
|
if (strf != NULL) {
|
||||||
gint ba = strf->blockalign;
|
gint ba = strf->blockalign;
|
||||||
gint ws = strf->size;
|
gint ws = strf->size;
|
||||||
gint depth = ws;
|
gint wd = ba * 8 / strf->channels;
|
||||||
|
|
||||||
if (valid_bits_per_sample != 0)
|
if (valid_bits_per_sample != 0)
|
||||||
depth = valid_bits_per_sample;
|
ws = valid_bits_per_sample;
|
||||||
|
|
||||||
caps = gst_caps_new_simple ("audio/x-raw-int",
|
caps = gst_caps_new_simple ("audio/x-raw-int",
|
||||||
"endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
|
"endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
|
||||||
"channels", G_TYPE_INT, strf->channels,
|
"channels", G_TYPE_INT, strf->channels,
|
||||||
"width", G_TYPE_INT, (int) (ba * 8 / strf->channels),
|
"width", G_TYPE_INT, wd,
|
||||||
"depth", G_TYPE_INT, depth,
|
"depth", G_TYPE_INT, ws,
|
||||||
"rate", G_TYPE_INT, strf->rate,
|
"rate", G_TYPE_INT, strf->rate,
|
||||||
"signed", G_TYPE_BOOLEAN, (depth > 8) ? TRUE : FALSE, NULL);
|
"signed", G_TYPE_BOOLEAN, wd != 8, NULL);
|
||||||
|
|
||||||
if (!gst_riff_wavext_add_channel_layout (caps, channel_mask)) {
|
/* If channel_mask == 0 and channels <= 2, 4, 6 or 8 let's
|
||||||
|
* assume default layout as some wav files don't have the
|
||||||
|
* channel mask set */
|
||||||
|
|
||||||
|
if (channel_mask == 0) {
|
||||||
|
switch (strf->channels) {
|
||||||
|
case 4:
|
||||||
|
channel_mask = 0x33;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
channel_mask = 0x3f;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
channel_mask = 0xff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((channel_mask != 0 || strf->channels > 2) &&
|
||||||
|
!gst_riff_wavext_add_channel_layout (caps, channel_mask)) {
|
||||||
GST_WARNING ("failed to add channel layout");
|
GST_WARNING ("failed to add channel layout");
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
caps = NULL;
|
caps = NULL;
|
||||||
|
@ -1097,7 +1128,97 @@ gst_riff_create_audio_caps (guint16 codec_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (subformat_guid[0] == 0x00000003) {
|
} else if (subformat_guid[0] == 0x00000003) {
|
||||||
GST_DEBUG ("FIXME: handle IEEE float format");
|
GST_DEBUG ("FLOAT");
|
||||||
|
if (strf != NULL) {
|
||||||
|
gint ba = strf->blockalign;
|
||||||
|
gint ws = strf->size;
|
||||||
|
gint wd = ba * 8 / strf->channels;
|
||||||
|
|
||||||
|
if (valid_bits_per_sample != 0)
|
||||||
|
ws = valid_bits_per_sample;
|
||||||
|
|
||||||
|
caps = gst_caps_new_simple ("audio/x-raw-float",
|
||||||
|
"endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
|
||||||
|
"channels", G_TYPE_INT, strf->channels,
|
||||||
|
"width", G_TYPE_INT, wd, "rate", G_TYPE_INT, strf->rate, NULL);
|
||||||
|
|
||||||
|
/* If channel_mask == 0 and channels <= 2, 4, 6 or 8 let's
|
||||||
|
* assume default layout as some wav files don't have the
|
||||||
|
* channel mask set */
|
||||||
|
|
||||||
|
if (channel_mask == 0) {
|
||||||
|
switch (strf->channels) {
|
||||||
|
case 4:
|
||||||
|
channel_mask = 0x33;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
channel_mask = 0x3f;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
channel_mask = 0xff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((channel_mask != 0 || strf->channels > 2) &&
|
||||||
|
!gst_riff_wavext_add_channel_layout (caps, channel_mask)) {
|
||||||
|
GST_WARNING ("failed to add channel layout");
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
caps = NULL;
|
||||||
|
}
|
||||||
|
rate_chan = FALSE;
|
||||||
|
|
||||||
|
if (codec_name) {
|
||||||
|
*codec_name =
|
||||||
|
g_strdup_printf ("Uncompressed %d-bit IEEE float audio",
|
||||||
|
strf->size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (subformat_guid[0] == 00000006) {
|
||||||
|
GST_DEBUG ("ALAW");
|
||||||
|
if (strf != NULL) {
|
||||||
|
if (strf->size != 8) {
|
||||||
|
GST_WARNING ("invalid depth (%d) of alaw audio, overwriting.",
|
||||||
|
strf->size);
|
||||||
|
strf->size = 8;
|
||||||
|
strf->av_bps = 8;
|
||||||
|
strf->blockalign = strf->av_bps * strf->channels;
|
||||||
|
}
|
||||||
|
if (strf->av_bps == 0 || strf->blockalign == 0) {
|
||||||
|
GST_WARNING
|
||||||
|
("fixing av_bps (%d) and blockalign (%d) of alaw audio",
|
||||||
|
strf->av_bps, strf->blockalign);
|
||||||
|
strf->av_bps = strf->size;
|
||||||
|
strf->blockalign = strf->av_bps * strf->channels;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rate_max = 48000;
|
||||||
|
caps = gst_caps_new_simple ("audio/x-alaw", NULL);
|
||||||
|
|
||||||
|
if (codec_name)
|
||||||
|
*codec_name = g_strdup ("A-law audio");
|
||||||
|
} else if (subformat_guid[0] == 0x00000007) {
|
||||||
|
GST_DEBUG ("MULAW");
|
||||||
|
if (strf != NULL) {
|
||||||
|
if (strf->size != 8) {
|
||||||
|
GST_WARNING ("invalid depth (%d) of mulaw audio, overwriting.",
|
||||||
|
strf->size);
|
||||||
|
strf->size = 8;
|
||||||
|
strf->av_bps = 8;
|
||||||
|
strf->blockalign = strf->av_bps * strf->channels;
|
||||||
|
}
|
||||||
|
if (strf->av_bps == 0 || strf->blockalign == 0) {
|
||||||
|
GST_WARNING
|
||||||
|
("fixing av_bps (%d) and blockalign (%d) of mulaw audio",
|
||||||
|
strf->av_bps, strf->blockalign);
|
||||||
|
strf->av_bps = strf->size;
|
||||||
|
strf->blockalign = strf->av_bps * strf->channels;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rate_max = 48000;
|
||||||
|
caps = gst_caps_new_simple ("audio/x-mulaw", NULL);
|
||||||
|
if (codec_name)
|
||||||
|
*codec_name = g_strdup ("Mu-law audio");
|
||||||
} else if (subformat_guid[0] == 0x00000092) {
|
} else if (subformat_guid[0] == 0x00000092) {
|
||||||
GST_DEBUG ("FIXME: handle DOLBY AC3 SPDIF format");
|
GST_DEBUG ("FIXME: handle DOLBY AC3 SPDIF format");
|
||||||
}
|
}
|
||||||
|
@ -1316,7 +1437,9 @@ gst_riff_create_audio_template_caps (void)
|
||||||
GST_RIFF_WAVE_FORMAT_WMAV1,
|
GST_RIFF_WAVE_FORMAT_WMAV1,
|
||||||
GST_RIFF_WAVE_FORMAT_WMAV2,
|
GST_RIFF_WAVE_FORMAT_WMAV2,
|
||||||
GST_RIFF_WAVE_FORMAT_WMAV3,
|
GST_RIFF_WAVE_FORMAT_WMAV3,
|
||||||
GST_RIFF_WAVE_FORMAT_SONY_ATRAC3
|
GST_RIFF_WAVE_FORMAT_SONY_ATRAC3,
|
||||||
|
GST_RIFF_WAVE_FORMAT_IEEE_FLOAT,
|
||||||
|
GST_RIFF_WAVE_FORMAT_VOXWARE
|
||||||
/* FILL ME */
|
/* FILL ME */
|
||||||
};
|
};
|
||||||
guint i;
|
guint i;
|
||||||
|
|
Loading…
Reference in a new issue