build: fprintf, sprintf, sscanf need stdio.h
[platform/upstream/gstreamer.git] / gst / rtp / gstrtph264depay.c
1 /* GStreamer
2  * Copyright (C) <2006> 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., 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 <stdio.h>
25 #include <string.h>
26
27 #include <gst/rtp/gstrtpbuffer.h>
28 #include "gstrtph264depay.h"
29
30 GST_DEBUG_CATEGORY_STATIC (rtph264depay_debug);
31 #define GST_CAT_DEFAULT (rtph264depay_debug)
32
33 #define DEFAULT_BYTE_STREAM     TRUE
34
35 enum
36 {
37   PROP_0,
38   PROP_BYTE_STREAM,
39   PROP_LAST
40 };
41
42
43 /* 3 zero bytes syncword */
44 static const guint8 sync_bytes[] = { 0, 0, 0, 1 };
45
46 /* elementfactory information */
47 static const GstElementDetails gst_rtp_h264depay_details =
48 GST_ELEMENT_DETAILS ("RTP H264 depayloader",
49     "Codec/Depayloader/Network",
50     "Extracts H264 video from RTP packets (RFC 3984)",
51     "Wim Taymans <wim.taymans@gmail.com>");
52
53 static GstStaticPadTemplate gst_rtp_h264_depay_src_template =
54 GST_STATIC_PAD_TEMPLATE ("src",
55     GST_PAD_SRC,
56     GST_PAD_ALWAYS,
57     GST_STATIC_CAPS ("video/x-h264")
58     );
59
60 static GstStaticPadTemplate gst_rtp_h264_depay_sink_template =
61 GST_STATIC_PAD_TEMPLATE ("sink",
62     GST_PAD_SINK,
63     GST_PAD_ALWAYS,
64     GST_STATIC_CAPS ("application/x-rtp, "
65         "media = (string) \"video\", "
66         "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
67         "clock-rate = (int) 90000, " "encoding-name = (string) \"H264\"")
68         /** optional parameters **/
69     /* "profile-level-id = (string) ANY, " */
70     /* "max-mbps = (string) ANY, " */
71     /* "max-fs = (string) ANY, " */
72     /* "max-cpb = (string) ANY, " */
73     /* "max-dpb = (string) ANY, " */
74     /* "max-br = (string) ANY, " */
75     /* "redundant-pic-cap = (string) { \"0\", \"1\" }, " */
76     /* "sprop-parameter-sets = (string) ANY, " */
77     /* "parameter-add = (string) { \"0\", \"1\" }, " */
78     /* "packetization-mode = (string) { \"0\", \"1\", \"2\" }, " */
79     /* "sprop-interleaving-depth = (string) ANY, " */
80     /* "sprop-deint-buf-req = (string) ANY, " */
81     /* "deint-buf-cap = (string) ANY, " */
82     /* "sprop-init-buf-time = (string) ANY, " */
83     /* "sprop-max-don-diff = (string) ANY, " */
84     /* "max-rcmd-nalu-size = (string) ANY " */
85     );
86
87 GST_BOILERPLATE (GstRtpH264Depay, gst_rtp_h264_depay, GstBaseRTPDepayload,
88     GST_TYPE_BASE_RTP_DEPAYLOAD);
89
90 static void gst_rtp_h264_depay_finalize (GObject * object);
91 static void gst_rtp_h264_depay_set_property (GObject * object, guint prop_id,
92     const GValue * value, GParamSpec * pspec);
93 static void gst_rtp_h264_depay_get_property (GObject * object, guint prop_id,
94     GValue * value, GParamSpec * pspec);
95
96 static GstStateChangeReturn gst_rtp_h264_depay_change_state (GstElement *
97     element, GstStateChange transition);
98
99 static GstBuffer *gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload,
100     GstBuffer * buf);
101 static gboolean gst_rtp_h264_depay_setcaps (GstBaseRTPDepayload * filter,
102     GstCaps * caps);
103
104 static void
105 gst_rtp_h264_depay_base_init (gpointer klass)
106 {
107   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
108
109   gst_element_class_add_pad_template (element_class,
110       gst_static_pad_template_get (&gst_rtp_h264_depay_src_template));
111   gst_element_class_add_pad_template (element_class,
112       gst_static_pad_template_get (&gst_rtp_h264_depay_sink_template));
113
114   gst_element_class_set_details (element_class, &gst_rtp_h264depay_details);
115 }
116
117 static void
118 gst_rtp_h264_depay_class_init (GstRtpH264DepayClass * klass)
119 {
120   GObjectClass *gobject_class;
121   GstElementClass *gstelement_class;
122   GstBaseRTPDepayloadClass *gstbasertpdepayload_class;
123
124   gobject_class = (GObjectClass *) klass;
125   gstelement_class = (GstElementClass *) klass;
126   gstbasertpdepayload_class = (GstBaseRTPDepayloadClass *) klass;
127
128   gobject_class->finalize = gst_rtp_h264_depay_finalize;
129
130   gobject_class->set_property = gst_rtp_h264_depay_set_property;
131   gobject_class->get_property = gst_rtp_h264_depay_get_property;
132
133   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BYTE_STREAM,
134       g_param_spec_boolean ("byte-stream", "Byte Stream",
135           "Generate byte stream format of NALU", DEFAULT_BYTE_STREAM,
136           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
137
138   gstelement_class->change_state = gst_rtp_h264_depay_change_state;
139
140   gstbasertpdepayload_class->process = gst_rtp_h264_depay_process;
141   gstbasertpdepayload_class->set_caps = gst_rtp_h264_depay_setcaps;
142
143   GST_DEBUG_CATEGORY_INIT (rtph264depay_debug, "rtph264depay", 0,
144       "H264 Video RTP Depayloader");
145 }
146
147 static void
148 gst_rtp_h264_depay_init (GstRtpH264Depay * rtph264depay,
149     GstRtpH264DepayClass * klass)
150 {
151   rtph264depay->adapter = gst_adapter_new ();
152   rtph264depay->byte_stream = DEFAULT_BYTE_STREAM;
153 }
154
155 static void
156 gst_rtp_h264_depay_finalize (GObject * object)
157 {
158   GstRtpH264Depay *rtph264depay;
159
160   rtph264depay = GST_RTP_H264_DEPAY (object);
161
162   if (rtph264depay->codec_data)
163     gst_buffer_unref (rtph264depay->codec_data);
164
165   g_object_unref (rtph264depay->adapter);
166
167   G_OBJECT_CLASS (parent_class)->finalize (object);
168 }
169
170 static void
171 gst_rtp_h264_depay_set_property (GObject * object, guint prop_id,
172     const GValue * value, GParamSpec * pspec)
173 {
174   GstRtpH264Depay *rtph264depay;
175
176   rtph264depay = GST_RTP_H264_DEPAY (object);
177
178   switch (prop_id) {
179     case PROP_BYTE_STREAM:
180       rtph264depay->byte_stream = g_value_get_boolean (value);
181       break;
182     default:
183       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
184       break;
185   }
186 }
187
188 static void
189 gst_rtp_h264_depay_get_property (GObject * object, guint prop_id,
190     GValue * value, GParamSpec * pspec)
191 {
192   GstRtpH264Depay *rtph264depay;
193
194   rtph264depay = GST_RTP_H264_DEPAY (object);
195
196   switch (prop_id) {
197     case PROP_BYTE_STREAM:
198       g_value_set_boolean (value, rtph264depay->byte_stream);
199       break;
200     default:
201       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
202       break;
203   }
204 }
205
206 static gboolean
207 gst_rtp_h264_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
208 {
209   GstCaps *srccaps;
210   gint clock_rate;
211   GstStructure *structure = gst_caps_get_structure (caps, 0);
212   GstRtpH264Depay *rtph264depay;
213   const gchar *ps, *profile;
214   GstBuffer *codec_data;
215   guint8 *b64;
216   gboolean res;
217
218   rtph264depay = GST_RTP_H264_DEPAY (depayload);
219
220   if (!gst_structure_get_int (structure, "clock-rate", &clock_rate))
221     clock_rate = 90000;
222   depayload->clock_rate = clock_rate;
223
224   srccaps = gst_caps_new_simple ("video/x-h264", NULL);
225
226   /* Base64 encoded, comma separated config NALs */
227   ps = gst_structure_get_string (structure, "sprop-parameter-sets");
228   /* hex: AVCProfileIndication:8 | profile_compat:8 | AVCLevelIndication:8 */
229   profile = gst_structure_get_string (structure, "profile-level-id");
230
231   if (rtph264depay->byte_stream && ps != NULL) {
232     /* for bytestream we only need the parameter sets but we don't error out
233      * when they are not there, we assume they are in the stream. */
234     gchar **params;
235     guint len, total;
236     gint i;
237
238     params = g_strsplit (ps, ",", 0);
239
240     /* count total number of bytes in base64. Also include the sync bytes in
241      * front of the params. */
242     len = 0;
243     for (i = 0; params[i]; i++) {
244       len += strlen (params[i]);
245       len += sizeof (sync_bytes);
246     }
247     /* we seriously overshoot the length, but it's fine. */
248     codec_data = gst_buffer_new_and_alloc (len);
249     b64 = GST_BUFFER_DATA (codec_data);
250     total = 0;
251     for (i = 0; params[i]; i++) {
252       guint save = 0;
253       gint state = 0;
254
255       GST_DEBUG_OBJECT (depayload, "decoding param %d (%s)", i, params[i]);
256       memcpy (b64, sync_bytes, sizeof (sync_bytes));
257       b64 += sizeof (sync_bytes);
258       len =
259           g_base64_decode_step (params[i], strlen (params[i]), b64, &state,
260           &save);
261       GST_DEBUG_OBJECT (depayload, "decoded %d bytes", len);
262       total += len + sizeof (sync_bytes);
263       b64 += len;
264     }
265     GST_BUFFER_SIZE (codec_data) = total;
266     g_strfreev (params);
267
268     /* keep the codec_data, we need to send it as the first buffer. We cannot
269      * push it in the adapter because the adapter might be flushed on discont.
270      */
271     if (rtph264depay->codec_data)
272       gst_buffer_unref (rtph264depay->codec_data);
273     rtph264depay->codec_data = codec_data;
274   } else if (!rtph264depay->byte_stream) {
275     gchar **params;
276     guint8 **sps, **pps;
277     guint len, num_sps, num_pps;
278     gint i;
279     guint8 *data;
280     guint32 profile_id;
281
282     if (ps == NULL || profile == NULL)
283       goto incomplete_caps;
284
285     params = g_strsplit (ps, ",", 0);
286     len = g_strv_length (params);
287
288     GST_DEBUG_OBJECT (depayload, "we have %d params", len);
289
290     sps = g_new0 (guint8 *, len + 1);
291     pps = g_new0 (guint8 *, len + 1);
292     num_sps = num_pps = 0;
293
294     /* start with 7 bytes header */
295     len = 7;
296     for (i = 0; params[i]; i++) {
297       gsize nal_len;
298       guint8 *nalp;
299       guint save = 0;
300       gint state = 0;
301
302       nal_len = strlen (params[i]);
303       nalp = g_malloc (nal_len + 2);
304
305       nal_len =
306           g_base64_decode_step (params[i], nal_len, nalp + 2, &state, &save);
307       nalp[0] = (nal_len >> 8) & 0xff;
308       nalp[1] = nal_len & 0xff;
309       len += nal_len + 2;
310
311       /* copy to the right list */
312       if ((nalp[2] & 0x1f) == 7) {
313         GST_DEBUG_OBJECT (depayload, "adding param %d as SPS %d", i, num_sps);
314         sps[num_sps++] = nalp;
315       } else {
316         GST_DEBUG_OBJECT (depayload, "adding param %d as PPS %d", i, num_pps);
317         pps[num_pps++] = nalp;
318       }
319     }
320     g_strfreev (params);
321
322     codec_data = gst_buffer_new_and_alloc (len);
323     data = GST_BUFFER_DATA (codec_data);
324
325     /* 8 bits version == 1 */
326     *data++ = 1;
327     /* hex: AVCProfileIndication:8 | profile_compat:8 | AVCLevelIndication:8 */
328     sscanf (profile, "%6x", &profile_id);
329     *data++ = (profile_id >> 16) & 0xff;
330     *data++ = (profile_id >> 8) & 0xff;
331     *data++ = profile_id & 0xff;
332     /* 6 bits reserved | 2 bits lengthSizeMinusOn */
333     *data++ = 0xff;
334     /* 3 bits reserved | 5 bits numOfSequenceParameterSets */
335     *data++ = 0xe0 | (num_sps & 0x1f);
336
337     /* copy all SPS */
338     for (i = 0; sps[i]; i++) {
339       len = ((sps[i][0] << 8) | sps[i][1]) + 2;
340       GST_DEBUG_OBJECT (depayload, "copy SPS %d of length %d", i, len);
341       memcpy (data, sps[i], len);
342       g_free (sps[i]);
343       data += len;
344     }
345     g_free (sps);
346     /* 8 bits numOfPictureParameterSets */
347     *data++ = num_pps;
348     /* copy all PPS */
349     for (i = 0; pps[i]; i++) {
350       len = ((pps[i][0] << 8) | pps[i][1]) + 2;
351       GST_DEBUG_OBJECT (depayload, "copy PPS %d of length %d", i, len);
352       memcpy (data, pps[i], len);
353       g_free (pps[i]);
354       data += len;
355     }
356     g_free (pps);
357     GST_BUFFER_SIZE (codec_data) = data - GST_BUFFER_DATA (codec_data);
358
359     gst_caps_set_simple (srccaps,
360         "codec_data", GST_TYPE_BUFFER, codec_data, NULL);
361   }
362
363   res = gst_pad_set_caps (depayload->srcpad, srccaps);
364   gst_caps_unref (srccaps);
365
366   return res;
367
368   /* ERRORS */
369 incomplete_caps:
370   {
371     GST_DEBUG_OBJECT (depayload, "we have incomplete caps");
372     gst_caps_unref (srccaps);
373     return FALSE;
374   }
375 }
376
377 /* FIXME, non-bytestream handling is freaking out ffmpeg. Apparently we need to
378  * group all NAL units belonging to one frame together */
379 static GstBuffer *
380 gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
381 {
382   GstRtpH264Depay *rtph264depay;
383   GstBuffer *outbuf;
384   guint8 nal_unit_type;
385
386   rtph264depay = GST_RTP_H264_DEPAY (depayload);
387
388   /* flush remaining data on discont */
389   if (GST_BUFFER_IS_DISCONT (buf)) {
390     gst_adapter_clear (rtph264depay->adapter);
391     rtph264depay->wait_start = TRUE;
392   }
393
394   {
395     gint payload_len;
396     guint8 *payload;
397     guint header_len;
398     guint8 nal_ref_idc;
399     guint8 *outdata;
400     guint outsize, nalu_size;
401
402     payload_len = gst_rtp_buffer_get_payload_len (buf);
403     payload = gst_rtp_buffer_get_payload (buf);
404
405     GST_DEBUG_OBJECT (rtph264depay, "receiving %d bytes", payload_len);
406
407     /* +---------------+
408      * |0|1|2|3|4|5|6|7|
409      * +-+-+-+-+-+-+-+-+
410      * |F|NRI|  Type   |
411      * +---------------+
412      *
413      * F must be 0.
414      */
415     nal_ref_idc = (payload[0] & 0x60) >> 5;
416     nal_unit_type = payload[0] & 0x1f;
417
418     /* at least one byte header with type */
419     header_len = 1;
420
421     GST_DEBUG_OBJECT (rtph264depay, "NRI %d, Type %d", nal_ref_idc,
422         nal_unit_type);
423
424     switch (nal_unit_type) {
425       case 0:
426       case 30:
427       case 31:
428         /* undefined */
429         goto undefined_type;
430       case 25:
431         /* STAP-B    Single-time aggregation packet     5.7.1 */
432         /* 2 byte extra header for DON */
433         header_len += 2;
434         /* fallthrough */
435       case 24:
436       {
437         /* strip headers */
438         payload += header_len;
439         payload_len -= header_len;
440
441         rtph264depay->wait_start = FALSE;
442
443         /* prepend codec_data */
444         if (rtph264depay->codec_data) {
445           gst_adapter_push (rtph264depay->adapter, rtph264depay->codec_data);
446           rtph264depay->codec_data = NULL;
447         }
448
449         /* STAP-A    Single-time aggregation packet     5.7.1 */
450         while (payload_len > 2) {
451           /*                      1          
452            *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 
453            * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
454            * |         NALU Size             |
455            * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
456            */
457           nalu_size = (payload[0] << 8) | payload[1];
458
459           if (nalu_size > payload_len)
460             nalu_size = payload_len;
461
462           outsize = nalu_size + sizeof (sync_bytes);
463           outbuf = gst_buffer_new_and_alloc (outsize);
464           outdata = GST_BUFFER_DATA (outbuf);
465           if (rtph264depay->byte_stream) {
466             memcpy (outdata, sync_bytes, sizeof (sync_bytes));
467           } else {
468             outdata[0] = outdata[1] = 0;
469             outdata[2] = payload[0];
470             outdata[3] = payload[1];
471           }
472
473           /* strip NALU size */
474           payload += 2;
475           payload_len -= 2;
476
477           outdata += sizeof (sync_bytes);
478           memcpy (outdata, payload, nalu_size);
479
480           gst_adapter_push (rtph264depay->adapter, outbuf);
481
482           payload += nalu_size;
483           payload_len -= nalu_size;
484         }
485
486         outsize = gst_adapter_available (rtph264depay->adapter);
487         outbuf = gst_adapter_take_buffer (rtph264depay->adapter, outsize);
488
489         gst_buffer_set_caps (outbuf, GST_PAD_CAPS (depayload->srcpad));
490
491         return outbuf;
492       }
493       case 26:
494         /* MTAP16    Multi-time aggregation packet      5.7.2 */
495         header_len = 5;
496         /* fallthrough, not implemented */
497       case 27:
498         /* MTAP24    Multi-time aggregation packet      5.7.2 */
499         header_len = 6;
500         goto not_implemented;
501         break;
502       case 28:
503       case 29:
504       {
505         /* FU-A      Fragmentation unit                 5.8 */
506         /* FU-B      Fragmentation unit                 5.8 */
507         gboolean S, E;
508
509         /* +---------------+
510          * |0|1|2|3|4|5|6|7|
511          * +-+-+-+-+-+-+-+-+
512          * |S|E|R|  Type   |
513          * +---------------+
514          *
515          * R is reserved and always 0
516          */
517         S = (payload[1] & 0x80) == 0x80;
518         E = (payload[1] & 0x40) == 0x40;
519
520         GST_DEBUG_OBJECT (rtph264depay, "S %d, E %d", S, E);
521
522         if (rtph264depay->wait_start && !S)
523           goto waiting_start;
524
525         if (S) {
526           /* NAL unit starts here */
527           guint8 nal_header;
528
529           rtph264depay->wait_start = FALSE;
530
531           /* reconstruct NAL header */
532           nal_header = (payload[0] & 0xe0) | (payload[1] & 0x1f);
533
534           /* strip type header, keep FU header, we'll reuse it to reconstruct
535            * the NAL header. */
536           payload += 1;
537           payload_len -= 1;
538
539           nalu_size = payload_len;
540           outsize = nalu_size + sizeof (sync_bytes);
541           outbuf = gst_buffer_new_and_alloc (outsize);
542           outdata = GST_BUFFER_DATA (outbuf);
543           outdata += sizeof (sync_bytes);
544           memcpy (outdata, payload, nalu_size);
545           outdata[0] = nal_header;
546
547           GST_DEBUG_OBJECT (rtph264depay, "queueing %d bytes", outsize);
548
549           /* and assemble in the adapter */
550           gst_adapter_push (rtph264depay->adapter, outbuf);
551         } else {
552           /* strip off FU indicator and FU header bytes */
553           payload += 2;
554           payload_len -= 2;
555
556           outsize = payload_len;
557           outbuf = gst_buffer_new_and_alloc (outsize);
558           outdata = GST_BUFFER_DATA (outbuf);
559           memcpy (outdata, payload, outsize);
560
561           GST_DEBUG_OBJECT (rtph264depay, "queueing %d bytes", outsize);
562
563           /* and assemble in the adapter */
564           gst_adapter_push (rtph264depay->adapter, outbuf);
565         }
566
567         /* if NAL unit ends, flush the adapter */
568         if (E) {
569           GST_DEBUG_OBJECT (rtph264depay, "output %d bytes", outsize);
570
571           outsize = gst_adapter_available (rtph264depay->adapter);
572           outbuf = gst_adapter_take_buffer (rtph264depay->adapter, outsize);
573           outdata = GST_BUFFER_DATA (outbuf);
574
575           if (rtph264depay->byte_stream) {
576             memcpy (outdata, sync_bytes, sizeof (sync_bytes));
577           } else {
578             outsize -= 4;
579             outdata[0] = (outsize >> 24);
580             outdata[1] = (outsize >> 16);
581             outdata[2] = (outsize >> 8);
582             outdata[3] = (outsize);
583           }
584           gst_buffer_set_caps (outbuf, GST_PAD_CAPS (depayload->srcpad));
585
586           /* push codec_data first */
587           if (rtph264depay->codec_data) {
588             gst_buffer_set_caps (rtph264depay->codec_data,
589                 GST_PAD_CAPS (depayload->srcpad));
590             gst_base_rtp_depayload_push (depayload, rtph264depay->codec_data);
591             rtph264depay->codec_data = NULL;
592           }
593           return outbuf;
594         }
595         break;
596       }
597       default:
598       {
599         rtph264depay->wait_start = FALSE;
600
601         /* 1-23   NAL unit  Single NAL unit packet per H.264   5.6 */
602         /* the entire payload is the output buffer */
603         nalu_size = payload_len;
604         outsize = nalu_size + sizeof (sync_bytes);
605         outbuf = gst_buffer_new_and_alloc (outsize);
606         outdata = GST_BUFFER_DATA (outbuf);
607         if (rtph264depay->byte_stream) {
608           memcpy (outdata, sync_bytes, sizeof (sync_bytes));
609         } else {
610           outdata[0] = outdata[1] = 0;
611           outdata[2] = nalu_size >> 8;
612           outdata[3] = nalu_size & 0xff;
613         }
614         outdata += sizeof (sync_bytes);
615         memcpy (outdata, payload, nalu_size);
616
617         gst_buffer_set_caps (outbuf, GST_PAD_CAPS (depayload->srcpad));
618
619         /* push codec_data first */
620         if (rtph264depay->codec_data) {
621           gst_buffer_set_caps (rtph264depay->codec_data,
622               GST_PAD_CAPS (depayload->srcpad));
623           gst_base_rtp_depayload_push (depayload, rtph264depay->codec_data);
624           rtph264depay->codec_data = NULL;
625         }
626         return outbuf;
627       }
628     }
629   }
630
631   return NULL;
632
633   /* ERRORS */
634 undefined_type:
635   {
636     GST_ELEMENT_WARNING (rtph264depay, STREAM, DECODE,
637         (NULL), ("Undefined packet type"));
638     return NULL;
639   }
640 waiting_start:
641   {
642     GST_DEBUG_OBJECT (rtph264depay, "waiting for start");
643     return NULL;
644   }
645 not_implemented:
646   {
647     GST_ELEMENT_ERROR (rtph264depay, STREAM, FORMAT,
648         (NULL), ("NAL unit type %d not supported yet", nal_unit_type));
649     return NULL;
650   }
651 }
652
653 static GstStateChangeReturn
654 gst_rtp_h264_depay_change_state (GstElement * element,
655     GstStateChange transition)
656 {
657   GstRtpH264Depay *rtph264depay;
658   GstStateChangeReturn ret;
659
660   rtph264depay = GST_RTP_H264_DEPAY (element);
661
662   switch (transition) {
663     case GST_STATE_CHANGE_NULL_TO_READY:
664       break;
665     case GST_STATE_CHANGE_READY_TO_PAUSED:
666       gst_adapter_clear (rtph264depay->adapter);
667       rtph264depay->wait_start = TRUE;
668       break;
669     default:
670       break;
671   }
672
673   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
674
675   switch (transition) {
676     case GST_STATE_CHANGE_READY_TO_NULL:
677       break;
678     default:
679       break;
680   }
681   return ret;
682 }
683
684 gboolean
685 gst_rtp_h264_depay_plugin_init (GstPlugin * plugin)
686 {
687   return gst_element_register (plugin, "rtph264depay",
688       GST_RANK_MARGINAL, GST_TYPE_RTP_H264_DEPAY);
689 }