flacdec: improve and relax audio frame parsing

... so as to properly recognize first audio frame.

Fixes https://bugzilla.gnome.org/show_bug.cgi?id=681077

Conflicts:

	ext/flac/gstflacdec.c
This commit is contained in:
Mark Nauwelaerts 2012-08-03 14:02:23 +02:00
parent 75ee20ec67
commit 94ab6e17f5

View file

@ -377,6 +377,38 @@ gst_flac_dec_scan_got_frame (GstFlacDec * flacdec, guint8 * data, guint size,
else if (sr == 0x0D || sr == 0x0E)
sr_from_end = 16;
val = data[4];
/* This is slightly faster than a loop */
if (!(val & 0x80)) {
val = 0;
} else if ((val & 0xc0) && !(val & 0x20)) {
val = 1;
} else if ((val & 0xe0) && !(val & 0x10)) {
val = 2;
} else if ((val & 0xf0) && !(val & 0x08)) {
val = 3;
} else if ((val & 0xf8) && !(val & 0x04)) {
val = 4;
} else if ((val & 0xfc) && !(val & 0x02)) {
val = 5;
} else if ((val & 0xfe) && !(val & 0x01)) {
val = 6;
} else {
GST_LOG_OBJECT (flacdec, "failed to read sample/frame");
return FALSE;
}
val++;
headerlen = 4 + val + (bs_from_end / 8) + (sr_from_end / 8);
if (gst_flac_calculate_crc8 (data, headerlen) != data[headerlen]) {
GST_LOG_OBJECT (flacdec, "invalid checksum");
return FALSE;
}
if (!last_sample_num)
return TRUE;
/* FIXME: This is can be 36 bit if variable block size is used,
* fortunately not encoder supports this yet and we check for that
* above.
@ -388,14 +420,6 @@ gst_flac_dec_scan_got_frame (GstFlacDec * flacdec, guint8 * data, guint size,
return FALSE;
}
headerlen = 4 + g_unichar_to_utf8 ((gunichar) val, NULL) +
(bs_from_end / 8) + (sr_from_end / 8);
if (gst_flac_calculate_crc8 (data, headerlen) != data[headerlen]) {
GST_LOG_OBJECT (flacdec, "invalid checksum");
return FALSE;
}
if (flacdec->min_blocksize == flacdec->max_blocksize) {
*last_sample_num = (val + 1) * flacdec->min_blocksize;
} else {
@ -768,13 +792,12 @@ gst_flac_dec_handle_frame (GstAudioDecoder * audio_dec, GstBuffer * buf)
/* drop any in-stream headers, we've processed those in set_format already */
if (G_UNLIKELY (!dec->got_headers)) {
gboolean got_audio_frame;
gint64 unused;
GstMapInfo map;
/* check if this is a flac audio frame (rather than a header or junk) */
gst_buffer_map (buf, &map, GST_MAP_READ);
got_audio_frame =
gst_flac_dec_scan_got_frame (dec, map.data, map.size, &unused);
gst_flac_dec_scan_got_frame (dec, map.data, map.size, NULL);
gst_buffer_unmap (buf, &map);
if (!got_audio_frame) {