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 <stdio.h>
26 #include <string.h>
27 
28 #include <gst/base/gstbitreader.h>
29 #include <gst/rtp/gstrtpbuffer.h>
30 #include <gst/video/video.h>
31 #include "gstrtph265depay.h"
32 #include "gstrtputils.h"
33 
34 GST_DEBUG_CATEGORY_STATIC (rtph265depay_debug);
35 #define GST_CAT_DEFAULT (rtph265depay_debug)
36 
37 /* This is what we'll default to when downstream hasn't
38  * expressed a restriction or preference via caps */
39 #define DEFAULT_STREAM_FORMAT GST_H265_STREAM_FORMAT_BYTESTREAM
40 #define DEFAULT_ACCESS_UNIT   FALSE
41 
42 /* 3 zero bytes syncword */
43 static const guint8 sync_bytes[] = { 0, 0, 0, 1 };
44 
45 static GstStaticPadTemplate gst_rtp_h265_depay_src_template =
46     GST_STATIC_PAD_TEMPLATE ("src",
47     GST_PAD_SRC,
48     GST_PAD_ALWAYS,
49     GST_STATIC_CAPS
50     ("video/x-h265, stream-format=(string)hvc1, alignment=(string)au; "
51         /* FIXME: hev1 format is not supported yet */
52         /* "video/x-h265, "
53            "stream-format = (string) hev1, alignment = (string) au; " */
54         "video/x-h265, "
55         "stream-format = (string) byte-stream, alignment = (string) { nal, au }")
56     );
57 
58 static GstStaticPadTemplate gst_rtp_h265_depay_sink_template =
59 GST_STATIC_PAD_TEMPLATE ("sink",
60     GST_PAD_SINK,
61     GST_PAD_ALWAYS,
62     GST_STATIC_CAPS ("application/x-rtp, "
63         "media = (string) \"video\", "
64         "clock-rate = (int) 90000, " "encoding-name = (string) \"H265\"")
65         /** optional parameters **/
66     /* "profile-space = (int) [ 0, 3 ], " */
67     /* "profile-id = (int) [ 0, 31 ], " */
68     /* "tier-flag = (int) [ 0, 1 ], " */
69     /* "level-id = (int) [ 0, 255 ], " */
70     /* "interop-constraints = (string) ANY, " */
71     /* "profile-compatibility-indicator = (string) ANY, " */
72     /* "sprop-sub-layer-id = (int) [ 0, 6 ], " */
73     /* "recv-sub-layer-id = (int) [ 0, 6 ], " */
74     /* "max-recv-level-id = (int) [ 0, 255 ], " */
75     /* "tx-mode = (string) {MST , SST}, " */
76     /* "sprop-vps = (string) ANY, " */
77     /* "sprop-sps = (string) ANY, " */
78     /* "sprop-pps = (string) ANY, " */
79     /* "sprop-sei = (string) ANY, " */
80     /* "max-lsr = (int) ANY, " *//* MUST be in the range of MaxLumaSR to 16 * MaxLumaSR, inclusive */
81     /* "max-lps = (int) ANY, " *//* MUST be in the range of MaxLumaPS to 16 * MaxLumaPS, inclusive */
82     /* "max-cpb = (int) ANY, " *//* MUST be in the range of MaxCPB to 16 * MaxCPB, inclusive */
83     /* "max-dpb = (int) [1, 16], " */
84     /* "max-br = (int) ANY, " *//* MUST be in the range of MaxBR to 16 * MaxBR, inclusive, for the highest level */
85     /* "max-tr = (int) ANY, " *//* MUST be in the range of MaxTileRows to 16 * MaxTileRows, inclusive, for the highest level */
86     /* "max-tc = (int) ANY, " *//* MUST be in the range of MaxTileCols to 16 * MaxTileCols, inclusive, for the highest level */
87     /* "max-fps = (int) ANY, " */
88     /* "sprop-max-don-diff = (int) [0, 32767], " */
89     /* "sprop-depack-buf-nalus = (int) [0, 32767], " */
90     /* "sprop-depack-buf-nalus = (int) [0, 4294967295], " */
91     /* "depack-buf-cap = (int) [1, 4294967295], " */
92     /* "sprop-segmentation-id = (int) [0, 3], " */
93     /* "sprop-spatial-segmentation-idc = (string) ANY, " */
94     /* "dec-parallel-cap = (string) ANY, " */
95     );
96 
97 #define gst_rtp_h265_depay_parent_class parent_class
98 G_DEFINE_TYPE (GstRtpH265Depay, gst_rtp_h265_depay,
99     GST_TYPE_RTP_BASE_DEPAYLOAD);
100 
101 static void gst_rtp_h265_depay_finalize (GObject * object);
102 
103 static GstStateChangeReturn gst_rtp_h265_depay_change_state (GstElement *
104     element, GstStateChange transition);
105 
106 static GstBuffer *gst_rtp_h265_depay_process (GstRTPBaseDepayload * depayload,
107     GstRTPBuffer * rtp);
108 static gboolean gst_rtp_h265_depay_setcaps (GstRTPBaseDepayload * filter,
109     GstCaps * caps);
110 static gboolean gst_rtp_h265_depay_handle_event (GstRTPBaseDepayload * depay,
111     GstEvent * event);
112 static GstBuffer *gst_rtp_h265_complete_au (GstRtpH265Depay * rtph265depay,
113     GstClockTime * out_timestamp, gboolean * out_keyframe);
114 static void gst_rtp_h265_depay_push (GstRtpH265Depay * rtph265depay,
115     GstBuffer * outbuf, gboolean keyframe, GstClockTime timestamp,
116     gboolean marker);
117 
118 
119 static void
gst_rtp_h265_depay_class_init(GstRtpH265DepayClass * klass)120 gst_rtp_h265_depay_class_init (GstRtpH265DepayClass * klass)
121 {
122   GObjectClass *gobject_class;
123   GstElementClass *gstelement_class;
124   GstRTPBaseDepayloadClass *gstrtpbasedepayload_class;
125 
126   gobject_class = (GObjectClass *) klass;
127   gstelement_class = (GstElementClass *) klass;
128   gstrtpbasedepayload_class = (GstRTPBaseDepayloadClass *) klass;
129 
130   gobject_class->finalize = gst_rtp_h265_depay_finalize;
131 
132   gst_element_class_add_static_pad_template (gstelement_class,
133       &gst_rtp_h265_depay_src_template);
134   gst_element_class_add_static_pad_template (gstelement_class,
135       &gst_rtp_h265_depay_sink_template);
136 
137   gst_element_class_set_static_metadata (gstelement_class,
138       "RTP H265 depayloader", "Codec/Depayloader/Network/RTP",
139       "Extracts H265 video from RTP packets (RFC 7798)",
140       "Jurgen Slowack <jurgenslowack@gmail.com>");
141   gstelement_class->change_state = gst_rtp_h265_depay_change_state;
142 
143   gstrtpbasedepayload_class->process_rtp_packet = gst_rtp_h265_depay_process;
144   gstrtpbasedepayload_class->set_caps = gst_rtp_h265_depay_setcaps;
145   gstrtpbasedepayload_class->handle_event = gst_rtp_h265_depay_handle_event;
146 }
147 
148 static void
gst_rtp_h265_depay_init(GstRtpH265Depay * rtph265depay)149 gst_rtp_h265_depay_init (GstRtpH265Depay * rtph265depay)
150 {
151   rtph265depay->adapter = gst_adapter_new ();
152   rtph265depay->picture_adapter = gst_adapter_new ();
153   rtph265depay->output_format = DEFAULT_STREAM_FORMAT;
154   rtph265depay->byte_stream =
155       (DEFAULT_STREAM_FORMAT == GST_H265_STREAM_FORMAT_BYTESTREAM);
156   rtph265depay->stream_format = NULL;
157   rtph265depay->merge = DEFAULT_ACCESS_UNIT;
158   rtph265depay->vps = g_ptr_array_new_with_free_func (
159       (GDestroyNotify) gst_buffer_unref);
160   rtph265depay->sps = g_ptr_array_new_with_free_func (
161       (GDestroyNotify) gst_buffer_unref);
162   rtph265depay->pps = g_ptr_array_new_with_free_func (
163       (GDestroyNotify) gst_buffer_unref);
164 }
165 
166 static void
gst_rtp_h265_depay_reset(GstRtpH265Depay * rtph265depay,gboolean hard)167 gst_rtp_h265_depay_reset (GstRtpH265Depay * rtph265depay, gboolean hard)
168 {
169   gst_adapter_clear (rtph265depay->adapter);
170   rtph265depay->wait_start = TRUE;
171   gst_adapter_clear (rtph265depay->picture_adapter);
172   rtph265depay->picture_start = FALSE;
173   rtph265depay->last_keyframe = FALSE;
174   rtph265depay->last_ts = 0;
175   rtph265depay->current_fu_type = 0;
176   rtph265depay->new_codec_data = FALSE;
177   g_ptr_array_set_size (rtph265depay->vps, 0);
178   g_ptr_array_set_size (rtph265depay->sps, 0);
179   g_ptr_array_set_size (rtph265depay->pps, 0);
180 
181   if (hard) {
182     if (rtph265depay->allocator != NULL) {
183       gst_object_unref (rtph265depay->allocator);
184       rtph265depay->allocator = NULL;
185     }
186     gst_allocation_params_init (&rtph265depay->params);
187   }
188 }
189 
190 static void
gst_rtp_h265_depay_drain(GstRtpH265Depay * rtph265depay)191 gst_rtp_h265_depay_drain (GstRtpH265Depay * rtph265depay)
192 {
193   GstClockTime timestamp;
194   gboolean keyframe;
195   GstBuffer *outbuf;
196 
197   if (!rtph265depay->picture_start)
198     return;
199 
200   outbuf = gst_rtp_h265_complete_au (rtph265depay, &timestamp, &keyframe);
201   if (outbuf)
202     gst_rtp_h265_depay_push (rtph265depay, outbuf, keyframe, timestamp, FALSE);
203 }
204 
205 static void
gst_rtp_h265_depay_finalize(GObject * object)206 gst_rtp_h265_depay_finalize (GObject * object)
207 {
208   GstRtpH265Depay *rtph265depay;
209 
210   rtph265depay = GST_RTP_H265_DEPAY (object);
211 
212   if (rtph265depay->codec_data)
213     gst_buffer_unref (rtph265depay->codec_data);
214 
215   g_object_unref (rtph265depay->adapter);
216   g_object_unref (rtph265depay->picture_adapter);
217 
218   g_ptr_array_free (rtph265depay->vps, TRUE);
219   g_ptr_array_free (rtph265depay->sps, TRUE);
220   g_ptr_array_free (rtph265depay->pps, TRUE);
221 
222   G_OBJECT_CLASS (parent_class)->finalize (object);
223 }
224 
225 static inline const gchar *
stream_format_get_nick(GstH265StreamFormat fmt)226 stream_format_get_nick (GstH265StreamFormat fmt)
227 {
228   switch (fmt) {
229     case GST_H265_STREAM_FORMAT_BYTESTREAM:
230       return "byte-stream";
231     case GST_H265_STREAM_FORMAT_HVC1:
232       return "hvc1";
233     case GST_H265_STREAM_FORMAT_HEV1:
234       return "hev1";
235     default:
236       break;
237   }
238   return "unknown";
239 }
240 
241 static void
gst_rtp_h265_depay_negotiate(GstRtpH265Depay * rtph265depay)242 gst_rtp_h265_depay_negotiate (GstRtpH265Depay * rtph265depay)
243 {
244   GstH265StreamFormat stream_format = GST_H265_STREAM_FORMAT_UNKNOWN;
245   GstCaps *caps;
246   gint merge = -1;
247 
248   caps =
249       gst_pad_get_allowed_caps (GST_RTP_BASE_DEPAYLOAD_SRCPAD (rtph265depay));
250 
251   GST_DEBUG_OBJECT (rtph265depay, "allowed caps: %" GST_PTR_FORMAT, caps);
252 
253   if (caps) {
254     if (gst_caps_get_size (caps) > 0) {
255       GstStructure *s = gst_caps_get_structure (caps, 0);
256       const gchar *str = NULL;
257 
258       if ((str = gst_structure_get_string (s, "stream-format"))) {
259         rtph265depay->stream_format = g_intern_string (str);
260 
261         if (strcmp (str, "hev1") == 0) {
262           stream_format = GST_H265_STREAM_FORMAT_HEV1;
263         } else if (strcmp (str, "hvc1") == 0) {
264           stream_format = GST_H265_STREAM_FORMAT_HVC1;
265         } else if (strcmp (str, "byte-stream") == 0) {
266           stream_format = GST_H265_STREAM_FORMAT_BYTESTREAM;
267         } else {
268           GST_DEBUG_OBJECT (rtph265depay, "unknown stream-format: %s", str);
269         }
270       }
271 
272       if ((str = gst_structure_get_string (s, "alignment"))) {
273         if (strcmp (str, "au") == 0) {
274           merge = TRUE;
275         } else if (strcmp (str, "nal") == 0) {
276           merge = FALSE;
277         } else {
278           GST_DEBUG_OBJECT (rtph265depay, "unknown alignment: %s", str);
279         }
280       }
281     }
282     gst_caps_unref (caps);
283   }
284 
285   if (stream_format != GST_H265_STREAM_FORMAT_UNKNOWN) {
286     GST_DEBUG_OBJECT (rtph265depay, "downstream wants stream-format %s",
287         stream_format_get_nick (stream_format));
288     rtph265depay->output_format = stream_format;
289   } else {
290     GST_DEBUG_OBJECT (rtph265depay, "defaulting to output stream-format %s",
291         stream_format_get_nick (DEFAULT_STREAM_FORMAT));
292     rtph265depay->stream_format =
293         stream_format_get_nick (DEFAULT_STREAM_FORMAT);
294     rtph265depay->output_format = DEFAULT_STREAM_FORMAT;
295   }
296   rtph265depay->byte_stream =
297       (rtph265depay->output_format == GST_H265_STREAM_FORMAT_BYTESTREAM);
298 
299   if (merge != -1) {
300     GST_DEBUG_OBJECT (rtph265depay, "downstream requires merge %d", merge);
301     rtph265depay->merge = merge;
302   } else {
303     GST_DEBUG_OBJECT (rtph265depay, "defaulting to merge %d",
304         DEFAULT_ACCESS_UNIT);
305     rtph265depay->merge = DEFAULT_ACCESS_UNIT;
306   }
307 }
308 
309 static gboolean
parse_sps(GstMapInfo * map,guint32 * sps_id)310 parse_sps (GstMapInfo * map, guint32 * sps_id)
311 {                               /* To parse seq_parameter_set_id */
312   GstBitReader br = GST_BIT_READER_INIT (map->data + 15,
313       map->size - 15);
314 
315   GST_MEMDUMP ("SPS", map->data, map->size);
316 
317   if (map->size < 16)
318     return FALSE;
319 
320   if (!gst_rtp_read_golomb (&br, sps_id))
321     return FALSE;
322 
323   return TRUE;
324 }
325 
326 static gboolean
parse_pps(GstMapInfo * map,guint32 * sps_id,guint32 * pps_id)327 parse_pps (GstMapInfo * map, guint32 * sps_id, guint32 * pps_id)
328 {                               /* To parse picture_parameter_set_id */
329   GstBitReader br = GST_BIT_READER_INIT (map->data + 2,
330       map->size - 2);
331 
332   GST_MEMDUMP ("PPS", map->data, map->size);
333 
334   if (map->size < 3)
335     return FALSE;
336 
337   if (!gst_rtp_read_golomb (&br, pps_id))
338     return FALSE;
339   if (!gst_rtp_read_golomb (&br, sps_id))
340     return FALSE;
341 
342   return TRUE;
343 }
344 
345 static gboolean
gst_rtp_h265_depay_set_output_caps(GstRtpH265Depay * rtph265depay,GstCaps * caps)346 gst_rtp_h265_depay_set_output_caps (GstRtpH265Depay * rtph265depay,
347     GstCaps * caps)
348 {
349   GstAllocationParams params;
350   GstAllocator *allocator = NULL;
351   GstPad *srcpad;
352   gboolean res;
353 
354   gst_allocation_params_init (&params);
355 
356   srcpad = GST_RTP_BASE_DEPAYLOAD_SRCPAD (rtph265depay);
357 
358   res = gst_pad_set_caps (srcpad, caps);
359 
360   if (res) {
361     GstQuery *query;
362 
363     query = gst_query_new_allocation (caps, TRUE);
364     if (!gst_pad_peer_query (srcpad, query)) {
365       GST_DEBUG_OBJECT (rtph265depay, "downstream ALLOCATION query failed");
366     }
367 
368     if (gst_query_get_n_allocation_params (query) > 0) {
369       gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
370     }
371 
372     gst_query_unref (query);
373   }
374 
375   if (rtph265depay->allocator)
376     gst_object_unref (rtph265depay->allocator);
377 
378   rtph265depay->allocator = allocator;
379   rtph265depay->params = params;
380 
381   return res;
382 }
383 
384 static gboolean
gst_rtp_h265_set_src_caps(GstRtpH265Depay * rtph265depay)385 gst_rtp_h265_set_src_caps (GstRtpH265Depay * rtph265depay)
386 {
387   gboolean res, update_caps;
388   GstCaps *old_caps;
389   GstCaps *srccaps;
390   GstPad *srcpad;
391 
392   if (!rtph265depay->byte_stream &&
393       (!rtph265depay->new_codec_data ||
394           rtph265depay->vps->len == 0 || rtph265depay->sps->len == 0
395           || rtph265depay->pps->len == 0))
396     return TRUE;
397 
398   srccaps = gst_caps_new_simple ("video/x-h265",
399       "stream-format", G_TYPE_STRING, rtph265depay->stream_format,
400       "alignment", G_TYPE_STRING, rtph265depay->merge ? "au" : "nal", NULL);
401 
402   if (!rtph265depay->byte_stream) {
403     GstBuffer *codec_data;
404     gint i = 0;
405     gint len;
406     guint num_vps = rtph265depay->vps->len;
407     guint num_sps = rtph265depay->sps->len;
408     guint num_pps = rtph265depay->pps->len;
409     GstMapInfo map, nalmap;
410     guint8 *data;
411     guint8 num_arrays = 0;
412     guint new_size;
413     GstBitReader br;
414     guint32 tmp;
415     guint8 tmp8 = 0;
416     guint32 max_sub_layers_minus1, temporal_id_nesting_flag, chroma_format_idc,
417         bit_depth_luma_minus8, bit_depth_chroma_minus8,
418         min_spatial_segmentation_idc;
419 
420     /* Fixme: Current implementation is not embedding SEI in codec_data */
421 
422     if (num_sps == 0)
423       return FALSE;
424 
425     /* start with 23 bytes header */
426     len = 23;
427 
428     num_arrays = (num_vps > 0) + (num_sps > 0) + (num_pps > 0);
429     len += 3 * num_arrays;
430 
431     /* add size of vps, sps & pps */
432     for (i = 0; i < num_vps; i++)
433       len += 2 + gst_buffer_get_size (g_ptr_array_index (rtph265depay->vps, i));
434     for (i = 0; i < num_sps; i++)
435       len += 2 + gst_buffer_get_size (g_ptr_array_index (rtph265depay->sps, i));
436     for (i = 0; i < num_pps; i++)
437       len += 2 + gst_buffer_get_size (g_ptr_array_index (rtph265depay->pps, i));
438 
439     GST_DEBUG_OBJECT (rtph265depay,
440         "constructing codec_data: num_vps =%d num_sps=%d, num_pps=%d", num_vps,
441         num_sps, num_pps);
442 
443     codec_data = gst_buffer_new_and_alloc (len);
444     gst_buffer_map (codec_data, &map, GST_MAP_READWRITE);
445     data = map.data;
446 
447     memset (data, 0, map.size);
448 
449     /* Parsing sps to get the info required further on */
450 
451     gst_buffer_map (g_ptr_array_index (rtph265depay->sps, 0), &nalmap,
452         GST_MAP_READ);
453 
454     max_sub_layers_minus1 = ((nalmap.data[2]) >> 1) & 0x07;
455     temporal_id_nesting_flag = nalmap.data[2] & 0x01;
456 
457     gst_bit_reader_init (&br, nalmap.data + 15, nalmap.size - 15);
458 
459     gst_rtp_read_golomb (&br, &tmp);    /* sps_seq_parameter_set_id */
460     gst_rtp_read_golomb (&br, &chroma_format_idc);      /* chroma_format_idc */
461 
462     if (chroma_format_idc == 3)
463 
464       gst_bit_reader_get_bits_uint8 (&br, &tmp8, 1);    /* separate_colour_plane_flag */
465 
466     gst_rtp_read_golomb (&br, &tmp);    /* pic_width_in_luma_samples */
467     gst_rtp_read_golomb (&br, &tmp);    /* pic_height_in_luma_samples */
468 
469     gst_bit_reader_get_bits_uint8 (&br, &tmp8, 1);      /* conformance_window_flag */
470     if (tmp8) {
471       gst_rtp_read_golomb (&br, &tmp);  /* conf_win_left_offset */
472       gst_rtp_read_golomb (&br, &tmp);  /* conf_win_right_offset */
473       gst_rtp_read_golomb (&br, &tmp);  /* conf_win_top_offset */
474       gst_rtp_read_golomb (&br, &tmp);  /* conf_win_bottom_offset */
475     }
476 
477     gst_rtp_read_golomb (&br, &bit_depth_luma_minus8);  /* bit_depth_luma_minus8 */
478     gst_rtp_read_golomb (&br, &bit_depth_chroma_minus8);        /* bit_depth_chroma_minus8 */
479 
480     GST_DEBUG_OBJECT (rtph265depay,
481         "Ignoring min_spatial_segmentation for now (assuming zero)");
482 
483     min_spatial_segmentation_idc = 0;   /* NOTE - we ignore this for now, but in a perfect world, we should continue parsing to obtain the real value */
484 
485     gst_buffer_unmap (g_ptr_array_index (rtph265depay->sps, 0), &nalmap);
486 
487     /* HEVCDecoderConfigurationVersion = 1 */
488     data[0] = 1;
489 
490     /* Copy from profile_tier_level (Rec. ITU-T H.265 (04/2013) section 7.3.3
491      *
492      * profile_space | tier_flat | profile_idc |
493      * profile_compatibility_flags | constraint_indicator_flags |
494      * level_idc | progressive_source_flag | interlaced_source_flag
495      * non_packed_constraint_flag | frame_only_constraint_flag
496      * reserved_zero_44bits | level_idc */
497     gst_buffer_map (g_ptr_array_index (rtph265depay->sps, 0), &nalmap,
498         GST_MAP_READ);
499     for (i = 0; i < 12; i++)
500       data[i + 1] = nalmap.data[i];
501     gst_buffer_unmap (g_ptr_array_index (rtph265depay->sps, 0), &nalmap);
502 
503     /* min_spatial_segmentation_idc */
504     GST_WRITE_UINT16_BE (data + 13, min_spatial_segmentation_idc);
505     data[13] |= 0xf0;
506     data[15] = 0xfc;            /* keeping parrallelismType as zero (unknown) */
507     data[16] = 0xfc | chroma_format_idc;
508     data[17] = 0xf8 | bit_depth_luma_minus8;
509     data[18] = 0xf8 | bit_depth_chroma_minus8;
510     data[19] = 0x00;            /* keep avgFrameRate as unspecified */
511     data[20] = 0x00;            /* keep avgFrameRate as unspecified */
512     /* constFrameRate(2 bits): 0, stream may or may not be of constant framerate
513      * numTemporalLayers (3 bits): number of temporal layers, value from SPS
514      * TemporalIdNested (1 bit): sps_temporal_id_nesting_flag from SPS
515      * lengthSizeMinusOne (2 bits): plus 1 indicates the length of the NALUnitLength */
516     /* we always output NALs with 4-byte nal unit length markers (or sync code) */
517     data[21] = rtph265depay->byte_stream ? 0x00 : 0x03;
518     data[21] |= ((max_sub_layers_minus1 + 1) << 3);
519     data[21] |= (temporal_id_nesting_flag << 2);
520     GST_WRITE_UINT8 (data + 22, num_arrays);    /* numOfArrays */
521 
522     data += 23;
523 
524     /* copy all VPS */
525     if (num_vps > 0) {
526       /* array_completeness | reserved_zero bit | nal_unit_type */
527       data[0] = 0x00 | 0x20;
528       data++;
529 
530       GST_WRITE_UINT16_BE (data, num_vps);
531       data += 2;
532 
533       for (i = 0; i < num_vps; i++) {
534         gsize nal_size =
535             gst_buffer_get_size (g_ptr_array_index (rtph265depay->vps, i));
536         GST_WRITE_UINT16_BE (data, nal_size);
537         gst_buffer_extract (g_ptr_array_index (rtph265depay->vps, i), 0,
538             data + 2, nal_size);
539         data += 2 + nal_size;
540         GST_DEBUG_OBJECT (rtph265depay, "Copied VPS %d of length %u", i,
541             (guint) nal_size);
542       }
543     }
544 
545     /* copy all SPS */
546     if (num_sps > 0) {
547       /* array_completeness | reserved_zero bit | nal_unit_type */
548       data[0] = 0x00 | 0x21;
549       data++;
550 
551       GST_WRITE_UINT16_BE (data, num_sps);
552       data += 2;
553 
554       for (i = 0; i < num_sps; i++) {
555         gsize nal_size =
556             gst_buffer_get_size (g_ptr_array_index (rtph265depay->sps, i));
557         GST_WRITE_UINT16_BE (data, nal_size);
558         gst_buffer_extract (g_ptr_array_index (rtph265depay->sps, i), 0,
559             data + 2, nal_size);
560         data += 2 + nal_size;
561         GST_DEBUG_OBJECT (rtph265depay, "Copied SPS %d of length %u", i,
562             (guint) nal_size);
563       }
564     }
565 
566     /* copy all PPS */
567     if (num_pps > 0) {
568       /* array_completeness | reserved_zero bit | nal_unit_type */
569       data[0] = 0x00 | 0x22;
570       data++;
571 
572       GST_WRITE_UINT16_BE (data, num_pps);
573       data += 2;
574 
575       for (i = 0; i < num_pps; i++) {
576         gsize nal_size =
577             gst_buffer_get_size (g_ptr_array_index (rtph265depay->pps, i));
578         GST_WRITE_UINT16_BE (data, nal_size);
579         gst_buffer_extract (g_ptr_array_index (rtph265depay->pps, i), 0,
580             data + 2, nal_size);
581         data += 2 + nal_size;
582         GST_DEBUG_OBJECT (rtph265depay, "Copied PPS %d of length %u", i,
583             (guint) nal_size);
584       }
585     }
586 
587     new_size = data - map.data;
588     gst_buffer_unmap (codec_data, &map);
589     gst_buffer_set_size (codec_data, new_size);
590 
591     gst_caps_set_simple (srccaps,
592         "codec_data", GST_TYPE_BUFFER, codec_data, NULL);
593     gst_buffer_unref (codec_data);
594   }
595 
596   srcpad = GST_RTP_BASE_DEPAYLOAD_SRCPAD (rtph265depay);
597 
598   old_caps = gst_pad_get_current_caps (srcpad);
599   if (old_caps != NULL) {
600 
601     /* Only update the caps if they are not equal. For
602      * AVC we don't update caps if only the codec_data
603      * changes. This is the same behaviour as in h264parse
604      * and gstrtph264depay
605      */
606     if (rtph265depay->byte_stream) {
607       update_caps = !gst_caps_is_equal (srccaps, old_caps);
608     } else {
609       GstCaps *tmp_caps = gst_caps_copy (srccaps);
610       GstStructure *old_s, *tmp_s;
611 
612       old_s = gst_caps_get_structure (old_caps, 0);
613       tmp_s = gst_caps_get_structure (tmp_caps, 0);
614       if (gst_structure_has_field (old_s, "codec_data"))
615         gst_structure_set_value (tmp_s, "codec_data",
616             gst_structure_get_value (old_s, "codec_data"));
617 
618       update_caps = !gst_caps_is_equal (old_caps, tmp_caps);
619       gst_caps_unref (tmp_caps);
620     }
621     gst_caps_unref (old_caps);
622   } else {
623     update_caps = TRUE;
624   }
625 
626   if (update_caps) {
627     res = gst_rtp_h265_depay_set_output_caps (rtph265depay, srccaps);
628   } else {
629     res = TRUE;
630   }
631 
632   gst_caps_unref (srccaps);
633 
634   /* Insert SPS and PPS into the stream on next opportunity */
635   if (rtph265depay->output_format != GST_H265_STREAM_FORMAT_HVC1
636       && (rtph265depay->sps->len > 0 || rtph265depay->pps->len > 0)) {
637     gint i;
638     GstBuffer *codec_data;
639     GstMapInfo map;
640     guint8 *data;
641     guint len = 0;
642 
643     for (i = 0; i < rtph265depay->sps->len; i++) {
644       len += 4 + gst_buffer_get_size (g_ptr_array_index (rtph265depay->sps, i));
645     }
646 
647     for (i = 0; i < rtph265depay->pps->len; i++) {
648       len += 4 + gst_buffer_get_size (g_ptr_array_index (rtph265depay->pps, i));
649     }
650 
651     codec_data = gst_buffer_new_and_alloc (len);
652     gst_buffer_map (codec_data, &map, GST_MAP_WRITE);
653     data = map.data;
654 
655     for (i = 0; i < rtph265depay->sps->len; i++) {
656       GstBuffer *sps_buf = g_ptr_array_index (rtph265depay->sps, i);
657       guint sps_size = gst_buffer_get_size (sps_buf);
658 
659       if (rtph265depay->byte_stream)
660         memcpy (data, sync_bytes, sizeof (sync_bytes));
661       else
662         GST_WRITE_UINT32_BE (data, sps_size);
663       gst_buffer_extract (sps_buf, 0, data + 4, -1);
664       data += 4 + sps_size;
665     }
666 
667     for (i = 0; i < rtph265depay->pps->len; i++) {
668       GstBuffer *pps_buf = g_ptr_array_index (rtph265depay->pps, i);
669       guint pps_size = gst_buffer_get_size (pps_buf);
670 
671       if (rtph265depay->byte_stream)
672         memcpy (data, sync_bytes, sizeof (sync_bytes));
673       else
674         GST_WRITE_UINT32_BE (data, pps_size);
675       gst_buffer_extract (pps_buf, 0, data + 4, -1);
676       data += 4 + pps_size;
677     }
678 
679     gst_buffer_unmap (codec_data, &map);
680     if (rtph265depay->codec_data)
681       gst_buffer_unref (rtph265depay->codec_data);
682     rtph265depay->codec_data = codec_data;
683   }
684 
685   if (res)
686     rtph265depay->new_codec_data = FALSE;
687 
688   return res;
689 }
690 
691 gboolean
gst_rtp_h265_add_vps_sps_pps(GstElement * rtph265,GPtrArray * vps_array,GPtrArray * sps_array,GPtrArray * pps_array,GstBuffer * nal)692 gst_rtp_h265_add_vps_sps_pps (GstElement * rtph265, GPtrArray * vps_array,
693     GPtrArray * sps_array, GPtrArray * pps_array, GstBuffer * nal)
694 {
695   GstMapInfo map;
696   guchar type;
697   guint i;
698 
699   gst_buffer_map (nal, &map, GST_MAP_READ);
700 
701   type = (map.data[0] >> 1) & 0x3f;
702 
703   if (type == GST_H265_VPS_NUT) {
704     guint32 vps_id = (map.data[2] >> 4) & 0x0f;
705 
706     for (i = 0; i < vps_array->len; i++) {
707       GstBuffer *vps = g_ptr_array_index (vps_array, i);
708       GstMapInfo vpsmap;
709       guint32 tmp_vps_id;
710 
711       gst_buffer_map (vps, &vpsmap, GST_MAP_READ);
712       tmp_vps_id = (vpsmap.data[2] >> 4) & 0x0f;
713 
714       if (vps_id == tmp_vps_id) {
715         if (map.size == vpsmap.size &&
716             memcmp (map.data, vpsmap.data, vpsmap.size) == 0) {
717           GST_LOG_OBJECT (rtph265, "Unchanged VPS %u, not updating", vps_id);
718           gst_buffer_unmap (vps, &vpsmap);
719           goto drop;
720         } else {
721           gst_buffer_unmap (vps, &vpsmap);
722           g_ptr_array_remove_index_fast (vps_array, i);
723           g_ptr_array_add (vps_array, nal);
724           GST_LOG_OBJECT (rtph265, "Modified VPS %u, replacing", vps_id);
725           goto done;
726         }
727       }
728       gst_buffer_unmap (vps, &vpsmap);
729     }
730     GST_LOG_OBJECT (rtph265, "Adding new VPS %u", vps_id);
731     g_ptr_array_add (vps_array, nal);
732   } else if (type == GST_H265_SPS_NUT) {
733     guint32 sps_id;
734 
735     if (!parse_sps (&map, &sps_id)) {
736       GST_WARNING_OBJECT (rtph265, "Invalid SPS,"
737           " can't parse seq_parameter_set_id");
738       goto drop;
739     }
740 
741     for (i = 0; i < sps_array->len; i++) {
742       GstBuffer *sps = g_ptr_array_index (sps_array, i);
743       GstMapInfo spsmap;
744       guint32 tmp_sps_id;
745 
746       gst_buffer_map (sps, &spsmap, GST_MAP_READ);
747       parse_sps (&spsmap, &tmp_sps_id);
748 
749       if (sps_id == tmp_sps_id) {
750         if (map.size == spsmap.size &&
751             memcmp (map.data, spsmap.data, spsmap.size) == 0) {
752           GST_LOG_OBJECT (rtph265, "Unchanged SPS %u, not updating", sps_id);
753           gst_buffer_unmap (sps, &spsmap);
754           goto drop;
755         } else {
756           gst_buffer_unmap (sps, &spsmap);
757           g_ptr_array_remove_index_fast (sps_array, i);
758           g_ptr_array_add (sps_array, nal);
759           GST_LOG_OBJECT (rtph265, "Modified SPS %u, replacing", sps_id);
760           goto done;
761         }
762       }
763       gst_buffer_unmap (sps, &spsmap);
764     }
765     GST_LOG_OBJECT (rtph265, "Adding new SPS %u", sps_id);
766     g_ptr_array_add (sps_array, nal);
767   } else if (type == GST_H265_PPS_NUT) {
768     guint32 sps_id;
769     guint32 pps_id;
770 
771     if (!parse_pps (&map, &sps_id, &pps_id)) {
772       GST_WARNING_OBJECT (rtph265, "Invalid PPS,"
773           " can't parse seq_parameter_set_id or pic_parameter_set_id");
774       goto drop;
775     }
776 
777     for (i = 0; i < pps_array->len; i++) {
778       GstBuffer *pps = g_ptr_array_index (pps_array, i);
779       GstMapInfo ppsmap;
780       guint32 tmp_sps_id;
781       guint32 tmp_pps_id;
782 
783 
784       gst_buffer_map (pps, &ppsmap, GST_MAP_READ);
785       parse_pps (&ppsmap, &tmp_sps_id, &tmp_pps_id);
786 
787       if (pps_id == tmp_pps_id) {
788         if (map.size == ppsmap.size &&
789             memcmp (map.data, ppsmap.data, ppsmap.size) == 0) {
790           GST_LOG_OBJECT (rtph265, "Unchanged PPS %u:%u, not updating", sps_id,
791               pps_id);
792           gst_buffer_unmap (pps, &ppsmap);
793           goto drop;
794         } else {
795           gst_buffer_unmap (pps, &ppsmap);
796           g_ptr_array_remove_index_fast (pps_array, i);
797           g_ptr_array_add (pps_array, nal);
798           GST_LOG_OBJECT (rtph265, "Modified PPS %u:%u, replacing",
799               sps_id, pps_id);
800           goto done;
801         }
802       }
803       gst_buffer_unmap (pps, &ppsmap);
804     }
805     GST_LOG_OBJECT (rtph265, "Adding new PPS %u:%i", sps_id, pps_id);
806     g_ptr_array_add (pps_array, nal);
807   } else {
808     goto drop;
809   }
810 
811 done:
812   gst_buffer_unmap (nal, &map);
813 
814   return TRUE;
815 
816 drop:
817   gst_buffer_unmap (nal, &map);
818   gst_buffer_unref (nal);
819 
820   return FALSE;
821 }
822 
823 
824 static void
gst_rtp_h265_depay_add_vps_sps_pps(GstRtpH265Depay * rtph265depay,GstBuffer * nal)825 gst_rtp_h265_depay_add_vps_sps_pps (GstRtpH265Depay * rtph265depay,
826     GstBuffer * nal)
827 {
828   if (gst_rtp_h265_add_vps_sps_pps (GST_ELEMENT (rtph265depay),
829           rtph265depay->vps, rtph265depay->sps, rtph265depay->pps, nal))
830     rtph265depay->new_codec_data = TRUE;
831 }
832 
833 static gboolean
gst_rtp_h265_depay_setcaps(GstRTPBaseDepayload * depayload,GstCaps * caps)834 gst_rtp_h265_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
835 {
836   gint clock_rate;
837   GstStructure *structure = gst_caps_get_structure (caps, 0);
838   GstRtpH265Depay *rtph265depay;
839   const gchar *vps;
840   const gchar *sps;
841   const gchar *pps;
842   gchar *ps;
843   GstMapInfo map;
844   guint8 *ptr;
845 
846   rtph265depay = GST_RTP_H265_DEPAY (depayload);
847 
848   if (!gst_structure_get_int (structure, "clock-rate", &clock_rate))
849     clock_rate = 90000;
850   depayload->clock_rate = clock_rate;
851 
852   /* Base64 encoded, comma separated config NALs */
853   vps = gst_structure_get_string (structure, "sprop-vps");
854   sps = gst_structure_get_string (structure, "sprop-sps");
855   pps = gst_structure_get_string (structure, "sprop-pps");
856   if (vps == NULL || sps == NULL || pps == NULL) {
857     ps = NULL;
858   } else {
859     ps = g_strdup_printf ("%s,%s,%s", vps, sps, pps);
860   }
861 
862   /* negotiate with downstream w.r.t. output format and alignment */
863   gst_rtp_h265_depay_negotiate (rtph265depay);
864 
865   if (rtph265depay->byte_stream && ps != NULL) {
866     /* for bytestream we only need the parameter sets but we don't error out
867      * when they are not there, we assume they are in the stream. */
868     gchar **params;
869     GstBuffer *codec_data;
870     guint len, total;
871     gint i;
872 
873     params = g_strsplit (ps, ",", 0);
874 
875     /* count total number of bytes in base64. Also include the sync bytes in
876      * front of the params. */
877     len = 0;
878     for (i = 0; params[i]; i++) {
879       len += strlen (params[i]);
880       len += sizeof (sync_bytes);
881     }
882     /* we seriously overshoot the length, but it's fine. */
883     codec_data = gst_buffer_new_and_alloc (len);
884 
885     gst_buffer_map (codec_data, &map, GST_MAP_WRITE);
886     ptr = map.data;
887     total = 0;
888     for (i = 0; params[i]; i++) {
889       guint save = 0;
890       gint state = 0;
891 
892       GST_DEBUG_OBJECT (depayload, "decoding param %d (%s)", i, params[i]);
893       memcpy (ptr, sync_bytes, sizeof (sync_bytes));
894       ptr += sizeof (sync_bytes);
895       len =
896           g_base64_decode_step (params[i], strlen (params[i]), ptr, &state,
897           &save);
898       GST_DEBUG_OBJECT (depayload, "decoded %d bytes", len);
899       total += len + sizeof (sync_bytes);
900       ptr += len;
901     }
902     gst_buffer_unmap (codec_data, &map);
903     gst_buffer_resize (codec_data, 0, total);
904     g_strfreev (params);
905 
906     /* keep the codec_data, we need to send it as the first buffer. We cannot
907      * push it in the adapter because the adapter might be flushed on discont.
908      */
909     if (rtph265depay->codec_data)
910       gst_buffer_unref (rtph265depay->codec_data);
911     rtph265depay->codec_data = codec_data;
912   } else if (!rtph265depay->byte_stream) {
913     gchar **params;
914     gint i;
915 
916     if (ps == NULL)
917       goto incomplete_caps;
918 
919     params = g_strsplit (ps, ",", 0);
920 
921     GST_DEBUG_OBJECT (depayload, "we have %d params", g_strv_length (params));
922 
923     /* start with 23 bytes header */
924     for (i = 0; params[i]; i++) {
925       GstBuffer *nal;
926       GstMapInfo nalmap;
927       gsize nal_len;
928       guint save = 0;
929       gint state = 0;
930 
931       nal_len = strlen (params[i]);
932       if (nal_len == 0) {
933         GST_WARNING_OBJECT (depayload, "empty param '%s' (#%d)", params[i], i);
934         continue;
935       }
936       nal = gst_buffer_new_and_alloc (nal_len);
937       gst_buffer_map (nal, &nalmap, GST_MAP_READWRITE);
938 
939       nal_len =
940           g_base64_decode_step (params[i], nal_len, nalmap.data, &state, &save);
941 
942       GST_DEBUG_OBJECT (depayload, "adding param %d as %s", i,
943           (((nalmap.data[0] >> 1) & 0x3f) ==
944               32) ? "VPS" : (((nalmap.data[0] >> 1) & 0x3f) ==
945               33) ? "SPS" : "PPS");
946 
947       gst_buffer_unmap (nal, &nalmap);
948       gst_buffer_set_size (nal, nal_len);
949 
950       gst_rtp_h265_depay_add_vps_sps_pps (rtph265depay, nal);
951     }
952     g_strfreev (params);
953 
954     if (rtph265depay->vps->len == 0 || rtph265depay->sps->len == 0 ||
955         rtph265depay->pps->len == 0) {
956       goto incomplete_caps;
957     }
958   }
959 
960   g_free (ps);
961 
962   return gst_rtp_h265_set_src_caps (rtph265depay);
963 
964   /* ERRORS */
965 incomplete_caps:
966   {
967     GST_DEBUG_OBJECT (depayload, "we have incomplete caps,"
968         " doing setcaps later");
969     g_free (ps);
970     return TRUE;
971   }
972 }
973 
974 static GstBuffer *
gst_rtp_h265_depay_allocate_output_buffer(GstRtpH265Depay * depay,gsize size)975 gst_rtp_h265_depay_allocate_output_buffer (GstRtpH265Depay * depay, gsize size)
976 {
977   GstBuffer *buffer = NULL;
978 
979   g_return_val_if_fail (size > 0, NULL);
980 
981   GST_LOG_OBJECT (depay, "want output buffer of %u bytes", (guint) size);
982 
983   buffer = gst_buffer_new_allocate (depay->allocator, size, &depay->params);
984   if (buffer == NULL) {
985     GST_INFO_OBJECT (depay, "couldn't allocate output buffer");
986     buffer = gst_buffer_new_allocate (NULL, size, NULL);
987   }
988 
989   return buffer;
990 }
991 
992 static GstBuffer *
gst_rtp_h265_complete_au(GstRtpH265Depay * rtph265depay,GstClockTime * out_timestamp,gboolean * out_keyframe)993 gst_rtp_h265_complete_au (GstRtpH265Depay * rtph265depay,
994     GstClockTime * out_timestamp, gboolean * out_keyframe)
995 {
996   GstBufferList *list;
997   GstMapInfo outmap;
998   GstBuffer *outbuf;
999   guint outsize, offset = 0;
1000   gint b, n_bufs, m, n_mem;
1001 
1002   /* we had a picture in the adapter and we completed it */
1003   GST_DEBUG_OBJECT (rtph265depay, "taking completed AU");
1004   outsize = gst_adapter_available (rtph265depay->picture_adapter);
1005 
1006   outbuf = gst_rtp_h265_depay_allocate_output_buffer (rtph265depay, outsize);
1007 
1008   if (outbuf == NULL)
1009     return NULL;
1010 
1011   if (!gst_buffer_map (outbuf, &outmap, GST_MAP_WRITE))
1012     return NULL;
1013 
1014   list = gst_adapter_take_buffer_list (rtph265depay->picture_adapter, outsize);
1015 
1016   n_bufs = gst_buffer_list_length (list);
1017   for (b = 0; b < n_bufs; ++b) {
1018     GstBuffer *buf = gst_buffer_list_get (list, b);
1019 
1020     n_mem = gst_buffer_n_memory (buf);
1021     for (m = 0; m < n_mem; ++m) {
1022       GstMemory *mem = gst_buffer_peek_memory (buf, m);
1023       gsize mem_size = gst_memory_get_sizes (mem, NULL, NULL);
1024       GstMapInfo mem_map;
1025 
1026       if (gst_memory_map (mem, &mem_map, GST_MAP_READ)) {
1027         memcpy (outmap.data + offset, mem_map.data, mem_size);
1028         gst_memory_unmap (mem, &mem_map);
1029       } else {
1030         memset (outmap.data + offset, 0, mem_size);
1031       }
1032       offset += mem_size;
1033     }
1034 
1035     gst_rtp_copy_video_meta (rtph265depay, outbuf, buf);
1036   }
1037   gst_buffer_list_unref (list);
1038   gst_buffer_unmap (outbuf, &outmap);
1039 
1040   *out_timestamp = rtph265depay->last_ts;
1041   *out_keyframe = rtph265depay->last_keyframe;
1042 
1043   rtph265depay->last_keyframe = FALSE;
1044   rtph265depay->picture_start = FALSE;
1045 
1046   return outbuf;
1047 }
1048 
1049 /* VPS/SPS/PPS/RADL/TSA/RASL/IDR/CRA is considered key, all others DELTA;
1050  * so downstream waiting for keyframe can pick up at VPS/SPS/PPS/IDR */
1051 
1052 #define NAL_TYPE_IS_PARAMETER_SET(nt) (		((nt) == GST_H265_VPS_NUT)\
1053 										||  ((nt) == GST_H265_SPS_NUT)\
1054 										||  ((nt) == GST_H265_PPS_NUT)				)
1055 
1056 #define NAL_TYPE_IS_CODED_SLICE_SEGMENT(nt) (		((nt) == GST_H265_NAL_SLICE_TRAIL_N)\
1057 												|| 	((nt) == GST_H265_NAL_SLICE_TRAIL_R)\
1058 												||  ((nt) == GST_H265_NAL_SLICE_TSA_N)\
1059 												||  ((nt) == GST_H265_NAL_SLICE_TSA_R)\
1060 												||  ((nt) == GST_H265_NAL_SLICE_STSA_N)\
1061 												||  ((nt) == GST_H265_NAL_SLICE_STSA_R)\
1062 												||  ((nt) == GST_H265_NAL_SLICE_RASL_N)\
1063 												||  ((nt) == GST_H265_NAL_SLICE_RASL_R)\
1064 												||  ((nt) == GST_H265_NAL_SLICE_BLA_W_LP)\
1065 												||  ((nt) == GST_H265_NAL_SLICE_BLA_W_RADL)\
1066 												||  ((nt) == GST_H265_NAL_SLICE_BLA_N_LP)\
1067 												||  ((nt) == GST_H265_NAL_SLICE_IDR_W_RADL)\
1068 												||  ((nt) == GST_H265_NAL_SLICE_IDR_N_LP)\
1069 												||  ((nt) == GST_H265_NAL_SLICE_CRA_NUT)		)
1070 
1071 /* Intra random access point */
1072 #define NAL_TYPE_IS_IRAP(nt)   (((nt) == GST_H265_NAL_SLICE_BLA_W_LP)   \
1073                              || ((nt) == GST_H265_NAL_SLICE_BLA_W_RADL) \
1074                              || ((nt) == GST_H265_NAL_SLICE_BLA_N_LP)   \
1075                              || ((nt) == GST_H265_NAL_SLICE_IDR_W_RADL) \
1076                              || ((nt) == GST_H265_NAL_SLICE_IDR_N_LP)   \
1077                              || ((nt) == GST_H265_NAL_SLICE_CRA_NUT))
1078 
1079 #define NAL_TYPE_IS_KEY(nt) (NAL_TYPE_IS_PARAMETER_SET(nt) || NAL_TYPE_IS_IRAP(nt))
1080 
1081 static void
gst_rtp_h265_depay_push(GstRtpH265Depay * rtph265depay,GstBuffer * outbuf,gboolean keyframe,GstClockTime timestamp,gboolean marker)1082 gst_rtp_h265_depay_push (GstRtpH265Depay * rtph265depay, GstBuffer * outbuf,
1083     gboolean keyframe, GstClockTime timestamp, gboolean marker)
1084 {
1085   /* prepend codec_data */
1086   if (rtph265depay->codec_data) {
1087     GST_DEBUG_OBJECT (rtph265depay, "prepending codec_data");
1088     gst_rtp_copy_video_meta (rtph265depay, rtph265depay->codec_data, outbuf);
1089     outbuf = gst_buffer_append (rtph265depay->codec_data, outbuf);
1090     rtph265depay->codec_data = NULL;
1091     keyframe = TRUE;
1092   }
1093   outbuf = gst_buffer_make_writable (outbuf);
1094 
1095   gst_rtp_drop_non_video_meta (rtph265depay, outbuf);
1096 
1097   GST_BUFFER_PTS (outbuf) = timestamp;
1098 
1099   if (keyframe)
1100     GST_BUFFER_FLAG_UNSET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
1101   else
1102     GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
1103 
1104   if (marker)
1105     GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_MARKER);
1106 
1107   gst_rtp_base_depayload_push (GST_RTP_BASE_DEPAYLOAD (rtph265depay), outbuf);
1108 }
1109 
1110 static void
gst_rtp_h265_depay_handle_nal(GstRtpH265Depay * rtph265depay,GstBuffer * nal,GstClockTime in_timestamp,gboolean marker)1111 gst_rtp_h265_depay_handle_nal (GstRtpH265Depay * rtph265depay, GstBuffer * nal,
1112     GstClockTime in_timestamp, gboolean marker)
1113 {
1114   GstRTPBaseDepayload *depayload = GST_RTP_BASE_DEPAYLOAD (rtph265depay);
1115   gint nal_type;
1116   GstMapInfo map;
1117   GstBuffer *outbuf = NULL;
1118   GstClockTime out_timestamp;
1119   gboolean keyframe, out_keyframe;
1120 
1121   gst_buffer_map (nal, &map, GST_MAP_READ);
1122   if (G_UNLIKELY (map.size < 5))
1123     goto short_nal;
1124 
1125   nal_type = (map.data[4] >> 1) & 0x3f;
1126   GST_DEBUG_OBJECT (rtph265depay, "handle NAL type %d (RTP marker bit %d)",
1127       nal_type, marker);
1128 
1129   keyframe = NAL_TYPE_IS_KEY (nal_type);
1130 
1131   out_keyframe = keyframe;
1132   out_timestamp = in_timestamp;
1133 
1134   if (!rtph265depay->byte_stream) {
1135     if (NAL_TYPE_IS_PARAMETER_SET (nal_type)) {
1136       gst_rtp_h265_depay_add_vps_sps_pps (rtph265depay,
1137           gst_buffer_copy_region (nal, GST_BUFFER_COPY_ALL,
1138               4, gst_buffer_get_size (nal) - 4));
1139       gst_buffer_unmap (nal, &map);
1140       gst_buffer_unref (nal);
1141       return;
1142     } else if (rtph265depay->sps->len == 0 || rtph265depay->pps->len == 0) {
1143       /* Down push down any buffer in non-bytestream mode if the SPS/PPS haven't
1144        * go through yet
1145        */
1146       gst_pad_push_event (GST_RTP_BASE_DEPAYLOAD_SINKPAD (depayload),
1147           gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM,
1148               gst_structure_new ("GstForceKeyUnit",
1149                   "all-headers", G_TYPE_BOOLEAN, TRUE, NULL)));
1150       gst_buffer_unmap (nal, &map);
1151       gst_buffer_unref (nal);
1152       return;
1153     }
1154 
1155     if (rtph265depay->new_codec_data &&
1156         rtph265depay->sps->len > 0 && rtph265depay->pps->len > 0)
1157       gst_rtp_h265_set_src_caps (rtph265depay);
1158   }
1159 
1160   if (rtph265depay->merge) {
1161     gboolean start = FALSE, complete = FALSE;
1162 
1163     /* marker bit isn't mandatory so in the following code we try to detect
1164      * an AU boundary (see H.265 spec section 7.4.2.4.4) */
1165     if (!marker) {
1166       if (NAL_TYPE_IS_CODED_SLICE_SEGMENT (nal_type)) {
1167         /* A NAL unit (X) ends an access unit if the next-occurring VCL NAL unit (Y) has the high-order bit of the first byte after its NAL unit header equal to 1 */
1168         start = TRUE;
1169         if (((map.data[6] >> 7) & 0x01) == 1) {
1170           complete = TRUE;
1171         }
1172       } else if ((nal_type >= 32 && nal_type <= 35)
1173           || nal_type == 39 || (nal_type >= 41 && nal_type <= 44)
1174           || (nal_type >= 48 && nal_type <= 55)) {
1175         /* VPS, SPS, PPS, SEI, ... terminate an access unit */
1176         complete = TRUE;
1177       }
1178       GST_DEBUG_OBJECT (depayload, "start %d, complete %d", start, complete);
1179 
1180       if (complete && rtph265depay->picture_start)
1181         outbuf = gst_rtp_h265_complete_au (rtph265depay, &out_timestamp,
1182             &out_keyframe);
1183     }
1184     /* add to adapter */
1185     gst_buffer_unmap (nal, &map);
1186 
1187     GST_DEBUG_OBJECT (depayload, "adding NAL to picture adapter");
1188     gst_adapter_push (rtph265depay->picture_adapter, nal);
1189     rtph265depay->last_ts = in_timestamp;
1190     rtph265depay->last_keyframe |= keyframe;
1191     rtph265depay->picture_start |= start;
1192 
1193     if (marker)
1194       outbuf = gst_rtp_h265_complete_au (rtph265depay, &out_timestamp,
1195           &out_keyframe);
1196   } else {
1197     /* no merge, output is input nal */
1198     GST_DEBUG_OBJECT (depayload, "using NAL as output");
1199     outbuf = nal;
1200     gst_buffer_unmap (nal, &map);
1201   }
1202 
1203   if (outbuf) {
1204     gst_rtp_h265_depay_push (rtph265depay, outbuf, out_keyframe, out_timestamp,
1205         marker);
1206   }
1207 
1208   return;
1209 
1210   /* ERRORS */
1211 short_nal:
1212   {
1213     GST_WARNING_OBJECT (depayload, "dropping short NAL");
1214     gst_buffer_unmap (nal, &map);
1215     gst_buffer_unref (nal);
1216     return;
1217   }
1218 }
1219 
1220 static void
gst_rtp_h265_finish_fragmentation_unit(GstRtpH265Depay * rtph265depay)1221 gst_rtp_h265_finish_fragmentation_unit (GstRtpH265Depay * rtph265depay)
1222 {
1223   guint outsize;
1224   GstMapInfo map;
1225   GstBuffer *outbuf;
1226 
1227   outsize = gst_adapter_available (rtph265depay->adapter);
1228   g_assert (outsize >= 4);
1229 
1230   outbuf = gst_adapter_take_buffer (rtph265depay->adapter, outsize);
1231 
1232   gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
1233   GST_DEBUG_OBJECT (rtph265depay, "output %d bytes", outsize);
1234 
1235   if (rtph265depay->byte_stream) {
1236     memcpy (map.data, sync_bytes, sizeof (sync_bytes));
1237   } else {
1238     GST_WRITE_UINT32_BE (map.data, outsize - 4);
1239   }
1240   gst_buffer_unmap (outbuf, &map);
1241 
1242   rtph265depay->current_fu_type = 0;
1243 
1244   gst_rtp_h265_depay_handle_nal (rtph265depay, outbuf,
1245       rtph265depay->fu_timestamp, rtph265depay->fu_marker);
1246 }
1247 
1248 static GstBuffer *
gst_rtp_h265_depay_process(GstRTPBaseDepayload * depayload,GstRTPBuffer * rtp)1249 gst_rtp_h265_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
1250 {
1251   GstRtpH265Depay *rtph265depay;
1252   GstBuffer *outbuf = NULL;
1253   guint8 nal_unit_type;
1254 
1255   rtph265depay = GST_RTP_H265_DEPAY (depayload);
1256 
1257   /* flush remaining data on discont */
1258   if (GST_BUFFER_IS_DISCONT (rtp->buffer)) {
1259     gst_adapter_clear (rtph265depay->adapter);
1260     rtph265depay->wait_start = TRUE;
1261     rtph265depay->current_fu_type = 0;
1262   }
1263 
1264   {
1265     gint payload_len;
1266     guint8 *payload;
1267     guint header_len;
1268     GstMapInfo map;
1269     guint outsize, nalu_size;
1270     GstClockTime timestamp;
1271     gboolean marker;
1272     guint8 nuh_layer_id, nuh_temporal_id_plus1;
1273     guint8 S, E;
1274     guint16 nal_header;
1275 #if 0
1276     gboolean donl_present = FALSE;
1277 #endif
1278 
1279     timestamp = GST_BUFFER_PTS (rtp->buffer);
1280 
1281     payload_len = gst_rtp_buffer_get_payload_len (rtp);
1282     payload = gst_rtp_buffer_get_payload (rtp);
1283     marker = gst_rtp_buffer_get_marker (rtp);
1284 
1285     GST_DEBUG_OBJECT (rtph265depay, "receiving %d bytes", payload_len);
1286 
1287     if (payload_len == 0)
1288       goto empty_packet;
1289 
1290     /* +---------------+---------------+
1291      * |0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|
1292      * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1293      * |F|   Type    |  LayerId  | TID |
1294      * +-------------+-----------------+
1295      *
1296      * F must be 0.
1297      *
1298      */
1299     nal_unit_type = (payload[0] >> 1) & 0x3f;
1300     nuh_layer_id = ((payload[0] & 0x01) << 5) | (payload[1] >> 3);      /* should be zero for now but this could change in future HEVC extensions */
1301     nuh_temporal_id_plus1 = payload[1] & 0x03;
1302 
1303     /* At least two byte header with type */
1304     header_len = 2;
1305 
1306     GST_DEBUG_OBJECT (rtph265depay,
1307         "NAL header nal_unit_type %d, nuh_temporal_id_plus1 %d", nal_unit_type,
1308         nuh_temporal_id_plus1);
1309 
1310     GST_FIXME_OBJECT (rtph265depay, "Assuming DONL field is not present");
1311 
1312     /* FIXME - assuming DONL field is not present for now */
1313     /*donl_present = (tx-mode == "MST") || (sprop-max-don-diff > 0); */
1314 
1315     /* If FU unit was being processed, but the current nal is of a different
1316      * type.  Assume that the remote payloader is buggy (didn't set the end bit
1317      * when the FU ended) and send out what we gathered thusfar */
1318     if (G_UNLIKELY (rtph265depay->current_fu_type != 0 &&
1319             nal_unit_type != rtph265depay->current_fu_type))
1320       gst_rtp_h265_finish_fragmentation_unit (rtph265depay);
1321 
1322     switch (nal_unit_type) {
1323       case 48:
1324       {
1325         GST_DEBUG_OBJECT (rtph265depay, "Processing aggregation packet");
1326 
1327         /* Aggregation packet (section 4.7) */
1328 
1329         /*  An example of an AP packet containing two aggregation units
1330            without the DONL and DOND fields
1331 
1332            0                   1                   2                   3
1333            0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1334            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1335            |                          RTP Header                           |
1336            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1337            |   PayloadHdr (Type=48)        |         NALU 1 Size           |
1338            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1339            |          NALU 1 HDR           |                               |
1340            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+         NALU 1 Data           |
1341            |                   . . .                                       |
1342            |                                                               |
1343            +               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1344            |  . . .        | NALU 2 Size                   | NALU 2 HDR    |
1345            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1346            | NALU 2 HDR    |                                               |
1347            +-+-+-+-+-+-+-+-+              NALU 2 Data                      |
1348            |                   . . .                                       |
1349            |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1350            |                               :...OPTIONAL RTP padding        |
1351            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1352          */
1353 
1354         /* strip headers */
1355         payload += header_len;
1356         payload_len -= header_len;
1357 
1358         rtph265depay->wait_start = FALSE;
1359 
1360 #if 0
1361         if (donl_present)
1362           goto not_implemented_donl_present;
1363 #endif
1364 
1365         while (payload_len > 2) {
1366           gboolean last = FALSE;
1367 
1368           nalu_size = (payload[0] << 8) | payload[1];
1369 
1370           /* dont include nalu_size */
1371           if (nalu_size > (payload_len - 2))
1372             nalu_size = payload_len - 2;
1373 
1374           outsize = nalu_size + sizeof (sync_bytes);
1375           outbuf = gst_buffer_new_and_alloc (outsize);
1376 
1377           gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
1378           if (rtph265depay->byte_stream) {
1379             memcpy (map.data, sync_bytes, sizeof (sync_bytes));
1380           } else {
1381             GST_WRITE_UINT32_BE (map.data, nalu_size);
1382           }
1383 
1384           /* strip NALU size */
1385           payload += 2;
1386           payload_len -= 2;
1387 
1388           memcpy (map.data + sizeof (sync_bytes), payload, nalu_size);
1389           gst_buffer_unmap (outbuf, &map);
1390 
1391           gst_rtp_copy_video_meta (rtph265depay, outbuf, rtp->buffer);
1392 
1393           if (payload_len - nalu_size <= 2)
1394             last = TRUE;
1395 
1396           gst_rtp_h265_depay_handle_nal (rtph265depay, outbuf, timestamp,
1397               marker && last);
1398 
1399           payload += nalu_size;
1400           payload_len -= nalu_size;
1401         }
1402         break;
1403       }
1404       case 49:
1405       {
1406         GST_DEBUG_OBJECT (rtph265depay, "Processing Fragmentation Unit");
1407 
1408         /* Fragmentation units (FUs)  Section 4.8 */
1409 
1410         /*    The structure of a Fragmentation Unit (FU)
1411          *
1412          *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1413          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1414          |    PayloadHdr (Type=49)       |   FU header   | DONL (cond)   |
1415          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
1416          | DONL (cond)   |                                               |
1417          |-+-+-+-+-+-+-+-+                                               |
1418          |                         FU payload                            |
1419          |                                                               |
1420          |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1421          |                               :...OPTIONAL RTP padding        |
1422          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1423          *
1424          *
1425          */
1426 
1427         /* strip headers */
1428         payload += header_len;
1429         payload_len -= header_len;
1430 
1431         /* processing FU header */
1432         S = (payload[0] & 0x80) == 0x80;
1433         E = (payload[0] & 0x40) == 0x40;
1434 
1435         GST_DEBUG_OBJECT (rtph265depay,
1436             "FU header with S %d, E %d, nal_unit_type %d", S, E,
1437             payload[0] & 0x3f);
1438 
1439         if (rtph265depay->wait_start && !S)
1440           goto waiting_start;
1441 
1442 #if 0
1443         if (donl_present)
1444           goto not_implemented_donl_present;
1445 #endif
1446 
1447         if (S) {
1448 
1449           GST_DEBUG_OBJECT (rtph265depay, "Start of Fragmentation Unit");
1450 
1451           /* If a new FU unit started, while still processing an older one.
1452            * Assume that the remote payloader is buggy (doesn't set the end
1453            * bit) and send out what we've gathered thusfar */
1454           if (G_UNLIKELY (rtph265depay->current_fu_type != 0))
1455             gst_rtp_h265_finish_fragmentation_unit (rtph265depay);
1456 
1457           rtph265depay->current_fu_type = nal_unit_type;
1458           rtph265depay->fu_timestamp = timestamp;
1459 
1460           rtph265depay->wait_start = FALSE;
1461 
1462           /* reconstruct NAL header */
1463           nal_header =
1464               ((payload[0] & 0x3f) << 9) | (nuh_layer_id << 3) |
1465               nuh_temporal_id_plus1;
1466 
1467           /* go back one byte so we can copy the payload + two bytes more in the front which
1468            * will be overwritten by the nal_header
1469            */
1470           payload -= 1;
1471           payload_len += 1;
1472 
1473           nalu_size = payload_len;
1474           outsize = nalu_size + sizeof (sync_bytes);
1475           outbuf = gst_buffer_new_and_alloc (outsize);
1476 
1477           gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
1478           if (rtph265depay->byte_stream) {
1479             GST_WRITE_UINT32_BE (map.data, 0x00000001);
1480           } else {
1481             /* will be fixed up in finish_fragmentation_unit() */
1482             GST_WRITE_UINT32_BE (map.data, 0xffffffff);
1483           }
1484           memcpy (map.data + sizeof (sync_bytes), payload, nalu_size);
1485           map.data[4] = nal_header >> 8;
1486           map.data[5] = nal_header & 0xff;
1487           gst_buffer_unmap (outbuf, &map);
1488 
1489           gst_rtp_copy_video_meta (rtph265depay, outbuf, rtp->buffer);
1490 
1491           GST_DEBUG_OBJECT (rtph265depay, "queueing %d bytes", outsize);
1492 
1493           /* and assemble in the adapter */
1494           gst_adapter_push (rtph265depay->adapter, outbuf);
1495         } else {
1496 
1497           GST_DEBUG_OBJECT (rtph265depay,
1498               "Following part of Fragmentation Unit");
1499 
1500           /* strip off FU header byte */
1501           payload += 1;
1502           payload_len -= 1;
1503 
1504           outsize = payload_len;
1505           outbuf = gst_buffer_new_and_alloc (outsize);
1506           gst_buffer_fill (outbuf, 0, payload, outsize);
1507 
1508           gst_rtp_copy_video_meta (rtph265depay, outbuf, rtp->buffer);
1509 
1510           GST_DEBUG_OBJECT (rtph265depay, "queueing %d bytes", outsize);
1511 
1512           /* and assemble in the adapter */
1513           gst_adapter_push (rtph265depay->adapter, outbuf);
1514         }
1515 
1516         outbuf = NULL;
1517         rtph265depay->fu_marker = marker;
1518 
1519         /* if NAL unit ends, flush the adapter */
1520         if (E) {
1521           gst_rtp_h265_finish_fragmentation_unit (rtph265depay);
1522           GST_DEBUG_OBJECT (rtph265depay, "End of Fragmentation Unit");
1523         }
1524         break;
1525       }
1526       case 50:
1527         goto not_implemented;   /* PACI packets  Section 4.9 */
1528       default:
1529       {
1530         rtph265depay->wait_start = FALSE;
1531 
1532         /* All other cases: Single NAL unit packet   Section 4.6 */
1533         /* the entire payload is the output buffer */
1534 
1535 #if 0
1536         if (donl_present)
1537           goto not_implemented_donl_present;
1538 #endif
1539 
1540         nalu_size = payload_len;
1541         outsize = nalu_size + sizeof (sync_bytes);
1542         outbuf = gst_buffer_new_and_alloc (outsize);
1543 
1544         gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
1545         if (rtph265depay->byte_stream) {
1546           memcpy (map.data, sync_bytes, sizeof (sync_bytes));
1547         } else {
1548           GST_WRITE_UINT32_BE (map.data, nalu_size);
1549         }
1550         memcpy (map.data + 4, payload, nalu_size);
1551         gst_buffer_unmap (outbuf, &map);
1552 
1553         gst_rtp_copy_video_meta (rtph265depay, outbuf, rtp->buffer);
1554 
1555         gst_rtp_h265_depay_handle_nal (rtph265depay, outbuf, timestamp, marker);
1556         break;
1557       }
1558     }
1559   }
1560 
1561   return NULL;
1562 
1563   /* ERRORS */
1564 empty_packet:
1565   {
1566     GST_DEBUG_OBJECT (rtph265depay, "empty packet");
1567     return NULL;
1568   }
1569 waiting_start:
1570   {
1571     GST_DEBUG_OBJECT (rtph265depay, "waiting for start");
1572     return NULL;
1573   }
1574 #if 0
1575 not_implemented_donl_present:
1576   {
1577     GST_ELEMENT_ERROR (rtph265depay, STREAM, FORMAT,
1578         (NULL), ("DONL field present not supported yet"));
1579     return NULL;
1580   }
1581 #endif
1582 not_implemented:
1583   {
1584     GST_ELEMENT_ERROR (rtph265depay, STREAM, FORMAT,
1585         (NULL), ("NAL unit type %d not supported yet", nal_unit_type));
1586     return NULL;
1587   }
1588 }
1589 
1590 static gboolean
gst_rtp_h265_depay_handle_event(GstRTPBaseDepayload * depay,GstEvent * event)1591 gst_rtp_h265_depay_handle_event (GstRTPBaseDepayload * depay, GstEvent * event)
1592 {
1593   GstRtpH265Depay *rtph265depay;
1594 
1595   rtph265depay = GST_RTP_H265_DEPAY (depay);
1596 
1597   switch (GST_EVENT_TYPE (event)) {
1598     case GST_EVENT_FLUSH_STOP:
1599       gst_rtp_h265_depay_reset (rtph265depay, FALSE);
1600       break;
1601     case GST_EVENT_EOS:
1602       gst_rtp_h265_depay_drain (rtph265depay);
1603       break;
1604     default:
1605       break;
1606   }
1607 
1608   return
1609       GST_RTP_BASE_DEPAYLOAD_CLASS (parent_class)->handle_event (depay, event);
1610 }
1611 
1612 static GstStateChangeReturn
gst_rtp_h265_depay_change_state(GstElement * element,GstStateChange transition)1613 gst_rtp_h265_depay_change_state (GstElement * element,
1614     GstStateChange transition)
1615 {
1616   GstRtpH265Depay *rtph265depay;
1617   GstStateChangeReturn ret;
1618 
1619   rtph265depay = GST_RTP_H265_DEPAY (element);
1620 
1621   switch (transition) {
1622     case GST_STATE_CHANGE_NULL_TO_READY:
1623       break;
1624     case GST_STATE_CHANGE_READY_TO_PAUSED:
1625       gst_rtp_h265_depay_reset (rtph265depay, TRUE);
1626       break;
1627     default:
1628       break;
1629   }
1630 
1631   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1632 
1633   switch (transition) {
1634     case GST_STATE_CHANGE_PAUSED_TO_READY:
1635       gst_rtp_h265_depay_reset (rtph265depay, TRUE);
1636       break;
1637     case GST_STATE_CHANGE_READY_TO_NULL:
1638       break;
1639     default:
1640       break;
1641   }
1642   return ret;
1643 }
1644 
1645 gboolean
gst_rtp_h265_depay_plugin_init(GstPlugin * plugin)1646 gst_rtp_h265_depay_plugin_init (GstPlugin * plugin)
1647 {
1648   GST_DEBUG_CATEGORY_INIT (rtph265depay_debug, "rtph265depay", 0,
1649       "H265 Video RTP Depayloader");
1650 
1651   return gst_element_register (plugin, "rtph265depay",
1652       GST_RANK_SECONDARY, GST_TYPE_RTP_H265_DEPAY);
1653 }
1654