rtp: Update codes based on 1.18.4
[platform/upstream/gst-plugins-good.git] / gst / rtp / gstrtph265pay.c
1 /* GStreamer
2  * Copyright (C) <2006> Wim Taymans <wim.taymans@gmail.com>
3  * Copyright (C) <2014> Jurgen Slowack <jurgenslowack@gmail.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #  include "config.h"
23 #endif
24
25 #include <string.h>
26 #include <stdlib.h>
27
28 #include <gst/rtp/gstrtpbuffer.h>
29 #include <gst/pbutils/pbutils.h>
30 #include <gst/video/video.h>
31
32 /* Included to not duplicate gst_rtp_h265_add_vps_sps_pps () */
33 #include "gstrtph265depay.h"
34
35 #include "gstrtph265pay.h"
36 #include "gstrtputils.h"
37 #include "gstbuffermemory.h"
38
39 #define AP_TYPE_ID  48
40 #define FU_TYPE_ID  49
41
42 GST_DEBUG_CATEGORY_STATIC (rtph265pay_debug);
43 #define GST_CAT_DEFAULT (rtph265pay_debug)
44
45 #define GST_TYPE_RTP_H265_AGGREGATE_MODE \
46   (gst_rtp_h265_aggregate_mode_get_type ())
47
48
49 static GType
50 gst_rtp_h265_aggregate_mode_get_type (void)
51 {
52   static GType type = 0;
53   static const GEnumValue values[] = {
54     {GST_RTP_H265_AGGREGATE_NONE, "Do not aggregate NAL units", "none"},
55     {GST_RTP_H265_AGGREGATE_ZERO_LATENCY,
56           "Aggregate NAL units until a VCL or suffix unit is included",
57         "zero-latency"},
58     {GST_RTP_H265_AGGREGATE_MAX,
59         "Aggregate all NAL units with the same timestamp (adds one frame of"
60           " latency)", "max"},
61     {0, NULL, NULL},
62   };
63
64   if (!type) {
65     type = g_enum_register_static ("GstRtpH265AggregateMode", values);
66   }
67   return type;
68 }
69
70
71
72 /* references:
73  *
74  * Internet Draft RTP Payload Format for High Efficiency Video Coding
75  *
76  *                   draft-ietf-payload-rtp-h265-03.txt
77  *
78  * This draft will be replaced with an RFC, so some details may change.
79  *
80  */
81
82 static GstStaticPadTemplate gst_rtp_h265_pay_sink_template =
83     GST_STATIC_PAD_TEMPLATE ("sink",
84     GST_PAD_SINK,
85     GST_PAD_ALWAYS,
86     GST_STATIC_CAPS (
87         /* only hvc1 and byte-stream formats supported for now */
88         "video/x-h265, stream-format = (string) hvc1, alignment = (string) au; "
89         /* "video/x-h265, "
90            "stream-format = (string) hev1, alignment = (string) au; " */
91         "video/x-h265, stream-format = (string) byte-stream, "
92         "alignment = (string) { nal, au }")
93     );
94
95 static GstStaticPadTemplate gst_rtp_h265_pay_src_template =
96 GST_STATIC_PAD_TEMPLATE ("src",
97     GST_PAD_SRC,
98     GST_PAD_ALWAYS,
99     GST_STATIC_CAPS ("application/x-rtp, "
100         "media = (string) \"video\", "
101         "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
102         "clock-rate = (int) 90000, " "encoding-name = (string) \"H265\"")
103     /* optional parameters */
104     /* "profile-space = (int) [ 0, 3 ], " */
105     /* "profile-id = (int) [ 0, 31 ], " */
106     /* "tier-flag = (int) [ 0, 1 ], " */
107     /* "level-id = (int) [ 0, 255 ], " */
108     /* "interop-constraints = (string) ANY, " */
109     /* "profile-compatibility-indicator = (string) ANY, " */
110     /* "sprop-sub-layer-id = (int) [ 0, 6 ], " */
111     /* "recv-sub-layer-id = (int) [ 0, 6 ], " */
112     /* "max-recv-level-id = (int) [ 0, 255 ], " */
113     /* "tx-mode = (string) {MST , SST}, " */
114     /* "sprop-vps = (string) ANY, " */
115     /* "sprop-sps = (string) ANY, " */
116     /* "sprop-pps = (string) ANY, " */
117     /* "sprop-sei = (string) ANY, " */
118     /* "max-lsr = (int) ANY, " *//* MUST be in the range of MaxLumaSR to 16 * MaxLumaSR, inclusive */
119     /* "max-lps = (int) ANY, " *//* MUST be in the range of MaxLumaPS to 16 * MaxLumaPS, inclusive */
120     /* "max-cpb = (int) ANY, " *//* MUST be in the range of MaxCPB to 16 * MaxCPB, inclusive */
121     /* "max-dpb = (int) [1, 16], " */
122     /* "max-br = (int) ANY, " *//* MUST be in the range of MaxBR to 16 * MaxBR, inclusive, for the highest level */
123     /* "max-tr = (int) ANY, " *//* MUST be in the range of MaxTileRows to 16 * MaxTileRows, inclusive, for the highest level */
124     /* "max-tc = (int) ANY, " *//* MUST be in the range of MaxTileCols to 16 * MaxTileCols, inclusive, for the highest level */
125     /* "max-fps = (int) ANY, " */
126     /* "sprop-max-don-diff = (int) [0, 32767], " */
127     /* "sprop-depack-buf-nalus = (int) [0, 32767], " */
128     /* "sprop-depack-buf-nalus = (int) [0, 4294967295], " */
129     /* "depack-buf-cap = (int) [1, 4294967295], " */
130     /* "sprop-segmentation-id = (int) [0, 3], " */
131     /* "sprop-spatial-segmentation-idc = (string) ANY, " */
132     /* "dec-parallel-cap = (string) ANY, " */
133     );
134
135 #define DEFAULT_CONFIG_INTERVAL         0
136 #define DEFAULT_AGGREGATE_MODE          GST_RTP_H265_AGGREGATE_NONE
137
138 enum
139 {
140   PROP_0,
141   PROP_CONFIG_INTERVAL,
142   PROP_AGGREGATE_MODE,
143 };
144
145 static void gst_rtp_h265_pay_finalize (GObject * object);
146
147 static void gst_rtp_h265_pay_set_property (GObject * object, guint prop_id,
148     const GValue * value, GParamSpec * pspec);
149 static void gst_rtp_h265_pay_get_property (GObject * object, guint prop_id,
150     GValue * value, GParamSpec * pspec);
151
152 static GstCaps *gst_rtp_h265_pay_getcaps (GstRTPBasePayload * payload,
153     GstPad * pad, GstCaps * filter);
154 static gboolean gst_rtp_h265_pay_setcaps (GstRTPBasePayload * basepayload,
155     GstCaps * caps);
156 static GstFlowReturn gst_rtp_h265_pay_handle_buffer (GstRTPBasePayload * pad,
157     GstBuffer * buffer);
158 static gboolean gst_rtp_h265_pay_sink_event (GstRTPBasePayload * payload,
159     GstEvent * event);
160 static GstStateChangeReturn gst_rtp_h265_pay_change_state (GstElement *
161     element, GstStateChange transition);
162 static gboolean gst_rtp_h265_pay_src_query (GstPad * pad, GstObject * parent,
163     GstQuery * query);
164
165 static void gst_rtp_h265_pay_reset_bundle (GstRtpH265Pay * rtph265pay);
166
167 #define gst_rtp_h265_pay_parent_class parent_class
168 G_DEFINE_TYPE (GstRtpH265Pay, gst_rtp_h265_pay, GST_TYPE_RTP_BASE_PAYLOAD);
169
170 static void
171 gst_rtp_h265_pay_class_init (GstRtpH265PayClass * klass)
172 {
173   GObjectClass *gobject_class;
174   GstElementClass *gstelement_class;
175   GstRTPBasePayloadClass *gstrtpbasepayload_class;
176
177   gobject_class = (GObjectClass *) klass;
178   gstelement_class = (GstElementClass *) klass;
179   gstrtpbasepayload_class = (GstRTPBasePayloadClass *) klass;
180
181   gobject_class->set_property = gst_rtp_h265_pay_set_property;
182   gobject_class->get_property = gst_rtp_h265_pay_get_property;
183
184   g_object_class_install_property (G_OBJECT_CLASS (klass),
185       PROP_CONFIG_INTERVAL,
186       g_param_spec_int ("config-interval",
187           "VPS SPS PPS Send Interval",
188           "Send VPS, SPS and PPS Insertion Interval in seconds (sprop parameter sets "
189           "will be multiplexed in the data stream when detected.) "
190           "(0 = disabled, -1 = send with every IDR frame)",
191           -1, 3600, DEFAULT_CONFIG_INTERVAL,
192           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
193       );
194
195   /**
196    * GstRtpH265Pay:aggregate-mode
197    *
198    * Bundle suitable SPS/PPS NAL units into STAP-A aggregate packets.
199    *
200    * This can potentially reduce RTP packetization overhead but not all
201    * RTP implementations handle it correctly.
202    *
203    * For best compatibility, it is recommended to set this to "none" (the
204    * default) for RTSP and for WebRTC to "zero-latency".
205    *
206    * Since: 1.18
207    */
208   g_object_class_install_property (G_OBJECT_CLASS (klass),
209       PROP_AGGREGATE_MODE,
210       g_param_spec_enum ("aggregate-mode",
211           "Attempt to use aggregate packets",
212           "Bundle suitable SPS/PPS NAL units into aggregate packets.",
213           GST_TYPE_RTP_H265_AGGREGATE_MODE,
214           DEFAULT_AGGREGATE_MODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
215       );
216
217   gobject_class->finalize = gst_rtp_h265_pay_finalize;
218
219   gst_element_class_add_static_pad_template (gstelement_class,
220       &gst_rtp_h265_pay_src_template);
221   gst_element_class_add_static_pad_template (gstelement_class,
222       &gst_rtp_h265_pay_sink_template);
223
224   gst_element_class_set_static_metadata (gstelement_class, "RTP H265 payloader",
225       "Codec/Payloader/Network/RTP",
226       "Payload-encode H265 video into RTP packets (RFC 7798)",
227       "Jurgen Slowack <jurgenslowack@gmail.com>");
228
229   gstelement_class->change_state =
230       GST_DEBUG_FUNCPTR (gst_rtp_h265_pay_change_state);
231
232   gstrtpbasepayload_class->get_caps = gst_rtp_h265_pay_getcaps;
233   gstrtpbasepayload_class->set_caps = gst_rtp_h265_pay_setcaps;
234   gstrtpbasepayload_class->handle_buffer = gst_rtp_h265_pay_handle_buffer;
235   gstrtpbasepayload_class->sink_event = gst_rtp_h265_pay_sink_event;
236
237   GST_DEBUG_CATEGORY_INIT (rtph265pay_debug, "rtph265pay", 0,
238       "H265 RTP Payloader");
239
240 #ifndef TIZEN_FEATURE_GST_UPSTREAM_AVOID_BUILD_BREAK
241   gst_type_mark_as_plugin_api (GST_TYPE_RTP_H265_AGGREGATE_MODE, 0);
242 #endif
243 }
244
245 static void
246 gst_rtp_h265_pay_init (GstRtpH265Pay * rtph265pay)
247 {
248   rtph265pay->queue = g_array_new (FALSE, FALSE, sizeof (guint));
249   rtph265pay->sps = g_ptr_array_new_with_free_func (
250       (GDestroyNotify) gst_buffer_unref);
251   rtph265pay->pps = g_ptr_array_new_with_free_func (
252       (GDestroyNotify) gst_buffer_unref);
253   rtph265pay->vps = g_ptr_array_new_with_free_func (
254       (GDestroyNotify) gst_buffer_unref);
255   rtph265pay->last_vps_sps_pps = -1;
256   rtph265pay->vps_sps_pps_interval = DEFAULT_CONFIG_INTERVAL;
257   rtph265pay->aggregate_mode = DEFAULT_AGGREGATE_MODE;
258
259   rtph265pay->adapter = gst_adapter_new ();
260
261   gst_pad_set_query_function (GST_RTP_BASE_PAYLOAD_SRCPAD (rtph265pay),
262       gst_rtp_h265_pay_src_query);
263 }
264
265 static void
266 gst_rtp_h265_pay_clear_vps_sps_pps (GstRtpH265Pay * rtph265pay)
267 {
268   g_ptr_array_set_size (rtph265pay->vps, 0);
269   g_ptr_array_set_size (rtph265pay->sps, 0);
270   g_ptr_array_set_size (rtph265pay->pps, 0);
271 }
272
273 static void
274 gst_rtp_h265_pay_finalize (GObject * object)
275 {
276   GstRtpH265Pay *rtph265pay;
277
278   rtph265pay = GST_RTP_H265_PAY (object);
279
280   g_array_free (rtph265pay->queue, TRUE);
281
282   g_ptr_array_free (rtph265pay->sps, TRUE);
283   g_ptr_array_free (rtph265pay->pps, TRUE);
284   g_ptr_array_free (rtph265pay->vps, TRUE);
285
286   g_object_unref (rtph265pay->adapter);
287
288   gst_rtp_h265_pay_reset_bundle (rtph265pay);
289
290   G_OBJECT_CLASS (parent_class)->finalize (object);
291 }
292
293 static gboolean
294 gst_rtp_h265_pay_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
295 {
296   GstRtpH265Pay *rtph265pay = GST_RTP_H265_PAY (parent);
297
298   if (GST_QUERY_TYPE (query) == GST_QUERY_LATENCY) {
299     gboolean retval;
300     gboolean live;
301     GstClockTime min_latency, max_latency;
302
303     retval = gst_pad_query_default (pad, parent, query);
304     if (!retval)
305       return retval;
306
307     if (rtph265pay->stream_format == GST_H265_STREAM_FORMAT_UNKNOWN ||
308         rtph265pay->alignment == GST_H265_ALIGNMENT_UNKNOWN)
309       return FALSE;
310
311     gst_query_parse_latency (query, &live, &min_latency, &max_latency);
312
313     if (rtph265pay->aggregate_mode == GST_RTP_H265_AGGREGATE_MAX &&
314         rtph265pay->alignment != GST_H265_ALIGNMENT_AU && rtph265pay->fps_num) {
315       GstClockTime one_frame = gst_util_uint64_scale_int (GST_SECOND,
316           rtph265pay->fps_denum, rtph265pay->fps_num);
317
318       min_latency += one_frame;
319       max_latency += one_frame;
320       gst_query_set_latency (query, live, min_latency, max_latency);
321     }
322     return TRUE;
323   }
324
325   return gst_pad_query_default (pad, parent, query);
326 }
327
328
329 static const gchar all_levels[][4] = {
330   "1",
331   "2",
332   "2.1",
333   "3",
334   "3.1",
335   "4",
336   "4.1",
337   "5",
338   "5.1",
339   "5.2",
340   "6",
341   "6.1",
342   "6.2"
343 };
344
345 static gboolean
346 parse_field (GstStructure * s, const gchar * field, gulong min, gulong max,
347     guint8 * result)
348 {
349   const gchar *str;
350
351   g_assert (result != NULL);
352
353   str = gst_structure_get_string (s, field);
354   if (str != NULL && *str != '\0') {
355     gulong value;
356     gchar *end;
357
358     value = strtoul (str, &end, 10);
359     if (*end == '\0' && value >= min && value <= max) {
360       *result = (guint8) value;
361     } else {
362       return FALSE;
363     }
364   } else {
365     return FALSE;
366   }
367
368   return TRUE;
369 }
370
371 static GstCaps *
372 gst_rtp_h265_pay_getcaps (GstRTPBasePayload * payload, GstPad * pad,
373     GstCaps * filter)
374 {
375   GstCaps *template_caps;
376   GstCaps *allowed_caps;
377   GstCaps *caps;
378   GstCaps *icaps;
379   guint i;
380
381   allowed_caps =
382       gst_pad_peer_query_caps (GST_RTP_BASE_PAYLOAD_SRCPAD (payload), NULL);
383
384   if (allowed_caps == NULL)
385     return NULL;
386
387   template_caps =
388       gst_static_pad_template_get_caps (&gst_rtp_h265_pay_sink_template);
389
390   if (gst_caps_is_any (allowed_caps)) {
391     caps = gst_caps_ref (template_caps);
392     goto done;
393   }
394
395   if (gst_caps_is_empty (allowed_caps)) {
396     caps = gst_caps_ref (allowed_caps);
397     goto done;
398   }
399
400   caps = gst_caps_new_empty ();
401   for (i = 0; i < gst_caps_get_size (allowed_caps); i++) {
402     GstStructure *s = gst_caps_get_structure (allowed_caps, i);
403     GstStructure *new_s = gst_structure_new_empty ("video/x-h265");
404     guint8 ptl[12] = { 0, };
405     guint8 value;
406
407     if (parse_field (s, "profile-id", 0, 31, &value)) {
408       const gchar *profile;
409
410       ptl[0] = value;
411       profile = gst_codec_utils_h265_get_profile (ptl, sizeof (ptl));
412       if (profile != NULL) {
413         GST_DEBUG_OBJECT (payload, "profile %s", profile);
414         gst_structure_set (new_s, "profile", G_TYPE_STRING, profile, NULL);
415       } else {
416         GST_WARNING_OBJECT (payload, "invalid profile-id %d in caps", value);
417       }
418     } else {
419       GST_DEBUG_OBJECT (payload, "no valid profile-id in caps");
420     }
421
422     if (parse_field (s, "tier-flag", 0, 1, &value)) {
423       const gchar *tier;
424
425       ptl[0] |= value << 5;
426       tier = gst_codec_utils_h265_get_tier (ptl, sizeof (ptl));
427       GST_DEBUG_OBJECT (payload, "tier %s", tier);
428       gst_structure_set (new_s, "tier", G_TYPE_STRING, tier, NULL);
429     } else {
430       GST_DEBUG_OBJECT (payload, "no valid tier-flag in caps");
431     }
432
433     if (parse_field (s, "level-id", 0, 255, &value)) {
434       const gchar *level;
435
436       ptl[11] = value;
437       level = gst_codec_utils_h265_get_level (ptl, sizeof (ptl));
438       if (level != NULL) {
439         GST_DEBUG_OBJECT (payload, "level %s", level);
440         if (strcmp (level, "1") == 0) {
441           gst_structure_set (new_s, "level", G_TYPE_STRING, level, NULL);
442         } else {
443           GValue levels = { 0, };
444           GValue val = { 0, };
445           int j;
446
447           g_value_init (&levels, GST_TYPE_LIST);
448           g_value_init (&val, G_TYPE_STRING);
449
450           for (j = 0; j < G_N_ELEMENTS (all_levels); j++) {
451             g_value_set_static_string (&val, all_levels[j]);
452             gst_value_list_prepend_value (&levels, &val);
453             if (!strcmp (level, all_levels[j]))
454               break;
455           }
456           gst_structure_take_value (new_s, "level", &levels);
457         }
458       } else {
459         GST_WARNING_OBJECT (payload, "invalid level-id %d in caps", value);
460       }
461     } else {
462       GST_DEBUG_OBJECT (payload, "no valid level-id in caps");
463     }
464
465     caps = gst_caps_merge_structure (caps, new_s);
466   }
467
468   icaps = gst_caps_intersect (caps, template_caps);
469   gst_caps_unref (caps);
470   caps = icaps;
471
472 done:
473
474   if (filter) {
475     GstCaps *tmp;
476
477     GST_DEBUG_OBJECT (payload, "Intersect %" GST_PTR_FORMAT " and filter %"
478         GST_PTR_FORMAT, caps, filter);
479     tmp = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
480     gst_caps_unref (caps);
481     caps = tmp;
482   }
483
484   gst_caps_unref (template_caps);
485   gst_caps_unref (allowed_caps);
486
487   GST_LOG_OBJECT (payload, "returning caps %" GST_PTR_FORMAT, caps);
488   return caps;
489 }
490
491 /* take the currently configured VPS, SPS and PPS lists and set them on the
492  * caps */
493 static gboolean
494 gst_rtp_h265_pay_set_vps_sps_pps (GstRTPBasePayload * basepayload)
495 {
496   GstRtpH265Pay *payloader = GST_RTP_H265_PAY (basepayload);
497   gchar *set;
498   GString *vps;
499   GString *sps;
500   GString *pps;
501   guint count;
502   gboolean res;
503   GstMapInfo map;
504   guint i;
505
506   vps = g_string_new ("");
507   sps = g_string_new ("");
508   pps = g_string_new ("");
509   count = 0;
510
511   for (i = 0; i < payloader->vps->len; i++) {
512     GstBuffer *vps_buf =
513         GST_BUFFER_CAST (g_ptr_array_index (payloader->vps, i));
514
515     gst_buffer_map (vps_buf, &map, GST_MAP_READ);
516     set = g_base64_encode (map.data, map.size);
517     gst_buffer_unmap (vps_buf, &map);
518
519     g_string_append_printf (vps, "%s%s", i ? "," : "", set);
520     g_free (set);
521     count++;
522   }
523   for (i = 0; i < payloader->sps->len; i++) {
524     GstBuffer *sps_buf =
525         GST_BUFFER_CAST (g_ptr_array_index (payloader->sps, i));
526
527     gst_buffer_map (sps_buf, &map, GST_MAP_READ);
528     set = g_base64_encode (map.data, map.size);
529     gst_buffer_unmap (sps_buf, &map);
530
531     g_string_append_printf (sps, "%s%s", i ? "," : "", set);
532     g_free (set);
533     count++;
534   }
535   for (i = 0; i < payloader->pps->len; i++) {
536     GstBuffer *pps_buf =
537         GST_BUFFER_CAST (g_ptr_array_index (payloader->pps, i));
538
539     gst_buffer_map (pps_buf, &map, GST_MAP_READ);
540     set = g_base64_encode (map.data, map.size);
541     gst_buffer_unmap (pps_buf, &map);
542
543     g_string_append_printf (pps, "%s%s", i ? "," : "", set);
544     g_free (set);
545     count++;
546   }
547
548   if (G_LIKELY (count)) {
549     /* combine into output caps */
550     res = gst_rtp_base_payload_set_outcaps (basepayload,
551         "sprop-vps", G_TYPE_STRING, vps->str,
552         "sprop-sps", G_TYPE_STRING, sps->str,
553         "sprop-pps", G_TYPE_STRING, pps->str, NULL);
554   } else {
555     res = gst_rtp_base_payload_set_outcaps (basepayload, NULL);
556   }
557   g_string_free (vps, TRUE);
558   g_string_free (sps, TRUE);
559   g_string_free (pps, TRUE);
560
561   return res;
562 }
563
564
565 static gboolean
566 gst_rtp_h265_pay_setcaps (GstRTPBasePayload * basepayload, GstCaps * caps)
567 {
568   GstRtpH265Pay *rtph265pay;
569   GstStructure *str;
570   const GValue *value;
571   GstMapInfo map;
572   guint8 *data;
573   gsize size;
574   GstBuffer *buffer;
575   const gchar *alignment, *stream_format;
576   guint8 num_arrays;
577
578   rtph265pay = GST_RTP_H265_PAY (basepayload);
579
580   str = gst_caps_get_structure (caps, 0);
581
582   /* we can only set the output caps when we found the sprops and profile
583    * NALs */
584   gst_rtp_base_payload_set_options (basepayload, "video", TRUE, "H265", 90000);
585
586   rtph265pay->alignment = GST_H265_ALIGNMENT_UNKNOWN;
587   alignment = gst_structure_get_string (str, "alignment");
588   if (alignment) {
589     if (g_str_equal (alignment, "au"))
590       rtph265pay->alignment = GST_H265_ALIGNMENT_AU;
591     if (g_str_equal (alignment, "nal"))
592       rtph265pay->alignment = GST_H265_ALIGNMENT_NAL;
593   }
594
595   rtph265pay->stream_format = GST_H265_STREAM_FORMAT_UNKNOWN;
596   stream_format = gst_structure_get_string (str, "stream-format");
597   if (stream_format) {
598     if (g_str_equal (stream_format, "hvc1"))
599       rtph265pay->stream_format = GST_H265_STREAM_FORMAT_HVC1;
600     if (g_str_equal (stream_format, "hev1"))
601       rtph265pay->stream_format = GST_H265_STREAM_FORMAT_HEV1;
602     if (g_str_equal (stream_format, "byte-stream"))
603       rtph265pay->stream_format = GST_H265_STREAM_FORMAT_BYTESTREAM;
604   }
605
606   if (!gst_structure_get_fraction (str, "framerate", &rtph265pay->fps_num,
607           &rtph265pay->fps_denum))
608     rtph265pay->fps_num = rtph265pay->fps_denum = 0;
609
610
611   /* packetized HEVC video has a codec_data */
612   if ((value = gst_structure_get_value (str, "codec_data"))) {
613     guint num_vps, num_sps, num_pps;
614     gint i, j, nal_size;
615
616     GST_DEBUG_OBJECT (rtph265pay, "have packetized h265");
617
618     buffer = gst_value_get_buffer (value);
619
620     gst_buffer_map (buffer, &map, GST_MAP_READ);
621     data = map.data;
622     size = map.size;
623
624     /* parse the hevcC data */
625     if (size < 23)
626       goto hevcc_too_small;
627     /* HEVCDecoderConfigurationVersion (must be 1) */
628     if (data[0] != 1)
629       goto wrong_version;
630
631     /* profile_space | tier_flag | profile_idc */
632     GST_DEBUG_OBJECT (rtph265pay, "profile %06x", data[1]);
633
634     /* profile_compatibility_flags */
635     for (i = 2; i < 6; i++) {
636       for (j = 7; j >= 0; j--) {
637         GST_DEBUG_OBJECT (rtph265pay, "profile_compatibility_flag %06x",
638             (data[i] >> j) & 1);
639       }
640     }
641
642     GST_DEBUG_OBJECT (rtph265pay, "progressive_source_flag %06x",
643         (data[6] >> 7) & 1);
644     GST_DEBUG_OBJECT (rtph265pay, "interlaced_source_flag %06x",
645         (data[6] >> 6) & 1);
646     GST_DEBUG_OBJECT (rtph265pay, "non_packed_constraint_flag %06x",
647         (data[6] >> 5) & 1);
648     GST_DEBUG_OBJECT (rtph265pay, "frame_only_constraint_flag %06x",
649         (data[6] >> 4) & 1);
650
651     GST_DEBUG_OBJECT (rtph265pay, "level_idc %06x", data[12]);
652
653     GST_DEBUG_OBJECT (rtph265pay, "min_spatial_segmentation_idc %06x",
654         ((data[13] ^ 0xf0) << 8) + data[14]);
655     GST_DEBUG_OBJECT (rtph265pay, "parrallelismType %06x (ignored by paloader)",
656         data[15]);
657
658     GST_DEBUG_OBJECT (rtph265pay, "sps_chroma_format_idc %06x",
659         data[16] ^ 0xfc);
660     GST_DEBUG_OBJECT (rtph265pay, "bit_depth_luma_minus8 %06x",
661         data[17] ^ 0xf8);
662     GST_DEBUG_OBJECT (rtph265pay, "bit_depth_chroma_minus8 %06x",
663         data[18] ^ 0xf8);
664     GST_DEBUG_OBJECT (rtph265pay, "avgFrameRate %06x", data[19]);
665     GST_DEBUG_OBJECT (rtph265pay, "avgFrameRate %06x", data[20]);
666
667     /* constFrameRate(2 bits): 0, stream may or may not be of constant framerate
668      * numTemporalLayers (3 bits): number of temporal layers, value from SPS
669      * TemporalIdNested (1 bit): sps_temporal_id_nesting_flag from SPS
670      * lengthSizeMinusOne (2 bits): plus 1 indicates the length of the NALUnitLength */
671     GST_DEBUG_OBJECT (rtph265pay, "constFrameRate %06x",
672         (data[21] >> 6) & 0x03);
673     GST_DEBUG_OBJECT (rtph265pay, "numTemporalLayers %06x",
674         (data[21] >> 3) & 0x07);
675     GST_DEBUG_OBJECT (rtph265pay, "temporal_id_nesting_flag %06x",
676         (data[21] >> 2) & 0x01);
677
678     rtph265pay->nal_length_size = (data[21] & 0x3) + 1;
679     GST_DEBUG_OBJECT (rtph265pay, "nal length %u", rtph265pay->nal_length_size);
680
681     num_arrays = GST_READ_UINT8 (data + 22);
682
683     data += 23;
684     size -= 23;
685
686     if (num_arrays > 0) {
687       if ((data[0] & 0x3f) == 0x20) {   /* VPS */
688
689         data++;
690         num_vps = data[0] << 8 | data[1];
691         data += 2;
692         size -= 2;
693
694         for (i = 0; i < num_vps; i++) {
695
696           GstBuffer *vps_buf;
697
698           if (size < 2)
699             goto hevcc_error;
700
701           nal_size = (data[0] << 8) | data[1];
702           data += 2;
703           size -= 2;
704
705           GST_LOG_OBJECT (rtph265pay, "VPS %d size %d", i, nal_size);
706
707           if (size < nal_size)
708             goto hevcc_error;
709
710           /* make a buffer out of it and add to VPS list */
711           vps_buf = gst_buffer_new_and_alloc (nal_size);
712           gst_buffer_fill (vps_buf, 0, data, nal_size);
713           gst_rtp_h265_add_vps_sps_pps (GST_ELEMENT (rtph265pay),
714               rtph265pay->vps, rtph265pay->sps, rtph265pay->pps, vps_buf);
715           data += nal_size;
716           size -= nal_size;
717         }
718       }
719
720       --num_arrays;
721     }
722
723     if (num_arrays > 0) {
724       if ((data[0] & 0x3f) == 0x21) {   /* SPS */
725
726         data++;
727         num_sps = data[0] << 8 | data[1];
728         data += 2;
729         size -= 2;
730
731         for (i = 0; i < num_sps; i++) {
732
733           GstBuffer *sps_buf;
734
735           if (size < 2)
736             goto hevcc_error;
737
738           nal_size = (data[0] << 8) | data[1];
739           data += 2;
740           size -= 2;
741
742           GST_LOG_OBJECT (rtph265pay, "SPS %d size %d", i, nal_size);
743
744           if (size < nal_size)
745             goto hevcc_error;
746
747           /* make a buffer out of it and add to SPS list */
748           sps_buf = gst_buffer_new_and_alloc (nal_size);
749           gst_buffer_fill (sps_buf, 0, data, nal_size);
750           gst_rtp_h265_add_vps_sps_pps (GST_ELEMENT (rtph265pay),
751               rtph265pay->vps, rtph265pay->sps, rtph265pay->pps, sps_buf);
752           data += nal_size;
753           size -= nal_size;
754         }
755       }
756
757       --num_arrays;
758     }
759
760     if (num_arrays > 0) {
761       if ((data[0] & 0x3f) == 0x22) {   /* PPS */
762
763         data++;
764         num_pps = data[0] << 8 | data[1];
765         data += 2;
766         size -= 2;
767
768         for (i = 0; i < num_pps; i++) {
769
770           GstBuffer *pps_buf;
771
772           if (size < 2)
773             goto hevcc_error;
774
775           nal_size = (data[0] << 8) | data[1];
776           data += 2;
777           size -= 2;
778
779           GST_LOG_OBJECT (rtph265pay, "PPS %d size %d", i, nal_size);
780
781           if (size < nal_size)
782             goto hevcc_error;
783
784           /* make a buffer out of it and add to PPS list */
785           pps_buf = gst_buffer_new_and_alloc (nal_size);
786           gst_buffer_fill (pps_buf, 0, data, nal_size);
787           gst_rtp_h265_add_vps_sps_pps (GST_ELEMENT (rtph265pay),
788               rtph265pay->vps, rtph265pay->sps, rtph265pay->pps, pps_buf);
789           data += nal_size;
790           size -= nal_size;
791         }
792       }
793
794       --num_arrays;
795     }
796
797     /* and update the caps with the collected data */
798     if (!gst_rtp_h265_pay_set_vps_sps_pps (basepayload))
799       goto set_vps_sps_pps_failed;
800
801     GST_DEBUG_OBJECT (rtph265pay, "Caps have been set");
802
803     gst_buffer_unmap (buffer, &map);
804   } else {
805     GST_DEBUG_OBJECT (rtph265pay, "have bytestream h265");
806   }
807
808   return TRUE;
809
810 hevcc_too_small:
811   {
812     GST_ERROR_OBJECT (rtph265pay, "hevcC size %" G_GSIZE_FORMAT " < 7", size);
813     goto error;
814   }
815 wrong_version:
816   {
817     GST_ERROR_OBJECT (rtph265pay, "wrong hevcC version");
818     goto error;
819   }
820 hevcc_error:
821   {
822     GST_ERROR_OBJECT (rtph265pay, "hevcC too small ");
823     goto error;
824   }
825 set_vps_sps_pps_failed:
826   {
827     GST_ERROR_OBJECT (rtph265pay, "failed to set vps/sps/pps");
828     goto error;
829   }
830 error:
831   {
832     gst_buffer_unmap (buffer, &map);
833     return FALSE;
834   }
835 }
836
837 static guint
838 next_start_code (const guint8 * data, guint size)
839 {
840   /* Boyer-Moore string matching algorithm, in a degenerative
841    * sense because our search 'alphabet' is binary - 0 & 1 only.
842    * This allow us to simplify the general BM algorithm to a very
843    * simple form. */
844   /* assume 1 is in the 3rd byte */
845   guint offset = 2;
846
847   while (offset < size) {
848     if (1 == data[offset]) {
849       unsigned int shift = offset;
850
851       if (0 == data[--shift]) {
852         if (0 == data[--shift]) {
853           return shift;
854         }
855       }
856       /* The jump is always 3 because of the 1 previously matched.
857        * All the 0's must be after this '1' matched at offset */
858       offset += 3;
859     } else if (0 == data[offset]) {
860       /* maybe next byte is 1? */
861       offset++;
862     } else {
863       /* can jump 3 bytes forward */
864       offset += 3;
865     }
866     /* at each iteration, we rescan in a backward manner until
867      * we match 0.0.1 in reverse order. Since our search string
868      * has only 2 'alpabets' (i.e. 0 & 1), we know that any
869      * mismatch will force us to shift a fixed number of steps */
870   }
871   GST_DEBUG ("Cannot find next NAL start code. returning %u", size);
872
873   return size;
874 }
875
876 static gboolean
877 gst_rtp_h265_pay_decode_nal (GstRtpH265Pay * payloader,
878     const guint8 * data, guint size, GstClockTime dts, GstClockTime pts)
879 {
880   guint8 type;
881   gboolean updated;
882
883   /* default is no update */
884   updated = FALSE;
885
886   GST_DEBUG_OBJECT (payloader, "NAL payload size %u", size);
887
888   type = (data[0] >> 1) & 0x3f;
889
890   /* We record the timestamp of the last SPS/PPS so
891    * that we can insert them at regular intervals and when needed. */
892   if (GST_H265_NAL_VPS == type || GST_H265_NAL_SPS == type
893       || GST_H265_NAL_PPS == type) {
894     GstBuffer *nal;
895
896     /* trailing 0x0 are not part of the VPS/SPS/PPS */
897     while (size > 0 && data[size - 1] == 0x0)
898       size--;
899
900     /* encode the entire NAL in base64 */
901     GST_DEBUG_OBJECT (payloader, "found %s (type 0x%x), size %u",
902         type == GST_H265_NAL_VPS ? "VPS" : type == GST_H265_NAL_SPS ?
903         "SPS" : "PPS", type, size);
904
905     nal = gst_buffer_new_allocate (NULL, size, NULL);
906     gst_buffer_fill (nal, 0, data, size);
907
908     updated = gst_rtp_h265_add_vps_sps_pps (GST_ELEMENT (payloader),
909         payloader->vps, payloader->sps, payloader->pps, nal);
910
911     /* remember when we last saw VPS */
912     if (pts != -1)
913       payloader->last_vps_sps_pps =
914           gst_segment_to_running_time (&GST_RTP_BASE_PAYLOAD_CAST
915           (payloader)->segment, GST_FORMAT_TIME, pts);
916   } else {
917     GST_DEBUG_OBJECT (payloader, "NALU type 0x%x, size %u", type, size);
918   }
919
920   return updated;
921 }
922
923 static GstFlowReturn gst_rtp_h265_pay_payload_nal (GstRTPBasePayload *
924     basepayload, GPtrArray * paybufs, GstClockTime dts, GstClockTime pts);
925 static GstFlowReturn gst_rtp_h265_pay_payload_nal_single (GstRTPBasePayload *
926     basepayload, GstBuffer * paybuf, GstClockTime dts, GstClockTime pts,
927     gboolean marker);
928 static GstFlowReturn gst_rtp_h265_pay_payload_nal_fragment (GstRTPBasePayload *
929     basepayload, GstBuffer * paybuf, GstClockTime dts, GstClockTime pts,
930     gboolean marker, guint mtu, guint8 nal_type, const guint8 * nal_header,
931     int size);
932 static GstFlowReturn gst_rtp_h265_pay_payload_nal_bundle (GstRTPBasePayload *
933     basepayload, GstBuffer * paybuf, GstClockTime dts, GstClockTime pts,
934     gboolean marker, guint8 nal_type, const guint8 * nal_header, int size);
935
936 static GstFlowReturn
937 gst_rtp_h265_pay_send_vps_sps_pps (GstRTPBasePayload * basepayload,
938     GstRtpH265Pay * rtph265pay, GstClockTime dts, GstClockTime pts)
939 {
940   GstFlowReturn ret = GST_FLOW_OK;
941   gboolean sent_all_vps_sps_pps = TRUE;
942   guint i;
943   GPtrArray *bufs;
944
945   bufs = g_ptr_array_new ();
946
947   for (i = 0; i < rtph265pay->vps->len; i++) {
948     GstBuffer *vps_buf =
949         GST_BUFFER_CAST (g_ptr_array_index (rtph265pay->vps, i));
950
951     GST_DEBUG_OBJECT (rtph265pay, "inserting VPS in the stream");
952     g_ptr_array_add (bufs, gst_buffer_ref (vps_buf));
953   }
954   for (i = 0; i < rtph265pay->sps->len; i++) {
955     GstBuffer *sps_buf =
956         GST_BUFFER_CAST (g_ptr_array_index (rtph265pay->sps, i));
957
958     GST_DEBUG_OBJECT (rtph265pay, "inserting SPS in the stream");
959     g_ptr_array_add (bufs, gst_buffer_ref (sps_buf));
960   }
961   for (i = 0; i < rtph265pay->pps->len; i++) {
962     GstBuffer *pps_buf =
963         GST_BUFFER_CAST (g_ptr_array_index (rtph265pay->pps, i));
964
965     GST_DEBUG_OBJECT (rtph265pay, "inserting PPS in the stream");
966     g_ptr_array_add (bufs, gst_buffer_ref (pps_buf));
967   }
968
969   ret = gst_rtp_h265_pay_payload_nal (basepayload, bufs, dts, pts);
970   if (ret != GST_FLOW_OK) {
971     /* not critical but warn */
972     GST_WARNING_OBJECT (basepayload, "failed pushing VPS/SPS/PPS");
973
974     sent_all_vps_sps_pps = FALSE;
975   }
976
977   if (pts != -1 && sent_all_vps_sps_pps)
978     rtph265pay->last_vps_sps_pps =
979         gst_segment_to_running_time (&basepayload->segment, GST_FORMAT_TIME,
980         pts);
981
982   return ret;
983 }
984
985 static void
986 gst_rtp_h265_pay_reset_bundle (GstRtpH265Pay * rtph265pay)
987 {
988   g_clear_pointer (&rtph265pay->bundle, gst_buffer_list_unref);
989   rtph265pay->bundle_size = 0;
990   rtph265pay->bundle_contains_vcl_or_suffix = FALSE;
991 }
992
993 static GstFlowReturn
994 gst_rtp_h265_pay_payload_nal (GstRTPBasePayload * basepayload,
995     GPtrArray * paybufs, GstClockTime dts, GstClockTime pts)
996 {
997   GstRtpH265Pay *rtph265pay;
998   guint mtu;
999   GstFlowReturn ret;
1000   gint i;
1001   gboolean sent_ps;
1002
1003   rtph265pay = GST_RTP_H265_PAY (basepayload);
1004   mtu = GST_RTP_BASE_PAYLOAD_MTU (rtph265pay);
1005
1006   /* should set src caps before pushing stuff,
1007    * and if we did not see enough VPS/SPS/PPS, that may not be the case */
1008   if (G_UNLIKELY (!gst_pad_has_current_caps (GST_RTP_BASE_PAYLOAD_SRCPAD
1009               (basepayload))))
1010     gst_rtp_h265_pay_set_vps_sps_pps (basepayload);
1011
1012   ret = GST_FLOW_OK;
1013   sent_ps = FALSE;
1014   for (i = 0; i < paybufs->len; i++) {
1015     guint8 nal_header[2];
1016     guint8 nal_type;
1017     GstBuffer *paybuf;
1018     gboolean send_ps;
1019     guint size;
1020     gboolean marker;
1021
1022     paybuf = g_ptr_array_index (paybufs, i);
1023
1024     if (ret != GST_FLOW_OK) {
1025       /* unref buffers that will not be payloaded after a flow error */
1026       gst_buffer_unref (paybuf);
1027       continue;
1028     }
1029
1030     marker = GST_BUFFER_FLAG_IS_SET (paybuf, GST_BUFFER_FLAG_MARKER);
1031
1032     size = gst_buffer_get_size (paybuf);
1033     gst_buffer_extract (paybuf, 0, nal_header, 2);
1034     nal_type = (nal_header[0] >> 1) & 0x3f;
1035
1036     GST_DEBUG_OBJECT (rtph265pay, "payloading NAL Unit: datasize=%u type=%d"
1037         " pts=%" GST_TIME_FORMAT, size, nal_type, GST_TIME_ARGS (pts));
1038
1039     send_ps = FALSE;
1040
1041     /* check if we need to emit an VPS/SPS/PPS now */
1042     if ((nal_type == GST_H265_NAL_SLICE_TRAIL_N)
1043         || (nal_type == GST_H265_NAL_SLICE_TRAIL_R)
1044         || (nal_type == GST_H265_NAL_SLICE_TSA_N)
1045         || (nal_type == GST_H265_NAL_SLICE_TSA_R)
1046         || (nal_type == GST_H265_NAL_SLICE_STSA_N)
1047         || (nal_type == GST_H265_NAL_SLICE_STSA_R)
1048         || (nal_type == GST_H265_NAL_SLICE_RASL_N)
1049         || (nal_type == GST_H265_NAL_SLICE_RASL_R)
1050         || (nal_type == GST_H265_NAL_SLICE_BLA_W_LP)
1051         || (nal_type == GST_H265_NAL_SLICE_BLA_W_RADL)
1052         || (nal_type == GST_H265_NAL_SLICE_BLA_N_LP)
1053         || (nal_type == GST_H265_NAL_SLICE_IDR_W_RADL)
1054         || (nal_type == GST_H265_NAL_SLICE_IDR_N_LP)
1055         || (nal_type == GST_H265_NAL_SLICE_CRA_NUT)) {
1056       if (rtph265pay->vps_sps_pps_interval > 0) {
1057         if (rtph265pay->last_vps_sps_pps != -1) {
1058           guint64 diff;
1059           GstClockTime running_time =
1060               gst_segment_to_running_time (&basepayload->segment,
1061               GST_FORMAT_TIME, pts);
1062
1063           GST_LOG_OBJECT (rtph265pay,
1064               "now %" GST_TIME_FORMAT ", last VPS/SPS/PPS %" GST_TIME_FORMAT,
1065               GST_TIME_ARGS (running_time),
1066               GST_TIME_ARGS (rtph265pay->last_vps_sps_pps));
1067
1068           /* calculate diff between last SPS/PPS in milliseconds */
1069           if (running_time > rtph265pay->last_vps_sps_pps)
1070             diff = running_time - rtph265pay->last_vps_sps_pps;
1071           else
1072             diff = 0;
1073
1074           GST_DEBUG_OBJECT (rtph265pay,
1075               "interval since last VPS/SPS/PPS %" GST_TIME_FORMAT,
1076               GST_TIME_ARGS (diff));
1077
1078           /* bigger than interval, queue SPS/PPS */
1079           if (GST_TIME_AS_SECONDS (diff) >= rtph265pay->vps_sps_pps_interval) {
1080             GST_DEBUG_OBJECT (rtph265pay, "time to send VPS/SPS/PPS");
1081             send_ps = TRUE;
1082           }
1083         } else {
1084           /* no known previous SPS/PPS time, send now */
1085           GST_DEBUG_OBJECT (rtph265pay,
1086               "no previous VPS/SPS/PPS time, send now");
1087           send_ps = TRUE;
1088         }
1089       } else if (rtph265pay->vps_sps_pps_interval == -1
1090           && (nal_type == GST_H265_NAL_SLICE_IDR_W_RADL
1091               || nal_type == GST_H265_NAL_SLICE_IDR_N_LP)) {
1092         /* send VPS/SPS/PPS before every IDR frame */
1093         send_ps = TRUE;
1094       }
1095     }
1096
1097     if (!sent_ps && (send_ps || rtph265pay->send_vps_sps_pps)) {
1098       /* we need to send SPS/PPS now first. FIXME, don't use the pts for
1099        * checking when we need to send SPS/PPS but convert to running_time
1100        * first */
1101       rtph265pay->send_vps_sps_pps = FALSE;
1102       sent_ps = TRUE;
1103       GST_DEBUG_OBJECT (rtph265pay, "sending VPS/SPS/PPS before current frame");
1104       ret =
1105           gst_rtp_h265_pay_send_vps_sps_pps (basepayload, rtph265pay, dts, pts);
1106       if (ret != GST_FLOW_OK) {
1107         gst_buffer_unref (paybuf);
1108         continue;
1109       }
1110     }
1111
1112     if (rtph265pay->aggregate_mode != GST_RTP_H265_AGGREGATE_NONE)
1113       ret = gst_rtp_h265_pay_payload_nal_bundle (basepayload, paybuf, dts, pts,
1114           marker, nal_type, nal_header, size);
1115     else
1116       ret = gst_rtp_h265_pay_payload_nal_fragment (basepayload, paybuf, dts,
1117           pts, marker, mtu, nal_type, nal_header, size);
1118   }
1119
1120   g_ptr_array_free (paybufs, TRUE);
1121
1122   return ret;
1123 }
1124
1125 static GstFlowReturn
1126 gst_rtp_h265_pay_payload_nal_single (GstRTPBasePayload * basepayload,
1127     GstBuffer * paybuf, GstClockTime dts, GstClockTime pts, gboolean marker)
1128 {
1129   GstBufferList *outlist;
1130   GstBuffer *outbuf;
1131   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
1132
1133   /* use buffer lists
1134    * create buffer without payload containing only the RTP header
1135    * (memory block at index 0) */
1136   outbuf = gst_rtp_buffer_new_allocate (0, 0, 0);
1137
1138   gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp);
1139
1140   /* Mark the end of a frame */
1141   gst_rtp_buffer_set_marker (&rtp, marker);
1142
1143   /* timestamp the outbuffer */
1144   GST_BUFFER_PTS (outbuf) = pts;
1145   GST_BUFFER_DTS (outbuf) = dts;
1146
1147   /* insert payload memory block */
1148   gst_rtp_copy_video_meta (basepayload, outbuf, paybuf);
1149   outbuf = gst_buffer_append (outbuf, paybuf);
1150
1151   outlist = gst_buffer_list_new ();
1152
1153   /* add the buffer to the buffer list */
1154   gst_buffer_list_add (outlist, outbuf);
1155
1156   gst_rtp_buffer_unmap (&rtp);
1157
1158   /* push the list to the next element in the pipe */
1159   return gst_rtp_base_payload_push_list (basepayload, outlist);
1160 }
1161
1162 static GstFlowReturn
1163 gst_rtp_h265_pay_payload_nal_fragment (GstRTPBasePayload * basepayload,
1164     GstBuffer * paybuf, GstClockTime dts, GstClockTime pts, gboolean marker,
1165     guint mtu, guint8 nal_type, const guint8 * nal_header, int size)
1166 {
1167   GstRtpH265Pay *rtph265pay = (GstRtpH265Pay *) basepayload;
1168   GstFlowReturn ret;
1169   guint max_fragment_size, ii, pos;
1170   GstBuffer *outbuf;
1171   GstBufferList *outlist = NULL;
1172   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
1173   guint8 *payload;
1174
1175   if (gst_rtp_buffer_calc_packet_len (size, 0, 0) < mtu) {
1176     GST_DEBUG_OBJECT (rtph265pay,
1177         "NAL Unit fit in one packet datasize=%d mtu=%d", size, mtu);
1178     /* will fit in one packet */
1179     return gst_rtp_h265_pay_payload_nal_single (basepayload, paybuf, dts, pts,
1180         marker);
1181   }
1182
1183   GST_DEBUG_OBJECT (basepayload,
1184       "NAL Unit DOES NOT fit in one packet datasize=%d mtu=%d", size, mtu);
1185
1186   GST_DEBUG_OBJECT (basepayload, "Using FU fragmentation for data size=%d",
1187       size - 2);
1188
1189   /* We keep 3 bytes for PayloadHdr and FU Header */
1190   max_fragment_size = gst_rtp_buffer_calc_payload_len (mtu - 3, 0, 0);
1191
1192   outlist = gst_buffer_list_new ();
1193
1194   for (pos = 2, ii = 0; pos < size; pos += max_fragment_size, ii++) {
1195     guint remaining, fragment_size;
1196     gboolean first_fragment, last_fragment;
1197
1198     remaining = size - pos;
1199     fragment_size = MIN (remaining, max_fragment_size);
1200     first_fragment = (pos == 2);
1201     last_fragment = (remaining <= max_fragment_size);
1202
1203     GST_DEBUG_OBJECT (basepayload,
1204         "Inside  FU fragmentation fragment_size=%u iteration=%d %s%s",
1205         fragment_size, ii, first_fragment ? "first" : "",
1206         last_fragment ? "last" : "");
1207
1208     /* use buffer lists
1209      * create buffer without payload containing only the RTP header
1210      * (memory block at index 0), and with space for PayloadHdr and FU header */
1211     outbuf = gst_rtp_buffer_new_allocate (3, 0, 0);
1212
1213     gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp);
1214
1215     GST_BUFFER_DTS (outbuf) = dts;
1216     GST_BUFFER_PTS (outbuf) = pts;
1217     payload = gst_rtp_buffer_get_payload (&rtp);
1218
1219     /* PayloadHdr (type = FU_TYPE_ID (49)) */
1220     payload[0] = (nal_header[0] & 0x81) | (FU_TYPE_ID << 1);
1221     payload[1] = nal_header[1];
1222
1223     /* If it's the last fragment and the end of this au, mark the end of
1224      * slice */
1225     gst_rtp_buffer_set_marker (&rtp, last_fragment && marker);
1226
1227     /* FU Header */
1228     payload[2] = (first_fragment << 7) | (last_fragment << 6) |
1229         (nal_type & 0x3f);
1230
1231     gst_rtp_buffer_unmap (&rtp);
1232
1233     /* insert payload memory block */
1234     gst_rtp_copy_video_meta (rtph265pay, outbuf, paybuf);
1235     gst_buffer_copy_into (outbuf, paybuf, GST_BUFFER_COPY_MEMORY, pos,
1236         fragment_size);
1237     /* add the buffer to the buffer list */
1238     gst_buffer_list_add (outlist, outbuf);
1239   }
1240
1241   ret = gst_rtp_base_payload_push_list (basepayload, outlist);
1242   gst_buffer_unref (paybuf);
1243
1244   return ret;
1245 }
1246
1247 static GstFlowReturn
1248 gst_rtp_h265_pay_send_bundle (GstRtpH265Pay * rtph265pay, gboolean marker)
1249 {
1250   GstRTPBasePayload *basepayload;
1251   GstBufferList *bundle;
1252   guint length, bundle_size;
1253   GstBuffer *first, *outbuf;
1254   GstClockTime dts, pts;
1255
1256   bundle_size = rtph265pay->bundle_size;
1257
1258   if (bundle_size == 0) {
1259     GST_DEBUG_OBJECT (rtph265pay, "no bundle, nothing to send");
1260     return GST_FLOW_OK;
1261   }
1262
1263   basepayload = GST_RTP_BASE_PAYLOAD (rtph265pay);
1264   bundle = rtph265pay->bundle;
1265   length = gst_buffer_list_length (bundle);
1266
1267   first = gst_buffer_list_get (bundle, 0);
1268   dts = GST_BUFFER_DTS (first);
1269   pts = GST_BUFFER_PTS (first);
1270
1271   if (length == 1) {
1272     /* Push unaggregated NALU */
1273     outbuf = gst_buffer_ref (first);
1274
1275     GST_DEBUG_OBJECT (rtph265pay,
1276         "sending NAL Unit unaggregated: datasize=%u", bundle_size - 2);
1277   } else {
1278     guint8 ap_header[2];
1279     guint i;
1280     guint8 layer_id = 0xFF;
1281     guint8 temporal_id = 0xFF;
1282
1283     outbuf = gst_buffer_new_allocate (NULL, sizeof ap_header, NULL);
1284
1285     for (i = 0; i < length; i++) {
1286       GstBuffer *buf = gst_buffer_list_get (bundle, i);
1287       guint8 nal_header[2];
1288       GstMemory *size_header;
1289       GstMapInfo map;
1290       guint8 nal_layer_id;
1291       guint8 nal_temporal_id;
1292
1293       gst_buffer_extract (buf, 0, &nal_header, sizeof nal_header);
1294
1295       /* Propagate F bit */
1296       if ((nal_header[0] & 0x80))
1297         ap_header[0] |= 0x80;
1298
1299       /* Select lowest layer_id & temporal_id */
1300       nal_layer_id = ((nal_header[0] & 0x01) << 5) |
1301           ((nal_header[1] >> 3) & 0x1F);
1302       nal_temporal_id = nal_header[1] & 0x7;
1303       layer_id = MIN (layer_id, nal_layer_id);
1304       temporal_id = MIN (temporal_id, nal_temporal_id);
1305
1306       /* append NALU size */
1307       size_header = gst_allocator_alloc (NULL, 2, NULL);
1308       gst_memory_map (size_header, &map, GST_MAP_WRITE);
1309       GST_WRITE_UINT16_BE (map.data, gst_buffer_get_size (buf));
1310       gst_memory_unmap (size_header, &map);
1311       gst_buffer_append_memory (outbuf, size_header);
1312
1313       /* append NALU data */
1314       outbuf = gst_buffer_append (outbuf, gst_buffer_ref (buf));
1315     }
1316
1317     ap_header[0] = (AP_TYPE_ID << 1) | (layer_id & 0x20);
1318     ap_header[1] = ((layer_id & 0x1F) << 3) | (temporal_id & 0x07);
1319
1320     gst_buffer_fill (outbuf, 0, &ap_header, sizeof ap_header);
1321
1322     GST_DEBUG_OBJECT (rtph265pay,
1323         "sending AP bundle: n=%u header=%02x%02x datasize=%u",
1324         length, ap_header[0], ap_header[1], bundle_size);
1325   }
1326
1327   gst_rtp_h265_pay_reset_bundle (rtph265pay);
1328   return gst_rtp_h265_pay_payload_nal_single (basepayload, outbuf, dts, pts,
1329       marker);
1330 }
1331
1332 static gboolean
1333 gst_rtp_h265_pay_payload_nal_bundle (GstRTPBasePayload * basepayload,
1334     GstBuffer * paybuf, GstClockTime dts, GstClockTime pts,
1335     gboolean marker, guint8 nal_type, const guint8 * nal_header, int size)
1336 {
1337   GstRtpH265Pay *rtph265pay;
1338   GstFlowReturn ret;
1339   guint pay_size, bundle_size;
1340   GstBufferList *bundle;
1341   gboolean start_of_au;
1342   guint mtu;
1343
1344   rtph265pay = GST_RTP_H265_PAY (basepayload);
1345   mtu = GST_RTP_BASE_PAYLOAD_MTU (rtph265pay);
1346   pay_size = 2 + gst_buffer_get_size (paybuf);
1347   bundle = rtph265pay->bundle;
1348   start_of_au = FALSE;
1349
1350   if (bundle) {
1351     GstBuffer *first = gst_buffer_list_get (bundle, 0);
1352
1353     if (nal_type == GST_H265_NAL_AUD) {
1354       GST_DEBUG_OBJECT (rtph265pay, "found access delimiter");
1355       start_of_au = TRUE;
1356     } else if (GST_BUFFER_IS_DISCONT (paybuf)) {
1357       GST_DEBUG_OBJECT (rtph265pay, "found discont");
1358       start_of_au = TRUE;
1359     } else if (GST_BUFFER_PTS (first) != pts || GST_BUFFER_DTS (first) != dts) {
1360       GST_DEBUG_OBJECT (rtph265pay, "found timestamp mismatch");
1361       start_of_au = TRUE;
1362     }
1363   }
1364
1365   if (start_of_au) {
1366     GST_DEBUG_OBJECT (rtph265pay, "sending bundle before start of AU");
1367
1368     ret = gst_rtp_h265_pay_send_bundle (rtph265pay, TRUE);
1369     if (ret != GST_FLOW_OK)
1370       goto out;
1371
1372     bundle = NULL;
1373   }
1374
1375   bundle_size = 2 + pay_size;
1376
1377   if (gst_rtp_buffer_calc_packet_len (bundle_size, 0, 0) > mtu) {
1378     GST_DEBUG_OBJECT (rtph265pay, "NAL Unit cannot fit in a bundle");
1379
1380     ret = gst_rtp_h265_pay_send_bundle (rtph265pay, FALSE);
1381     if (ret != GST_FLOW_OK)
1382       goto out;
1383
1384     return gst_rtp_h265_pay_payload_nal_fragment (basepayload, paybuf, dts, pts,
1385         marker, mtu, nal_type, nal_header, size);
1386   }
1387
1388   bundle_size = rtph265pay->bundle_size + pay_size;
1389
1390   if (gst_rtp_buffer_calc_packet_len (bundle_size, 0, 0) > mtu) {
1391     GST_DEBUG_OBJECT (rtph265pay,
1392         "bundle overflows, sending: bundlesize=%u datasize=2+%u mtu=%u",
1393         rtph265pay->bundle_size, pay_size - 2, mtu);
1394
1395     ret = gst_rtp_h265_pay_send_bundle (rtph265pay, FALSE);
1396     if (ret != GST_FLOW_OK)
1397       goto out;
1398
1399     bundle = NULL;
1400   }
1401
1402   if (!bundle) {
1403     GST_DEBUG_OBJECT (rtph265pay, "creating new AP aggregate");
1404     bundle = rtph265pay->bundle = gst_buffer_list_new ();
1405     bundle_size = rtph265pay->bundle_size = 2;
1406     rtph265pay->bundle_contains_vcl_or_suffix = FALSE;
1407   }
1408
1409   GST_DEBUG_OBJECT (rtph265pay,
1410       "bundling NAL Unit: bundlesize=%u datasize=2+%u mtu=%u",
1411       rtph265pay->bundle_size, pay_size - 2, mtu);
1412
1413   paybuf = gst_buffer_make_writable (paybuf);
1414   GST_BUFFER_PTS (paybuf) = pts;
1415   GST_BUFFER_DTS (paybuf) = dts;
1416
1417   gst_buffer_list_add (bundle, gst_buffer_ref (paybuf));
1418   rtph265pay->bundle_size += pay_size;
1419   ret = GST_FLOW_OK;
1420
1421   /* In H.265, all VCL NAL units are < 32 */
1422   if (nal_type < 32 || nal_type == GST_H265_NAL_EOS ||
1423       nal_type == GST_H265_NAL_EOB || nal_type == GST_H265_NAL_SUFFIX_SEI ||
1424       (nal_type >= 45 && nal_type <= 47) || (nal_type >= 56 && nal_type < 63))
1425     rtph265pay->bundle_contains_vcl_or_suffix = TRUE;
1426
1427   if (marker) {
1428     GST_DEBUG_OBJECT (rtph265pay, "sending bundle at marker");
1429     ret = gst_rtp_h265_pay_send_bundle (rtph265pay, TRUE);
1430   }
1431
1432 out:
1433   gst_buffer_unref (paybuf);
1434   return ret;
1435 }
1436
1437 static GstFlowReturn
1438 gst_rtp_h265_pay_handle_buffer (GstRTPBasePayload * basepayload,
1439     GstBuffer * buffer)
1440 {
1441   GstRtpH265Pay *rtph265pay;
1442   GstFlowReturn ret;
1443   gsize size;
1444   guint nal_len, i;
1445   const guint8 *data;
1446   GstClockTime dts, pts;
1447   GArray *nal_queue;
1448   gboolean hevc;
1449   GstBuffer *paybuf = NULL;
1450   gsize skip;
1451   gboolean marker = FALSE;
1452   gboolean discont = FALSE;
1453   gboolean draining = (buffer == NULL);
1454
1455   rtph265pay = GST_RTP_H265_PAY (basepayload);
1456
1457   /* the input buffer contains one or more NAL units */
1458
1459   hevc = (rtph265pay->stream_format == GST_H265_STREAM_FORMAT_HEV1)
1460       || (rtph265pay->stream_format == GST_H265_STREAM_FORMAT_HVC1);
1461
1462   if (hevc) {
1463     /* In hevc mode, there is no adapter, so nothing to drain */
1464     if (draining)
1465       return GST_FLOW_OK;
1466   } else {
1467     if (buffer) {
1468       if (gst_adapter_available (rtph265pay->adapter) == 0)
1469         discont = GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT);
1470       marker = GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_MARKER);
1471       gst_adapter_push (rtph265pay->adapter, buffer);
1472       buffer = NULL;
1473     }
1474
1475     /* We want to use the first TS used to construct the following NAL */
1476     dts = gst_adapter_prev_dts (rtph265pay->adapter, NULL);
1477     pts = gst_adapter_prev_pts (rtph265pay->adapter, NULL);
1478
1479     size = gst_adapter_available (rtph265pay->adapter);
1480     /* Nothing to do here if the adapter is empty, e.g. on EOS */
1481     if (size == 0)
1482       return GST_FLOW_OK;
1483     data = gst_adapter_map (rtph265pay->adapter, size);
1484     GST_DEBUG_OBJECT (basepayload, "got %" G_GSIZE_FORMAT " bytes", size);
1485   }
1486
1487   ret = GST_FLOW_OK;
1488
1489   /* now loop over all NAL units and put them in a packet */
1490   if (hevc) {
1491     GstBufferMemoryMap memory;
1492     gsize remaining_buffer_size;
1493     guint nal_length_size;
1494     gsize offset = 0;
1495     GPtrArray *paybufs;
1496
1497     paybufs = g_ptr_array_new ();
1498     nal_length_size = rtph265pay->nal_length_size;
1499
1500     gst_buffer_memory_map (buffer, &memory);
1501     remaining_buffer_size = gst_buffer_get_size (buffer);
1502
1503     pts = GST_BUFFER_PTS (buffer);
1504     dts = GST_BUFFER_DTS (buffer);
1505     marker = GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_MARKER);
1506     GST_DEBUG_OBJECT (basepayload, "got %" G_GSIZE_FORMAT " bytes",
1507         remaining_buffer_size);
1508
1509     while (remaining_buffer_size > nal_length_size) {
1510       gint i;
1511
1512       nal_len = 0;
1513       for (i = 0; i < nal_length_size; i++) {
1514         nal_len = (nal_len << 8) + *memory.data;
1515         if (!gst_buffer_memory_advance_bytes (&memory, 1))
1516           break;
1517       }
1518
1519       offset += nal_length_size;
1520       remaining_buffer_size -= nal_length_size;
1521
1522       if (remaining_buffer_size >= nal_len) {
1523         GST_DEBUG_OBJECT (basepayload, "got NAL of size %u", nal_len);
1524       } else {
1525         nal_len = remaining_buffer_size;
1526         GST_DEBUG_OBJECT (basepayload, "got incomplete NAL of size %u",
1527             nal_len);
1528       }
1529
1530       paybuf = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, offset,
1531           nal_len);
1532       g_ptr_array_add (paybufs, paybuf);
1533
1534       /* If we're at the end of the buffer, then we're at the end of the
1535        * access unit
1536        */
1537       GST_BUFFER_FLAG_UNSET (paybuf, GST_BUFFER_FLAG_MARKER);
1538       if (remaining_buffer_size - nal_len <= nal_length_size) {
1539         if (rtph265pay->alignment == GST_H265_ALIGNMENT_AU || marker)
1540           GST_BUFFER_FLAG_SET (paybuf, GST_BUFFER_FLAG_MARKER);
1541       }
1542
1543       GST_BUFFER_FLAG_UNSET (paybuf, GST_BUFFER_FLAG_DISCONT);
1544       if (discont) {
1545         GST_BUFFER_FLAG_SET (paybuf, GST_BUFFER_FLAG_DISCONT);
1546         discont = FALSE;
1547       }
1548
1549       /* Skip current nal. If it is split over multiple GstMemory
1550        * advance_bytes () will switch to the correct GstMemory. The payloader
1551        * does not access those bytes directly but uses gst_buffer_copy_region ()
1552        * to create a sub-buffer referencing the nal instead */
1553       if (!gst_buffer_memory_advance_bytes (&memory, nal_len))
1554         break;
1555       offset += nal_len;
1556       remaining_buffer_size -= nal_len;
1557     }
1558     ret = gst_rtp_h265_pay_payload_nal (basepayload, paybufs, dts, pts);
1559
1560     gst_buffer_memory_unmap (&memory);
1561     gst_buffer_unref (buffer);
1562   } else {
1563     guint next;
1564     gboolean update = FALSE;
1565     GPtrArray *paybufs;
1566
1567     /* get offset of first start code */
1568     next = next_start_code (data, size);
1569
1570     /* skip to start code, if no start code is found, next will be size and we
1571      * will not collect data. */
1572     data += next;
1573     size -= next;
1574     nal_queue = rtph265pay->queue;
1575     skip = next;
1576
1577     /* array must be empty when we get here */
1578     g_assert (nal_queue->len == 0);
1579
1580     GST_DEBUG_OBJECT (basepayload,
1581         "found first start at %u, bytes left %" G_GSIZE_FORMAT, next, size);
1582
1583     paybufs = g_ptr_array_new ();
1584
1585     /* first pass to locate NALs and parse VPS/SPS/PPS */
1586     while (size > 4) {
1587       /* skip start code */
1588       data += 3;
1589       size -= 3;
1590
1591       /* use next_start_code() to scan buffer.
1592        * next_start_code() returns the offset in data,
1593        * starting from zero to the first byte of 0.0.0.1
1594        * If no start code is found, it returns the value of the
1595        * 'size' parameter.
1596        * data is unchanged by the call to next_start_code()
1597        */
1598       next = next_start_code (data, size);
1599
1600       /* nal or au aligned input needs no delaying until next time */
1601       if (next == size && !draining &&
1602           rtph265pay->alignment == GST_H265_ALIGNMENT_UNKNOWN) {
1603         /* Didn't find the start of next NAL and it's not EOS,
1604          * handle it next time */
1605         break;
1606       }
1607
1608       /* nal length is distance to next start code */
1609       nal_len = next;
1610
1611       GST_DEBUG_OBJECT (basepayload, "found next start at %u of size %u", next,
1612           nal_len);
1613
1614       /* We know our stream is a valid H265 NAL packet,
1615        * go parse it for VPS/SPS/PPS to enrich the caps */
1616       /* order: make sure to check nal */
1617       update = gst_rtp_h265_pay_decode_nal (rtph265pay, data, nal_len, dts, pts)
1618           || update;
1619
1620       /* move to next NAL packet */
1621       data += nal_len;
1622       size -= nal_len;
1623
1624       g_array_append_val (nal_queue, nal_len);
1625     }
1626
1627     /* if has new VPS, SPS & PPS, update the output caps */
1628     if (G_UNLIKELY (update))
1629       if (!gst_rtp_h265_pay_set_vps_sps_pps (basepayload))
1630         goto caps_rejected;
1631
1632     /* second pass to payload and push */
1633
1634     if (nal_queue->len != 0)
1635       gst_adapter_flush (rtph265pay->adapter, skip);
1636
1637     for (i = 0; i < nal_queue->len; i++) {
1638       guint size;
1639
1640       nal_len = g_array_index (nal_queue, guint, i);
1641       /* skip start code */
1642       gst_adapter_flush (rtph265pay->adapter, 3);
1643
1644       /* Trim the end unless we're the last NAL in the stream.
1645        * In case we're not at the end of the buffer we know the next block
1646        * starts with 0x000001 so all the 0x00 bytes at the end of this one are
1647        * trailing 0x0 that can be discarded */
1648       size = nal_len;
1649       data = gst_adapter_map (rtph265pay->adapter, size);
1650       if (i + 1 != nal_queue->len || !draining)
1651         for (; size > 2 && data[size - 1] == 0x0; size--)
1652           /* skip */ ;
1653
1654       paybuf = gst_adapter_take_buffer (rtph265pay->adapter, size);
1655       g_assert (paybuf);
1656       g_ptr_array_add (paybufs, paybuf);
1657
1658       /* If it's the last nal unit we have in non-bytestream mode, we can
1659        * assume it's the end of an access-unit */
1660       GST_BUFFER_FLAG_UNSET (paybuf, GST_BUFFER_FLAG_MARKER);
1661       if (i == nal_queue->len - 1) {
1662         if (rtph265pay->alignment == GST_H265_ALIGNMENT_AU ||
1663             marker || draining)
1664           GST_BUFFER_FLAG_SET (paybuf, GST_BUFFER_FLAG_MARKER);
1665       }
1666
1667       GST_BUFFER_FLAG_UNSET (paybuf, GST_BUFFER_FLAG_DISCONT);
1668       if (discont) {
1669         GST_BUFFER_FLAG_SET (paybuf, GST_BUFFER_FLAG_DISCONT);
1670         discont = FALSE;
1671       }
1672
1673       /* move to next NAL packet */
1674       /* Skips the trailing zeros */
1675       gst_adapter_flush (rtph265pay->adapter, nal_len - size);
1676     }
1677     /* put the data in one or more RTP packets */
1678     ret = gst_rtp_h265_pay_payload_nal (basepayload, paybufs, dts, pts);
1679     g_array_set_size (nal_queue, 0);
1680   }
1681
1682   if (ret == GST_FLOW_OK && rtph265pay->bundle_size > 0 &&
1683       rtph265pay->aggregate_mode == GST_RTP_H265_AGGREGATE_ZERO_LATENCY &&
1684       rtph265pay->bundle_contains_vcl_or_suffix) {
1685     GST_DEBUG_OBJECT (rtph265pay, "sending bundle at end incoming packet");
1686     ret = gst_rtp_h265_pay_send_bundle (rtph265pay, FALSE);
1687   }
1688
1689 done:
1690   if (!hevc) {
1691     gst_adapter_unmap (rtph265pay->adapter);
1692   }
1693
1694   return ret;
1695
1696 caps_rejected:
1697   {
1698     GST_WARNING_OBJECT (basepayload, "Could not set outcaps");
1699     g_array_set_size (nal_queue, 0);
1700     ret = GST_FLOW_NOT_NEGOTIATED;
1701     goto done;
1702   }
1703 }
1704
1705 static gboolean
1706 gst_rtp_h265_pay_sink_event (GstRTPBasePayload * payload, GstEvent * event)
1707 {
1708   gboolean res;
1709   const GstStructure *s;
1710   GstRtpH265Pay *rtph265pay = GST_RTP_H265_PAY (payload);
1711   GstFlowReturn ret = GST_FLOW_OK;
1712
1713   switch (GST_EVENT_TYPE (event)) {
1714     case GST_EVENT_FLUSH_STOP:
1715       gst_adapter_clear (rtph265pay->adapter);
1716       gst_rtp_h265_pay_reset_bundle (rtph265pay);
1717       break;
1718     case GST_EVENT_CUSTOM_DOWNSTREAM:
1719       s = gst_event_get_structure (event);
1720       if (gst_structure_has_name (s, "GstForceKeyUnit")) {
1721         gboolean resend_codec_data;
1722
1723         if (gst_structure_get_boolean (s, "all-headers",
1724                 &resend_codec_data) && resend_codec_data)
1725           rtph265pay->send_vps_sps_pps = TRUE;
1726       }
1727       break;
1728     case GST_EVENT_EOS:
1729     {
1730       /* call handle_buffer with NULL to flush last NAL from adapter
1731        * in byte-stream mode
1732        */
1733       gst_rtp_h265_pay_handle_buffer (payload, NULL);
1734       ret = gst_rtp_h265_pay_send_bundle (rtph265pay, TRUE);
1735
1736       break;
1737     }
1738     case GST_EVENT_STREAM_START:
1739       GST_DEBUG_OBJECT (rtph265pay,
1740           "New stream detected => Clear VPS, SPS and PPS");
1741       gst_rtp_h265_pay_clear_vps_sps_pps (rtph265pay);
1742       break;
1743     default:
1744       break;
1745   }
1746
1747   if (ret != GST_FLOW_OK)
1748     return FALSE;
1749
1750   res = GST_RTP_BASE_PAYLOAD_CLASS (parent_class)->sink_event (payload, event);
1751
1752   return res;
1753 }
1754
1755 static GstStateChangeReturn
1756 gst_rtp_h265_pay_change_state (GstElement * element, GstStateChange transition)
1757 {
1758   GstStateChangeReturn ret;
1759   GstRtpH265Pay *rtph265pay = GST_RTP_H265_PAY (element);
1760
1761   switch (transition) {
1762     case GST_STATE_CHANGE_READY_TO_PAUSED:
1763       rtph265pay->send_vps_sps_pps = FALSE;
1764       gst_adapter_clear (rtph265pay->adapter);
1765       gst_rtp_h265_pay_reset_bundle (rtph265pay);
1766       break;
1767     default:
1768       break;
1769   }
1770
1771   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1772
1773   switch (transition) {
1774     case GST_STATE_CHANGE_PAUSED_TO_READY:
1775       rtph265pay->last_vps_sps_pps = -1;
1776       gst_rtp_h265_pay_clear_vps_sps_pps (rtph265pay);
1777       break;
1778     default:
1779       break;
1780   }
1781
1782   return ret;
1783 }
1784
1785 static void
1786 gst_rtp_h265_pay_set_property (GObject * object, guint prop_id,
1787     const GValue * value, GParamSpec * pspec)
1788 {
1789   GstRtpH265Pay *rtph265pay;
1790
1791   rtph265pay = GST_RTP_H265_PAY (object);
1792
1793   switch (prop_id) {
1794     case PROP_CONFIG_INTERVAL:
1795       rtph265pay->vps_sps_pps_interval = g_value_get_int (value);
1796       break;
1797     case PROP_AGGREGATE_MODE:
1798       rtph265pay->aggregate_mode = g_value_get_enum (value);
1799       break;
1800     default:
1801       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1802       break;
1803   }
1804 }
1805
1806 static void
1807 gst_rtp_h265_pay_get_property (GObject * object, guint prop_id,
1808     GValue * value, GParamSpec * pspec)
1809 {
1810   GstRtpH265Pay *rtph265pay;
1811
1812   rtph265pay = GST_RTP_H265_PAY (object);
1813
1814   switch (prop_id) {
1815     case PROP_CONFIG_INTERVAL:
1816       g_value_set_int (value, rtph265pay->vps_sps_pps_interval);
1817       break;
1818     case PROP_AGGREGATE_MODE:
1819       g_value_set_enum (value, rtph265pay->aggregate_mode);
1820       break;
1821     default:
1822       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1823       break;
1824   }
1825 }
1826
1827 gboolean
1828 gst_rtp_h265_pay_plugin_init (GstPlugin * plugin)
1829 {
1830   return gst_element_register (plugin, "rtph265pay",
1831       GST_RANK_SECONDARY, GST_TYPE_RTP_H265_PAY);
1832 }