File: 0001-fdkaac-Add-support-for-LATM.patch

package info (click to toggle)
gst-plugins-bad1.0-contrib 1.26.9-1
  • links: PTS, VCS
  • area: contrib
  • in suites: sid
  • size: 69,920 kB
  • sloc: ansic: 722,582; cpp: 278,151; objc: 3,556; xml: 3,351; sh: 1,035; python: 473; makefile: 91; java: 75
file content (187 lines) | stat: -rw-r--r-- 7,986 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
From c348f01f5e70bd7b540774fe06eb2e2aa204264d Mon Sep 17 00:00:00 2001
From: Sanchayan Maity <sanchayan@asymptotic.io>
Date: Thu, 12 Nov 2020 20:03:11 +0530
Subject: [PATCH 1/7] fdkaac: Add support for LATM

ISO/IEC 14496-3 (MPEG-4 Audio) defines the LATM/LOAS mechanism to transport
streams without using ISO/IEC 14496-1 (MPEG-4 Systems) for audio only
applications. The transport mechanism uses a two-layer approach, namely a
multiplex layer and a synchronization layer. The multiplex layer viz.
(Low-overhead MPEG-4 Audio Transport Multiplex: LATM) manages multiplexing
of several MPEG-4 Audio payloads and their AudioSpecificConfig elements.
LATM might be considered as LOAS without the synchronization layer.

As per the spec, the multiplexed element viz. AudioMuxElement without
synchronization shall only be used for transmission channels where the
underlying transport layer already provides frame synchronization. An
example case is using AAC with bluetooth.

LATM MCP1 encoded data can be payloaded in RTP for sending the AAC
stream via bluetooth.

For details on bitstream, see the Fraunhofer IIS Application Bulletin on
AAC transport formats.
https://www.iis.fraunhofer.de/content/dam/iis/de/doc/ame/wp/FraunhoferIIS_Application-Bulletin_AAC-Transport-Formats.pdf

Note that muxConfigPresent needs to be set at the application layer and
signals whether the configuration is sent within or outside the stream.
This cannot be determined by parsing the bitstream. We introduce two
different stream formats to be able to distinguish between the MCP0 and
MCP1 case, viz. latm-mcp0/1.
---
 .../gst-plugins-bad/ext/fdkaac/gstfdkaacdec.c | 17 ++++-
 .../gst-plugins-bad/ext/fdkaac/gstfdkaacenc.c | 67 ++++++++++++++++++-
 2 files changed, 79 insertions(+), 5 deletions(-)

Index: gst-plugins-bad1.0-contrib/ext/fdkaac/gstfdkaacdec.c
===================================================================
--- gst-plugins-bad1.0-contrib.orig/ext/fdkaac/gstfdkaacdec.c
+++ gst-plugins-bad1.0-contrib/ext/fdkaac/gstfdkaacdec.c
@@ -45,7 +45,11 @@ static GstStaticPadTemplate sink_templat
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS ("audio/mpeg, "
         "mpegversion = (int) {2, 4}, "
-        "stream-format = (string) { adts, adif, raw }, " CHANNELS_CAPS_STR)
+        "stream-format = (string) { adts, adif, raw }, "
+        CHANNELS_CAPS_STR ";  "
+        "audio/mpeg, "
+        "mpegversion = (int) 4, "
+        "stream-format = (string) { latm-mcp0, latm-mcp1 }, " CHANNELS_CAPS_STR)
     );
 
 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
@@ -126,6 +130,10 @@ gst_fdkaacdec_set_format (GstAudioDecode
     transport_format = TT_MP4_ADIF;
   } else if (strcmp (stream_format, "adts") == 0) {
     transport_format = TT_MP4_ADTS;
+  } else if (strcmp (stream_format, "latm-mcp0") == 0) {
+    transport_format = TT_MP4_LATM_MCP0;
+  } else if (strcmp (stream_format, "latm-mcp1") == 0) {
+    transport_format = TT_MP4_LATM_MCP1;
   } else {
     g_assert_not_reached ();
   }
@@ -136,7 +144,12 @@ gst_fdkaacdec_set_format (GstAudioDecode
     return FALSE;
   }
 
-  if (transport_format == TT_MP4_RAW) {
+  /*
+   * If out of band config data either AudioSpecificConfig or StreamMuxConfig
+   * is applicable with raw or LATM MCP0 respectively, aacDecoder_ConfigRaw
+   * must be called with this data before beginning the decoding process.
+   */
+  if (transport_format == TT_MP4_RAW || transport_format == TT_MP4_LATM_MCP0) {
     GstBuffer *codec_data = NULL;
     GstMapInfo map;
     guint8 *data;
Index: gst-plugins-bad1.0-contrib/ext/fdkaac/gstfdkaacenc.c
===================================================================
--- gst-plugins-bad1.0-contrib.orig/ext/fdkaac/gstfdkaacenc.c
+++ gst-plugins-bad1.0-contrib/ext/fdkaac/gstfdkaacenc.c
@@ -24,6 +24,7 @@
 #include "gstfdkaac.h"
 #include "gstfdkaacenc.h"
 
+#include <gst/base/gstbitwriter.h>
 #include <gst/pbutils/pbutils.h>
 
 #include <string.h>
@@ -79,7 +80,7 @@ static GstStaticPadTemplate src_template
         "mpegversion = (int) 4, "
         "rate = (int) { " SAMPLE_RATES " }, "
         "channels = (int) {1, 2, 3, 4, 5, 6, 8}, "
-        "stream-format = (string) { adts, adif, raw }, "
+        "stream-format = (string) { adts, adif, raw }, latm-mcp0, latm-mcp1 }, "
         "profile = (string) { lc, he-aac-v1, he-aac-v2, ld }, "
         "framed = (boolean) true")
     );
