mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 02:31:03 +00:00
gst/typefind/gsttypefindfunctions.c: Fix wavpack typefinding to work in more cases (don't peek for chunks of multiple...
Original commit message from CVS: * gst/typefind/gsttypefindfunctions.c: (wavpack_type_find): Fix wavpack typefinding to work in more cases (don't peek for chunks of multiple hundred kBs at once, but process things step-by-step in smaller units). Fixes #339786.
This commit is contained in:
parent
ffc01d2492
commit
b0091828ba
2 changed files with 52 additions and 51 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
2006-04-28 Tim-Philipp Müller <tim at centricular dot net>
|
||||||
|
|
||||||
|
* gst/typefind/gsttypefindfunctions.c: (wavpack_type_find):
|
||||||
|
Fix wavpack typefinding to work in more cases (don't peek
|
||||||
|
for chunks of multiple hundred kBs at once, but process
|
||||||
|
things step-by-step in smaller units). Fixes #339786.
|
||||||
|
|
||||||
2006-04-28 Thomas Vander Stichele <thomas at apestaart dot org>
|
2006-04-28 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||||
|
|
||||||
* configure.ac:
|
* configure.ac:
|
||||||
|
|
|
@ -816,64 +816,58 @@ GST_STATIC_CAPS ("audio/x-wavpack-correction, framed = (boolean) false");
|
||||||
static void
|
static void
|
||||||
wavpack_type_find (GstTypeFind * tf, gpointer unused)
|
wavpack_type_find (GstTypeFind * tf, gpointer unused)
|
||||||
{
|
{
|
||||||
guint8 *data = gst_type_find_peek (tf, 0, 32);
|
guint64 offset;
|
||||||
|
guint32 blocksize;
|
||||||
|
guint8 *data;
|
||||||
|
|
||||||
|
data = gst_type_find_peek (tf, 0, 32);
|
||||||
if (!data)
|
if (!data)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (data[0] == 'w' && data[1] == 'v' && data[2] == 'p' && data[3] == 'k') {
|
if (data[0] != 'w' || data[1] != 'v' || data[2] != 'p' || data[3] != 'k')
|
||||||
guint32 blocksize, sublen;
|
return;
|
||||||
gint32 left;
|
|
||||||
|
|
||||||
GST_LOG ("got wavpack header");
|
/* Note: wavpack blocks can be fairly large (easily 60-110k), possibly
|
||||||
|
* larger than the max. limits imposed by certain typefinding elements
|
||||||
|
* like id3demux or apedemux, so typefinding is most likely only going to
|
||||||
|
* work in pull-mode */
|
||||||
|
blocksize = GST_READ_UINT32_LE (data + 4);
|
||||||
|
GST_LOG ("wavpack header, blocksize=0x%04x", blocksize);
|
||||||
|
offset = 32;
|
||||||
|
while (offset < 32 + blocksize) {
|
||||||
|
guint32 sublen;
|
||||||
|
|
||||||
/* wavpack blocks can be fairly large, possibly larger than the max.
|
/* get chunk header */
|
||||||
* limits imposed by certain typefinding elements like id3demux or
|
GST_LOG ("peeking at chunk at offset 0x%04x", (guint) offset);
|
||||||
* apedemux. So if the first wavpack block is larger than any particular
|
data = gst_type_find_peek (tf, offset, 4);
|
||||||
* limit, we try to get a smaller chunk and hope we get lucky parsing
|
if (data == NULL)
|
||||||
* only bits of it (case at hand: first wavpack block: 42kB, with a
|
break;
|
||||||
* max. limit imposed by apedemux/id3demux: 40kB) */
|
sublen = ((guint32) data[1]) << 1;
|
||||||
blocksize = GST_READ_UINT32_LE (data + 4);
|
if (data[0] & 0x80) {
|
||||||
do {
|
sublen |= (((guint32) data[2]) << 9) | (((guint32) data[3]) << 17);
|
||||||
/* peek from offset 0, otherwise it won't work with apedemux */
|
sublen += 1 + 3; /* id + length */
|
||||||
data = gst_type_find_peek (tf, 0, 32 + blocksize);
|
} else {
|
||||||
if (data != NULL)
|
sublen += 1 + 1; /* id + length */
|
||||||
break;
|
|
||||||
if (32 + blocksize < 512) /* random threshold */
|
|
||||||
break;
|
|
||||||
blocksize = (blocksize * 3) / 4;
|
|
||||||
} while (data == NULL);
|
|
||||||
if (!data)
|
|
||||||
return;
|
|
||||||
data += 32;
|
|
||||||
left = (gint32) blocksize;
|
|
||||||
while (left > 2) {
|
|
||||||
sublen = ((guint32) data[1]) << 1;
|
|
||||||
if (data[0] & 0x80) {
|
|
||||||
sublen |= (((guint32) data[2]) << 9) | (((guint32) data[3]) << 17);
|
|
||||||
sublen += 1 + 3; /* id + length */
|
|
||||||
} else {
|
|
||||||
sublen += 1 + 1; /* id + length */
|
|
||||||
}
|
|
||||||
if (sublen > blocksize)
|
|
||||||
return;
|
|
||||||
if ((data[0] & 0x20) == 0) {
|
|
||||||
switch (data[0] & 0x0f) {
|
|
||||||
case 0xa: /* ID_WV_BITSTREAM */
|
|
||||||
case 0xc: /* ID_WVX_BITSTREAM */
|
|
||||||
gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, WAVPACK_CAPS);
|
|
||||||
return;
|
|
||||||
case 0xb: /* ID_WVC_BITSTREAM */
|
|
||||||
gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY,
|
|
||||||
WAVPACK_CORRECTION_CAPS);
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
left -= sublen;
|
|
||||||
data += sublen;
|
|
||||||
}
|
}
|
||||||
|
if (sublen > blocksize - offset + 32) {
|
||||||
|
GST_LOG ("chunk length too big (%u > %u)", sublen, blocksize - offset);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((data[0] & 0x20) == 0) {
|
||||||
|
switch (data[0] & 0x0f) {
|
||||||
|
case 0xa: /* ID_WV_BITSTREAM */
|
||||||
|
case 0xc: /* ID_WVX_BITSTREAM */
|
||||||
|
gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, WAVPACK_CAPS);
|
||||||
|
return;
|
||||||
|
case 0xb: /* ID_WVC_BITSTREAM */
|
||||||
|
gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY,
|
||||||
|
WAVPACK_CORRECTION_CAPS);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offset += sublen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue