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