@@ -297,6 +298,7 @@ gst_fdkaacenc_set_format (GstAudioEncode
   CHANNEL_MODE channel_mode = MODE_INVALID;
   AACENC_InfoStruct enc_info = { 0 };
   gint bitrate, signaling_mode;
+  guint8 audio_spec_conf[2] = { 0 };
   guint bitrate_mode;
 
   if (self->enc && !self->is_drained) {
@@ -324,6 +326,20 @@ gst_fdkaacenc_set_format (GstAudioEncode
       } else if (strcmp (str, "raw") == 0) {
         GST_DEBUG_OBJECT (self, "use RAW format for output");
         transmux = 0;
+      } else if (strcmp (str, "latm-mcp1") == 0) {
+        /*
+         * Enable TT_MP4_LATM_MCP1. Sets muxConfigPresent = 1. See Section 4.1 of
+         * RFC 3016.
+         */
+        GST_DEBUG_OBJECT (self, "use LATM MCP1 format for output");
+        transmux = 6;
+      } else if (strcmp (str, "latm-mcp0") == 0) {
+        /*
+         * Enable TT_MP4_LATM_MCP0. Sets muxConfigPresent = 0. See Section 4.1 of
+         * RFC 3016.
+         */
+        GST_DEBUG_OBJECT (self, "use LATM MCP0 format for output");
+        transmux = 7;
       }
     }
 
@@ -572,12 +588,57 @@ gst_fdkaacenc_set_format (GstAudioEncode
   } else if (transmux == 2) {
     gst_caps_set_simple (src_caps, "stream-format", G_TYPE_STRING, "adts",
         NULL);
+  } else if (transmux == 6 || transmux == 7) {
+    GstBitWriter bw;
+    guint rate = GST_AUDIO_INFO_RATE (info);
+    guint8 channels = GST_AUDIO_INFO_CHANNELS (info);
+    GstBuffer *codec_data;
+
+    /*
+     * Craft a AudioSpecificConfig manually to be used for setting level and
+     * profile later as when LATM_MCP0/1 is enabled enc_info.confBuf won't have
+     * AudioSpecificConfig but StreamMuxConfig. Since gst_codec_utils expects
+     * an AudioSpecificConfig to retrieve aot, rate and channel config
+     * information, it will fail. We pass this manually constructed
+     * AudioSpecificConfig when LATM is requested.
+     */
+    gst_bit_writer_init_with_data (&bw, audio_spec_conf,
+        sizeof (audio_spec_conf), FALSE);
+    gst_bit_writer_put_bits_uint8 (&bw, 2 /* AOT_AAC_LC */ , 5);
+    gst_bit_writer_put_bits_uint8 (&bw,
+        gst_codec_utils_aac_get_index_from_sample_rate (rate), 4);
+    gst_bit_writer_put_bits_uint8 (&bw, channels, 4);
+
+    codec_data =
+        gst_buffer_new_wrapped (g_memdup (enc_info.confBuf, enc_info.confSize),
+        enc_info.confSize);
+    /*
+     * For MCP0 the config is out of band, so set codec_data to
+     * StreamMuxConfig. For MCP1, the config is in band and need not be send
+     * via any out of band means like codec_data.
+     */
+    if (transmux == 6)
+      gst_caps_set_simple (src_caps, "stream-format", G_TYPE_STRING,
+          "latm-mcp1", NULL);
+    else
+      gst_caps_set_simple (src_caps, "codec_data", GST_TYPE_BUFFER, codec_data,
+          "stream-format", G_TYPE_STRING, "latm-mcp0", NULL);
+    gst_buffer_unref (codec_data);
   } else {
     g_assert_not_reached ();
   }
 
-  gst_codec_utils_aac_caps_set_level_and_profile (src_caps, enc_info.confBuf,
-      enc_info.confSize);
+  if (transmux != 6 && transmux != 7)
+    gst_codec_utils_aac_caps_set_level_and_profile (src_caps,
+        enc_info.confBuf, enc_info.confSize);
+  else
+    /*
+     * For LATM, confBuf is StreamMuxConfig and not AudioSpecificConfig.
+     * In this case, pass in the manually constructed AudioSpecificConfig
+     * buffer above.
+     */
+    gst_codec_utils_aac_caps_set_level_and_profile (src_caps, audio_spec_conf,
+        sizeof (audio_spec_conf));
 
   /* The above only parses the "base" profile, which is always going to be LC.
    * Set actual profile. */