rtpmp4a(de)pay: Only accept raw aac
[platform/upstream/gstreamer.git] / gst / rtp / gstrtpmp4adepay.c
1 /* GStreamer
2  * Copyright (C) <2007> Nokia Corporation (contact <stefan.kost@nokia.com>)
3  *               <2007> Wim Taymans <wim.taymans@gmail.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License version 2 as published by the Free Software Foundation.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #  include "config.h"
22 #endif
23
24 #include <gst/rtp/gstrtpbuffer.h>
25
26 #include <string.h>
27 #include "gstrtpmp4adepay.h"
28
29 GST_DEBUG_CATEGORY_STATIC (rtpmp4adepay_debug);
30 #define GST_CAT_DEFAULT (rtpmp4adepay_debug)
31
32 /* elementfactory information */
33 static const GstElementDetails gst_rtp_mp4adepay_details =
34 GST_ELEMENT_DETAILS ("RTP MPEG4 audio depayloader",
35     "Codec/Depayloader/Network",
36     "Extracts MPEG4 audio from RTP packets (RFC 3016)",
37     "Nokia Corporation (contact <stefan.kost@nokia.com>), "
38     "Wim Taymans <wim.taymans@gmail.com>");
39
40 static GstStaticPadTemplate gst_rtp_mp4a_depay_src_template =
41 GST_STATIC_PAD_TEMPLATE ("src",
42     GST_PAD_SRC,
43     GST_PAD_ALWAYS,
44     GST_STATIC_CAPS ("audio/mpeg,"
45         "mpegversion = (int) 4," "framed = (boolean) true, "
46         "stream-format = (string) raw")
47     );
48
49 static GstStaticPadTemplate gst_rtp_mp4a_depay_sink_template =
50 GST_STATIC_PAD_TEMPLATE ("sink",
51     GST_PAD_SINK,
52     GST_PAD_ALWAYS,
53     GST_STATIC_CAPS ("application/x-rtp, "
54         "media = (string) \"audio\", "
55         "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
56         "clock-rate = (int) [1, MAX ], "
57         "encoding-name = (string) \"MP4A-LATM\""
58         /* All optional parameters
59          *
60          * "profile-level-id=[1,MAX]"
61          * "config=" 
62          */
63     )
64     );
65
66 GST_BOILERPLATE (GstRtpMP4ADepay, gst_rtp_mp4a_depay, GstBaseRTPDepayload,
67     GST_TYPE_BASE_RTP_DEPAYLOAD);
68
69 static void gst_rtp_mp4a_depay_finalize (GObject * object);
70
71 static gboolean gst_rtp_mp4a_depay_setcaps (GstBaseRTPDepayload * depayload,
72     GstCaps * caps);
73 static GstBuffer *gst_rtp_mp4a_depay_process (GstBaseRTPDepayload * depayload,
74     GstBuffer * buf);
75
76 static GstStateChangeReturn gst_rtp_mp4a_depay_change_state (GstElement *
77     element, GstStateChange transition);
78
79
80 static void
81 gst_rtp_mp4a_depay_base_init (gpointer klass)
82 {
83   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
84
85   gst_element_class_add_pad_template (element_class,
86       gst_static_pad_template_get (&gst_rtp_mp4a_depay_src_template));
87   gst_element_class_add_pad_template (element_class,
88       gst_static_pad_template_get (&gst_rtp_mp4a_depay_sink_template));
89
90   gst_element_class_set_details (element_class, &gst_rtp_mp4adepay_details);
91 }
92
93 static void
94 gst_rtp_mp4a_depay_class_init (GstRtpMP4ADepayClass * klass)
95 {
96   GObjectClass *gobject_class;
97   GstElementClass *gstelement_class;
98   GstBaseRTPDepayloadClass *gstbasertpdepayload_class;
99
100   gobject_class = (GObjectClass *) klass;
101   gstelement_class = (GstElementClass *) klass;
102   gstbasertpdepayload_class = (GstBaseRTPDepayloadClass *) klass;
103
104   gobject_class->finalize = gst_rtp_mp4a_depay_finalize;
105
106   gstelement_class->change_state = gst_rtp_mp4a_depay_change_state;
107
108   gstbasertpdepayload_class->process = gst_rtp_mp4a_depay_process;
109   gstbasertpdepayload_class->set_caps = gst_rtp_mp4a_depay_setcaps;
110
111   GST_DEBUG_CATEGORY_INIT (rtpmp4adepay_debug, "rtpmp4adepay", 0,
112       "MPEG4 audio RTP Depayloader");
113 }
114
115 static void
116 gst_rtp_mp4a_depay_init (GstRtpMP4ADepay * rtpmp4adepay,
117     GstRtpMP4ADepayClass * klass)
118 {
119   rtpmp4adepay->adapter = gst_adapter_new ();
120 }
121
122 static void
123 gst_rtp_mp4a_depay_finalize (GObject * object)
124 {
125   GstRtpMP4ADepay *rtpmp4adepay;
126
127   rtpmp4adepay = GST_RTP_MP4A_DEPAY (object);
128
129   g_object_unref (rtpmp4adepay->adapter);
130   rtpmp4adepay->adapter = NULL;
131
132   G_OBJECT_CLASS (parent_class)->finalize (object);
133 }
134
135 static gboolean
136 gst_rtp_mp4a_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
137 {
138   GstStructure *structure;
139   GstRtpMP4ADepay *rtpmp4adepay;
140   GstCaps *srccaps;
141   const gchar *str;
142   gint clock_rate;
143   gint object_type;
144   gint channels = 2;            /* default */
145   gboolean res;
146
147   rtpmp4adepay = GST_RTP_MP4A_DEPAY (depayload);
148
149   structure = gst_caps_get_structure (caps, 0);
150
151   if (!gst_structure_get_int (structure, "clock-rate", &clock_rate))
152     clock_rate = 90000;         /* default */
153   depayload->clock_rate = clock_rate;
154
155   if (!gst_structure_get_int (structure, "object", &object_type))
156     object_type = 2;            /* AAC LC default */
157
158   srccaps = gst_caps_new_simple ("audio/mpeg",
159       "mpegversion", G_TYPE_INT, 4,
160       "framed", G_TYPE_BOOLEAN, TRUE, "channels", G_TYPE_INT, channels,
161       "stream-format", G_TYPE_STRING, "raw", NULL);
162
163   if ((str = gst_structure_get_string (structure, "config"))) {
164     GValue v = { 0 };
165
166     g_value_init (&v, GST_TYPE_BUFFER);
167     if (gst_value_deserialize (&v, str)) {
168       GstBuffer *buffer;
169       guint8 *data;
170       guint size;
171       gint i;
172
173       buffer = gst_value_get_buffer (&v);
174       gst_buffer_ref (buffer);
175       g_value_unset (&v);
176
177       data = GST_BUFFER_DATA (buffer);
178       size = GST_BUFFER_SIZE (buffer);
179
180       if (size < 2) {
181         GST_WARNING_OBJECT (depayload, "config too short (%d < 2)", size);
182         goto bad_config;
183       }
184
185       /* Parse StreamMuxConfig according to ISO/IEC 14496-3:
186        *
187        * audioMuxVersion           == 0 (1 bit)
188        * allStreamsSameTimeFraming == 1 (1 bit)
189        * numSubFrames              == rtpmp4adepay->numSubFrames (6 bits)
190        * numProgram                == 0 (4 bits)
191        * numLayer                  == 0 (3 bits)
192        *
193        * We only require audioMuxVersion == 0;
194        *
195        * The remaining bit of the second byte and the rest of the bits are used
196        * for audioSpecificConfig which we need to set in codec_info.
197        */
198       if ((data[0] & 0x80) != 0x00) {
199         GST_WARNING_OBJECT (depayload, "unknown audioMuxVersion 1");
200         goto bad_config;
201       }
202
203       rtpmp4adepay->numSubFrames = (data[0] & 0x3F);
204
205       GST_LOG_OBJECT (rtpmp4adepay, "numSubFrames %d",
206           rtpmp4adepay->numSubFrames);
207
208       /* shift rest of string 15 bits down */
209       size -= 2;
210       for (i = 0; i < size; i++) {
211         data[i] = ((data[i + 1] & 1) << 7) | ((data[i + 2] & 0xfe) >> 1);
212       }
213
214       /* ignore remaining bit, we're only interested in full bytes */
215       GST_BUFFER_SIZE (buffer) = size;
216
217       gst_caps_set_simple (srccaps,
218           "codec_data", GST_TYPE_BUFFER, buffer, NULL);
219       gst_buffer_unref (buffer);
220     } else {
221       g_warning ("cannot convert config to buffer");
222     }
223   }
224 bad_config:
225   res = gst_pad_set_caps (depayload->srcpad, srccaps);
226   gst_caps_unref (srccaps);
227
228   return res;
229 }
230
231 static GstBuffer *
232 gst_rtp_mp4a_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
233 {
234   GstRtpMP4ADepay *rtpmp4adepay;
235   GstBuffer *outbuf;
236
237   rtpmp4adepay = GST_RTP_MP4A_DEPAY (depayload);
238
239   /* flush remaining data on discont */
240   if (GST_BUFFER_IS_DISCONT (buf)) {
241     gst_adapter_clear (rtpmp4adepay->adapter);
242   }
243
244   outbuf = gst_rtp_buffer_get_payload_buffer (buf);
245
246   gst_adapter_push (rtpmp4adepay->adapter, outbuf);
247
248   /* RTP marker bit indicates the last packet of the AudioMuxElement => create
249    * and push a buffer */
250   if (gst_rtp_buffer_get_marker (buf)) {
251     guint avail;
252     guint i;
253     guint8 *data;
254     guint pos;
255
256     avail = gst_adapter_available (rtpmp4adepay->adapter);
257
258     GST_LOG_OBJECT (rtpmp4adepay, "have marker and %u available", avail);
259
260     outbuf = gst_adapter_take_buffer (rtpmp4adepay->adapter, avail);
261     data = GST_BUFFER_DATA (outbuf);
262     /* position in data we are at */
263     pos = 0;
264
265     /* looping through the number of sub-frames in the audio payload */
266     for (i = 0; i <= rtpmp4adepay->numSubFrames; i++) {
267       /* determine payload length and set buffer data pointer accordingly */
268       guint skip;
269       guint data_len;
270       guint32 timestamp;
271
272       GstBuffer *tmp = NULL;
273
274       timestamp = gst_rtp_buffer_get_timestamp (buf);
275
276       /* each subframe starts with a variable length encoding */
277       data_len = 0;
278       for (skip = 0; skip < avail; skip++) {
279         data_len += data[skip];
280         if (data[skip] != 0xff)
281           break;
282       }
283       skip++;
284
285       /* this can not be possible, we have not enough data or the length
286        * decoding failed because we ran out of data. */
287       if (skip + data_len > avail)
288         goto wrong_size;
289
290       GST_LOG_OBJECT (rtpmp4adepay,
291           "subframe %u, header len %u, data len %u, left %u", i, skip, data_len,
292           avail);
293
294       /* take data out, skip the header */
295       pos += skip;
296       tmp = gst_buffer_create_sub (outbuf, pos, data_len);
297
298       /* skip data too */
299       skip += data_len;
300       pos += data_len;
301
302       /* update our pointers whith what we consumed */
303       data += skip;
304       avail -= skip;
305
306       gst_buffer_set_caps (tmp, GST_PAD_CAPS (depayload->srcpad));
307
308       /* only apply the timestamp for the first buffer. Based on gstrtpmp4gdepay.c */
309       if (i == 0)
310         gst_base_rtp_depayload_push_ts (depayload, timestamp, tmp);
311       else
312         gst_base_rtp_depayload_push (depayload, tmp);
313     }
314
315     /* just a check that lengths match */
316     if (avail) {
317       GST_ELEMENT_WARNING (depayload, STREAM, DECODE,
318           ("Packet invalid"), ("Not all payload consumed: "
319               "possible wrongly encoded packet."));
320     }
321
322     gst_buffer_unref (outbuf);
323   }
324   return NULL;
325
326   /* ERRORS */
327 wrong_size:
328   {
329     GST_ELEMENT_WARNING (rtpmp4adepay, STREAM, DECODE,
330         ("Packet did not validate"), ("wrong packet size"));
331     gst_buffer_unref (outbuf);
332     return NULL;
333   }
334 }
335
336 static GstStateChangeReturn
337 gst_rtp_mp4a_depay_change_state (GstElement * element,
338     GstStateChange transition)
339 {
340   GstRtpMP4ADepay *rtpmp4adepay;
341   GstStateChangeReturn ret;
342
343   rtpmp4adepay = GST_RTP_MP4A_DEPAY (element);
344
345   switch (transition) {
346     case GST_STATE_CHANGE_READY_TO_PAUSED:
347       gst_adapter_clear (rtpmp4adepay->adapter);
348       break;
349     default:
350       break;
351   }
352
353   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
354
355   switch (transition) {
356     default:
357       break;
358   }
359   return ret;
360 }
361
362 gboolean
363 gst_rtp_mp4a_depay_plugin_init (GstPlugin * plugin)
364 {
365   return gst_element_register (plugin, "rtpmp4adepay",
366       GST_RANK_MARGINAL, GST_TYPE_RTP_MP4A_DEPAY);
367 }