From 7cb1276dac0f47109ac7a26ef7daae8c70282fa8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 19 May 2008 15:59:40 +0000 Subject: [PATCH] gst/typefind/gsttypefindfunctions.c: Use data scan helper in aac typefinder and stop scanning for headers when we've ... Original commit message from CVS: * gst/typefind/gsttypefindfunctions.c: (aac_type_find): Use data scan helper in aac typefinder and stop scanning for headers when we've found a type. Also fix potential invalid memory access when calculating the frame length. --- ChangeLog | 7 +++ gst/typefind/gsttypefindfunctions.c | 99 ++++++++++++++++++------------------- 2 files changed, 55 insertions(+), 51 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3807f6f..320fb72 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2008-05-19 Tim-Philipp Müller + * gst/typefind/gsttypefindfunctions.c: (aac_type_find): + Use data scan helper in aac typefinder and stop scanning + for headers when we've found a type. Also fix potential invalid + memory access when calculating the frame length. + +2008-05-19 Tim-Philipp Müller + * gst/typefind/gsttypefindfunctions.c: (data_scan_ctx_ensure_data), (mpeg_sys_is_valid_pack): Don't modify scan context when we return FALSE in ensure_data, so diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index d9eae0e..c428422 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -547,68 +547,65 @@ static GstStaticCaps aac_caps = GST_STATIC_CAPS ("audio/mpeg, " static void aac_type_find (GstTypeFind * tf, gpointer unused) { - guint8 *data = gst_type_find_peek (tf, 0, AAC_AMOUNT); - gint snc; - - /* detect adts header or adif header. - * The ADIF header is 4 bytes, that should be OK. The ADTS header, on - * the other hand, is 14 bits only, so we require one valid frame with - * again a valid syncpoint on the next one (28 bits) for certainty. We - * require 4 kB, which is quite a lot, since frames are generally 200-400 - * bytes. - */ - if (data) { - gint n; - - for (n = 0; n < AAC_AMOUNT - 3; n++) { - snc = GST_READ_UINT16_BE (&data[n]); - if ((snc & 0xfff6) == 0xfff0) { - /* ADTS header - find frame length */ - gint len; - - GST_DEBUG ("Found one ADTS syncpoint at offset 0x%x, tracing next...", - n); - if (AAC_AMOUNT - n < 5) { - GST_DEBUG ("Not enough data to parse ADTS header"); - break; - } - len = ((data[n + 3] & 0x03) << 11) | - (data[n + 4] << 3) | ((data[n + 5] & 0xe0) >> 5); - if (n + len + 2 >= AAC_AMOUNT) { - GST_DEBUG ("Next frame is not within reach"); - break; - } else if (len == 0) { - continue; - } - - snc = GST_READ_UINT16_BE (&data[n + len]); - if ((snc & 0xfff6) == 0xfff0) { - gint mpegversion = (data[n + 1] & 0x08) ? 2 : 4; - GstCaps *caps = gst_caps_new_simple ("audio/mpeg", - "framed", G_TYPE_BOOLEAN, FALSE, - "mpegversion", G_TYPE_INT, mpegversion, - NULL); + DataScanCtx c = { 0, NULL, 0 }; - gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, caps); - gst_caps_unref (caps); + while (c.offset < AAC_AMOUNT) { + guint snc, len; + + /* detect adts header or adif header. + * The ADIF header is 4 bytes, that should be OK. The ADTS header, on + * the other hand, is 14 bits only, so we require one valid frame with + * again a valid syncpoint on the next one (28 bits) for certainty. We + * require 4 kB, which is quite a lot, since frames are generally 200-400 + * bytes. + */ + if (G_UNLIKELY (!data_scan_ctx_ensure_data (tf, &c, 6))) + break; - GST_DEBUG ("Found ADTS-%d syncpoint at offset 0x%x (framelen %u)", - mpegversion, n, len); - break; - } + snc = GST_READ_UINT16_BE (c.data); + if (G_UNLIKELY ((snc & 0xfff6) == 0xfff0)) { + /* ADTS header - find frame length */ + GST_DEBUG ("Found one ADTS syncpoint at offset 0x%x, tracing next...", + c.offset); + len = ((c.data[3] & 0x03) << 11) | + (c.data[4] << 3) | ((c.data[5] & 0xe0) >> 5); + + if (len == 0 || !data_scan_ctx_ensure_data (tf, &c, len + 2)) { + GST_DEBUG ("Wrong sync or next frame not within reach, len=%u", len); + goto next; + } - GST_DEBUG ("No next frame found... (should be at 0x%x)", n + len); - } else if (!memcmp (&data[n], "ADIF", 4)) { - /* ADIF header */ + snc = GST_READ_UINT16_BE (c.data + len); + if ((snc & 0xfff6) == 0xfff0) { + gint mpegversion = (c.data[1] & 0x08) ? 2 : 4; GstCaps *caps = gst_caps_new_simple ("audio/mpeg", "framed", G_TYPE_BOOLEAN, FALSE, - "mpegversion", G_TYPE_INT, 4, + "mpegversion", G_TYPE_INT, mpegversion, NULL); gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, caps); gst_caps_unref (caps); + GST_DEBUG ("Found second ADTS-%d syncpoint at offset 0x%x, framelen %u", + mpegversion, c.offset, len); + break; } + + GST_DEBUG ("No next frame found... (should have been at 0x%x)", len); + } else if (!memcmp (c.data, "ADIF", 4)) { + /* ADIF header */ + GstCaps *caps = gst_caps_new_simple ("audio/mpeg", + "framed", G_TYPE_BOOLEAN, FALSE, + "mpegversion", G_TYPE_INT, 4, + NULL); + + gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, caps); + gst_caps_unref (caps); + break; } + + next: + + data_scan_ctx_advance (tf, &c, 1); } } -- 2.7.4