[gst-devel] [PATCH] typefinding: extend AAC typefinder for LOAS stream

Andrzej K. Haczewski ahaczewski at gmail.com
Thu Jul 8 15:43:17 CEST 2010


Signed-off-by: Andrzej K. Haczewski <ahaczewski at gmail.com>
---
 gst/typefind/gsttypefindfunctions.c |   54 +++++++++++++++++++++++++++++++++-
 1 files changed, 52 insertions(+), 2 deletions(-)

Hello all,

Here's a little patch to detect LOAS MPEG-4 streams that carry AAC. I also 
included additional file extensions for AAC. As the original typefind name
did not reflect the new capability, I also altered it to better reflect its
purpose, as it is currently capable of detecting any type of stream that
AAC can be natively transported in. Feel free to review and comment.

Regards,
Andrzej K. Haczewski

diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c
index 07d8747..25c08fc 100644
--- a/gst/typefind/gsttypefindfunctions.c
+++ b/gst/typefind/gsttypefindfunctions.c
@@ -679,6 +679,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;
@@ -756,6 +758,54 @@ 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)) {
+        GstCaps *caps;
+
+        GST_DEBUG ("Found second LOAS syncword at offset 0x%"
+            G_GINT64_MODIFIER "x, framelen %u", c.offset, len);
+
+        /* Set additional field to indicate which type of LOAS stream is found.
+         * It is purely informational field as receiving element have to parse
+         * the stream anyway. */
+        caps = gst_caps_new_simple ("audio/mpeg",
+            "framed", G_TYPE_BOOLEAN, FALSE,
+            "mpegversion", G_TYPE_INT, 4,
+            "stream-type", G_TYPE_STRING, "loas",
+            "error-resilient", G_TYPE_BOOLEAN, (snc == 0x4de1), NULL);
+
+        gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, caps);
+        gst_caps_unref (caps);
+        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",
@@ -3923,7 +3973,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 };
@@ -4156,7 +4206,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, "audio/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);
-- 
1.7.1





More information about the gstreamer-devel mailing list