rtpvorbisdepay: remove dead code
[platform/upstream/gst-plugins-good.git] / gst / rtp / gstrtph264pay.c
1 /* ex: set tabstop=2 shiftwidth=2 expandtab: */
2 /* GStreamer
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 <gst/rtp/gstrtpbuffer.h>
28 #include <gst/pbutils/pbutils.h>
29 #include <gst/video/video.h>
30
31 /* Included to not duplicate gst_rtp_h264_add_sps_pps () */
32 #include "gstrtph264depay.h"
33
34 #include "gstrtph264pay.h"
35 #include "gstrtputils.h"
36
37
38 #define IDR_TYPE_ID  5
39 #define SPS_TYPE_ID  7
40 #define PPS_TYPE_ID  8
41
42 GST_DEBUG_CATEGORY_STATIC (rtph264pay_debug);
43 #define GST_CAT_DEFAULT (rtph264pay_debug)
44
45 /* references:
46  *
47  * RFC 3984
48  */
49
50 static GstStaticPadTemplate gst_rtp_h264_pay_sink_template =
51     GST_STATIC_PAD_TEMPLATE ("sink",
52     GST_PAD_SINK,
53     GST_PAD_ALWAYS,
54     GST_STATIC_CAPS ("video/x-h264, "
55         "stream-format = (string) avc, alignment = (string) au;"
56         "video/x-h264, "
57         "stream-format = (string) byte-stream, alignment = (string) { nal, au }")
58     );
59
60 static GstStaticPadTemplate gst_rtp_h264_pay_src_template =
61 GST_STATIC_PAD_TEMPLATE ("src",
62     GST_PAD_SRC,
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     );
69
70 #define DEFAULT_SPROP_PARAMETER_SETS    NULL
71 #define DEFAULT_CONFIG_INTERVAL               0
72
73 enum
74 {
75   PROP_0,
76   PROP_SPROP_PARAMETER_SETS,
77   PROP_CONFIG_INTERVAL
78 };
79
80 #define IS_ACCESS_UNIT(x) (((x) > 0x00) && ((x) < 0x06))
81
82 static void gst_rtp_h264_pay_finalize (GObject * object);
83
84 static void gst_rtp_h264_pay_set_property (GObject * object, guint prop_id,
85     const GValue * value, GParamSpec * pspec);
86 static void gst_rtp_h264_pay_get_property (GObject * object, guint prop_id,
87     GValue * value, GParamSpec * pspec);
88
89 static GstCaps *gst_rtp_h264_pay_getcaps (GstRTPBasePayload * payload,
90     GstPad * pad, GstCaps * filter);
91 static gboolean gst_rtp_h264_pay_setcaps (GstRTPBasePayload * basepayload,
92     GstCaps * caps);
93 static GstFlowReturn gst_rtp_h264_pay_handle_buffer (GstRTPBasePayload * pad,
94     GstBuffer * buffer);
95 static gboolean gst_rtp_h264_pay_sink_event (GstRTPBasePayload * payload,
96     GstEvent * event);
97 static GstStateChangeReturn gst_rtp_h264_pay_change_state (GstElement *
98     element, GstStateChange transition);
99
100 #define gst_rtp_h264_pay_parent_class parent_class
101 G_DEFINE_TYPE (GstRtpH264Pay, gst_rtp_h264_pay, GST_TYPE_RTP_BASE_PAYLOAD);
102
103 static void
104 gst_rtp_h264_pay_class_init (GstRtpH264PayClass * klass)
105 {
106   GObjectClass *gobject_class;
107   GstElementClass *gstelement_class;
108   GstRTPBasePayloadClass *gstrtpbasepayload_class;
109
110   gobject_class = (GObjectClass *) klass;
111   gstelement_class = (GstElementClass *) klass;
112   gstrtpbasepayload_class = (GstRTPBasePayloadClass *) klass;
113
114   gobject_class->set_property = gst_rtp_h264_pay_set_property;
115   gobject_class->get_property = gst_rtp_h264_pay_get_property;
116
117   g_object_class_install_property (G_OBJECT_CLASS (klass),
118       PROP_SPROP_PARAMETER_SETS, g_param_spec_string ("sprop-parameter-sets",
119           "sprop-parameter-sets",
120           "The base64 sprop-parameter-sets to set in out caps (set to NULL to "
121           "extract from stream)",
122           DEFAULT_SPROP_PARAMETER_SETS,
123           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
124
125   g_object_class_install_property (G_OBJECT_CLASS (klass),
126       PROP_CONFIG_INTERVAL,
127       g_param_spec_int ("config-interval",
128           "SPS PPS Send Interval",
129           "Send SPS and PPS Insertion Interval in seconds (sprop parameter sets "
130           "will be multiplexed in the data stream when detected.) "
131           "(0 = disabled, -1 = send with every IDR frame)",
132           -1, 3600, DEFAULT_CONFIG_INTERVAL,
133           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
134       );
135
136   gobject_class->finalize = gst_rtp_h264_pay_finalize;
137
138   gst_element_class_add_static_pad_template (gstelement_class,
139       &gst_rtp_h264_pay_src_template);
140   gst_element_class_add_static_pad_template (gstelement_class,
141       &gst_rtp_h264_pay_sink_template);
142
143   gst_element_class_set_static_metadata (gstelement_class, "RTP H264 payloader",
144       "Codec/Payloader/Network/RTP",
145       "Payload-encode H264 video into RTP packets (RFC 3984)",
146       "Laurent Glayal <spglegle@yahoo.fr>");
147
148   gstelement_class->change_state =
149       GST_DEBUG_FUNCPTR (gst_rtp_h264_pay_change_state);
150
151   gstrtpbasepayload_class->get_caps = gst_rtp_h264_pay_getcaps;
152   gstrtpbasepayload_class->set_caps = gst_rtp_h264_pay_setcaps;
153   gstrtpbasepayload_class->handle_buffer = gst_rtp_h264_pay_handle_buffer;
154   gstrtpbasepayload_class->sink_event = gst_rtp_h264_pay_sink_event;
155
156   GST_DEBUG_CATEGORY_INIT (rtph264pay_debug, "rtph264pay", 0,
157       "H264 RTP Payloader");
158 }
159
160 static void
161 gst_rtp_h264_pay_init (GstRtpH264Pay * rtph264pay)
162 {
163   rtph264pay->queue = g_array_new (FALSE, FALSE, sizeof (guint));
164   rtph264pay->profile = 0;
165   rtph264pay->sps = g_ptr_array_new_with_free_func (
166       (GDestroyNotify) gst_buffer_unref);
167   rtph264pay->pps = g_ptr_array_new_with_free_func (
168       (GDestroyNotify) gst_buffer_unref);
169   rtph264pay->last_spspps = -1;
170   rtph264pay->spspps_interval = DEFAULT_CONFIG_INTERVAL;
171   rtph264pay->delta_unit = FALSE;
172   rtph264pay->discont = FALSE;
173
174   rtph264pay->adapter = gst_adapter_new ();
175 }
176
177 static void
178 gst_rtp_h264_pay_clear_sps_pps (GstRtpH264Pay * rtph264pay)
179 {
180   g_ptr_array_set_size (rtph264pay->sps, 0);
181   g_ptr_array_set_size (rtph264pay->pps, 0);
182 }
183
184 static void
185 gst_rtp_h264_pay_finalize (GObject * object)
186 {
187   GstRtpH264Pay *rtph264pay;
188
189   rtph264pay = GST_RTP_H264_PAY (object);
190
191   g_array_free (rtph264pay->queue, TRUE);
192
193   g_ptr_array_free (rtph264pay->sps, TRUE);
194   g_ptr_array_free (rtph264pay->pps, TRUE);
195
196   g_free (rtph264pay->sprop_parameter_sets);
197
198   g_object_unref (rtph264pay->adapter);
199
200   G_OBJECT_CLASS (parent_class)->finalize (object);
201 }
202
203 static const gchar all_levels[][4] = {
204   "1",
205   "1b",
206   "1.1",
207   "1.2",
208   "1.3",
209   "2",
210   "2.1",
211   "2.2",
212   "3",
213   "3.1",
214   "3.2",
215   "4",
216   "4.1",
217   "4.2",
218   "5",
219   "5.1"
220 };
221
222 static GstCaps *
223 gst_rtp_h264_pay_getcaps (GstRTPBasePayload * payload, GstPad * pad,
224     GstCaps * filter)
225 {
226   GstCaps *template_caps;
227   GstCaps *allowed_caps;
228   GstCaps *caps, *icaps;
229   gboolean append_unrestricted;
230   guint i;
231
232   allowed_caps =
233       gst_pad_peer_query_caps (GST_RTP_BASE_PAYLOAD_SRCPAD (payload), NULL);
234
235   if (allowed_caps == NULL)
236     return NULL;
237
238   template_caps =
239       gst_static_pad_template_get_caps (&gst_rtp_h264_pay_sink_template);
240
241   if (gst_caps_is_any (allowed_caps)) {
242     caps = gst_caps_ref (template_caps);
243     goto done;
244   }
245
246   if (gst_caps_is_empty (allowed_caps)) {
247     caps = gst_caps_ref (allowed_caps);
248     goto done;
249   }
250
251   caps = gst_caps_new_empty ();
252
253   append_unrestricted = FALSE;
254   for (i = 0; i < gst_caps_get_size (allowed_caps); i++) {
255     GstStructure *s = gst_caps_get_structure (allowed_caps, i);
256     GstStructure *new_s = gst_structure_new_empty ("video/x-h264");
257     const gchar *profile_level_id;
258
259     profile_level_id = gst_structure_get_string (s, "profile-level-id");
260
261     if (profile_level_id && strlen (profile_level_id) == 6) {
262       const gchar *profile;
263       const gchar *level;
264       long int spsint;
265       guint8 sps[3];
266
267       spsint = strtol (profile_level_id, NULL, 16);
268       sps[0] = spsint >> 16;
269       sps[1] = spsint >> 8;
270       sps[2] = spsint;
271
272       profile = gst_codec_utils_h264_get_profile (sps, 3);
273       level = gst_codec_utils_h264_get_level (sps, 3);
274
275       if (profile && level) {
276         GST_LOG_OBJECT (payload, "In caps, have profile %s and level %s",
277             profile, level);
278
279         if (!strcmp (profile, "constrained-baseline"))
280           gst_structure_set (new_s, "profile", G_TYPE_STRING, profile, NULL);
281         else {
282           GValue val = { 0, };
283           GValue profiles = { 0, };
284
285           g_value_init (&profiles, GST_TYPE_LIST);
286           g_value_init (&val, G_TYPE_STRING);
287
288           g_value_set_static_string (&val, profile);
289           gst_value_list_append_value (&profiles, &val);
290
291           g_value_set_static_string (&val, "constrained-baseline");
292           gst_value_list_append_value (&profiles, &val);
293
294           gst_structure_take_value (new_s, "profile", &profiles);
295         }
296
297         if (!strcmp (level, "1"))
298           gst_structure_set (new_s, "level", G_TYPE_STRING, level, NULL);
299         else {
300           GValue levels = { 0, };
301           GValue val = { 0, };
302           int j;
303
304           g_value_init (&levels, GST_TYPE_LIST);
305           g_value_init (&val, G_TYPE_STRING);
306
307           for (j = 0; j < G_N_ELEMENTS (all_levels); j++) {
308             g_value_set_static_string (&val, all_levels[j]);
309             gst_value_list_prepend_value (&levels, &val);
310             if (!strcmp (level, all_levels[j]))
311               break;
312           }
313           gst_structure_take_value (new_s, "level", &levels);
314         }
315       } else {
316         /* Invalid profile-level-id means baseline */
317
318         gst_structure_set (new_s,
319             "profile", G_TYPE_STRING, "constrained-baseline", NULL);
320       }
321     } else {
322       /* No profile-level-id means baseline or unrestricted */
323
324       gst_structure_set (new_s,
325           "profile", G_TYPE_STRING, "constrained-baseline", NULL);
326       append_unrestricted = TRUE;
327     }
328
329     caps = gst_caps_merge_structure (caps, new_s);
330   }
331
332   if (append_unrestricted) {
333     caps =
334         gst_caps_merge_structure (caps, gst_structure_new ("video/x-h264", NULL,
335             NULL));
336   }
337
338   icaps = gst_caps_intersect (caps, template_caps);
339   gst_caps_unref (caps);
340   caps = icaps;
341
342 done:
343
344   gst_caps_unref (template_caps);
345   gst_caps_unref (allowed_caps);
346
347   GST_LOG_OBJECT (payload, "returning caps %" GST_PTR_FORMAT, caps);
348   return caps;
349 }
350
351 /* take the currently configured SPS and PPS lists and set them on the caps as
352  * sprop-parameter-sets */
353 static gboolean
354 gst_rtp_h264_pay_set_sps_pps (GstRTPBasePayload * basepayload)
355 {
356   GstRtpH264Pay *payloader = GST_RTP_H264_PAY (basepayload);
357   gchar *profile;
358   gchar *set;
359   GString *sprops;
360   guint count;
361   gboolean res;
362   GstMapInfo map;
363   guint i;
364
365   sprops = g_string_new ("");
366   count = 0;
367
368   /* build the sprop-parameter-sets */
369   for (i = 0; i < payloader->sps->len; i++) {
370     GstBuffer *sps_buf =
371         GST_BUFFER_CAST (g_ptr_array_index (payloader->sps, i));
372
373     gst_buffer_map (sps_buf, &map, GST_MAP_READ);
374     set = g_base64_encode (map.data, map.size);
375     gst_buffer_unmap (sps_buf, &map);
376
377     g_string_append_printf (sprops, "%s%s", count ? "," : "", set);
378     g_free (set);
379     count++;
380   }
381   for (i = 0; i < payloader->pps->len; i++) {
382     GstBuffer *pps_buf =
383         GST_BUFFER_CAST (g_ptr_array_index (payloader->pps, i));
384
385     gst_buffer_map (pps_buf, &map, GST_MAP_READ);
386     set = g_base64_encode (map.data, map.size);
387     gst_buffer_unmap (pps_buf, &map);
388
389     g_string_append_printf (sprops, "%s%s", count ? "," : "", set);
390     g_free (set);
391     count++;
392   }
393
394   if (G_LIKELY (count)) {
395     if (payloader->profile != 0) {
396       /* profile is 24 bit. Force it to respect the limit */
397       profile = g_strdup_printf ("%06x", payloader->profile & 0xffffff);
398       /* combine into output caps */
399       res = gst_rtp_base_payload_set_outcaps (basepayload,
400           "packetization-mode", G_TYPE_STRING, "1",
401           "profile-level-id", G_TYPE_STRING, profile,
402           "sprop-parameter-sets", G_TYPE_STRING, sprops->str, NULL);
403       g_free (profile);
404     } else {
405       res = gst_rtp_base_payload_set_outcaps (basepayload,
406           "packetization-mode", G_TYPE_STRING, "1",
407           "sprop-parameter-sets", G_TYPE_STRING, sprops->str, NULL);
408     }
409
410   } else {
411     res = gst_rtp_base_payload_set_outcaps (basepayload, NULL);
412   }
413   g_string_free (sprops, TRUE);
414
415   return res;
416 }
417
418
419 static gboolean
420 gst_rtp_h264_pay_setcaps (GstRTPBasePayload * basepayload, GstCaps * caps)
421 {
422   GstRtpH264Pay *rtph264pay;
423   GstStructure *str;
424   const GValue *value;
425   GstMapInfo map;
426   guint8 *data;
427   gsize size;
428   GstBuffer *buffer;
429   const gchar *alignment, *stream_format;
430
431   rtph264pay = GST_RTP_H264_PAY (basepayload);
432
433   str = gst_caps_get_structure (caps, 0);
434
435   /* we can only set the output caps when we found the sprops and profile
436    * NALs */
437   gst_rtp_base_payload_set_options (basepayload, "video", TRUE, "H264", 90000);
438
439   rtph264pay->alignment = GST_H264_ALIGNMENT_UNKNOWN;
440   alignment = gst_structure_get_string (str, "alignment");
441   if (alignment) {
442     if (g_str_equal (alignment, "au"))
443       rtph264pay->alignment = GST_H264_ALIGNMENT_AU;
444     if (g_str_equal (alignment, "nal"))
445       rtph264pay->alignment = GST_H264_ALIGNMENT_NAL;
446   }
447
448   rtph264pay->stream_format = GST_H264_STREAM_FORMAT_UNKNOWN;
449   stream_format = gst_structure_get_string (str, "stream-format");
450   if (stream_format) {
451     if (g_str_equal (stream_format, "avc"))
452       rtph264pay->stream_format = GST_H264_STREAM_FORMAT_AVC;
453     if (g_str_equal (stream_format, "byte-stream"))
454       rtph264pay->stream_format = GST_H264_STREAM_FORMAT_BYTESTREAM;
455   }
456
457   /* packetized AVC video has a codec_data */
458   if ((value = gst_structure_get_value (str, "codec_data"))) {
459     guint num_sps, num_pps;
460     gint i, nal_size;
461
462     GST_DEBUG_OBJECT (rtph264pay, "have packetized h264");
463
464     buffer = gst_value_get_buffer (value);
465
466     gst_buffer_map (buffer, &map, GST_MAP_READ);
467     data = map.data;
468     size = map.size;
469
470     /* parse the avcC data */
471     if (size < 7)
472       goto avcc_too_small;
473     /* parse the version, this must be 1 */
474     if (data[0] != 1)
475       goto wrong_version;
476
477     /* AVCProfileIndication */
478     /* profile_compat */
479     /* AVCLevelIndication */
480     rtph264pay->profile = (data[1] << 16) | (data[2] << 8) | data[3];
481     GST_DEBUG_OBJECT (rtph264pay, "profile %06x", rtph264pay->profile);
482
483     /* 6 bits reserved | 2 bits lengthSizeMinusOne */
484     /* this is the number of bytes in front of the NAL units to mark their
485      * length */
486     rtph264pay->nal_length_size = (data[4] & 0x03) + 1;
487     GST_DEBUG_OBJECT (rtph264pay, "nal length %u", rtph264pay->nal_length_size);
488     /* 3 bits reserved | 5 bits numOfSequenceParameterSets */
489     num_sps = data[5] & 0x1f;
490     GST_DEBUG_OBJECT (rtph264pay, "num SPS %u", num_sps);
491
492     data += 6;
493     size -= 6;
494
495     /* create the sprop-parameter-sets */
496     for (i = 0; i < num_sps; i++) {
497       GstBuffer *sps_buf;
498
499       if (size < 2)
500         goto avcc_error;
501
502       nal_size = (data[0] << 8) | data[1];
503       data += 2;
504       size -= 2;
505
506       GST_LOG_OBJECT (rtph264pay, "SPS %d size %d", i, nal_size);
507
508       if (size < nal_size)
509         goto avcc_error;
510
511       /* make a buffer out of it and add to SPS list */
512       sps_buf = gst_buffer_new_and_alloc (nal_size);
513       gst_buffer_fill (sps_buf, 0, data, nal_size);
514       gst_rtp_h264_add_sps_pps (GST_ELEMENT (rtph264pay), rtph264pay->sps,
515           rtph264pay->pps, sps_buf);
516       data += nal_size;
517       size -= nal_size;
518     }
519     if (size < 1)
520       goto avcc_error;
521
522     /* 8 bits numOfPictureParameterSets */
523     num_pps = data[0];
524     data += 1;
525     size -= 1;
526
527     GST_DEBUG_OBJECT (rtph264pay, "num PPS %u", num_pps);
528     for (i = 0; i < num_pps; i++) {
529       GstBuffer *pps_buf;
530
531       if (size < 2)
532         goto avcc_error;
533
534       nal_size = (data[0] << 8) | data[1];
535       data += 2;
536       size -= 2;
537
538       GST_LOG_OBJECT (rtph264pay, "PPS %d size %d", i, nal_size);
539
540       if (size < nal_size)
541         goto avcc_error;
542
543       /* make a buffer out of it and add to PPS list */
544       pps_buf = gst_buffer_new_and_alloc (nal_size);
545       gst_buffer_fill (pps_buf, 0, data, nal_size);
546       gst_rtp_h264_add_sps_pps (GST_ELEMENT (rtph264pay), rtph264pay->sps,
547           rtph264pay->pps, pps_buf);
548
549       data += nal_size;
550       size -= nal_size;
551     }
552
553     /* and update the caps with the collected data */
554     if (!gst_rtp_h264_pay_set_sps_pps (basepayload))
555       goto set_sps_pps_failed;
556
557     gst_buffer_unmap (buffer, &map);
558   } else {
559     GST_DEBUG_OBJECT (rtph264pay, "have bytestream h264");
560   }
561
562   return TRUE;
563
564 avcc_too_small:
565   {
566     GST_ERROR_OBJECT (rtph264pay, "avcC size %" G_GSIZE_FORMAT " < 7", size);
567     goto error;
568   }
569 wrong_version:
570   {
571     GST_ERROR_OBJECT (rtph264pay, "wrong avcC version");
572     goto error;
573   }
574 avcc_error:
575   {
576     GST_ERROR_OBJECT (rtph264pay, "avcC too small ");
577     goto error;
578   }
579 set_sps_pps_failed:
580   {
581     GST_ERROR_OBJECT (rtph264pay, "failed to set sps/pps");
582     goto error;
583   }
584 error:
585   {
586     gst_buffer_unmap (buffer, &map);
587     return FALSE;
588   }
589 }
590
591 static void
592 gst_rtp_h264_pay_parse_sprop_parameter_sets (GstRtpH264Pay * rtph264pay)
593 {
594   const gchar *ps;
595   gchar **params;
596   guint len;
597   gint i;
598   GstBuffer *buf;
599
600   ps = rtph264pay->sprop_parameter_sets;
601   if (ps == NULL)
602     return;
603
604   gst_rtp_h264_pay_clear_sps_pps (rtph264pay);
605
606   params = g_strsplit (ps, ",", 0);
607   len = g_strv_length (params);
608
609   GST_DEBUG_OBJECT (rtph264pay, "we have %d params", len);
610
611   for (i = 0; params[i]; i++) {
612     gsize nal_len;
613     GstMapInfo map;
614     guint8 *nalp;
615     guint save = 0;
616     gint state = 0;
617
618     nal_len = strlen (params[i]);
619     buf = gst_buffer_new_and_alloc (nal_len);
620
621     gst_buffer_map (buf, &map, GST_MAP_WRITE);
622     nalp = map.data;
623     nal_len = g_base64_decode_step (params[i], nal_len, nalp, &state, &save);
624     gst_buffer_unmap (buf, &map);
625     gst_buffer_resize (buf, 0, nal_len);
626
627     if (!nal_len) {
628       gst_buffer_unref (buf);
629       continue;
630     }
631
632     gst_rtp_h264_add_sps_pps (GST_ELEMENT (rtph264pay), rtph264pay->sps,
633         rtph264pay->pps, buf);
634   }
635   g_strfreev (params);
636 }
637
638 static guint
639 next_start_code (const guint8 * data, guint size)
640 {
641   /* Boyer-Moore string matching algorithm, in a degenerative
642    * sense because our search 'alphabet' is binary - 0 & 1 only.
643    * This allow us to simplify the general BM algorithm to a very
644    * simple form. */
645   /* assume 1 is in the 3th byte */
646   guint offset = 2;
647
648   while (offset < size) {
649     if (1 == data[offset]) {
650       unsigned int shift = offset;
651
652       if (0 == data[--shift]) {
653         if (0 == data[--shift]) {
654           return shift;
655         }
656       }
657       /* The jump is always 3 because of the 1 previously matched.
658        * All the 0's must be after this '1' matched at offset */
659       offset += 3;
660     } else if (0 == data[offset]) {
661       /* maybe next byte is 1? */
662       offset++;
663     } else {
664       /* can jump 3 bytes forward */
665       offset += 3;
666     }
667     /* at each iteration, we rescan in a backward manner until
668      * we match 0.0.1 in reverse order. Since our search string
669      * has only 2 'alpabets' (i.e. 0 & 1), we know that any
670      * mismatch will force us to shift a fixed number of steps */
671   }
672   GST_DEBUG ("Cannot find next NAL start code. returning %u", size);
673
674   return size;
675 }
676
677 static gboolean
678 gst_rtp_h264_pay_decode_nal (GstRtpH264Pay * payloader,
679     const guint8 * data, guint size, GstClockTime dts, GstClockTime pts)
680 {
681   guint8 header, type;
682   gboolean updated;
683
684   /* default is no update */
685   updated = FALSE;
686
687   GST_DEBUG ("NAL payload len=%u", size);
688
689   header = data[0];
690   type = header & 0x1f;
691
692   /* We record the timestamp of the last SPS/PPS so
693    * that we can insert them at regular intervals and when needed. */
694   if (SPS_TYPE_ID == type || PPS_TYPE_ID == type) {
695     GstBuffer *nal;
696
697     /* encode the entire SPS NAL in base64 */
698     GST_DEBUG ("Found %s %x %x %x Len=%u", type == SPS_TYPE_ID ? "SPS" : "PPS",
699         (header >> 7), (header >> 5) & 3, type, size);
700
701     nal = gst_buffer_new_allocate (NULL, size, NULL);
702     gst_buffer_fill (nal, 0, data, size);
703
704     updated = gst_rtp_h264_add_sps_pps (GST_ELEMENT (payloader),
705         payloader->sps, payloader->pps, nal);
706
707     /* remember when we last saw SPS */
708     if (updated && pts != -1)
709       payloader->last_spspps = pts;
710   } else {
711     GST_DEBUG ("NAL: %x %x %x Len = %u", (header >> 7),
712         (header >> 5) & 3, type, size);
713   }
714
715   return updated;
716 }
717
718 static GstFlowReturn
719 gst_rtp_h264_pay_payload_nal (GstRTPBasePayload * basepayload,
720     GstBuffer * paybuf, GstClockTime dts, GstClockTime pts, gboolean end_of_au,
721     gboolean delta_unit, gboolean discont);
722
723 static GstFlowReturn
724 gst_rtp_h264_pay_send_sps_pps (GstRTPBasePayload * basepayload,
725     GstRtpH264Pay * rtph264pay, GstClockTime dts, GstClockTime pts)
726 {
727   GstFlowReturn ret = GST_FLOW_OK;
728   gboolean sent_all_sps_pps = TRUE;
729   guint i;
730
731   for (i = 0; i < rtph264pay->sps->len; i++) {
732     GstBuffer *sps_buf =
733         GST_BUFFER_CAST (g_ptr_array_index (rtph264pay->sps, i));
734
735     GST_DEBUG_OBJECT (rtph264pay, "inserting SPS in the stream");
736     /* resend SPS */
737     ret = gst_rtp_h264_pay_payload_nal (basepayload, gst_buffer_ref (sps_buf),
738         dts, pts, FALSE, FALSE, FALSE);
739     /* Not critical here; but throw a warning */
740     if (ret != GST_FLOW_OK) {
741       sent_all_sps_pps = FALSE;
742       GST_WARNING_OBJECT (basepayload, "Problem pushing SPS");
743     }
744   }
745   for (i = 0; i < rtph264pay->pps->len; i++) {
746     GstBuffer *pps_buf =
747         GST_BUFFER_CAST (g_ptr_array_index (rtph264pay->pps, i));
748
749     GST_DEBUG_OBJECT (rtph264pay, "inserting PPS in the stream");
750     /* resend PPS */
751     ret = gst_rtp_h264_pay_payload_nal (basepayload, gst_buffer_ref (pps_buf),
752         dts, pts, FALSE, FALSE, FALSE);
753     /* Not critical here; but throw a warning */
754     if (ret != GST_FLOW_OK) {
755       sent_all_sps_pps = FALSE;
756       GST_WARNING_OBJECT (basepayload, "Problem pushing PPS");
757     }
758   }
759
760   if (pts != -1 && sent_all_sps_pps)
761     rtph264pay->last_spspps = pts;
762
763   return ret;
764 }
765
766 /* @delta_unit: if %FALSE the first packet sent won't have the
767  * GST_BUFFER_FLAG_DELTA_UNIT flag.
768  * @discont: if %TRUE the first packet sent will have the
769  * GST_BUFFER_FLAG_DISCONT flag.
770  */
771 static GstFlowReturn
772 gst_rtp_h264_pay_payload_nal (GstRTPBasePayload * basepayload,
773     GstBuffer * paybuf, GstClockTime dts, GstClockTime pts, gboolean end_of_au,
774     gboolean delta_unit, gboolean discont)
775 {
776   GstRtpH264Pay *rtph264pay;
777   GstFlowReturn ret;
778   guint8 nalHeader;
779   guint8 nalType;
780   guint packet_len, payload_len, mtu;
781   GstBuffer *outbuf;
782   guint8 *payload;
783   GstBufferList *list = NULL;
784   gboolean send_spspps;
785   GstRTPBuffer rtp = { NULL };
786   guint size = gst_buffer_get_size (paybuf);
787
788   rtph264pay = GST_RTP_H264_PAY (basepayload);
789   mtu = GST_RTP_BASE_PAYLOAD_MTU (rtph264pay);
790
791   gst_buffer_extract (paybuf, 0, &nalHeader, 1);
792   nalType = nalHeader & 0x1f;
793
794   GST_DEBUG_OBJECT (rtph264pay, "Processing Buffer with NAL TYPE=%d", nalType);
795
796   /* should set src caps before pushing stuff,
797    * and if we did not see enough SPS/PPS, that may not be the case */
798   if (G_UNLIKELY (!gst_pad_has_current_caps (GST_RTP_BASE_PAYLOAD_SRCPAD
799               (basepayload))))
800     gst_rtp_h264_pay_set_sps_pps (basepayload);
801
802   send_spspps = FALSE;
803
804   /* check if we need to emit an SPS/PPS now */
805   if (nalType == IDR_TYPE_ID && rtph264pay->spspps_interval > 0) {
806     if (rtph264pay->last_spspps != -1) {
807       guint64 diff;
808
809       GST_LOG_OBJECT (rtph264pay,
810           "now %" GST_TIME_FORMAT ", last SPS/PPS %" GST_TIME_FORMAT,
811           GST_TIME_ARGS (pts), GST_TIME_ARGS (rtph264pay->last_spspps));
812
813       /* calculate diff between last SPS/PPS in milliseconds */
814       if (pts > rtph264pay->last_spspps)
815         diff = pts - rtph264pay->last_spspps;
816       else
817         diff = 0;
818
819       GST_DEBUG_OBJECT (rtph264pay,
820           "interval since last SPS/PPS %" GST_TIME_FORMAT,
821           GST_TIME_ARGS (diff));
822
823       /* bigger than interval, queue SPS/PPS */
824       if (GST_TIME_AS_SECONDS (diff) >= rtph264pay->spspps_interval) {
825         GST_DEBUG_OBJECT (rtph264pay, "time to send SPS/PPS");
826         send_spspps = TRUE;
827       }
828     } else {
829       /* no know previous SPS/PPS time, send now */
830       GST_DEBUG_OBJECT (rtph264pay, "no previous SPS/PPS time, send now");
831       send_spspps = TRUE;
832     }
833   } else if (nalType == IDR_TYPE_ID && rtph264pay->spspps_interval == -1) {
834     GST_DEBUG_OBJECT (rtph264pay, "sending SPS/PPS before current IDR frame");
835     /* send SPS/PPS before every IDR frame */
836     send_spspps = TRUE;
837   }
838
839   if (send_spspps || rtph264pay->send_spspps) {
840     /* we need to send SPS/PPS now first. FIXME, don't use the pts for
841      * checking when we need to send SPS/PPS but convert to running_time first. */
842     rtph264pay->send_spspps = FALSE;
843     ret = gst_rtp_h264_pay_send_sps_pps (basepayload, rtph264pay, dts, pts);
844     if (ret != GST_FLOW_OK) {
845       gst_buffer_unref (paybuf);
846       return ret;
847     }
848   }
849
850   packet_len = gst_rtp_buffer_calc_packet_len (size, 0, 0);
851
852   if (packet_len < mtu) {
853     /* will fit in one packet */
854     GST_DEBUG_OBJECT (basepayload,
855         "NAL Unit fit in one packet datasize=%d mtu=%d", size, mtu);
856
857     /* create buffer without payload containing only the RTP header
858      * (memory block at index 0) */
859     outbuf = gst_rtp_buffer_new_allocate (0, 0, 0);
860
861     gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp);
862
863     /* only set the marker bit on packets containing access units */
864     if (IS_ACCESS_UNIT (nalType) && end_of_au) {
865       gst_rtp_buffer_set_marker (&rtp, 1);
866     }
867
868     /* timestamp the outbuffer */
869     GST_BUFFER_PTS (outbuf) = pts;
870     GST_BUFFER_DTS (outbuf) = dts;
871
872     if (!delta_unit)
873       /* Only the first packet sent should not have the flag */
874       delta_unit = TRUE;
875     else
876       GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
877
878     if (discont) {
879       GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
880       /* Only the first packet sent should have the flag */
881       discont = FALSE;
882     }
883
884     gst_rtp_buffer_unmap (&rtp);
885
886     /* insert payload memory block */
887     gst_rtp_copy_meta (GST_ELEMENT_CAST (rtph264pay), outbuf, paybuf,
888         g_quark_from_static_string (GST_META_TAG_VIDEO_STR));
889     outbuf = gst_buffer_append (outbuf, paybuf);
890
891     /* push the buffer to the next element */
892     ret = gst_rtp_base_payload_push (basepayload, outbuf);
893   } else {
894     /* fragmentation Units FU-A */
895     guint limitedSize;
896     int ii = 0, start = 1, end = 0, pos = 0;
897
898     GST_DEBUG_OBJECT (basepayload,
899         "NAL Unit DOES NOT fit in one packet datasize=%d mtu=%d", size, mtu);
900
901     pos++;
902     size--;
903
904     ret = GST_FLOW_OK;
905
906     GST_DEBUG_OBJECT (basepayload, "Using FU-A fragmentation for data size=%d",
907         size);
908
909     /* We keep 2 bytes for FU indicator and FU Header */
910     payload_len = gst_rtp_buffer_calc_payload_len (mtu - 2, 0, 0);
911
912     list = gst_buffer_list_new_sized ((size / payload_len) + 1);
913
914     while (end == 0) {
915       limitedSize = size < payload_len ? size : payload_len;
916       GST_DEBUG_OBJECT (basepayload,
917           "Inside  FU-A fragmentation limitedSize=%d iteration=%d", limitedSize,
918           ii);
919
920       /* use buffer lists
921        * create buffer without payload containing only the RTP header
922        * (memory block at index 0) */
923       outbuf = gst_rtp_buffer_new_allocate (2, 0, 0);
924
925       gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp);
926
927       GST_BUFFER_DTS (outbuf) = dts;
928       GST_BUFFER_PTS (outbuf) = pts;
929       payload = gst_rtp_buffer_get_payload (&rtp);
930
931       if (limitedSize == size) {
932         GST_DEBUG_OBJECT (basepayload, "end size=%d iteration=%d", size, ii);
933         end = 1;
934       }
935       if (IS_ACCESS_UNIT (nalType)) {
936         gst_rtp_buffer_set_marker (&rtp, end && end_of_au);
937       }
938
939       /* FU indicator */
940       payload[0] = (nalHeader & 0x60) | 28;
941
942       /* FU Header */
943       payload[1] = (start << 7) | (end << 6) | (nalHeader & 0x1f);
944
945       gst_rtp_buffer_unmap (&rtp);
946
947       /* insert payload memory block */
948       gst_rtp_copy_meta (GST_ELEMENT_CAST (rtph264pay), outbuf, paybuf,
949           g_quark_from_static_string (GST_META_TAG_VIDEO_STR));
950       gst_buffer_copy_into (outbuf, paybuf, GST_BUFFER_COPY_MEMORY, pos,
951           limitedSize);
952
953       if (!delta_unit)
954         /* Only the first packet sent should not have the flag */
955         delta_unit = TRUE;
956       else
957         GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
958
959       if (discont) {
960         GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
961         /* Only the first packet sent should have the flag */
962         discont = FALSE;
963       }
964
965       /* add the buffer to the buffer list */
966       gst_buffer_list_add (list, outbuf);
967
968
969       size -= limitedSize;
970       pos += limitedSize;
971       ii++;
972       start = 0;
973     }
974
975     ret = gst_rtp_base_payload_push_list (basepayload, list);
976     gst_buffer_unref (paybuf);
977   }
978   return ret;
979 }
980
981 static GstFlowReturn
982 gst_rtp_h264_pay_handle_buffer (GstRTPBasePayload * basepayload,
983     GstBuffer * buffer)
984 {
985   GstRtpH264Pay *rtph264pay;
986   GstFlowReturn ret;
987   gsize size;
988   guint nal_len, i;
989   GstMapInfo map;
990   const guint8 *data;
991   GstClockTime dts, pts;
992   GArray *nal_queue;
993   gboolean avc;
994   GstBuffer *paybuf = NULL;
995   gsize skip;
996   gboolean delayed_not_delta_unit = FALSE;
997   gboolean delayed_discont = FALSE;
998
999   rtph264pay = GST_RTP_H264_PAY (basepayload);
1000
1001   /* the input buffer contains one or more NAL units */
1002
1003   avc = rtph264pay->stream_format == GST_H264_STREAM_FORMAT_AVC;
1004
1005   if (avc) {
1006     /* In AVC mode, there is no adapter, so nothign to flush */
1007     if (buffer == NULL)
1008       return GST_FLOW_OK;
1009     gst_buffer_map (buffer, &map, GST_MAP_READ);
1010     data = map.data;
1011     size = map.size;
1012     pts = GST_BUFFER_PTS (buffer);
1013     dts = GST_BUFFER_DTS (buffer);
1014     rtph264pay->delta_unit = GST_BUFFER_FLAG_IS_SET (buffer,
1015         GST_BUFFER_FLAG_DELTA_UNIT);
1016     rtph264pay->discont = GST_BUFFER_IS_DISCONT (buffer);
1017     GST_DEBUG_OBJECT (basepayload, "got %" G_GSIZE_FORMAT " bytes", size);
1018   } else {
1019     dts = gst_adapter_prev_dts (rtph264pay->adapter, NULL);
1020     pts = gst_adapter_prev_pts (rtph264pay->adapter, NULL);
1021     if (buffer) {
1022       if (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT)) {
1023         if (gst_adapter_available (rtph264pay->adapter) == 0)
1024           rtph264pay->delta_unit = FALSE;
1025         else
1026           /* This buffer contains a key frame but the adapter isn't empty. So
1027            * we'll purge it first by sending a first packet and then the second
1028            * one won't have the DELTA_UNIT flag. */
1029           delayed_not_delta_unit = TRUE;
1030       }
1031
1032       if (GST_BUFFER_IS_DISCONT (buffer)) {
1033         if (gst_adapter_available (rtph264pay->adapter) == 0)
1034           rtph264pay->discont = TRUE;
1035         else
1036           /* This buffer has the DISCONT flag but the adapter isn't empty. So
1037            * we'll purge it first by sending a first packet and then the second
1038            * one will have the DISCONT flag set. */
1039           delayed_discont = TRUE;
1040       }
1041
1042       if (!GST_CLOCK_TIME_IS_VALID (dts))
1043         dts = GST_BUFFER_DTS (buffer);
1044       if (!GST_CLOCK_TIME_IS_VALID (pts))
1045         pts = GST_BUFFER_PTS (buffer);
1046
1047       gst_adapter_push (rtph264pay->adapter, buffer);
1048     }
1049     size = gst_adapter_available (rtph264pay->adapter);
1050     /* Nothing to do here if the adapter is empty, e.g. on EOS */
1051     if (size == 0)
1052       return GST_FLOW_OK;
1053     data = gst_adapter_map (rtph264pay->adapter, size);
1054     GST_DEBUG_OBJECT (basepayload,
1055         "got %" G_GSIZE_FORMAT " bytes (%" G_GSIZE_FORMAT ")", size,
1056         buffer ? gst_buffer_get_size (buffer) : 0);
1057   }
1058
1059   ret = GST_FLOW_OK;
1060
1061   /* now loop over all NAL units and put them in a packet
1062    * FIXME, we should really try to pack multiple NAL units into one RTP packet
1063    * if we can, especially for the config packets that wont't cause decoder 
1064    * latency. */
1065   if (avc) {
1066     guint nal_length_size;
1067     gsize offset = 0;
1068
1069     nal_length_size = rtph264pay->nal_length_size;
1070
1071     while (size > nal_length_size) {
1072       gint i;
1073       gboolean end_of_au = FALSE;
1074
1075       nal_len = 0;
1076       for (i = 0; i < nal_length_size; i++) {
1077         nal_len = ((nal_len << 8) + data[i]);
1078       }
1079
1080       /* skip the length bytes, make sure we don't run past the buffer size */
1081       data += nal_length_size;
1082       offset += nal_length_size;
1083       size -= nal_length_size;
1084
1085       if (size >= nal_len) {
1086         GST_DEBUG_OBJECT (basepayload, "got NAL of size %u", nal_len);
1087       } else {
1088         nal_len = size;
1089         GST_DEBUG_OBJECT (basepayload, "got incomplete NAL of size %u",
1090             nal_len);
1091       }
1092
1093       /* If we're at the end of the buffer, then we're at the end of the
1094        * access unit
1095        */
1096       if (rtph264pay->alignment == GST_H264_ALIGNMENT_AU
1097           && size - nal_len <= nal_length_size) {
1098         end_of_au = TRUE;
1099       }
1100
1101       paybuf = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, offset,
1102           nal_len);
1103       ret =
1104           gst_rtp_h264_pay_payload_nal (basepayload, paybuf, dts, pts,
1105           end_of_au, rtph264pay->delta_unit, rtph264pay->discont);
1106
1107       if (!rtph264pay->delta_unit)
1108         /* Only the first outgoing packet doesn't have the DELTA_UNIT flag */
1109         rtph264pay->delta_unit = TRUE;
1110
1111       if (rtph264pay->discont)
1112         /* Only the first outgoing packet have the DISCONT flag */
1113         rtph264pay->discont = FALSE;
1114
1115       if (ret != GST_FLOW_OK)
1116         break;
1117
1118       data += nal_len;
1119       offset += nal_len;
1120       size -= nal_len;
1121     }
1122   } else {
1123     guint next;
1124     gboolean update = FALSE;
1125
1126     /* get offset of first start code */
1127     next = next_start_code (data, size);
1128
1129     /* skip to start code, if no start code is found, next will be size and we
1130      * will not collect data. */
1131     data += next;
1132     size -= next;
1133     nal_queue = rtph264pay->queue;
1134     skip = next;
1135
1136     /* array must be empty when we get here */
1137     g_assert (nal_queue->len == 0);
1138
1139     GST_DEBUG_OBJECT (basepayload,
1140         "found first start at %u, bytes left %" G_GSIZE_FORMAT, next, size);
1141
1142     /* first pass to locate NALs and parse SPS/PPS */
1143     while (size > 4) {
1144       /* skip start code */
1145       data += 3;
1146       size -= 3;
1147
1148       /* use next_start_code() to scan buffer.
1149        * next_start_code() returns the offset in data, 
1150        * starting from zero to the first byte of 0.0.0.1
1151        * If no start code is found, it returns the value of the 
1152        * 'size' parameter. 
1153        * data is unchanged by the call to next_start_code()
1154        */
1155       next = next_start_code (data, size);
1156
1157       /* nal or au aligned input needs no delaying until next time */
1158       if (next == size && buffer != NULL &&
1159           rtph264pay->alignment == GST_H264_ALIGNMENT_UNKNOWN) {
1160         /* Didn't find the start of next NAL and it's not EOS,
1161          * handle it next time */
1162         break;
1163       }
1164
1165       /* nal length is distance to next start code */
1166       nal_len = next;
1167
1168       GST_DEBUG_OBJECT (basepayload, "found next start at %u of size %u", next,
1169           nal_len);
1170
1171       if (rtph264pay->sprop_parameter_sets != NULL) {
1172         /* explicitly set profile and sprop, use those */
1173         if (rtph264pay->update_caps) {
1174           if (!gst_rtp_base_payload_set_outcaps (basepayload,
1175                   "sprop-parameter-sets", G_TYPE_STRING,
1176                   rtph264pay->sprop_parameter_sets, NULL))
1177             goto caps_rejected;
1178
1179           /* parse SPS and PPS from provided parameter set (for insertion) */
1180           gst_rtp_h264_pay_parse_sprop_parameter_sets (rtph264pay);
1181
1182           rtph264pay->update_caps = FALSE;
1183
1184           GST_DEBUG ("outcaps update: sprop-parameter-sets=%s",
1185               rtph264pay->sprop_parameter_sets);
1186         }
1187       } else {
1188         /* We know our stream is a valid H264 NAL packet,
1189          * go parse it for SPS/PPS to enrich the caps */
1190         /* order: make sure to check nal */
1191         update =
1192             gst_rtp_h264_pay_decode_nal (rtph264pay, data, nal_len, dts, pts)
1193             || update;
1194       }
1195       /* move to next NAL packet */
1196       data += nal_len;
1197       size -= nal_len;
1198
1199       g_array_append_val (nal_queue, nal_len);
1200     }
1201
1202     /* if has new SPS & PPS, update the output caps */
1203     if (G_UNLIKELY (update))
1204       if (!gst_rtp_h264_pay_set_sps_pps (basepayload))
1205         goto caps_rejected;
1206
1207     /* second pass to payload and push */
1208
1209     if (nal_queue->len != 0)
1210       gst_adapter_flush (rtph264pay->adapter, skip);
1211
1212     for (i = 0; i < nal_queue->len; i++) {
1213       guint size;
1214       gboolean end_of_au = FALSE;
1215
1216       nal_len = g_array_index (nal_queue, guint, i);
1217       /* skip start code */
1218       gst_adapter_flush (rtph264pay->adapter, 3);
1219
1220       /* Trim the end unless we're the last NAL in the stream.
1221        * In case we're not at the end of the buffer we know the next block
1222        * starts with 0x000001 so all the 0x00 bytes at the end of this one are
1223        * trailing 0x0 that can be discarded */
1224       size = nal_len;
1225       data = gst_adapter_map (rtph264pay->adapter, size);
1226       if (i + 1 != nal_queue->len || buffer != NULL)
1227         for (; size > 1 && data[size - 1] == 0x0; size--)
1228           /* skip */ ;
1229
1230
1231       /* If it's the last nal unit we have in non-bytestream mode, we can
1232        * assume it's the end of an access-unit
1233        *
1234        * FIXME: We need to wait until the next packet or EOS to
1235        * actually payload the NAL so we can know if the current NAL is
1236        * the last one of an access unit or not if we are in bytestream mode
1237        */
1238       if ((rtph264pay->alignment == GST_H264_ALIGNMENT_AU || buffer == NULL) &&
1239           i == nal_queue->len - 1)
1240         end_of_au = TRUE;
1241       paybuf = gst_adapter_take_buffer (rtph264pay->adapter, size);
1242       g_assert (paybuf);
1243
1244       /* put the data in one or more RTP packets */
1245       ret =
1246           gst_rtp_h264_pay_payload_nal (basepayload, paybuf, dts, pts,
1247           end_of_au, rtph264pay->delta_unit, rtph264pay->discont);
1248
1249       if (delayed_not_delta_unit) {
1250         rtph264pay->delta_unit = FALSE;
1251         delayed_not_delta_unit = FALSE;
1252       } else {
1253         /* Only the first outgoing packet doesn't have the DELTA_UNIT flag */
1254         rtph264pay->delta_unit = TRUE;
1255       }
1256
1257       if (delayed_discont) {
1258         rtph264pay->discont = TRUE;
1259         delayed_discont = FALSE;
1260       } else {
1261         /* Only the first outgoing packet have the DISCONT flag */
1262         rtph264pay->discont = FALSE;
1263       }
1264
1265       if (ret != GST_FLOW_OK) {
1266         break;
1267       }
1268
1269       /* move to next NAL packet */
1270       /* Skips the trailing zeros */
1271       gst_adapter_flush (rtph264pay->adapter, nal_len - size);
1272     }
1273     g_array_set_size (nal_queue, 0);
1274   }
1275
1276 done:
1277   if (avc) {
1278     gst_buffer_unmap (buffer, &map);
1279     gst_buffer_unref (buffer);
1280   } else {
1281     gst_adapter_unmap (rtph264pay->adapter);
1282   }
1283
1284   return ret;
1285
1286 caps_rejected:
1287   {
1288     GST_WARNING_OBJECT (basepayload, "Could not set outcaps");
1289     g_array_set_size (nal_queue, 0);
1290     ret = GST_FLOW_NOT_NEGOTIATED;
1291     goto done;
1292   }
1293 }
1294
1295 static gboolean
1296 gst_rtp_h264_pay_sink_event (GstRTPBasePayload * payload, GstEvent * event)
1297 {
1298   gboolean res;
1299   const GstStructure *s;
1300   GstRtpH264Pay *rtph264pay = GST_RTP_H264_PAY (payload);
1301
1302   switch (GST_EVENT_TYPE (event)) {
1303     case GST_EVENT_FLUSH_STOP:
1304       gst_adapter_clear (rtph264pay->adapter);
1305       break;
1306     case GST_EVENT_CUSTOM_DOWNSTREAM:
1307       s = gst_event_get_structure (event);
1308       if (gst_structure_has_name (s, "GstForceKeyUnit")) {
1309         gboolean resend_codec_data;
1310
1311         if (gst_structure_get_boolean (s, "all-headers",
1312                 &resend_codec_data) && resend_codec_data)
1313           rtph264pay->send_spspps = TRUE;
1314       }
1315       break;
1316     case GST_EVENT_EOS:
1317     {
1318       /* call handle_buffer with NULL to flush last NAL from adapter
1319        * in byte-stream mode
1320        */
1321       gst_rtp_h264_pay_handle_buffer (payload, NULL);
1322       break;
1323     }
1324     case GST_EVENT_STREAM_START:
1325       GST_DEBUG_OBJECT (rtph264pay, "New stream detected => Clear SPS and PPS");
1326       gst_rtp_h264_pay_clear_sps_pps (rtph264pay);
1327       break;
1328     default:
1329       break;
1330   }
1331
1332   res = GST_RTP_BASE_PAYLOAD_CLASS (parent_class)->sink_event (payload, event);
1333
1334   return res;
1335 }
1336
1337 static GstStateChangeReturn
1338 gst_rtp_h264_pay_change_state (GstElement * element, GstStateChange transition)
1339 {
1340   GstStateChangeReturn ret;
1341   GstRtpH264Pay *rtph264pay = GST_RTP_H264_PAY (element);
1342
1343   switch (transition) {
1344     case GST_STATE_CHANGE_READY_TO_PAUSED:
1345       rtph264pay->send_spspps = FALSE;
1346       gst_adapter_clear (rtph264pay->adapter);
1347       break;
1348     default:
1349       break;
1350   }
1351
1352   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1353
1354   switch (transition) {
1355     case GST_STATE_CHANGE_PAUSED_TO_READY:
1356       rtph264pay->last_spspps = -1;
1357       gst_rtp_h264_pay_clear_sps_pps (rtph264pay);
1358       break;
1359     default:
1360       break;
1361   }
1362
1363   return ret;
1364 }
1365
1366 static void
1367 gst_rtp_h264_pay_set_property (GObject * object, guint prop_id,
1368     const GValue * value, GParamSpec * pspec)
1369 {
1370   GstRtpH264Pay *rtph264pay;
1371
1372   rtph264pay = GST_RTP_H264_PAY (object);
1373
1374   switch (prop_id) {
1375     case PROP_SPROP_PARAMETER_SETS:
1376       g_free (rtph264pay->sprop_parameter_sets);
1377       rtph264pay->sprop_parameter_sets = g_value_dup_string (value);
1378       rtph264pay->update_caps = TRUE;
1379       break;
1380     case PROP_CONFIG_INTERVAL:
1381       rtph264pay->spspps_interval = g_value_get_int (value);
1382       break;
1383     default:
1384       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1385       break;
1386   }
1387 }
1388
1389 static void
1390 gst_rtp_h264_pay_get_property (GObject * object, guint prop_id,
1391     GValue * value, GParamSpec * pspec)
1392 {
1393   GstRtpH264Pay *rtph264pay;
1394
1395   rtph264pay = GST_RTP_H264_PAY (object);
1396
1397   switch (prop_id) {
1398     case PROP_SPROP_PARAMETER_SETS:
1399       g_value_set_string (value, rtph264pay->sprop_parameter_sets);
1400       break;
1401     case PROP_CONFIG_INTERVAL:
1402       g_value_set_int (value, rtph264pay->spspps_interval);
1403       break;
1404     default:
1405       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1406       break;
1407   }
1408 }
1409
1410 gboolean
1411 gst_rtp_h264_pay_plugin_init (GstPlugin * plugin)
1412 {
1413   return gst_element_register (plugin, "rtph264pay",
1414       GST_RANK_SECONDARY, GST_TYPE_RTP_H264_PAY);
1415 }