From 94ab6e17f500be381dfa6aa0e1d20ce73b4d06fe Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Fri, 3 Aug 2012 14:02:23 +0200 Subject: [PATCH] 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 --- ext/flac/gstflacdec.c | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/ext/flac/gstflacdec.c b/ext/flac/gstflacdec.c index 57cc6aa8e8..af86a9cf84 100644 --- a/ext/flac/gstflacdec.c +++ b/ext/flac/gstflacdec.c @@ -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) {