From 6c5cee1d02956e7ad6e692687c3c50daa023736c Mon Sep 17 00:00:00 2001 From: "Andrzej K. Haczewski" Date: Thu, 8 Jul 2010 15:22:08 +0200 Subject: [PATCH] typefinding: extend AAC typefinder to detect LOAS streams Extend AAC typefinder to recognize LOAS stream as specified by ISO/IEC 14496-3:2009. https://bugzilla.gnome.org/show_bug.cgi?id=623918 --- gst/typefind/gsttypefindfunctions.c | 45 +++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index 81d21d0..dbe4cd4 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -671,6 +671,8 @@ aac_type_find (GstTypeFind * tf, gpointer unused) * 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. + * LOAS has 2 possible syncwords, which are 11 bits and 16 bits long. + * The following stream syntax depends on which one is found. */ if (G_UNLIKELY (!data_scan_ctx_ensure_data (tf, &c, 6))) break; @@ -744,6 +746,45 @@ aac_type_find (GstTypeFind * tf, gpointer unused) } GST_DEBUG ("No next frame found... (should have been at 0x%x)", len); + } else if (G_UNLIKELY (((snc & 0xffe0) == 0x56e0) || (snc == 0x4de1))) { + /* LOAS frame */ + + GST_DEBUG ("Found one LOAS syncword at offset 0x%" G_GINT64_MODIFIER + "x, tracing next...", c.offset); + + /* check length of frame for each type of detectable LOAS streams */ + if (snc == 0x4de1) { + /* EPAudioSyncStream */ + len = ((c.data[2] & 0x0f) << 9) | (c.data[3] << 1) | + ((c.data[4] & 0x80) >> 7); + /* add size of EP sync stream header */ + len += 7; + } else { + /* AudioSyncStream */ + len = ((c.data[1] & 0x1f) << 8) | c.data[2]; + /* add size of sync stream header */ + len += 3; + } + + 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; + } + + /* check if there's a second LOAS frame */ + snc = GST_READ_UINT16_BE (c.data + len); + if (((snc & 0xffe0) == 0x56e0) || (snc == 0x4de1)) { + GST_DEBUG ("Found second LOAS syncword at offset 0x%" + G_GINT64_MODIFIER "x, framelen %u", c.offset, len); + + gst_type_find_suggest_simple (tf, GST_TYPE_FIND_LIKELY, "audio/mpeg", + "framed", G_TYPE_BOOLEAN, FALSE, + "mpegversion", G_TYPE_INT, 4, + "stream-format", G_TYPE_STRING, "loas", NULL); + break; + } + + GST_DEBUG ("No next frame found... (should have been at 0x%x)", len); } else if (!memcmp (c.data, "ADIF", 4)) { /* ADIF header */ gst_type_find_suggest_simple (tf, GST_TYPE_FIND_LIKELY, "audio/mpeg", @@ -3966,7 +4007,7 @@ plugin_init (GstPlugin * plugin) static const gchar *compress_exts[] = { "Z", NULL }; static const gchar *m4a_exts[] = { "m4a", NULL }; static const gchar *q3gp_exts[] = { "3gp", NULL }; - static const gchar *aac_exts[] = { "aac", NULL }; + static const gchar *aac_exts[] = { "aac", "adts", "adif", "loas", NULL }; static const gchar *spc_exts[] = { "spc", NULL }; static const gchar *wavpack_exts[] = { "wv", "wvp", NULL }; static const gchar *wavpack_correction_exts[] = { "wvc", NULL }; @@ -4199,7 +4240,7 @@ plugin_init (GstPlugin * plugin) NULL, CMML_CAPS, NULL, NULL); TYPE_FIND_REGISTER_START_WITH (plugin, "application/x-executable", GST_RANK_MARGINAL, NULL, "\177ELF", 4, GST_TYPE_FIND_MAXIMUM); - TYPE_FIND_REGISTER (plugin, "adts_mpeg_stream", GST_RANK_SECONDARY, + TYPE_FIND_REGISTER (plugin, "aac", GST_RANK_SECONDARY, aac_type_find, aac_exts, AAC_CAPS, NULL, NULL); TYPE_FIND_REGISTER_START_WITH (plugin, "audio/x-spc", GST_RANK_SECONDARY, spc_exts, "SNES-SPC700 Sound File Data", 27, GST_TYPE_FIND_MAXIMUM); -- 2.7.4