audio: add support for AAC pass-through
authorAkihiro Tsukada <atsukada@users.sourceforge.net>
Fri, 22 Feb 2013 12:02:19 +0000 (21:02 +0900)
committerTim-Philipp Müller <tim@centricular.net>
Wed, 27 Feb 2013 00:38:05 +0000 (00:38 +0000)
https://bugzilla.gnome.org/show_bug.cgi?id=694443

gst-libs/gst/audio/gstaudioiec61937.c
gst-libs/gst/audio/gstaudioringbuffer.c

index ebd0d33..b1ad046 100644 (file)
@@ -40,6 +40,7 @@
 #define IEC61937_HEADER_SIZE      8
 #define IEC61937_PAYLOAD_SIZE_AC3 (1536 * 4)
 #define IEC61937_PAYLOAD_SIZE_EAC3 (6144 * 4)
+#define IEC61937_PAYLOAD_SIZE_AAC (1024 * 4)
 
 static gint
 caps_get_int_field (const GstCaps * caps, const gchar * field)
@@ -123,6 +124,12 @@ gst_audio_iec61937_frame_size (const GstAudioRingBufferSpec * spec)
       return frames * 4;
     }
 
+    case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG2_AAC:
+    case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG4_AAC:
+    {
+      return IEC61937_PAYLOAD_SIZE_AAC;
+    }
+
     default:
       return 0;
   }
@@ -287,6 +294,41 @@ gst_audio_iec61937_payload (const guint8 * src, guint src_n, guint8 * dst,
       break;
     }
 
+    case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG2_AAC:
+      /* HACK. disguising MPEG4 AAC as MPEG2 AAC seems to work. */
+      /* TODO: set the right Pc,Pd for MPEG4 in accordance with IEC61937-6 */
+    case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG4_AAC:
+    {
+      int num_rd_blks;
+
+      g_return_val_if_fail (src_n >= 7, FALSE);
+      num_rd_blks = (src[6] & 0x03) + 1;
+
+      /* Pc: bit 13-15 - stream number (0)
+       *     bit 11-12 - reserved (0)
+       *     bit  8-10 - reserved? (0) */
+      dst[four] = 0;
+      /* Pc: bit    7  - error bit (0)
+       *     bit  5-6  - reserved (0)
+       *     bit  0-4  - data type (07 = MPEG2 AAC ADTS
+       *                            19 = MPEG2 AAC ADTS half-rate LSF
+       *                            51 = MPEG2 AAC ADTS quater-rate LSF */
+      if (num_rd_blks == 1)
+        dst[five] = 0x07;
+      else if (num_rd_blks == 2)
+        dst[five] = 0x13;
+      else if (num_rd_blks == 4)
+        dst[five] = 0x33;
+      else
+        g_return_val_if_reached (FALSE);
+
+      /* Pd: bit 15-0  - frame size in bits */
+      tmp = GST_ROUND_UP_2 (src_n) * 8;
+      dst[six] = (guint8) (tmp >> 8);
+      dst[seven] = (guint8) (tmp & 0xff);
+      break;
+    }
+
     default:
       return FALSE;
   }
index 3c7884e..8f7e598 100644 (file)
@@ -124,7 +124,9 @@ static const gchar *format_type_names[] = {
   "iec958",
   "ac3",
   "eac3",
-  "dts"
+  "dts",
+  "aac mpeg2",
+  "aac mpeg4"
 };
 #endif
 
@@ -263,6 +265,17 @@ gst_audio_ring_buffer_parse_caps (GstAudioRingBufferSpec * spec, GstCaps * caps)
 
     spec->type = GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG;
     info.bpf = 4;
+  } else if (g_str_equal (mimetype, "audio/mpeg") &&
+      gst_structure_get_int (structure, "mpegversion", &i) &&
+      (i == 2 || i == 4) &&
+      !g_strcmp0 (gst_structure_get_string (structure, "stream-format"),
+          "adts")) {
+    /* MPEG-2 AAC or MPEG-4 AAC */
+    if (!(gst_structure_get_int (structure, "rate", &info.rate)))
+      goto parse_error;
+    spec->type = (i == 2) ? GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG2_AAC :
+        GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG4_AAC;
+    info.bpf = 4;
   } else {
     goto parse_error;
   }