webrtc/nice: Support domain name as connection-address of ICE candidate
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-good / gst / rtp / gstrtpgstdepay.c
1 /* GStreamer
2  * Copyright (C) <2010> Wim Taymans <wim.taymans@gmail.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
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., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #  include "config.h"
22 #endif
23
24 #include <string.h>
25 #include <stdlib.h>
26
27 #include "gstrtpelements.h"
28 #include "gstrtpgstdepay.h"
29 #include "gstrtputils.h"
30
31 #include <gst/video/video.h>
32
33 GST_DEBUG_CATEGORY_STATIC (rtpgstdepay_debug);
34 #define GST_CAT_DEFAULT (rtpgstdepay_debug)
35
36 static GstStaticPadTemplate gst_rtp_gst_depay_src_template =
37 GST_STATIC_PAD_TEMPLATE ("src",
38     GST_PAD_SRC,
39     GST_PAD_ALWAYS,
40     GST_STATIC_CAPS_ANY);
41
42 static GstStaticPadTemplate gst_rtp_gst_depay_sink_template =
43 GST_STATIC_PAD_TEMPLATE ("sink",
44     GST_PAD_SINK,
45     GST_PAD_ALWAYS,
46     GST_STATIC_CAPS ("application/x-rtp, "
47         "media = (string) \"application\", "
48         "clock-rate = (int) 90000, " "encoding-name = (string) \"X-GST\"")
49     );
50
51 #define gst_rtp_gst_depay_parent_class parent_class
52 G_DEFINE_TYPE (GstRtpGSTDepay, gst_rtp_gst_depay, GST_TYPE_RTP_BASE_DEPAYLOAD);
53 GST_ELEMENT_REGISTER_DEFINE_WITH_CODE (rtpgstdepay, "rtpgstdepay",
54     GST_RANK_MARGINAL, GST_TYPE_RTP_GST_DEPAY, rtp_element_init (plugin));
55
56 static void gst_rtp_gst_depay_finalize (GObject * object);
57
58 static gboolean gst_rtp_gst_depay_handle_event (GstRTPBaseDepayload * depay,
59     GstEvent * event);
60 static GstStateChangeReturn gst_rtp_gst_depay_change_state (GstElement *
61     element, GstStateChange transition);
62
63 static void gst_rtp_gst_depay_reset (GstRtpGSTDepay * rtpgstdepay, gboolean
64     full);
65 static gboolean gst_rtp_gst_depay_setcaps (GstRTPBaseDepayload * depayload,
66     GstCaps * caps);
67 static GstBuffer *gst_rtp_gst_depay_process (GstRTPBaseDepayload * depayload,
68     GstRTPBuffer * rtp);
69
70 static void
71 gst_rtp_gst_depay_class_init (GstRtpGSTDepayClass * klass)
72 {
73   GObjectClass *gobject_class;
74   GstElementClass *gstelement_class;
75   GstRTPBaseDepayloadClass *gstrtpbasedepayload_class;
76
77   GST_DEBUG_CATEGORY_INIT (rtpgstdepay_debug, "rtpgstdepay", 0,
78       "Gstreamer RTP Depayloader");
79
80   gobject_class = (GObjectClass *) klass;
81   gstelement_class = (GstElementClass *) klass;
82   gstrtpbasedepayload_class = (GstRTPBaseDepayloadClass *) klass;
83
84   gobject_class->finalize = gst_rtp_gst_depay_finalize;
85
86   gstelement_class->change_state = gst_rtp_gst_depay_change_state;
87
88   gst_element_class_add_static_pad_template (gstelement_class,
89       &gst_rtp_gst_depay_src_template);
90   gst_element_class_add_static_pad_template (gstelement_class,
91       &gst_rtp_gst_depay_sink_template);
92
93   gst_element_class_set_static_metadata (gstelement_class,
94       "GStreamer depayloader", "Codec/Depayloader/Network",
95       "Extracts GStreamer buffers from RTP packets",
96       "Wim Taymans <wim.taymans@gmail.com>");
97
98   gstrtpbasedepayload_class->handle_event = gst_rtp_gst_depay_handle_event;
99   gstrtpbasedepayload_class->set_caps = gst_rtp_gst_depay_setcaps;
100   gstrtpbasedepayload_class->process_rtp_packet = gst_rtp_gst_depay_process;
101 }
102
103 static void
104 gst_rtp_gst_depay_init (GstRtpGSTDepay * rtpgstdepay)
105 {
106   rtpgstdepay->adapter = gst_adapter_new ();
107 }
108
109 static void
110 gst_rtp_gst_depay_finalize (GObject * object)
111 {
112   GstRtpGSTDepay *rtpgstdepay;
113
114   rtpgstdepay = GST_RTP_GST_DEPAY (object);
115
116   gst_rtp_gst_depay_reset (rtpgstdepay, TRUE);
117   g_object_unref (rtpgstdepay->adapter);
118
119   G_OBJECT_CLASS (parent_class)->finalize (object);
120 }
121
122 static void
123 gst_rtp_gst_depay_reset (GstRtpGSTDepay * rtpgstdepay, gboolean full)
124 {
125   gst_adapter_clear (rtpgstdepay->adapter);
126   if (full) {
127     rtpgstdepay->current_CV = 0;
128     gst_caps_replace (&rtpgstdepay->current_caps, NULL);
129     g_free (rtpgstdepay->stream_id);
130     rtpgstdepay->stream_id = NULL;
131     if (rtpgstdepay->tags)
132       gst_tag_list_unref (rtpgstdepay->tags);
133     rtpgstdepay->tags = NULL;
134   }
135 }
136
137 static gboolean
138 gst_rtp_gst_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
139 {
140   GstRtpGSTDepay *rtpgstdepay;
141   GstStructure *structure;
142   gint clock_rate;
143   gboolean res;
144   const gchar *capsenc;
145
146   rtpgstdepay = GST_RTP_GST_DEPAY (depayload);
147
148   structure = gst_caps_get_structure (caps, 0);
149
150   if (!gst_structure_get_int (structure, "clock-rate", &clock_rate))
151     clock_rate = 90000;
152   depayload->clock_rate = clock_rate;
153
154   capsenc = gst_structure_get_string (structure, "caps");
155   if (capsenc) {
156     GstCaps *outcaps;
157     gsize out_len;
158     gchar *capsstr;
159     const gchar *capsver;
160     guint CV;
161
162     /* decode caps */
163     capsstr = (gchar *) g_base64_decode (capsenc, &out_len);
164     outcaps = gst_caps_from_string (capsstr);
165     g_free (capsstr);
166
167     /* parse version */
168     capsver = gst_structure_get_string (structure, "capsversion");
169     if (capsver) {
170       CV = atoi (capsver);
171     } else {
172       /* no version, assume 0 */
173       CV = 0;
174     }
175     /* store in cache */
176     rtpgstdepay->current_CV = CV;
177     gst_caps_replace (&rtpgstdepay->current_caps, outcaps);
178
179     res = gst_pad_set_caps (depayload->srcpad, outcaps);
180     gst_caps_unref (outcaps);
181   } else {
182     GST_WARNING_OBJECT (depayload, "no caps given");
183     rtpgstdepay->current_CV = -1;
184     gst_caps_replace (&rtpgstdepay->current_caps, NULL);
185     res = TRUE;
186   }
187
188   return res;
189 }
190
191 static gboolean
192 read_length (GstRtpGSTDepay * rtpgstdepay, guint8 * data, guint size,
193     guint * length, guint * skip)
194 {
195   guint b, len, offset;
196
197   /* start reading the length, we need this to skip to the data later */
198   len = offset = 0;
199   do {
200     if (offset >= size)
201       return FALSE;
202     b = data[offset++];
203     len = (len << 7) | (b & 0x7f);
204   } while (b & 0x80);
205
206   /* check remaining buffer size */
207   if (size - offset < len)
208     return FALSE;
209
210   *length = len;
211   *skip = offset;
212
213   return TRUE;
214 }
215
216 static GstCaps *
217 read_caps (GstRtpGSTDepay * rtpgstdepay, GstBuffer * buf, guint * skip)
218 {
219   guint offset, length;
220   GstCaps *caps;
221   GstMapInfo map;
222
223   gst_buffer_map (buf, &map, GST_MAP_READ);
224
225   GST_DEBUG_OBJECT (rtpgstdepay, "buffer size %" G_GSIZE_FORMAT, map.size);
226
227   if (!read_length (rtpgstdepay, map.data, map.size, &length, &offset))
228     goto too_small;
229
230   if (length == 0 || map.data[offset + length - 1] != '\0')
231     goto invalid_buffer;
232
233   GST_DEBUG_OBJECT (rtpgstdepay, "parsing caps %s", &map.data[offset]);
234
235   /* parse and store in cache */
236   caps = gst_caps_from_string ((gchar *) & map.data[offset]);
237   gst_buffer_unmap (buf, &map);
238
239   *skip = length + offset;
240
241   return caps;
242
243 too_small:
244   {
245     GST_ELEMENT_WARNING (rtpgstdepay, STREAM, DECODE,
246         ("Buffer too small."), (NULL));
247     gst_buffer_unmap (buf, &map);
248     return NULL;
249   }
250 invalid_buffer:
251   {
252     GST_ELEMENT_WARNING (rtpgstdepay, STREAM, DECODE,
253         ("caps string not 0-terminated."), (NULL));
254     gst_buffer_unmap (buf, &map);
255     return NULL;
256   }
257 }
258
259 static GstEvent *
260 read_event (GstRtpGSTDepay * rtpgstdepay, guint type,
261     GstBuffer * buf, guint * skip)
262 {
263   guint offset, length;
264   GstStructure *s;
265   GstEvent *event;
266   GstEventType etype;
267   gchar *end;
268   GstMapInfo map;
269
270   gst_buffer_map (buf, &map, GST_MAP_READ);
271
272   GST_DEBUG_OBJECT (rtpgstdepay, "buffer size %" G_GSIZE_FORMAT, map.size);
273
274   if (!read_length (rtpgstdepay, map.data, map.size, &length, &offset))
275     goto too_small;
276
277   if (length == 0)
278     goto invalid_buffer;
279   /* backward compat, old payloader did not put 0-byte at the end */
280   if (map.data[offset + length - 1] != '\0'
281       && map.data[offset + length - 1] != ';')
282     goto invalid_buffer;
283
284   GST_DEBUG_OBJECT (rtpgstdepay, "parsing event %s", &map.data[offset]);
285
286   /* parse */
287   s = gst_structure_from_string ((gchar *) & map.data[offset], &end);
288   gst_buffer_unmap (buf, &map);
289
290   if (s == NULL)
291     goto parse_failed;
292
293   switch (type) {
294     case 1:
295       etype = GST_EVENT_TAG;
296       break;
297     case 2:
298       etype = GST_EVENT_CUSTOM_DOWNSTREAM;
299       break;
300     case 3:
301       etype = GST_EVENT_CUSTOM_BOTH;
302       break;
303     case 4:
304       etype = GST_EVENT_STREAM_START;
305       break;
306     default:
307       goto unknown_event;
308   }
309   event = gst_event_new_custom (etype, s);
310
311   *skip = length + offset;
312
313   return event;
314
315 too_small:
316   {
317     GST_ELEMENT_WARNING (rtpgstdepay, STREAM, DECODE,
318         ("Buffer too small."), (NULL));
319     gst_buffer_unmap (buf, &map);
320     return NULL;
321   }
322 invalid_buffer:
323   {
324     GST_ELEMENT_WARNING (rtpgstdepay, STREAM, DECODE,
325         ("event string not 0-terminated."), (NULL));
326     gst_buffer_unmap (buf, &map);
327     return NULL;
328   }
329 parse_failed:
330   {
331     GST_WARNING_OBJECT (rtpgstdepay, "could not parse event");
332     return NULL;
333   }
334 unknown_event:
335   {
336     GST_DEBUG_OBJECT (rtpgstdepay, "unknown event type");
337     gst_structure_free (s);
338     return NULL;
339   }
340 }
341
342 static void
343 store_event (GstRtpGSTDepay * rtpgstdepay, GstEvent * event)
344 {
345   gboolean do_push = FALSE;
346
347   switch (GST_EVENT_TYPE (event)) {
348     case GST_EVENT_TAG:
349     {
350       GstTagList *old, *tags;
351
352       gst_event_parse_tag (event, &tags);
353
354       old = rtpgstdepay->tags;
355       if (!old || !gst_tag_list_is_equal (old, tags)) {
356         do_push = TRUE;
357         if (old)
358           gst_tag_list_unref (old);
359         rtpgstdepay->tags = gst_tag_list_ref (tags);
360       }
361       break;
362     }
363     case GST_EVENT_CUSTOM_DOWNSTREAM:
364     case GST_EVENT_CUSTOM_BOTH:
365       /* always push custom events */
366       do_push = TRUE;
367       break;
368     case GST_EVENT_STREAM_START:
369     {
370       gchar *old;
371       const gchar *stream_id = NULL;
372
373       gst_event_parse_stream_start (event, &stream_id);
374
375       old = rtpgstdepay->stream_id;
376       if (!old || g_strcmp0 (old, stream_id)) {
377         do_push = TRUE;
378         g_free (old);
379         rtpgstdepay->stream_id = g_strdup (stream_id);
380       }
381       break;
382     }
383     default:
384       /* unknown event, don't push */
385       break;
386   }
387   if (do_push)
388     gst_pad_push_event (GST_RTP_BASE_DEPAYLOAD (rtpgstdepay)->srcpad, event);
389   else
390     gst_event_unref (event);
391 }
392
393 static GstBuffer *
394 gst_rtp_gst_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
395 {
396   GstRtpGSTDepay *rtpgstdepay;
397   GstBuffer *subbuf, *outbuf = NULL;
398   gint payload_len;
399   guint8 *payload;
400   guint CV, frag_offset, avail, offset;
401
402   rtpgstdepay = GST_RTP_GST_DEPAY (depayload);
403
404   payload_len = gst_rtp_buffer_get_payload_len (rtp);
405
406   if (payload_len <= 8)
407     goto empty_packet;
408
409   if (GST_BUFFER_IS_DISCONT (rtp->buffer)) {
410     GST_WARNING_OBJECT (rtpgstdepay, "DISCONT, clear adapter");
411     gst_adapter_clear (rtpgstdepay->adapter);
412   }
413
414   payload = gst_rtp_buffer_get_payload (rtp);
415
416   /* strip off header
417    *
418    *  0                   1                   2                   3
419    *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
420    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
421    * |C| CV  |D|0|0|0|     ETYPE     |  MBZ                          |
422    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
423    * |                          Frag_offset                          |
424    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
425    */
426   frag_offset =
427       (payload[4] << 24) | (payload[5] << 16) | (payload[6] << 8) | payload[7];
428
429   avail = gst_adapter_available (rtpgstdepay->adapter);
430   if (avail != frag_offset)
431     goto wrong_frag;
432
433   /* subbuffer skipping the 8 header bytes */
434   subbuf = gst_rtp_buffer_get_payload_subbuffer (rtp, 8, -1);
435   gst_adapter_push (rtpgstdepay->adapter, subbuf);
436
437   offset = 0;
438   if (gst_rtp_buffer_get_marker (rtp)) {
439     guint avail;
440     GstCaps *outcaps;
441
442     /* take the buffer */
443     avail = gst_adapter_available (rtpgstdepay->adapter);
444     outbuf = gst_adapter_take_buffer (rtpgstdepay->adapter, avail);
445
446     CV = (payload[0] >> 4) & 0x7;
447
448     if (payload[0] & 0x80) {
449       guint size;
450
451       /* C bit, we have inline caps */
452       outcaps = read_caps (rtpgstdepay, outbuf, &size);
453       if (outcaps == NULL)
454         goto no_caps;
455
456       GST_DEBUG_OBJECT (rtpgstdepay,
457           "inline caps %u, length %u, %" GST_PTR_FORMAT, CV, size, outcaps);
458
459       if (!rtpgstdepay->current_caps
460           || !gst_caps_is_strictly_equal (rtpgstdepay->current_caps, outcaps))
461         gst_pad_set_caps (depayload->srcpad, outcaps);
462       gst_caps_replace (&rtpgstdepay->current_caps, outcaps);
463       gst_caps_unref (outcaps);
464       rtpgstdepay->current_CV = CV;
465
466       /* skip caps */
467       offset += size;
468       avail -= size;
469     }
470     if (payload[1]) {
471       guint size;
472       GstEvent *event;
473
474       /* we have an event */
475       event = read_event (rtpgstdepay, payload[1], outbuf, &size);
476       if (event == NULL)
477         goto no_event;
478
479       GST_DEBUG_OBJECT (rtpgstdepay,
480           "inline event, length %u, %" GST_PTR_FORMAT, size, event);
481
482       store_event (rtpgstdepay, event);
483
484       /* no buffer after event */
485       avail = 0;
486     }
487
488     if (avail) {
489       if (offset != 0) {
490         GstBuffer *temp;
491
492         GST_DEBUG_OBJECT (rtpgstdepay, "sub buffer: offset %u, size %u", offset,
493             avail);
494
495         temp =
496             gst_buffer_copy_region (outbuf, GST_BUFFER_COPY_ALL, offset, avail);
497
498         gst_buffer_unref (outbuf);
499         outbuf = temp;
500       }
501
502       /* see what caps we need */
503       if (CV != rtpgstdepay->current_CV) {
504         /* we need to switch caps but didn't receive the new caps yet */
505         gst_caps_replace (&rtpgstdepay->current_caps, NULL);
506         goto missing_caps;
507       }
508
509       if (payload[0] & 0x8)
510         GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
511     } else {
512       gst_buffer_unref (outbuf);
513       outbuf = NULL;
514     }
515   }
516
517   if (outbuf) {
518     gst_rtp_drop_meta (GST_ELEMENT_CAST (rtpgstdepay), outbuf, 0);
519   }
520
521   return outbuf;
522
523   /* ERRORS */
524 empty_packet:
525   {
526     GST_ELEMENT_WARNING (rtpgstdepay, STREAM, DECODE,
527         ("Empty Payload."), (NULL));
528     return NULL;
529   }
530 wrong_frag:
531   {
532     gst_adapter_clear (rtpgstdepay->adapter);
533     GST_LOG_OBJECT (rtpgstdepay, "wrong fragment, skipping");
534     return NULL;
535   }
536 no_caps:
537   {
538     GST_WARNING_OBJECT (rtpgstdepay, "failed to parse caps");
539     gst_buffer_unref (outbuf);
540     return NULL;
541   }
542 no_event:
543   {
544     GST_WARNING_OBJECT (rtpgstdepay, "failed to parse event");
545     gst_buffer_unref (outbuf);
546     return NULL;
547   }
548 missing_caps:
549   {
550     GST_INFO_OBJECT (rtpgstdepay, "No caps received yet %u", CV);
551     gst_buffer_unref (outbuf);
552
553     gst_pad_push_event (GST_RTP_BASE_DEPAYLOAD_SINKPAD (rtpgstdepay),
554         gst_video_event_new_upstream_force_key_unit (GST_CLOCK_TIME_NONE,
555             TRUE, 0));
556
557     return NULL;
558   }
559 }
560
561 static gboolean
562 gst_rtp_gst_depay_handle_event (GstRTPBaseDepayload * depay, GstEvent * event)
563 {
564   GstRtpGSTDepay *rtpgstdepay;
565
566   rtpgstdepay = GST_RTP_GST_DEPAY (depay);
567
568   switch (GST_EVENT_TYPE (event)) {
569     case GST_EVENT_FLUSH_STOP:
570       gst_rtp_gst_depay_reset (rtpgstdepay, FALSE);
571       break;
572     default:
573       break;
574   }
575
576   return
577       GST_RTP_BASE_DEPAYLOAD_CLASS (parent_class)->handle_event (depay, event);
578 }
579
580
581 static GstStateChangeReturn
582 gst_rtp_gst_depay_change_state (GstElement * element, GstStateChange transition)
583 {
584   GstRtpGSTDepay *rtpgstdepay;
585   GstStateChangeReturn ret;
586
587   rtpgstdepay = GST_RTP_GST_DEPAY (element);
588
589   switch (transition) {
590     case GST_STATE_CHANGE_READY_TO_PAUSED:
591       gst_rtp_gst_depay_reset (rtpgstdepay, TRUE);
592       break;
593     default:
594       break;
595   }
596
597   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
598
599   switch (transition) {
600     case GST_STATE_CHANGE_PAUSED_TO_READY:
601       gst_rtp_gst_depay_reset (rtpgstdepay, TRUE);
602       break;
603     default:
604       break;
605   }
606   return ret;
607 }