bc2e78c7450e8e5c0a4e25bdd04da2e3f58a0538
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-bad / gst / videoparsers / gsth265parse.c
1 /* GStreamer H.265 Parser
2  * Copyright (C) 2013 Intel Corporation
3  *  Contact:Sreerenj Balachandran <sreerenj.balachandran@intel.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 <gst/base/base.h>
26 #include <gst/pbutils/pbutils.h>
27 #include "gstvideoparserselements.h"
28 #include "gsth265parse.h"
29
30 #include <string.h>
31
32 GST_DEBUG_CATEGORY (h265_parse_debug);
33 #define GST_CAT_DEFAULT h265_parse_debug
34
35 #define DEFAULT_CONFIG_INTERVAL      (0)
36
37 enum
38 {
39   PROP_0,
40   PROP_CONFIG_INTERVAL
41 };
42
43 enum
44 {
45   GST_H265_PARSE_FORMAT_NONE,
46   GST_H265_PARSE_FORMAT_HVC1,
47   GST_H265_PARSE_FORMAT_HEV1,
48   GST_H265_PARSE_FORMAT_BYTE
49 };
50
51 enum
52 {
53   GST_H265_PARSE_ALIGN_NONE = 0,
54   GST_H265_PARSE_ALIGN_NAL,
55   GST_H265_PARSE_ALIGN_AU
56 };
57
58 enum
59 {
60   GST_H265_PARSE_STATE_GOT_SPS = 1 << 0,
61   GST_H265_PARSE_STATE_GOT_PPS = 1 << 1,
62   GST_H265_PARSE_STATE_GOT_SLICE = 1 << 2,
63
64   GST_H265_PARSE_STATE_VALID_PICTURE_HEADERS = (GST_H265_PARSE_STATE_GOT_SPS |
65       GST_H265_PARSE_STATE_GOT_PPS),
66   GST_H265_PARSE_STATE_VALID_PICTURE =
67       (GST_H265_PARSE_STATE_VALID_PICTURE_HEADERS |
68       GST_H265_PARSE_STATE_GOT_SLICE)
69 };
70
71 enum
72 {
73   GST_H265_PARSE_SEI_EXPIRED = 0,
74   GST_H265_PARSE_SEI_ACTIVE = 1,
75   GST_H265_PARSE_SEI_PARSED = 2,
76 };
77
78 #define GST_H265_PARSE_STATE_VALID(parse, expected_state) \
79   (((parse)->state & (expected_state)) == (expected_state))
80
81 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
82     GST_PAD_SINK,
83     GST_PAD_ALWAYS,
84     GST_STATIC_CAPS ("video/x-h265"));
85
86 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
87     GST_PAD_SRC,
88     GST_PAD_ALWAYS,
89     GST_STATIC_CAPS ("video/x-h265, parsed = (boolean) true, "
90         "stream-format=(string) { hvc1, hev1, byte-stream }, "
91         "alignment=(string) { au, nal }"));
92
93 #define parent_class gst_h265_parse_parent_class
94 G_DEFINE_TYPE (GstH265Parse, gst_h265_parse, GST_TYPE_BASE_PARSE);
95 GST_ELEMENT_REGISTER_DEFINE_WITH_CODE (h265parse, "h265parse",
96     GST_RANK_SECONDARY, GST_TYPE_H265_PARSE,
97     videoparsers_element_init (plugin));
98
99 static void gst_h265_parse_finalize (GObject * object);
100
101 static gboolean gst_h265_parse_start (GstBaseParse * parse);
102 static gboolean gst_h265_parse_stop (GstBaseParse * parse);
103 static GstFlowReturn gst_h265_parse_handle_frame (GstBaseParse * parse,
104     GstBaseParseFrame * frame, gint * skipsize);
105 static GstFlowReturn gst_h265_parse_parse_frame (GstBaseParse * parse,
106     GstBaseParseFrame * frame);
107 static GstFlowReturn gst_h265_parse_pre_push_frame (GstBaseParse * parse,
108     GstBaseParseFrame * frame);
109
110 static void gst_h265_parse_set_property (GObject * object, guint prop_id,
111     const GValue * value, GParamSpec * pspec);
112 static void gst_h265_parse_get_property (GObject * object, guint prop_id,
113     GValue * value, GParamSpec * pspec);
114
115 static gboolean gst_h265_parse_set_caps (GstBaseParse * parse, GstCaps * caps);
116 static GstCaps *gst_h265_parse_get_caps (GstBaseParse * parse,
117     GstCaps * filter);
118 static gboolean gst_h265_parse_event (GstBaseParse * parse, GstEvent * event);
119 static gboolean gst_h265_parse_src_event (GstBaseParse * parse,
120     GstEvent * event);
121 static void
122 gst_h265_parse_process_sei_user_data (GstH265Parse * h265parse,
123     GstH265RegisteredUserData * rud);
124
125 static void
126 gst_h265_parse_class_init (GstH265ParseClass * klass)
127 {
128   GObjectClass *gobject_class = (GObjectClass *) klass;
129   GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
130   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
131
132   GST_DEBUG_CATEGORY_INIT (h265_parse_debug, "h265parse", 0, "h265 parser");
133
134   gobject_class->finalize = gst_h265_parse_finalize;
135   gobject_class->set_property = gst_h265_parse_set_property;
136   gobject_class->get_property = gst_h265_parse_get_property;
137
138   g_object_class_install_property (gobject_class, PROP_CONFIG_INTERVAL,
139       g_param_spec_int ("config-interval",
140           "VPS SPS PPS Send Interval",
141           "Send VPS, SPS and PPS Insertion Interval in seconds (sprop parameter sets "
142           "will be multiplexed in the data stream when detected.) "
143           "(0 = disabled, -1 = send with every IDR frame)",
144           -1, 3600, DEFAULT_CONFIG_INTERVAL,
145           G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
146   /* Override BaseParse vfuncs */
147   parse_class->start = GST_DEBUG_FUNCPTR (gst_h265_parse_start);
148   parse_class->stop = GST_DEBUG_FUNCPTR (gst_h265_parse_stop);
149   parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_h265_parse_handle_frame);
150   parse_class->pre_push_frame =
151       GST_DEBUG_FUNCPTR (gst_h265_parse_pre_push_frame);
152   parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_h265_parse_set_caps);
153   parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_h265_parse_get_caps);
154   parse_class->sink_event = GST_DEBUG_FUNCPTR (gst_h265_parse_event);
155   parse_class->src_event = GST_DEBUG_FUNCPTR (gst_h265_parse_src_event);
156
157   gst_element_class_add_static_pad_template (gstelement_class, &srctemplate);
158   gst_element_class_add_static_pad_template (gstelement_class, &sinktemplate);
159
160   gst_element_class_set_static_metadata (gstelement_class, "H.265 parser",
161       "Codec/Parser/Converter/Video",
162       "Parses H.265 streams",
163       "Sreerenj Balachandran <sreerenj.balachandran@intel.com>");
164 }
165
166 static void
167 gst_h265_parse_init (GstH265Parse * h265parse)
168 {
169   h265parse->frame_out = gst_adapter_new ();
170   gst_base_parse_set_pts_interpolation (GST_BASE_PARSE (h265parse), FALSE);
171   gst_base_parse_set_infer_ts (GST_BASE_PARSE (h265parse), FALSE);
172   GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (h265parse));
173   GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (h265parse));
174 }
175
176
177 static void
178 gst_h265_parse_finalize (GObject * object)
179 {
180   GstH265Parse *h265parse = GST_H265_PARSE (object);
181
182   g_object_unref (h265parse->frame_out);
183
184   G_OBJECT_CLASS (parent_class)->finalize (object);
185 }
186
187 static void
188 gst_h265_parse_reset_frame (GstH265Parse * h265parse)
189 {
190   GST_DEBUG_OBJECT (h265parse, "reset frame");
191
192   /* done parsing; reset state */
193   h265parse->current_off = -1;
194
195   h265parse->update_caps = FALSE;
196   h265parse->idr_pos = -1;
197   h265parse->sei_pos = -1;
198   h265parse->keyframe = FALSE;
199   h265parse->predicted = FALSE;
200   h265parse->bidirectional = FALSE;
201   h265parse->header = FALSE;
202   h265parse->have_vps_in_frame = FALSE;
203   h265parse->have_sps_in_frame = FALSE;
204   h265parse->have_pps_in_frame = FALSE;
205   gst_adapter_clear (h265parse->frame_out);
206 }
207
208 static void
209 gst_h265_parse_reset_stream_info (GstH265Parse * h265parse)
210 {
211   gint i;
212
213   h265parse->width = 0;
214   h265parse->height = 0;
215   h265parse->fps_num = 0;
216   h265parse->fps_den = 0;
217   h265parse->upstream_par_n = -1;
218   h265parse->upstream_par_d = -1;
219   h265parse->parsed_par_n = 0;
220   h265parse->parsed_par_n = 0;
221   h265parse->parsed_colorimetry.range = GST_VIDEO_COLOR_RANGE_UNKNOWN;
222   h265parse->parsed_colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN;
223   h265parse->parsed_colorimetry.transfer = GST_VIDEO_TRANSFER_UNKNOWN;
224   h265parse->parsed_colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_UNKNOWN;
225   h265parse->have_pps = FALSE;
226   h265parse->have_sps = FALSE;
227   h265parse->have_vps = FALSE;
228
229   h265parse->align = GST_H265_PARSE_ALIGN_NONE;
230   h265parse->format = GST_H265_PARSE_FORMAT_NONE;
231
232   h265parse->transform = FALSE;
233   h265parse->nal_length_size = 4;
234   h265parse->packetized = FALSE;
235   h265parse->push_codec = FALSE;
236   h265parse->first_frame = TRUE;
237
238   gst_buffer_replace (&h265parse->codec_data, NULL);
239   gst_buffer_replace (&h265parse->codec_data_in, NULL);
240
241   gst_h265_parse_reset_frame (h265parse);
242
243   for (i = 0; i < GST_H265_MAX_VPS_COUNT; i++)
244     gst_buffer_replace (&h265parse->vps_nals[i], NULL);
245   for (i = 0; i < GST_H265_MAX_SPS_COUNT; i++)
246     gst_buffer_replace (&h265parse->sps_nals[i], NULL);
247   for (i = 0; i < GST_H265_MAX_PPS_COUNT; i++)
248     gst_buffer_replace (&h265parse->pps_nals[i], NULL);
249
250   gst_video_mastering_display_info_init (&h265parse->mastering_display_info);
251   h265parse->mastering_display_info_state = GST_H265_PARSE_SEI_EXPIRED;
252
253   gst_video_content_light_level_init (&h265parse->content_light_level);
254   h265parse->content_light_level_state = GST_H265_PARSE_SEI_EXPIRED;
255 }
256
257 static void
258 gst_h265_parse_reset (GstH265Parse * h265parse)
259 {
260   h265parse->last_report = GST_CLOCK_TIME_NONE;
261
262   h265parse->pending_key_unit_ts = GST_CLOCK_TIME_NONE;
263   gst_event_replace (&h265parse->force_key_unit_event, NULL);
264
265   h265parse->discont = FALSE;
266   h265parse->discard_bidirectional = FALSE;
267   h265parse->marker = FALSE;
268
269   gst_h265_parse_reset_stream_info (h265parse);
270 }
271
272 static gboolean
273 gst_h265_parse_start (GstBaseParse * parse)
274 {
275   GstH265Parse *h265parse = GST_H265_PARSE (parse);
276
277   GST_DEBUG_OBJECT (parse, "start");
278   gst_h265_parse_reset (h265parse);
279
280   h265parse->nalparser = gst_h265_parser_new ();
281   h265parse->state = 0;
282
283   gst_base_parse_set_min_frame_size (parse, 5);
284
285   return TRUE;
286 }
287
288 static gboolean
289 gst_h265_parse_stop (GstBaseParse * parse)
290 {
291   GstH265Parse *h265parse = GST_H265_PARSE (parse);
292
293   GST_DEBUG_OBJECT (parse, "stop");
294   gst_h265_parse_reset (h265parse);
295
296   gst_h265_parser_free (h265parse->nalparser);
297
298   return TRUE;
299 }
300
301 static const gchar *
302 gst_h265_parse_get_string (GstH265Parse * parse, gboolean format, gint code)
303 {
304   if (format) {
305     switch (code) {
306       case GST_H265_PARSE_FORMAT_HVC1:
307         return "hvc1";
308       case GST_H265_PARSE_FORMAT_HEV1:
309         return "hev1";
310       case GST_H265_PARSE_FORMAT_BYTE:
311         return "byte-stream";
312       default:
313         return "none";
314     }
315   } else {
316     switch (code) {
317       case GST_H265_PARSE_ALIGN_NAL:
318         return "nal";
319       case GST_H265_PARSE_ALIGN_AU:
320         return "au";
321       default:
322         return "none";
323     }
324   }
325 }
326
327 static void
328 gst_h265_parse_format_from_caps (GstCaps * caps, guint * format, guint * align)
329 {
330   g_return_if_fail (gst_caps_is_fixed (caps));
331
332   GST_DEBUG ("parsing caps: %" GST_PTR_FORMAT, caps);
333
334   if (format)
335     *format = GST_H265_PARSE_FORMAT_NONE;
336
337   if (align)
338     *align = GST_H265_PARSE_ALIGN_NONE;
339
340   if (caps && gst_caps_get_size (caps) > 0) {
341     GstStructure *s = gst_caps_get_structure (caps, 0);
342     const gchar *str = NULL;
343
344     if (format) {
345       if ((str = gst_structure_get_string (s, "stream-format"))) {
346         if (strcmp (str, "hvc1") == 0)
347           *format = GST_H265_PARSE_FORMAT_HVC1;
348         else if (strcmp (str, "hev1") == 0)
349           *format = GST_H265_PARSE_FORMAT_HEV1;
350         else if (strcmp (str, "byte-stream") == 0)
351           *format = GST_H265_PARSE_FORMAT_BYTE;
352       }
353     }
354
355     if (align) {
356       if ((str = gst_structure_get_string (s, "alignment"))) {
357         if (strcmp (str, "au") == 0)
358           *align = GST_H265_PARSE_ALIGN_AU;
359         else if (strcmp (str, "nal") == 0)
360           *align = GST_H265_PARSE_ALIGN_NAL;
361       }
362     }
363   }
364 }
365
366 /* check downstream caps to configure format and alignment */
367 static void
368 gst_h265_parse_negotiate (GstH265Parse * h265parse, gint in_format,
369     GstCaps * in_caps)
370 {
371   GstCaps *caps;
372   guint format = GST_H265_PARSE_FORMAT_NONE;
373   guint align = GST_H265_PARSE_ALIGN_NONE;
374
375   g_return_if_fail ((in_caps == NULL) || gst_caps_is_fixed (in_caps));
376
377   caps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (h265parse));
378   GST_DEBUG_OBJECT (h265parse, "allowed caps: %" GST_PTR_FORMAT, caps);
379
380   /* concentrate on leading structure, since decodebin parser
381    * capsfilter always includes parser template caps */
382   if (caps) {
383     caps = gst_caps_truncate (caps);
384     GST_DEBUG_OBJECT (h265parse, "negotiating with caps: %" GST_PTR_FORMAT,
385         caps);
386   }
387
388   if (in_caps && caps) {
389     if (gst_caps_can_intersect (in_caps, caps)) {
390       GST_DEBUG_OBJECT (h265parse, "downstream accepts upstream caps");
391       gst_h265_parse_format_from_caps (in_caps, &format, &align);
392       gst_caps_unref (caps);
393       caps = NULL;
394     }
395   }
396
397   /* FIXME We could fail the negotiation immediately if caps are empty */
398   if (caps && !gst_caps_is_empty (caps)) {
399     /* fixate to avoid ambiguity with lists when parsing */
400     caps = gst_caps_fixate (caps);
401     gst_h265_parse_format_from_caps (caps, &format, &align);
402   }
403
404   /* default */
405   if (!format)
406     format = GST_H265_PARSE_FORMAT_BYTE;
407   if (!align)
408     align = GST_H265_PARSE_ALIGN_AU;
409
410   GST_DEBUG_OBJECT (h265parse, "selected format %s, alignment %s",
411       gst_h265_parse_get_string (h265parse, TRUE, format),
412       gst_h265_parse_get_string (h265parse, FALSE, align));
413
414   h265parse->format = format;
415   h265parse->align = align;
416
417   h265parse->transform = in_format != h265parse->format ||
418       align == GST_H265_PARSE_ALIGN_AU;
419
420   if (caps)
421     gst_caps_unref (caps);
422 }
423
424 static GstBuffer *
425 gst_h265_parse_wrap_nal (GstH265Parse * h265parse, guint format, guint8 * data,
426     guint size)
427 {
428   GstBuffer *buf;
429   guint nl = h265parse->nal_length_size;
430   guint32 tmp;
431
432   GST_DEBUG_OBJECT (h265parse, "nal length %d", size);
433
434   buf = gst_buffer_new_allocate (NULL, 4 + size, NULL);
435   if (format == GST_H265_PARSE_FORMAT_HVC1
436       || format == GST_H265_PARSE_FORMAT_HEV1) {
437     tmp = GUINT32_TO_BE (size << (32 - 8 * nl));
438   } else {
439     /* HACK: nl should always be 4 here, otherwise this won't work.
440      * There are legit cases where nl in hevc stream is 2, but byte-stream
441      * SC is still always 4 bytes. */
442     nl = 4;
443     tmp = GUINT32_TO_BE (1);
444   }
445
446   gst_buffer_fill (buf, 0, &tmp, sizeof (guint32));
447   gst_buffer_fill (buf, nl, data, size);
448   gst_buffer_set_size (buf, size + nl);
449
450   return buf;
451 }
452
453 static void
454 gst_h265_parser_store_nal (GstH265Parse * h265parse, guint id,
455     GstH265NalUnitType naltype, GstH265NalUnit * nalu)
456 {
457   GstBuffer *buf, **store;
458   guint size = nalu->size, store_size;
459
460   if (naltype == GST_H265_NAL_VPS) {
461     store_size = GST_H265_MAX_VPS_COUNT;
462     store = h265parse->vps_nals;
463     GST_DEBUG_OBJECT (h265parse, "storing vps %u", id);
464   } else if (naltype == GST_H265_NAL_SPS) {
465     store_size = GST_H265_MAX_SPS_COUNT;
466     store = h265parse->sps_nals;
467     GST_DEBUG_OBJECT (h265parse, "storing sps %u", id);
468   } else if (naltype == GST_H265_NAL_PPS) {
469     store_size = GST_H265_MAX_PPS_COUNT;
470     store = h265parse->pps_nals;
471     GST_DEBUG_OBJECT (h265parse, "storing pps %u", id);
472   } else
473     return;
474
475   if (id >= store_size) {
476     GST_DEBUG_OBJECT (h265parse, "unable to store nal, id out-of-range %d", id);
477     return;
478   }
479
480   buf = gst_buffer_new_allocate (NULL, size, NULL);
481   gst_buffer_fill (buf, 0, nalu->data + nalu->offset, size);
482
483   /* Indicate that buffer contain a header needed for decoding */
484   if (naltype >= GST_H265_NAL_VPS && naltype <= GST_H265_NAL_PPS)
485     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
486
487   if (store[id])
488     gst_buffer_unref (store[id]);
489
490   store[id] = buf;
491 }
492
493 #ifndef GST_DISABLE_GST_DEBUG
494 static const gchar *nal_names[] = {
495   "Slice_TRAIL_N",
496   "Slice_TRAIL_R",
497   "Slice_TSA_N",
498   "Slice_TSA_R",
499   "Slice_STSA_N",
500   "Slice_STSA_R",
501   "Slice_RADL_N",
502   "Slice_RADL_R",
503   "SLICE_RASL_N",
504   "SLICE_RASL_R",
505   "Invalid (10)",
506   "Invalid (11)",
507   "Invalid (12)",
508   "Invalid (13)",
509   "Invalid (14)",
510   "Invalid (15)",
511   "SLICE_BLA_W_LP",
512   "SLICE_BLA_W_RADL",
513   "SLICE_BLA_N_LP",
514   "SLICE_IDR_W_RADL",
515   "SLICE_IDR_N_LP",
516   "SLICE_CRA_NUT",
517   "Invalid (22)",
518   "Invalid (23)",
519   "Invalid (24)",
520   "Invalid (25)",
521   "Invalid (26)",
522   "Invalid (27)",
523   "Invalid (28)",
524   "Invalid (29)",
525   "Invalid (30)",
526   "Invalid (31)",
527   "VPS",
528   "SPS",
529   "PPS",
530   "AUD",
531   "EOS",
532   "EOB",
533   "FD",
534   "PREFIX_SEI",
535   "SUFFIX_SEI"
536 };
537
538 static const gchar *
539 _nal_name (GstH265NalUnitType nal_type)
540 {
541   if (nal_type <= GST_H265_NAL_SUFFIX_SEI)
542     return nal_names[nal_type];
543   return "Invalid";
544 }
545 #endif
546
547 static void
548 gst_h265_parse_process_sei (GstH265Parse * h265parse, GstH265NalUnit * nalu)
549 {
550   GstH265SEIMessage sei;
551   GstH265Parser *nalparser = h265parse->nalparser;
552   GstH265ParserResult pres;
553   GArray *messages;
554   guint i;
555
556   pres = gst_h265_parser_parse_sei (nalparser, nalu, &messages);
557   if (pres != GST_H265_PARSER_OK)
558     GST_WARNING_OBJECT (h265parse, "failed to parse one or more SEI message");
559
560   /* Even if pres != GST_H265_PARSER_OK, some message could have been parsed and
561    * stored in messages.
562    */
563   for (i = 0; i < messages->len; i++) {
564     sei = g_array_index (messages, GstH265SEIMessage, i);
565     switch (sei.payloadType) {
566       case GST_H265_SEI_RECOVERY_POINT:
567         GST_LOG_OBJECT (h265parse, "recovery point found: %u %u %u",
568             sei.payload.recovery_point.recovery_poc_cnt,
569             sei.payload.recovery_point.exact_match_flag,
570             sei.payload.recovery_point.broken_link_flag);
571         h265parse->keyframe = TRUE;
572         break;
573       case GST_H265_SEI_TIME_CODE:
574         memcpy (&h265parse->time_code, &sei.payload.time_code,
575             sizeof (GstH265TimeCode));
576         break;
577       case GST_H265_SEI_PIC_TIMING:
578         h265parse->sei_pic_struct = sei.payload.pic_timing.pic_struct;
579         break;
580       case GST_H265_SEI_REGISTERED_USER_DATA:
581         gst_h265_parse_process_sei_user_data (h265parse,
582             &sei.payload.registered_user_data);
583         break;
584       case GST_H265_SEI_BUF_PERIOD:
585         /* FIXME */
586         break;
587       case GST_H265_SEI_MASTERING_DISPLAY_COLOUR_VOLUME:
588       {
589         /* Precision defined by spec.
590          * See D.3.28 Mastering display colour volume SEI message semantics */
591         GstVideoMasteringDisplayInfo minfo;
592         gint j, k;
593
594         /* GstVideoMasteringDisplayInfo::display_primaries is rgb order but
595          * HEVC uses gbr order
596          * See spec D.3.28 display_primaries_x and display_primaries_y
597          */
598         for (j = 0, k = 2; j < G_N_ELEMENTS (minfo.display_primaries); j++, k++) {
599           minfo.display_primaries[j].x =
600               sei.payload.
601               mastering_display_colour_volume.display_primaries_x[k % 3];
602           minfo.display_primaries[j].y =
603               sei.payload.
604               mastering_display_colour_volume.display_primaries_y[k % 3];
605         }
606
607         minfo.white_point.x =
608             sei.payload.mastering_display_colour_volume.white_point_x;
609         minfo.white_point.y =
610             sei.payload.mastering_display_colour_volume.white_point_y;
611         minfo.max_display_mastering_luminance =
612             sei.payload.mastering_display_colour_volume.
613             max_display_mastering_luminance;
614         minfo.min_display_mastering_luminance =
615             sei.payload.mastering_display_colour_volume.
616             min_display_mastering_luminance;
617
618         GST_LOG_OBJECT (h265parse, "mastering display info found: "
619             "Red(%u, %u) "
620             "Green(%u, %u) "
621             "Blue(%u, %u) "
622             "White(%u, %u) "
623             "max_luminance(%u) "
624             "min_luminance(%u) ",
625             minfo.display_primaries[0].x, minfo.display_primaries[0].y,
626             minfo.display_primaries[1].x, minfo.display_primaries[1].y,
627             minfo.display_primaries[2].x, minfo.display_primaries[2].y,
628             minfo.white_point.x, minfo.white_point.y,
629             minfo.max_display_mastering_luminance,
630             minfo.min_display_mastering_luminance);
631
632         if (h265parse->mastering_display_info_state ==
633             GST_H265_PARSE_SEI_EXPIRED) {
634           h265parse->update_caps = TRUE;
635         } else if (!gst_video_mastering_display_info_is_equal
636             (&h265parse->mastering_display_info, &minfo)) {
637           h265parse->update_caps = TRUE;
638         }
639
640         h265parse->mastering_display_info_state = GST_H265_PARSE_SEI_PARSED;
641         h265parse->mastering_display_info = minfo;
642
643         break;
644       }
645       case GST_H265_SEI_CONTENT_LIGHT_LEVEL:
646       {
647         GstVideoContentLightLevel cll;
648
649         cll.max_content_light_level =
650             sei.payload.content_light_level.max_content_light_level;
651         cll.max_frame_average_light_level =
652             sei.payload.content_light_level.max_pic_average_light_level;
653
654         GST_LOG_OBJECT (h265parse, "content light level found: "
655             "maxCLL:(%u), maxFALL:(%u)", cll.max_content_light_level,
656             cll.max_frame_average_light_level);
657
658         if (h265parse->content_light_level_state == GST_H265_PARSE_SEI_EXPIRED) {
659           h265parse->update_caps = TRUE;
660         } else if (cll.max_content_light_level !=
661             h265parse->content_light_level.max_content_light_level ||
662             cll.max_frame_average_light_level !=
663             h265parse->content_light_level.max_frame_average_light_level) {
664           h265parse->update_caps = TRUE;
665         }
666
667         h265parse->content_light_level_state = GST_H265_PARSE_SEI_PARSED;
668         h265parse->content_light_level = cll;
669
670         break;
671       }
672       default:
673         break;
674     }
675   }
676   g_array_free (messages, TRUE);
677 }
678
679 static void
680 gst_h265_parse_process_sei_user_data (GstH265Parse * h265parse,
681     GstH265RegisteredUserData * rud)
682 {
683   guint16 provider_code;
684   GstByteReader br;
685   GstVideoParseUtilsField field = GST_VIDEO_PARSE_UTILS_FIELD_1;
686
687   /* only US country code is currently supported */
688   switch (rud->country_code) {
689     case ITU_T_T35_COUNTRY_CODE_US:
690       break;
691     default:
692       GST_LOG_OBJECT (h265parse, "Unsupported country code %d",
693           rud->country_code);
694       return;
695   }
696
697   if (rud->data == NULL || rud->size < 2)
698     return;
699
700   gst_byte_reader_init (&br, rud->data, rud->size);
701
702   provider_code = gst_byte_reader_get_uint16_be_unchecked (&br);
703
704   if (h265parse->sei_pic_struct ==
705       (guint8) GST_H265_SEI_PIC_STRUCT_BOTTOM_FIELD)
706     field = GST_VIDEO_PARSE_UTILS_FIELD_1;
707   gst_video_parse_user_data ((GstElement *) h265parse, &h265parse->user_data,
708       &br, field, provider_code);
709
710 }
711
712 /* caller guarantees 2 bytes of nal payload */
713 static gboolean
714 gst_h265_parse_process_nal (GstH265Parse * h265parse, GstH265NalUnit * nalu)
715 {
716   GstH265PPS pps = { 0, };
717   GstH265SPS sps = { 0, };
718   GstH265VPS vps = { 0, };
719   guint nal_type;
720   GstH265Parser *nalparser = h265parse->nalparser;
721   GstH265ParserResult pres = GST_H265_PARSER_ERROR;
722
723   /* nothing to do for broken input */
724   if (G_UNLIKELY (nalu->size < 2)) {
725     GST_DEBUG_OBJECT (h265parse, "not processing nal size %u", nalu->size);
726     return TRUE;
727   }
728
729   /* we have a peek as well */
730   nal_type = nalu->type;
731
732   GST_DEBUG_OBJECT (h265parse, "processing nal of type %u %s, size %u",
733       nal_type, _nal_name (nal_type), nalu->size);
734   switch (nal_type) {
735     case GST_H265_NAL_VPS:
736       /* It is not mandatory to have VPS in the stream. But it might
737        * be needed for other extensions like svc */
738       pres = gst_h265_parser_parse_vps (nalparser, nalu, &vps);
739       if (pres != GST_H265_PARSER_OK) {
740         GST_WARNING_OBJECT (h265parse, "failed to parse VPS");
741         return FALSE;
742       }
743
744       GST_DEBUG_OBJECT (h265parse, "triggering src caps check");
745       h265parse->update_caps = TRUE;
746       h265parse->have_vps = TRUE;
747       h265parse->have_vps_in_frame = TRUE;
748       if (h265parse->push_codec && h265parse->have_pps) {
749         /* VPS/SPS/PPS found in stream before the first pre_push_frame, no need
750          * to forcibly push at start */
751         GST_INFO_OBJECT (h265parse, "have VPS/SPS/PPS in stream");
752         h265parse->push_codec = FALSE;
753         h265parse->have_vps = FALSE;
754         h265parse->have_sps = FALSE;
755         h265parse->have_pps = FALSE;
756       }
757
758       gst_h265_parser_store_nal (h265parse, vps.id, nal_type, nalu);
759       h265parse->header = TRUE;
760       break;
761     case GST_H265_NAL_SPS:
762       /* reset state, everything else is obsolete */
763       h265parse->state &= GST_H265_PARSE_STATE_GOT_PPS;
764
765       pres = gst_h265_parser_parse_sps (nalparser, nalu, &sps, TRUE);
766
767
768       /* arranged for a fallback sps.id, so use that one and only warn */
769       if (pres != GST_H265_PARSER_OK) {
770         /* try to not parse VUI */
771         pres = gst_h265_parser_parse_sps (nalparser, nalu, &sps, FALSE);
772         if (pres != GST_H265_PARSER_OK) {
773           GST_WARNING_OBJECT (h265parse, "failed to parse SPS:");
774           h265parse->state |= GST_H265_PARSE_STATE_GOT_SPS;
775           h265parse->header = TRUE;
776           return FALSE;
777         }
778         GST_WARNING_OBJECT (h265parse,
779             "failed to parse VUI of SPS, ignore VUI");
780       }
781
782       GST_DEBUG_OBJECT (h265parse, "triggering src caps check");
783       h265parse->update_caps = TRUE;
784       h265parse->have_sps = TRUE;
785       h265parse->have_sps_in_frame = TRUE;
786       if (h265parse->push_codec && h265parse->have_pps) {
787         /* SPS and PPS found in stream before the first pre_push_frame, no need
788          * to forcibly push at start */
789         GST_INFO_OBJECT (h265parse, "have SPS/PPS in stream");
790         h265parse->push_codec = FALSE;
791         h265parse->have_sps = FALSE;
792         h265parse->have_pps = FALSE;
793       }
794
795       gst_h265_parser_store_nal (h265parse, sps.id, nal_type, nalu);
796       h265parse->header = TRUE;
797       h265parse->state |= GST_H265_PARSE_STATE_GOT_SPS;
798       break;
799     case GST_H265_NAL_PPS:
800       pres = gst_h265_parser_parse_pps (nalparser, nalu, &pps);
801
802       /* arranged for a fallback pps.id, so use that one and only warn */
803       if (pres != GST_H265_PARSER_OK) {
804         GST_WARNING_OBJECT (h265parse, "failed to parse PPS:");
805         if (pres != GST_H265_PARSER_BROKEN_LINK)
806           return FALSE;
807       }
808
809       /* parameters might have changed, force caps check */
810       if (!h265parse->have_pps) {
811         GST_DEBUG_OBJECT (h265parse, "triggering src caps check");
812         h265parse->update_caps = TRUE;
813       }
814       h265parse->have_pps = TRUE;
815       h265parse->have_pps_in_frame = TRUE;
816       if (h265parse->push_codec && h265parse->have_sps) {
817         /* SPS and PPS found in stream before the first pre_push_frame, no need
818          * to forcibly push at start */
819         GST_INFO_OBJECT (h265parse, "have SPS/PPS in stream");
820         h265parse->push_codec = FALSE;
821         h265parse->have_sps = FALSE;
822         h265parse->have_pps = FALSE;
823       }
824
825       gst_h265_parser_store_nal (h265parse, pps.id, nal_type, nalu);
826       h265parse->header = TRUE;
827       h265parse->state |= GST_H265_PARSE_STATE_GOT_PPS;
828       break;
829     case GST_H265_NAL_PREFIX_SEI:
830     case GST_H265_NAL_SUFFIX_SEI:
831       /* expected state: got-sps */
832       if (!GST_H265_PARSE_STATE_VALID (h265parse, GST_H265_PARSE_STATE_GOT_SPS))
833         return FALSE;
834
835       h265parse->header = TRUE;
836
837       gst_h265_parse_process_sei (h265parse, nalu);
838
839       /* mark SEI pos */
840       if (nal_type == GST_H265_NAL_PREFIX_SEI && h265parse->sei_pos == -1) {
841         if (h265parse->transform)
842           h265parse->sei_pos = gst_adapter_available (h265parse->frame_out);
843         else
844           h265parse->sei_pos = nalu->sc_offset;
845         GST_DEBUG_OBJECT (h265parse, "marking SEI in frame at offset %d",
846             h265parse->sei_pos);
847       }
848       break;
849
850     case GST_H265_NAL_SLICE_TRAIL_N:
851     case GST_H265_NAL_SLICE_TRAIL_R:
852     case GST_H265_NAL_SLICE_TSA_N:
853     case GST_H265_NAL_SLICE_TSA_R:
854     case GST_H265_NAL_SLICE_STSA_N:
855     case GST_H265_NAL_SLICE_STSA_R:
856     case GST_H265_NAL_SLICE_RADL_N:
857     case GST_H265_NAL_SLICE_RADL_R:
858     case GST_H265_NAL_SLICE_RASL_N:
859     case GST_H265_NAL_SLICE_RASL_R:
860     case GST_H265_NAL_SLICE_BLA_W_LP:
861     case GST_H265_NAL_SLICE_BLA_W_RADL:
862     case GST_H265_NAL_SLICE_BLA_N_LP:
863     case GST_H265_NAL_SLICE_IDR_W_RADL:
864     case GST_H265_NAL_SLICE_IDR_N_LP:
865     case GST_H265_NAL_SLICE_CRA_NUT:
866     {
867       GstH265SliceHdr slice;
868       gboolean is_irap;
869       gboolean no_rasl_output_flag = FALSE;
870
871       /* expected state: got-sps|got-pps (valid picture headers) */
872       h265parse->state &= GST_H265_PARSE_STATE_VALID_PICTURE_HEADERS;
873       if (!GST_H265_PARSE_STATE_VALID (h265parse,
874               GST_H265_PARSE_STATE_VALID_PICTURE_HEADERS))
875         return FALSE;
876
877       /* This is similar to the GOT_SLICE state, but is only reset when the
878        * AU is complete. This is used to keep track of AU */
879       h265parse->picture_start = TRUE;
880
881       pres = gst_h265_parser_parse_slice_hdr (nalparser, nalu, &slice);
882
883       if (pres == GST_H265_PARSER_OK) {
884         if (GST_H265_IS_I_SLICE (&slice))
885           h265parse->keyframe = TRUE;
886         else if (GST_H265_IS_P_SLICE (&slice))
887           h265parse->predicted = TRUE;
888         else if (GST_H265_IS_B_SLICE (&slice))
889           h265parse->bidirectional = TRUE;
890
891         h265parse->state |= GST_H265_PARSE_STATE_GOT_SLICE;
892       }
893       if (slice.first_slice_segment_in_pic_flag == 1)
894         GST_DEBUG_OBJECT (h265parse,
895             "frame start, first_slice_segment_in_pic_flag = 1");
896
897       GST_DEBUG_OBJECT (h265parse,
898           "parse result %d, first slice_segment: %u, slice type: %u",
899           pres, slice.first_slice_segment_in_pic_flag, slice.type);
900
901       gst_h265_slice_hdr_free (&slice);
902
903       /* FIXME: NoRaslOutputFlag can be equal to 1 for CRA if
904        * 1) the first AU in bitstream is CRA
905        * 2) or the first AU following EOS nal is CRA
906        * 3) or it has HandleCraAsBlaFlag equal to 1 */
907       if (GST_H265_IS_NAL_TYPE_IDR (nal_type)) {
908         /* NoRaslOutputFlag is equal to 1 for each IDR */
909         no_rasl_output_flag = TRUE;
910       } else if (GST_H265_IS_NAL_TYPE_BLA (nal_type)) {
911         /* NoRaslOutputFlag is equal to 1 for each BLA */
912         no_rasl_output_flag = TRUE;
913       }
914
915       is_irap = GST_H265_IS_NAL_TYPE_IRAP (nal_type);
916
917       if (no_rasl_output_flag && is_irap
918           && slice.first_slice_segment_in_pic_flag == 1) {
919         if (h265parse->mastering_display_info_state ==
920             GST_H265_PARSE_SEI_PARSED)
921           h265parse->mastering_display_info_state = GST_H265_PARSE_SEI_ACTIVE;
922         else if (h265parse->mastering_display_info_state ==
923             GST_H265_PARSE_SEI_ACTIVE)
924           h265parse->mastering_display_info_state = GST_H265_PARSE_SEI_EXPIRED;
925
926         if (h265parse->content_light_level_state == GST_H265_PARSE_SEI_PARSED)
927           h265parse->content_light_level_state = GST_H265_PARSE_SEI_ACTIVE;
928         else if (h265parse->content_light_level_state ==
929             GST_H265_PARSE_SEI_ACTIVE)
930           h265parse->content_light_level_state = GST_H265_PARSE_SEI_EXPIRED;
931       }
932       if (G_LIKELY (!is_irap && !h265parse->push_codec))
933         break;
934
935       /* if we need to sneak codec NALs into the stream,
936        * this is a good place, so fake it as IDR
937        * (which should be at start anyway) */
938       /* mark where config needs to go if interval expired */
939       /* mind replacement buffer if applicable */
940       if (h265parse->idr_pos == -1) {
941         if (h265parse->transform)
942           h265parse->idr_pos = gst_adapter_available (h265parse->frame_out);
943         else
944           h265parse->idr_pos = nalu->sc_offset;
945         GST_DEBUG_OBJECT (h265parse, "marking IDR in frame at offset %d",
946             h265parse->idr_pos);
947       }
948       /* if SEI preceeds (faked) IDR, then we have to insert config there */
949       if (h265parse->sei_pos >= 0 && h265parse->idr_pos > h265parse->sei_pos) {
950         h265parse->idr_pos = h265parse->sei_pos;
951         GST_DEBUG_OBJECT (h265parse, "moved IDR mark to SEI position %d",
952             h265parse->idr_pos);
953       }
954       break;
955     }
956     case GST_H265_NAL_AUD:
957     default:
958       /* Just accumulate AU Delimiter, whether it's before SPS or not */
959       pres = gst_h265_parser_parse_nal (nalparser, nalu);
960       if (pres != GST_H265_PARSER_OK)
961         return FALSE;
962       break;
963   }
964
965   /* if HEVC output needed, collect properly prefixed nal in adapter,
966    * and use that to replace outgoing buffer data later on */
967   if (h265parse->transform) {
968     GstBuffer *buf;
969
970     GST_LOG_OBJECT (h265parse, "collecting NAL in HEVC frame");
971     buf = gst_h265_parse_wrap_nal (h265parse, h265parse->format,
972         nalu->data + nalu->offset, nalu->size);
973     gst_adapter_push (h265parse->frame_out, buf);
974   }
975
976   return TRUE;
977 }
978
979 /* caller guarantees at least 3 bytes of nal payload for each nal
980  * returns TRUE if next_nal indicates that nal terminates an AU */
981 static inline gboolean
982 gst_h265_parse_collect_nal (GstH265Parse * h265parse, const guint8 * data,
983     guint size, GstH265NalUnit * nalu)
984 {
985   GstH265NalUnitType nal_type = nalu->type;
986   gboolean complete;
987
988   /* determine if AU complete */
989   GST_LOG_OBJECT (h265parse, "next nal type: %d %s (picture started %i)",
990       nal_type, _nal_name (nal_type), h265parse->picture_start);
991
992   /* consider a coded slices (IRAP or not) to start a picture,
993    * (so ending the previous one) if first_slice_segment_in_pic_flag == 1*/
994   complete = h265parse->picture_start && ((nal_type >= GST_H265_NAL_VPS
995           && nal_type <= GST_H265_NAL_AUD)
996       || nal_type == GST_H265_NAL_PREFIX_SEI || (nal_type >= 41
997           && nal_type <= 44) || (nal_type >= 48 && nal_type <= 55));
998
999   /* Any VCL Nal unit with first_slice_segment_in_pic_flag == 1 considered start of frame */
1000   if (nalu->size > nalu->header_bytes) {
1001     complete |= h265parse->picture_start
1002         && (((nal_type >= GST_H265_NAL_SLICE_TRAIL_N
1003                 && nal_type <= GST_H265_NAL_SLICE_RASL_R)
1004             || GST_H265_IS_NAL_TYPE_IRAP (nal_type))
1005         && (nalu->data[nalu->offset + 2] & 0x80));
1006   }
1007
1008   GST_LOG_OBJECT (h265parse, "au complete: %d", complete);
1009
1010   if (complete)
1011     h265parse->picture_start = FALSE;
1012
1013   return complete;
1014 }
1015
1016 static GstFlowReturn
1017 gst_h265_parse_handle_frame_packetized (GstBaseParse * parse,
1018     GstBaseParseFrame * frame)
1019 {
1020   GstH265Parse *h265parse = GST_H265_PARSE (parse);
1021   GstBuffer *buffer = frame->buffer;
1022   GstFlowReturn ret = GST_FLOW_OK;
1023   GstH265ParserResult parse_res;
1024   GstH265NalUnit nalu;
1025   const guint nl = h265parse->nal_length_size;
1026   GstMapInfo map;
1027   gint left;
1028
1029   if (nl < 1 || nl > 4) {
1030     GST_DEBUG_OBJECT (h265parse, "insufficient data to split input");
1031     return GST_FLOW_NOT_NEGOTIATED;
1032   }
1033
1034   /* need to save buffer from invalidation upon _finish_frame */
1035   if (h265parse->split_packetized)
1036     buffer = gst_buffer_copy (frame->buffer);
1037
1038   gst_buffer_map (buffer, &map, GST_MAP_READ);
1039
1040   left = map.size;
1041
1042   GST_LOG_OBJECT (h265parse,
1043       "processing packet buffer of size %" G_GSIZE_FORMAT, map.size);
1044
1045   parse_res = gst_h265_parser_identify_nalu_hevc (h265parse->nalparser,
1046       map.data, 0, map.size, nl, &nalu);
1047
1048   while (parse_res == GST_H265_PARSER_OK) {
1049     GST_DEBUG_OBJECT (h265parse, "HEVC nal offset %d", nalu.offset + nalu.size);
1050
1051     /* either way, have a look at it */
1052     gst_h265_parse_process_nal (h265parse, &nalu);
1053
1054     /* dispatch per NALU if needed */
1055     if (h265parse->split_packetized) {
1056       GstBaseParseFrame tmp_frame;
1057
1058       gst_base_parse_frame_init (&tmp_frame);
1059       tmp_frame.flags |= frame->flags;
1060       tmp_frame.offset = frame->offset;
1061       tmp_frame.overhead = frame->overhead;
1062       tmp_frame.buffer = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL,
1063           nalu.offset, nalu.size);
1064       /* Don't lose timestamp when offset is not 0. */
1065       GST_BUFFER_PTS (tmp_frame.buffer) = GST_BUFFER_PTS (buffer);
1066       GST_BUFFER_DTS (tmp_frame.buffer) = GST_BUFFER_DTS (buffer);
1067       GST_BUFFER_DURATION (tmp_frame.buffer) = GST_BUFFER_DURATION (buffer);
1068
1069       /* Set marker on last packet */
1070       if (nl + nalu.size == left) {
1071         if (GST_BUFFER_FLAG_IS_SET (frame->buffer, GST_BUFFER_FLAG_MARKER))
1072           h265parse->marker = TRUE;
1073       }
1074
1075       /* note we don't need to come up with a sub-buffer, since
1076        * subsequent code only considers input buffer's metadata.
1077        * Real data is either taken from input by baseclass or
1078        * a replacement output buffer is provided anyway. */
1079       gst_h265_parse_parse_frame (parse, &tmp_frame);
1080       ret = gst_base_parse_finish_frame (parse, &tmp_frame, nl + nalu.size);
1081       left -= nl + nalu.size;
1082     }
1083
1084     parse_res = gst_h265_parser_identify_nalu_hevc (h265parse->nalparser,
1085         map.data, nalu.offset + nalu.size, map.size, nl, &nalu);
1086   }
1087
1088   gst_buffer_unmap (buffer, &map);
1089
1090   if (!h265parse->split_packetized) {
1091     h265parse->marker = TRUE;
1092     gst_h265_parse_parse_frame (parse, frame);
1093     ret = gst_base_parse_finish_frame (parse, frame, map.size);
1094   } else {
1095     gst_buffer_unref (buffer);
1096     if (G_UNLIKELY (left)) {
1097       /* should not be happening for nice HEVC */
1098       GST_WARNING_OBJECT (parse, "skipping leftover HEVC data %d", left);
1099       frame->flags |= GST_BASE_PARSE_FRAME_FLAG_DROP;
1100       ret = gst_base_parse_finish_frame (parse, frame, map.size);
1101     }
1102   }
1103
1104   if (parse_res == GST_H265_PARSER_NO_NAL_END ||
1105       parse_res == GST_H265_PARSER_BROKEN_DATA) {
1106
1107     if (h265parse->split_packetized) {
1108       GST_ELEMENT_ERROR (h265parse, STREAM, FAILED, (NULL),
1109           ("invalid HEVC input data"));
1110
1111       return GST_FLOW_ERROR;
1112     } else {
1113       /* do not meddle to much in this case */
1114       GST_DEBUG_OBJECT (h265parse, "parsing packet failed");
1115     }
1116   }
1117
1118   return ret;
1119 }
1120
1121 static GstFlowReturn
1122 gst_h265_parse_handle_frame (GstBaseParse * parse,
1123     GstBaseParseFrame * frame, gint * skipsize)
1124 {
1125   GstH265Parse *h265parse = GST_H265_PARSE (parse);
1126   GstBuffer *buffer = frame->buffer;
1127   GstMapInfo map;
1128   guint8 *data;
1129   gsize size;
1130   gint current_off = 0;
1131   gboolean drain, nonext;
1132   GstH265Parser *nalparser = h265parse->nalparser;
1133   GstH265NalUnit nalu;
1134   GstH265ParserResult pres;
1135   gint framesize;
1136
1137   if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (frame->buffer,
1138               GST_BUFFER_FLAG_DISCONT))) {
1139     h265parse->discont = TRUE;
1140   }
1141
1142   /* delegate in packetized case, no skipping should be needed */
1143   if (h265parse->packetized)
1144     return gst_h265_parse_handle_frame_packetized (parse, frame);
1145
1146   gst_buffer_map (buffer, &map, GST_MAP_READ);
1147   data = map.data;
1148   size = map.size;
1149
1150   /* expect at least 3 bytes start_code, and 2 bytes NALU header.
1151    * the length of the NALU payload can be zero.
1152    * (e.g. EOS/EOB placed at the end of an AU.) */
1153   if (G_UNLIKELY (size < 5)) {
1154     gst_buffer_unmap (buffer, &map);
1155     *skipsize = 1;
1156     return GST_FLOW_OK;
1157   }
1158
1159   /* need to configure aggregation */
1160   if (G_UNLIKELY (h265parse->format == GST_H265_PARSE_FORMAT_NONE))
1161     gst_h265_parse_negotiate (h265parse, GST_H265_PARSE_FORMAT_BYTE, NULL);
1162
1163   /* avoid stale cached parsing state */
1164   if (frame->flags & GST_BASE_PARSE_FRAME_FLAG_NEW_FRAME) {
1165     GST_LOG_OBJECT (h265parse, "parsing new frame");
1166     gst_h265_parse_reset_frame (h265parse);
1167   } else {
1168     GST_LOG_OBJECT (h265parse, "resuming frame parsing");
1169   }
1170
1171   /* Always consume the entire input buffer when in_align == ALIGN_AU */
1172   drain = GST_BASE_PARSE_DRAINING (parse)
1173       || h265parse->in_align == GST_H265_PARSE_ALIGN_AU;
1174   nonext = FALSE;
1175
1176   current_off = h265parse->current_off;
1177   if (current_off < 0)
1178     current_off = 0;
1179
1180   /* The parser is being drain, but no new data was added, just prentend this
1181    * AU is complete */
1182   if (drain && current_off == size) {
1183     GST_DEBUG_OBJECT (h265parse, "draining with no new data");
1184     nalu.size = 0;
1185     nalu.offset = current_off;
1186     goto end;
1187   }
1188
1189   g_assert (current_off < size);
1190   GST_DEBUG_OBJECT (h265parse, "last parse position %d", current_off);
1191
1192   /* check for initial skip */
1193   if (h265parse->current_off == -1) {
1194     pres =
1195         gst_h265_parser_identify_nalu_unchecked (nalparser, data, current_off,
1196         size, &nalu);
1197     switch (pres) {
1198       case GST_H265_PARSER_OK:
1199         if (nalu.sc_offset > 0) {
1200           *skipsize = nalu.sc_offset;
1201           goto skip;
1202         }
1203         break;
1204       case GST_H265_PARSER_NO_NAL:
1205         /* start code may have up to 4 bytes, and we may also get that return
1206          * value if only one of the two header bytes are present, make sure
1207          * not to skip too much */
1208         *skipsize = size - 5;
1209         goto skip;
1210       default:
1211         /* should not really occur either */
1212         GST_ELEMENT_ERROR (h265parse, STREAM, FORMAT,
1213             ("Error parsing H.265 stream"), ("Invalid H.265 stream"));
1214         goto invalid_stream;
1215     }
1216
1217     /* Ensure we use the TS of the first NAL. This avoids broken timestamp in
1218      * the case of a miss-placed filler byte. */
1219     gst_base_parse_set_ts_at_offset (parse, nalu.offset);
1220   }
1221
1222   while (TRUE) {
1223     pres =
1224         gst_h265_parser_identify_nalu (nalparser, data, current_off, size,
1225         &nalu);
1226
1227     switch (pres) {
1228       case GST_H265_PARSER_OK:
1229         GST_DEBUG_OBJECT (h265parse, "complete nal (offset, size): (%u, %u) ",
1230             nalu.offset, nalu.size);
1231         break;
1232       case GST_H265_PARSER_NO_NAL_END:
1233         /* In NAL alignment, assume the NAL is complete */
1234         if (h265parse->in_align == GST_H265_PARSE_ALIGN_NAL ||
1235             h265parse->in_align == GST_H265_PARSE_ALIGN_AU) {
1236           nonext = TRUE;
1237           nalu.size = size - nalu.offset;
1238           break;
1239         }
1240         GST_DEBUG_OBJECT (h265parse, "not a complete nal found at offset %u",
1241             nalu.offset);
1242         /* if draining, accept it as complete nal */
1243         if (drain) {
1244           nonext = TRUE;
1245           nalu.size = size - nalu.offset;
1246           GST_DEBUG_OBJECT (h265parse, "draining, accepting with size %u",
1247               nalu.size);
1248           /* if it's not too short at least */
1249           if (nalu.size < 3)
1250             goto broken;
1251           break;
1252         }
1253         /* otherwise need more */
1254         goto more;
1255       case GST_H265_PARSER_BROKEN_LINK:
1256         GST_ELEMENT_ERROR (h265parse, STREAM, FORMAT,
1257             ("Error parsing H.265 stream"),
1258             ("The link to structure needed for the parsing couldn't be found"));
1259         goto invalid_stream;
1260       case GST_H265_PARSER_ERROR:
1261         /* should not really occur either */
1262         GST_ELEMENT_ERROR (h265parse, STREAM, FORMAT,
1263             ("Error parsing H.265 stream"), ("Invalid H.265 stream"));
1264         goto invalid_stream;
1265       case GST_H265_PARSER_NO_NAL:
1266         GST_ELEMENT_ERROR (h265parse, STREAM, FORMAT,
1267             ("Error parsing H.265 stream"), ("No H.265 NAL unit found"));
1268         goto invalid_stream;
1269       case GST_H265_PARSER_BROKEN_DATA:
1270         GST_WARNING_OBJECT (h265parse, "input stream is corrupt; "
1271             "it contains a NAL unit of length %u", nalu.size);
1272       broken:
1273         /* broken nal at start -> arrange to skip it,
1274          * otherwise have it terminate current au
1275          * (and so it will be skipped on next frame round) */
1276         if (current_off == 0) {
1277           GST_DEBUG_OBJECT (h265parse, "skipping broken nal");
1278           *skipsize = nalu.offset;
1279           goto skip;
1280         } else {
1281           GST_DEBUG_OBJECT (h265parse, "terminating au");
1282           nalu.size = 0;
1283           nalu.offset = nalu.sc_offset;
1284           goto end;
1285         }
1286       default:
1287         g_assert_not_reached ();
1288         break;
1289     }
1290
1291     GST_DEBUG_OBJECT (h265parse, "%p complete nal found. Off: %u, Size: %u",
1292         data, nalu.offset, nalu.size);
1293
1294     if (gst_h265_parse_collect_nal (h265parse, data, size, &nalu)) {
1295       /* complete current frame, if it exist */
1296       if (current_off > 0) {
1297         nalu.size = 0;
1298         nalu.offset = nalu.sc_offset;
1299         h265parse->marker = TRUE;
1300         break;
1301       }
1302     }
1303
1304     if (!gst_h265_parse_process_nal (h265parse, &nalu)) {
1305       GST_WARNING_OBJECT (h265parse,
1306           "broken/invalid nal Type: %d %s, Size: %u will be dropped",
1307           nalu.type, _nal_name (nalu.type), nalu.size);
1308       *skipsize = nalu.size;
1309       goto skip;
1310     }
1311
1312     /* Do not push immediatly if we don't have all headers. This ensure that
1313      * our caps are complete, avoiding a renegotiation */
1314     if (h265parse->align == GST_H265_PARSE_ALIGN_NAL &&
1315         !GST_H265_PARSE_STATE_VALID (h265parse,
1316             GST_H265_PARSE_STATE_VALID_PICTURE_HEADERS))
1317       frame->flags |= GST_BASE_PARSE_FRAME_FLAG_QUEUE;
1318
1319     if (nonext) {
1320       /* If there is a marker flag, or input is AU, we know this is complete */
1321       if (GST_BUFFER_FLAG_IS_SET (frame->buffer, GST_BUFFER_FLAG_MARKER) ||
1322           h265parse->in_align == GST_H265_PARSE_ALIGN_AU) {
1323         h265parse->marker = TRUE;
1324         break;
1325       }
1326
1327       /* or if we are draining or producing NALs */
1328       if (drain || h265parse->align == GST_H265_PARSE_ALIGN_NAL)
1329         break;
1330
1331       current_off = nalu.offset + nalu.size;
1332       goto more;
1333     }
1334
1335     /* If the output is NAL, we are done */
1336     if (h265parse->align == GST_H265_PARSE_ALIGN_NAL)
1337       break;
1338
1339     GST_DEBUG_OBJECT (h265parse, "Looking for more");
1340     current_off = nalu.offset + nalu.size;
1341
1342     /* expect at least 3 bytes start_code, and 2 bytes NALU header.
1343      * the length of the NALU payload can be zero.
1344      * (e.g. EOS/EOB placed at the end of an AU.) */
1345     if (G_UNLIKELY (size - current_off < 5)) {
1346       /* Finish the frame if there is no more data in the stream */
1347       if (drain)
1348         break;
1349
1350       goto more;
1351     }
1352   }
1353
1354 end:
1355   framesize = nalu.offset + nalu.size;
1356
1357   gst_buffer_unmap (buffer, &map);
1358
1359   gst_h265_parse_parse_frame (parse, frame);
1360
1361   return gst_base_parse_finish_frame (parse, frame, framesize);
1362
1363 more:
1364   *skipsize = 0;
1365
1366   /* Restart parsing from here next time */
1367   if (current_off > 0)
1368     h265parse->current_off = current_off;
1369
1370   /* Fall-through. */
1371 out:
1372   gst_buffer_unmap (buffer, &map);
1373   return GST_FLOW_OK;
1374
1375 skip:
1376   GST_DEBUG_OBJECT (h265parse, "skipping %d", *skipsize);
1377   /* If we are collecting access units, we need to preserve the initial
1378    * config headers (SPS, PPS et al.) and only reset the frame if another
1379    * slice NAL was received. This means that broken pictures are discarded */
1380   if (h265parse->align != GST_H265_PARSE_ALIGN_AU ||
1381       !(h265parse->state & GST_H265_PARSE_STATE_VALID_PICTURE_HEADERS) ||
1382       (h265parse->state & GST_H265_PARSE_STATE_GOT_SLICE))
1383     gst_h265_parse_reset_frame (h265parse);
1384   goto out;
1385
1386 invalid_stream:
1387   gst_buffer_unmap (buffer, &map);
1388   return GST_FLOW_ERROR;
1389 }
1390
1391 /* byte together hevc codec data based on collected pps and sps so far */
1392 static GstBuffer *
1393 gst_h265_parse_make_codec_data (GstH265Parse * h265parse)
1394 {
1395   GstBuffer *buf, *nal;
1396   gint i, j, k = 0;
1397   guint vps_size = 0, sps_size = 0, pps_size = 0;
1398   guint num_vps = 0, num_sps = 0, num_pps = 0;
1399   gboolean found = FALSE;
1400   GstMapInfo map;
1401   guint8 *data;
1402   gint nl;
1403   guint8 num_arrays = 0;
1404   GstH265SPS *sps = NULL;
1405   guint16 min_spatial_segmentation_idc = 0;
1406   GstH265ProfileTierLevel *pft;
1407
1408   /* only nal payload in stored nals */
1409   /* Fixme: Current implementation is not embedding SEI in codec_data */
1410   for (i = 0; i < GST_H265_MAX_VPS_COUNT; i++) {
1411     if ((nal = h265parse->vps_nals[i])) {
1412       num_vps++;
1413       /* size bytes also count */
1414       vps_size += gst_buffer_get_size (nal) + 2;
1415     }
1416   }
1417   if (num_vps > 0)
1418     num_arrays++;
1419
1420   for (i = 0; i < GST_H265_MAX_SPS_COUNT; i++) {
1421     if ((nal = h265parse->sps_nals[i])) {
1422       num_sps++;
1423       /* size bytes also count */
1424       sps_size += gst_buffer_get_size (nal) + 2;
1425       found = TRUE;
1426     }
1427   }
1428   if (num_sps > 0)
1429     num_arrays++;
1430
1431   for (i = 0; i < GST_H265_MAX_PPS_COUNT; i++) {
1432     if ((nal = h265parse->pps_nals[i])) {
1433       num_pps++;
1434       /* size bytes also count */
1435       pps_size += gst_buffer_get_size (nal) + 2;
1436     }
1437   }
1438   if (num_pps > 0)
1439     num_arrays++;
1440
1441   GST_DEBUG_OBJECT (h265parse,
1442       "constructing codec_data: num_vps =%d num_sps=%d, num_pps=%d", num_vps,
1443       num_sps, num_pps);
1444
1445   if (!found)
1446     return NULL;
1447
1448   sps = h265parse->nalparser->last_sps;
1449   if (!sps)
1450     return NULL;
1451
1452   buf =
1453       gst_buffer_new_allocate (NULL,
1454       23 + (3 * num_arrays) + vps_size + sps_size + pps_size, NULL);
1455   gst_buffer_map (buf, &map, GST_MAP_WRITE);
1456   data = map.data;
1457   memset (data, 0, map.size);
1458   nl = h265parse->nal_length_size;
1459
1460   pft = &sps->profile_tier_level;
1461   if (sps->vui_parameters_present_flag)
1462     min_spatial_segmentation_idc = sps->vui_params.min_spatial_segmentation_idc;
1463
1464   /* HEVCDecoderConfigurationVersion = 1
1465    * profile_space | tier_flat | profile_idc |
1466    * profile_compatibility_flags | constraint_indicator_flags |
1467    * level_idc */
1468   data[0] = 1;
1469   data[1] =
1470       (pft->profile_space << 5) | (pft->tier_flag << 5) | pft->profile_idc;
1471   for (i = 2; i < 6; i++) {
1472     for (j = 7; j >= 0; j--) {
1473       data[i] |= (pft->profile_compatibility_flag[k] << j);
1474       k++;
1475     }
1476   }
1477
1478   data[6] =
1479       (pft->progressive_source_flag << 7) |
1480       (pft->interlaced_source_flag << 6) |
1481       (pft->non_packed_constraint_flag << 5) |
1482       (pft->frame_only_constraint_flag << 4) |
1483       (pft->max_12bit_constraint_flag << 3) |
1484       (pft->max_10bit_constraint_flag << 2) |
1485       (pft->max_8bit_constraint_flag << 1) |
1486       (pft->max_422chroma_constraint_flag);
1487
1488   data[7] =
1489       (pft->max_420chroma_constraint_flag << 7) |
1490       (pft->max_monochrome_constraint_flag << 6) |
1491       (pft->intra_constraint_flag << 5) |
1492       (pft->one_picture_only_constraint_flag << 4) |
1493       (pft->lower_bit_rate_constraint_flag << 3) |
1494       (pft->max_14bit_constraint_flag << 2);
1495
1496   data[12] = pft->level_idc;
1497   /* min_spatial_segmentation_idc */
1498   GST_WRITE_UINT16_BE (data + 13, min_spatial_segmentation_idc);
1499   data[13] |= 0xf0;
1500   data[15] = 0xfc;              /* keeping parrallelismType as zero (unknown) */
1501   data[16] = 0xfc | sps->chroma_format_idc;
1502   data[17] = 0xf8 | sps->bit_depth_luma_minus8;
1503   data[18] = 0xf8 | sps->bit_depth_chroma_minus8;
1504   data[19] = 0x00;              /* keep avgFrameRate as unspecified */
1505   data[20] = 0x00;              /* keep avgFrameRate as unspecified */
1506   /* constFrameRate(2 bits): 0, stream may or may not be of constant framerate
1507    * numTemporalLayers (3 bits): number of temporal layers, value from SPS
1508    * TemporalIdNested (1 bit): sps_temporal_id_nesting_flag from SPS
1509    * lengthSizeMinusOne (2 bits): plus 1 indicates the length of the NALUnitLength */
1510   data[21] =
1511       0x00 | ((sps->max_sub_layers_minus1 +
1512           1) << 3) | (sps->temporal_id_nesting_flag << 2) | (nl - 1);
1513   GST_WRITE_UINT8 (data + 22, num_arrays);      /* numOfArrays */
1514
1515   data += 23;
1516
1517   /* VPS */
1518   if (num_vps > 0) {
1519     /* array_completeness | reserved_zero bit | nal_unit_type */
1520     data[0] = 0x00 | 0x20;
1521     data++;
1522
1523     GST_WRITE_UINT16_BE (data, num_vps);
1524     data += 2;
1525
1526     for (i = 0; i < GST_H265_MAX_VPS_COUNT; i++) {
1527       if ((nal = h265parse->vps_nals[i])) {
1528         gsize nal_size = gst_buffer_get_size (nal);
1529         GST_WRITE_UINT16_BE (data, nal_size);
1530         gst_buffer_extract (nal, 0, data + 2, nal_size);
1531         data += 2 + nal_size;
1532       }
1533     }
1534   }
1535
1536   /* SPS */
1537   if (num_sps > 0) {
1538     /* array_completeness | reserved_zero bit | nal_unit_type */
1539     data[0] = 0x00 | 0x21;
1540     data++;
1541
1542     GST_WRITE_UINT16_BE (data, num_sps);
1543     data += 2;
1544
1545     for (i = 0; i < GST_H265_MAX_SPS_COUNT; i++) {
1546       if ((nal = h265parse->sps_nals[i])) {
1547         gsize nal_size = gst_buffer_get_size (nal);
1548         GST_WRITE_UINT16_BE (data, nal_size);
1549         gst_buffer_extract (nal, 0, data + 2, nal_size);
1550         data += 2 + nal_size;
1551       }
1552     }
1553   }
1554
1555   /* PPS */
1556   if (num_pps > 0) {
1557     /* array_completeness | reserved_zero bit | nal_unit_type */
1558     data[0] = 0x00 | 0x22;
1559     data++;
1560
1561     GST_WRITE_UINT16_BE (data, num_pps);
1562     data += 2;
1563
1564     for (i = 0; i < GST_H265_MAX_PPS_COUNT; i++) {
1565       if ((nal = h265parse->pps_nals[i])) {
1566         gsize nal_size = gst_buffer_get_size (nal);
1567         GST_WRITE_UINT16_BE (data, nal_size);
1568         gst_buffer_extract (nal, 0, data + 2, nal_size);
1569         data += 2 + nal_size;
1570       }
1571     }
1572   }
1573   gst_buffer_unmap (buf, &map);
1574
1575   return buf;
1576 }
1577
1578 static void
1579 gst_h265_parse_get_par (GstH265Parse * h265parse, gint * num, gint * den)
1580 {
1581   if (h265parse->upstream_par_n != -1 && h265parse->upstream_par_d != -1) {
1582     *num = h265parse->upstream_par_n;
1583     *den = h265parse->upstream_par_d;
1584   } else {
1585     *num = h265parse->parsed_par_n;
1586     *den = h265parse->parsed_par_d;
1587   }
1588 }
1589
1590 static const gchar *
1591 digit_to_string (guint digit)
1592 {
1593   static const char itoa[][2] = {
1594     "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
1595   };
1596
1597   if (G_LIKELY (digit < 10))
1598     return itoa[digit];
1599   else
1600     return NULL;
1601 }
1602
1603 static const gchar *
1604 get_tier_string (guint8 tier_flag)
1605 {
1606   const gchar *tier = NULL;
1607
1608   if (tier_flag)
1609     tier = "high";
1610   else
1611     tier = "main";
1612
1613   return tier;
1614 }
1615
1616 static const gchar *
1617 get_level_string (guint8 level_idc)
1618 {
1619   if (level_idc == 0)
1620     return NULL;
1621   else if (level_idc % 30 == 0)
1622     return digit_to_string (level_idc / 30);
1623   else {
1624     switch (level_idc) {
1625       case 63:
1626         return "2.1";
1627         break;
1628       case 93:
1629         return "3.1";
1630         break;
1631       case 123:
1632         return "4.1";
1633         break;
1634       case 153:
1635         return "5.1";
1636         break;
1637       case 156:
1638         return "5.2";
1639         break;
1640       case 183:
1641         return "6.1";
1642         break;
1643       case 186:
1644         return "6.2";
1645         break;
1646       default:
1647         return NULL;
1648     }
1649   }
1650 }
1651
1652 static inline guint64
1653 profile_to_flag (GstH265Profile p)
1654 {
1655   return (guint64) 1 << (guint64) p;
1656 }
1657
1658 static GstCaps *
1659 get_compatible_profile_caps (GstH265SPS * sps, GstH265Profile profile)
1660 {
1661   GstCaps *caps = NULL;
1662   gint i;
1663   GValue compat_profiles = G_VALUE_INIT;
1664   guint64 profiles = 0;
1665
1666   g_value_init (&compat_profiles, GST_TYPE_LIST);
1667
1668   /* Relaxing profiles condition based on decoder capability specified by spec */
1669   if (sps->profile_tier_level.profile_compatibility_flag[1])
1670     profiles |= profile_to_flag (GST_H265_PROFILE_MAIN);
1671
1672   if (sps->profile_tier_level.profile_compatibility_flag[2])
1673     profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_10);
1674
1675   if (sps->profile_tier_level.profile_compatibility_flag[3])
1676     profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_STILL_PICTURE);
1677
1678   switch (profile) {
1679     case GST_H265_PROFILE_MAIN_10:
1680     {
1681       /* A.3.5 */
1682       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_12);
1683       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_422_10);
1684       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_422_12);
1685       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_444_10);
1686       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_444_12);
1687
1688       /* A.3.7 */
1689       profiles |= profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_10);
1690
1691       /* H.11.1.1 */
1692       profiles |= profile_to_flag (GST_H265_PROFILE_SCALABLE_MAIN_10);
1693       break;
1694     }
1695     case GST_H265_PROFILE_MAIN:
1696     {
1697       /* A.3.3 */
1698       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_10);
1699
1700       /* A.3.5 */
1701       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_12);
1702       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_422_10);
1703       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_422_12);
1704       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_444_10);
1705       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_444_12);
1706
1707       /* A.3.7 */
1708       profiles |= profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN);
1709       profiles |= profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_10);
1710       profiles |= profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444);
1711       profiles |=
1712           profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444_10);
1713       profiles |=
1714           profile_to_flag
1715           (GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444);
1716       profiles |=
1717           profile_to_flag
1718           (GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_10);
1719       profiles |=
1720           profile_to_flag
1721           (GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14);
1722
1723       /* G.11.1.1 */
1724       profiles |= profile_to_flag (GST_H265_PROFILE_MULTIVIEW_MAIN);
1725
1726       /* H.11.1.1 */
1727       profiles |= profile_to_flag (GST_H265_PROFILE_SCALABLE_MAIN);
1728       profiles |= profile_to_flag (GST_H265_PROFILE_SCALABLE_MAIN_10);
1729
1730       /* I.11.1.1 */
1731       profiles |= profile_to_flag (GST_H265_PROFILE_3D_MAIN);
1732       break;
1733     }
1734     case GST_H265_PROFILE_MAIN_STILL_PICTURE:
1735     {
1736       /* A.3.2, A.3.4 */
1737       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN);
1738       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_10);
1739
1740       /* A.3.5 */
1741       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_12);
1742       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_422_10);
1743       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_422_12);
1744       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_444_10);
1745       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_444_12);
1746
1747       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_INTRA);
1748       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_10_INTRA);
1749       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_12_INTRA);
1750       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_422_10_INTRA);
1751       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_422_12_INTRA);
1752       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_444_INTRA);
1753       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_444_10_INTRA);
1754       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_444_12_INTRA);
1755       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_444_16_INTRA);
1756       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_444_STILL_PICTURE);
1757       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_444_16_STILL_PICTURE);
1758
1759       /* A.3.7 */
1760       profiles |= profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN);
1761       profiles |= profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_10);
1762       profiles |= profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444);
1763       profiles |=
1764           profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444_10);
1765       profiles |=
1766           profile_to_flag
1767           (GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444);
1768       profiles |=
1769           profile_to_flag
1770           (GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_10);
1771       profiles |=
1772           profile_to_flag
1773           (GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14);
1774       break;
1775     }
1776     case GST_H265_PROFILE_MONOCHROME:
1777     {
1778       /* A.3.7 */
1779       profiles |= profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN);
1780       profiles |= profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_10);
1781       profiles |= profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444);
1782       profiles |=
1783           profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444_10);
1784       profiles |=
1785           profile_to_flag
1786           (GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444);
1787       profiles |=
1788           profile_to_flag
1789           (GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_10);
1790       profiles |=
1791           profile_to_flag
1792           (GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14);
1793       break;
1794     }
1795     case GST_H265_PROFILE_MAIN_444:
1796     {
1797       /* A.3.7 */
1798       profiles |= profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444);
1799       profiles |=
1800           profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444_10);
1801       break;
1802     }
1803     case GST_H265_PROFILE_MAIN_444_10:
1804     {
1805       /* A.3.7 */
1806       profiles |=
1807           profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444_10);
1808       break;
1809     }
1810     case GST_H265_PROFILE_HIGH_THROUGHPUT_444:
1811     {
1812       /* A.3.7 */
1813       profiles |=
1814           profile_to_flag
1815           (GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444);
1816       profiles |=
1817           profile_to_flag
1818           (GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_10);
1819       profiles |=
1820           profile_to_flag
1821           (GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14);
1822       break;
1823     }
1824     case GST_H265_PROFILE_HIGH_THROUGHPUT_444_10:
1825     {
1826       /* A.3.7 */
1827       profiles |=
1828           profile_to_flag
1829           (GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_10);
1830       profiles |=
1831           profile_to_flag
1832           (GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14);
1833       break;
1834     }
1835     case GST_H265_PROFILE_HIGH_THROUGHPUT_444_14:
1836     {
1837       /* A.3.7 */
1838       profiles |=
1839           profile_to_flag
1840           (GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14);
1841       break;
1842     }
1843       /* All the -intra profiles can map to non-intra profiles, except
1844          the monochrome case for main and main-10. */
1845     case GST_H265_PROFILE_MAIN_INTRA:
1846     {
1847       if (sps->chroma_format_idc == 1) {
1848         profiles |= profile_to_flag (GST_H265_PROFILE_MAIN);
1849
1850         /* Add all main compatible profiles without monochrome. */
1851         /* A.3.3 */
1852         profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_10);
1853
1854         /* A.3.5 */
1855         profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_444_10);
1856         profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_444_12);
1857
1858         /* A.3.7 */
1859         profiles |= profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN);
1860         profiles |= profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_10);
1861         profiles |=
1862             profile_to_flag
1863             (GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444);
1864         profiles |=
1865             profile_to_flag
1866             (GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_10);
1867         profiles |=
1868             profile_to_flag
1869             (GST_H265_PROFILE_SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14);
1870
1871         /* G.11.1.1 */
1872         profiles |= profile_to_flag (GST_H265_PROFILE_MULTIVIEW_MAIN);
1873
1874         /* H.11.1.1 */
1875         profiles |= profile_to_flag (GST_H265_PROFILE_SCALABLE_MAIN);
1876         profiles |= profile_to_flag (GST_H265_PROFILE_SCALABLE_MAIN_10);
1877
1878         /* I.11.1.1 */
1879         profiles |= profile_to_flag (GST_H265_PROFILE_3D_MAIN);
1880       }
1881
1882       /* Add all main compatible profiles with monochrome. */
1883       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_12);
1884       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_422_10);
1885       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_422_12);
1886       profiles |= profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444);
1887       profiles |=
1888           profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444_10);
1889       break;
1890     }
1891     case GST_H265_PROFILE_MAIN_10_INTRA:
1892     {
1893       if (sps->chroma_format_idc == 1) {
1894         profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_10);
1895
1896         /* Add all main-10 compatible profiles without monochrome. */
1897         /* A.3.5 */
1898         profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_444_10);
1899         profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_444_12);
1900
1901         /* A.3.7 */
1902         profiles |= profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_10);
1903
1904         /* H.11.1.1 */
1905         profiles |= profile_to_flag (GST_H265_PROFILE_SCALABLE_MAIN_10);
1906       }
1907
1908       /* Add all main-10 compatible profiles with monochrome. */
1909       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_12);
1910       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_422_10);
1911       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_422_12);
1912       break;
1913     }
1914     case GST_H265_PROFILE_MAIN_12_INTRA:
1915       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_12);
1916       break;
1917     case GST_H265_PROFILE_MAIN_422_10_INTRA:
1918       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_422_10);
1919       break;
1920     case GST_H265_PROFILE_MAIN_422_12_INTRA:
1921       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_422_12);
1922       break;
1923     case GST_H265_PROFILE_MAIN_444_INTRA:
1924       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_444);
1925
1926       /* Add all main444 compatible profiles. */
1927       /* A.3.7 */
1928       profiles |= profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444);
1929       profiles |=
1930           profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444_10);
1931       break;
1932     case GST_H265_PROFILE_MAIN_444_10_INTRA:
1933       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_444_10);
1934
1935       /* Add all main444-10 compatible profiles. */
1936       /* A.3.7 */
1937       profiles |=
1938           profile_to_flag (GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444_10);
1939       break;
1940     case GST_H265_PROFILE_MAIN_444_12_INTRA:
1941       profiles |= profile_to_flag (GST_H265_PROFILE_MAIN_444_12);
1942       break;
1943     default:
1944       break;
1945   }
1946
1947   if (profiles) {
1948     GValue value = G_VALUE_INIT;
1949     const gchar *profile_str;
1950     caps = gst_caps_new_empty_simple ("video/x-h265");
1951
1952     for (i = GST_H265_PROFILE_MAIN; i < GST_H265_PROFILE_MAX; i++) {
1953       if ((profiles & profile_to_flag (i)) == profile_to_flag (i)) {
1954         profile_str = gst_h265_profile_to_string (i);
1955
1956         if (G_UNLIKELY (profile_str == NULL)) {
1957           GST_FIXME ("Unhandled profile index %d", i);
1958           continue;
1959         }
1960
1961         g_value_init (&value, G_TYPE_STRING);
1962         g_value_set_string (&value, profile_str);
1963         gst_value_list_append_value (&compat_profiles, &value);
1964         g_value_unset (&value);
1965       }
1966     }
1967
1968     gst_caps_set_value (caps, "profile", &compat_profiles);
1969     g_value_unset (&compat_profiles);
1970   }
1971
1972   return caps;
1973 }
1974
1975 static void
1976 fix_invalid_profile (GstH265Parse * h265parse, GstCaps * caps, GstH265SPS * sps)
1977 {
1978   /* HACK: This is a work-around to identify some main profile streams
1979    * having wrong profile_idc. There are some wrongly encoded main profile
1980    * streams which doesn't have any of the profile_idc values mentioned in
1981    * Annex-A. Just assuming them as MAIN profile for now if they meet the
1982    * A.3.2 requirement. */
1983   if (sps->chroma_format_idc == 1 && sps->bit_depth_luma_minus8 == 0 &&
1984       sps->bit_depth_chroma_minus8 == 0 && sps->sps_extension_flag == 0) {
1985     gst_caps_set_simple (caps, "profile", G_TYPE_STRING, "main", NULL);
1986     GST_WARNING_OBJECT (h265parse,
1987         "Wrong profile_idc = 0, setting it as main profile !!");
1988   }
1989 }
1990
1991 /* if downstream didn't support the exact profile indicated in sps header,
1992  * check for the compatible profiles also */
1993 static void
1994 ensure_caps_profile (GstH265Parse * h265parse, GstCaps * caps, GstH265SPS * sps,
1995     GstH265Profile profile)
1996 {
1997   GstCaps *peer_caps, *compat_caps;
1998
1999   if (profile == GST_H265_PROFILE_INVALID)
2000     fix_invalid_profile (h265parse, caps, sps);
2001
2002   peer_caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (h265parse));
2003   if (!peer_caps || !gst_caps_can_intersect (caps, peer_caps)) {
2004     GstCaps *filter_caps = gst_caps_new_empty_simple ("video/x-h265");
2005
2006     if (peer_caps)
2007       gst_caps_unref (peer_caps);
2008     peer_caps =
2009         gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (h265parse),
2010         filter_caps);
2011
2012     gst_caps_unref (filter_caps);
2013   }
2014
2015   if (peer_caps && !gst_caps_can_intersect (caps, peer_caps)) {
2016     GstStructure *structure;
2017
2018     compat_caps = get_compatible_profile_caps (sps, profile);
2019     if (compat_caps != NULL) {
2020       GstCaps *res_caps = NULL;
2021
2022       res_caps = gst_caps_intersect (peer_caps, compat_caps);
2023
2024       if (res_caps && !gst_caps_is_empty (res_caps)) {
2025         const gchar *profile_str = NULL;
2026
2027         res_caps = gst_caps_fixate (res_caps);
2028         structure = gst_caps_get_structure (res_caps, 0);
2029         profile_str = gst_structure_get_string (structure, "profile");
2030         if (profile_str) {
2031           gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile_str,
2032               NULL);
2033           GST_DEBUG_OBJECT (h265parse,
2034               "Setting compatible profile %s to the caps", profile_str);
2035         }
2036       }
2037       if (res_caps)
2038         gst_caps_unref (res_caps);
2039       gst_caps_unref (compat_caps);
2040     }
2041   }
2042   if (peer_caps)
2043     gst_caps_unref (peer_caps);
2044 }
2045
2046 static gboolean
2047 gst_h265_parse_is_field_interlaced (GstH265Parse * h265parse)
2048 {
2049   /* FIXME: The SEI is optional, so theoretically there could be files with
2050    * the interlaced_source_flag set to TRUE but no SEI present, or SEI present
2051    * but no pic_struct. Haven't seen any such files in practice, and we don't
2052    * know how to interpret the data without the pic_struct, so we'll treat
2053    * them as progressive */
2054
2055   switch (h265parse->sei_pic_struct) {
2056     case GST_H265_SEI_PIC_STRUCT_TOP_FIELD:
2057     case GST_H265_SEI_PIC_STRUCT_TOP_PAIRED_PREVIOUS_BOTTOM:
2058     case GST_H265_SEI_PIC_STRUCT_TOP_PAIRED_NEXT_BOTTOM:
2059     case GST_H265_SEI_PIC_STRUCT_BOTTOM_FIELD:
2060     case GST_H265_SEI_PIC_STRUCT_BOTTOM_PAIRED_PREVIOUS_TOP:
2061     case GST_H265_SEI_PIC_STRUCT_BOTTOM_PAIRED_NEXT_TOP:
2062       return TRUE;
2063       break;
2064     default:
2065       break;
2066   }
2067
2068   return FALSE;
2069 }
2070
2071 static void
2072 gst_h265_parse_update_src_caps (GstH265Parse * h265parse, GstCaps * caps)
2073 {
2074   GstH265SPS *sps = NULL;
2075   GstCaps *sink_caps, *src_caps;
2076   gboolean modified = FALSE;
2077   GstBuffer *buf = NULL;
2078   GstStructure *s = NULL;
2079   gint width, height;
2080
2081   if (G_UNLIKELY (!gst_pad_has_current_caps (GST_BASE_PARSE_SRC_PAD
2082               (h265parse))))
2083     modified = TRUE;
2084   else if (G_UNLIKELY (!h265parse->update_caps))
2085     return;
2086
2087   /* if this is being called from the first _setcaps call, caps on the sinkpad
2088    * aren't set yet and so they need to be passed as an argument */
2089   if (caps)
2090     sink_caps = gst_caps_ref (caps);
2091   else
2092     sink_caps = gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (h265parse));
2093
2094   /* carry over input caps as much as possible; override with our own stuff */
2095   if (!sink_caps)
2096     sink_caps = gst_caps_new_empty_simple ("video/x-h265");
2097   else
2098     s = gst_caps_get_structure (sink_caps, 0);
2099
2100   sps = h265parse->nalparser->last_sps;
2101   GST_DEBUG_OBJECT (h265parse, "sps: %p", sps);
2102
2103   /* only codec-data for nice-and-clean au aligned packetized hevc format */
2104   if ((h265parse->format == GST_H265_PARSE_FORMAT_HVC1
2105           || h265parse->format == GST_H265_PARSE_FORMAT_HEV1)
2106       && h265parse->align == GST_H265_PARSE_ALIGN_AU) {
2107     buf = gst_h265_parse_make_codec_data (h265parse);
2108     if (buf && h265parse->codec_data) {
2109       GstMapInfo map;
2110
2111       gst_buffer_map (buf, &map, GST_MAP_READ);
2112       if (map.size != gst_buffer_get_size (h265parse->codec_data) ||
2113           gst_buffer_memcmp (h265parse->codec_data, 0, map.data, map.size))
2114         modified = TRUE;
2115
2116       gst_buffer_unmap (buf, &map);
2117     } else {
2118       if (!buf && h265parse->codec_data_in)
2119         buf = gst_buffer_ref (h265parse->codec_data_in);
2120       modified = TRUE;
2121     }
2122   }
2123
2124   caps = NULL;
2125   if (G_UNLIKELY (!sps)) {
2126     caps = gst_caps_copy (sink_caps);
2127   } else {
2128     gint crop_width, crop_height;
2129     const gchar *chroma_format = NULL;
2130     guint bit_depth_chroma;
2131     GstH265VPS *vps = sps->vps;
2132     GstH265VUIParams *vui = &sps->vui_params;
2133     gchar *colorimetry = NULL;
2134
2135     GST_DEBUG_OBJECT (h265parse, "vps: %p", vps);
2136
2137     if (sps->conformance_window_flag) {
2138       crop_width = sps->crop_rect_width;
2139       crop_height = sps->crop_rect_height;
2140     } else {
2141       crop_width = sps->width;
2142       crop_height = sps->height;
2143     }
2144     if (gst_h265_parse_is_field_interlaced (h265parse)) {
2145       crop_height *= 2;
2146     }
2147
2148     if (G_UNLIKELY (h265parse->width != crop_width ||
2149             h265parse->height != crop_height)) {
2150       h265parse->width = crop_width;
2151       h265parse->height = crop_height;
2152       GST_INFO_OBJECT (h265parse, "resolution changed %dx%d",
2153           h265parse->width, h265parse->height);
2154       modified = TRUE;
2155     }
2156
2157     /* 0/1 is set as the default in the codec parser */
2158     if (vui->timing_info_present_flag) {
2159       gint fps_num = 0, fps_den = 1;
2160
2161       if (!(sps->fps_num == 0 && sps->fps_den == 1)) {
2162         fps_num = sps->fps_num;
2163         fps_den = sps->fps_den;
2164       } else if (!(sps->vui_params.time_scale == 0 &&
2165               sps->vui_params.num_units_in_tick == 1)) {
2166         fps_num = sps->vui_params.time_scale;
2167         fps_den = sps->vui_params.num_units_in_tick;
2168
2169         if (gst_h265_parse_is_field_interlaced (h265parse)
2170             && h265parse->framerate_from_caps) {
2171           gint new_fps_num, new_fps_den;
2172
2173           if (!gst_util_fraction_multiply (fps_num, fps_den, 1, 2, &new_fps_num,
2174                   &new_fps_den)) {
2175             GST_WARNING_OBJECT (h265parse, "Error calculating the new framerate"
2176                 " - integer overflow; setting it to 0/1");
2177             fps_num = 0;
2178             fps_den = 1;
2179           } else {
2180             fps_num = new_fps_num;
2181             fps_den = new_fps_den;
2182           }
2183           h265parse->framerate_from_caps = FALSE;
2184         }
2185       }
2186
2187       if (G_UNLIKELY (h265parse->fps_num != fps_num
2188               || h265parse->fps_den != fps_den)) {
2189         GST_INFO_OBJECT (h265parse, "framerate changed %d/%d",
2190             fps_num, fps_den);
2191         h265parse->fps_num = fps_num;
2192         h265parse->fps_den = fps_den;
2193         modified = TRUE;
2194       }
2195     }
2196
2197     if (vui->aspect_ratio_info_present_flag) {
2198       if (G_UNLIKELY ((h265parse->parsed_par_n != vui->par_n)
2199               && (h265parse->parsed_par_d != sps->vui_params.par_d))) {
2200         h265parse->parsed_par_n = vui->par_n;
2201         h265parse->parsed_par_d = vui->par_d;
2202         GST_INFO_OBJECT (h265parse, "pixel aspect ratio has been changed %d/%d",
2203             h265parse->parsed_par_n, h265parse->parsed_par_d);
2204         modified = TRUE;
2205       }
2206
2207     }
2208
2209     if (vui->video_signal_type_present_flag &&
2210         vui->colour_description_present_flag) {
2211       GstVideoColorimetry ci = { 0, };
2212       gchar *old_colorimetry = NULL;
2213
2214       if (vui->video_full_range_flag)
2215         ci.range = GST_VIDEO_COLOR_RANGE_0_255;
2216       else
2217         ci.range = GST_VIDEO_COLOR_RANGE_16_235;
2218
2219       ci.matrix = gst_video_color_matrix_from_iso (vui->matrix_coefficients);
2220       ci.transfer =
2221           gst_video_transfer_function_from_iso (vui->transfer_characteristics);
2222       ci.primaries = gst_video_color_primaries_from_iso (vui->colour_primaries);
2223
2224       old_colorimetry =
2225           gst_video_colorimetry_to_string (&h265parse->parsed_colorimetry);
2226       colorimetry = gst_video_colorimetry_to_string (&ci);
2227
2228       if (colorimetry && g_strcmp0 (old_colorimetry, colorimetry)) {
2229         GST_INFO_OBJECT (h265parse,
2230             "colorimetry has been changed from %s to %s",
2231             GST_STR_NULL (old_colorimetry), colorimetry);
2232         h265parse->parsed_colorimetry = ci;
2233         modified = TRUE;
2234       }
2235
2236       g_free (old_colorimetry);
2237     }
2238
2239     if (G_UNLIKELY (modified || h265parse->update_caps)) {
2240       gint fps_num = h265parse->fps_num;
2241       gint fps_den = h265parse->fps_den;
2242       GstClockTime latency = 0;
2243
2244       caps = gst_caps_copy (sink_caps);
2245
2246       /* sps should give this but upstream overrides */
2247       if (s && gst_structure_has_field (s, "width"))
2248         gst_structure_get_int (s, "width", &width);
2249       else
2250         width = h265parse->width;
2251
2252       if (s && gst_structure_has_field (s, "height"))
2253         gst_structure_get_int (s, "height", &height);
2254       else
2255         height = h265parse->height;
2256
2257       gst_caps_set_simple (caps, "width", G_TYPE_INT, width,
2258           "height", G_TYPE_INT, height, NULL);
2259
2260       h265parse->framerate_from_caps = FALSE;
2261       /* upstream overrides */
2262       if (s && gst_structure_has_field (s, "framerate"))
2263         gst_structure_get_fraction (s, "framerate", &fps_num, &fps_den);
2264
2265       /* but not necessarily or reliably this */
2266       if (fps_den > 0) {
2267         GstStructure *s2;
2268         GstClockTime val;
2269
2270         GST_INFO_OBJECT (h265parse, "setting framerate in caps");
2271         gst_caps_set_simple (caps, "framerate",
2272             GST_TYPE_FRACTION, fps_num, fps_den, NULL);
2273         s2 = gst_caps_get_structure (caps, 0);
2274         gst_structure_get_fraction (s2, "framerate", &h265parse->parsed_fps_n,
2275             &h265parse->parsed_fps_d);
2276         gst_base_parse_set_frame_rate (GST_BASE_PARSE (h265parse),
2277             fps_num, fps_den, 0, 0);
2278         val = sps->profile_tier_level.interlaced_source_flag ? GST_SECOND / 2 :
2279             GST_SECOND;
2280         h265parse->framerate_from_caps = TRUE;
2281
2282         /* If we know the frame duration, and if we are not in one of the zero
2283          * latency pattern, add one frame of latency */
2284         if (fps_num > 0 &&
2285             h265parse->in_align != GST_H265_PARSE_ALIGN_AU &&
2286             !(h265parse->in_align == GST_H265_PARSE_ALIGN_NAL &&
2287                 h265parse->align == GST_H265_PARSE_ALIGN_NAL))
2288           latency = gst_util_uint64_scale (val, fps_den, fps_num);
2289
2290         gst_base_parse_set_latency (GST_BASE_PARSE (h265parse), latency,
2291             latency);
2292       }
2293
2294       bit_depth_chroma = sps->bit_depth_chroma_minus8 + 8;
2295
2296       switch (sps->chroma_format_idc) {
2297         case 0:
2298           chroma_format = "4:0:0";
2299           bit_depth_chroma = 0;
2300           break;
2301         case 1:
2302           chroma_format = "4:2:0";
2303           break;
2304         case 2:
2305           chroma_format = "4:2:2";
2306           break;
2307         case 3:
2308           chroma_format = "4:4:4";
2309           break;
2310         default:
2311           break;
2312       }
2313
2314       if (chroma_format)
2315         gst_caps_set_simple (caps, "chroma-format", G_TYPE_STRING,
2316             chroma_format, "bit-depth-luma", G_TYPE_UINT,
2317             sps->bit_depth_luma_minus8 + 8, "bit-depth-chroma", G_TYPE_UINT,
2318             bit_depth_chroma, NULL);
2319
2320       if (colorimetry && (!s || !gst_structure_has_field (s, "colorimetry"))) {
2321         gst_caps_set_simple (caps, "colorimetry", G_TYPE_STRING, colorimetry,
2322             NULL);
2323       }
2324     }
2325
2326     g_free (colorimetry);
2327   }
2328
2329   if (caps) {
2330     gint par_n, par_d;
2331     const gchar *mdi_str = NULL;
2332     const gchar *cll_str = NULL;
2333     gboolean codec_data_modified = FALSE;
2334     GstStructure *st;
2335
2336     gst_caps_set_simple (caps, "parsed", G_TYPE_BOOLEAN, TRUE,
2337         "stream-format", G_TYPE_STRING,
2338         gst_h265_parse_get_string (h265parse, TRUE, h265parse->format),
2339         "alignment", G_TYPE_STRING,
2340         gst_h265_parse_get_string (h265parse, FALSE, h265parse->align), NULL);
2341
2342     gst_h265_parse_get_par (h265parse, &par_n, &par_d);
2343
2344     width = 0;
2345     height = 0;
2346     st = gst_caps_get_structure (caps, 0);
2347     gst_structure_get_int (st, "width", &width);
2348     gst_structure_get_int (st, "height", &height);
2349
2350     /* If no resolution info, do not consider aspect ratio */
2351     if (par_n != 0 && par_d != 0 && width > 0 && height > 0 &&
2352         (!s || !gst_structure_has_field (s, "pixel-aspect-ratio"))) {
2353       gint new_par_d = par_d;
2354       /* Special case for some encoders which provide an 1:2 pixel aspect ratio
2355        * for HEVC interlaced content, possibly to work around decoders that don't
2356        * support field-based interlacing. Add some defensive checks to check for
2357        * a "common" aspect ratio. */
2358       if (par_n == 1 && par_d == 2
2359           && gst_h265_parse_is_field_interlaced (h265parse)
2360           && !gst_video_is_common_aspect_ratio (width, height, par_n, par_d)
2361           && gst_video_is_common_aspect_ratio (width, height, 1, 1)) {
2362         GST_WARNING_OBJECT (h265parse, "PAR 1/2 makes the aspect ratio of "
2363             "a %d x %d frame uncommon. Switching to 1/1", width, height);
2364         new_par_d = 1;
2365       }
2366       GST_INFO_OBJECT (h265parse, "PAR %d/%d", par_n, new_par_d);
2367       gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION,
2368           par_n, new_par_d, NULL);
2369     }
2370
2371     /* set profile and level in caps */
2372     if (sps) {
2373       const gchar *profile, *tier, *level;
2374       GstH265Profile p;
2375
2376       p = gst_h265_get_profile_from_sps (sps);
2377       /* gst_h265_get_profile_from_sps() method will determine profile
2378        * as defined in spec, with allowing slightly broken profile-tier-level
2379        * bits, then it might not be able to cover all cases.
2380        * If it's still unknown, do guess again */
2381       if (p == GST_H265_PROFILE_INVALID) {
2382         GST_WARNING_OBJECT (h265parse, "Unknown profile, guessing");
2383         switch (sps->chroma_format_idc) {
2384           case 0:
2385             if (sps->bit_depth_luma_minus8 == 0) {
2386               p = GST_H265_PROFILE_MONOCHROME;
2387             } else if (sps->bit_depth_luma_minus8 <= 2) {
2388               p = GST_H265_PROFILE_MONOCHROME_10;
2389             } else if (sps->bit_depth_luma_minus8 <= 4) {
2390               p = GST_H265_PROFILE_MONOCHROME_12;
2391             } else {
2392               p = GST_H265_PROFILE_MONOCHROME_16;
2393             }
2394             break;
2395           case 1:
2396             if (sps->bit_depth_luma_minus8 == 0) {
2397               p = GST_H265_PROFILE_MAIN;
2398             } else if (sps->bit_depth_luma_minus8 <= 2) {
2399               p = GST_H265_PROFILE_MAIN_10;
2400             } else if (sps->bit_depth_luma_minus8 <= 4) {
2401               p = GST_H265_PROFILE_MAIN_12;
2402             } else {
2403               p = GST_H265_PROFILE_MAIN_444_16_INTRA;
2404             }
2405             break;
2406           case 2:
2407             if (sps->bit_depth_luma_minus8 <= 2) {
2408               p = GST_H265_PROFILE_MAIN_422_10;
2409             } else if (sps->bit_depth_luma_minus8 <= 4) {
2410               p = GST_H265_PROFILE_MAIN_422_12;
2411             } else {
2412               p = GST_H265_PROFILE_MAIN_444_16_INTRA;
2413             }
2414             break;
2415           case 3:
2416             if (sps->bit_depth_luma_minus8 == 0) {
2417               p = GST_H265_PROFILE_MAIN_444;
2418             } else if (sps->bit_depth_luma_minus8 <= 2) {
2419               p = GST_H265_PROFILE_MAIN_444_10;
2420             } else if (sps->bit_depth_luma_minus8 <= 4) {
2421               p = GST_H265_PROFILE_MAIN_444_12;
2422             } else {
2423               p = GST_H265_PROFILE_MAIN_444_16_INTRA;
2424             }
2425             break;
2426           default:
2427             break;
2428         }
2429       }
2430
2431       profile = gst_h265_profile_to_string (p);
2432
2433       if (s && gst_structure_has_field (s, "profile")) {
2434         const gchar *profile_sink = gst_structure_get_string (s, "profile");
2435         GstH265Profile p_sink = gst_h265_profile_from_string (profile_sink);
2436
2437         if (p != p_sink) {
2438           const gchar *profile_src;
2439
2440           p = MAX (p, p_sink);
2441           profile_src = (p == p_sink) ? profile_sink : profile;
2442           GST_INFO_OBJECT (h265parse,
2443               "Upstream profile (%s) is different than in SPS (%s). "
2444               "Using %s.", profile_sink, profile, profile_src);
2445           profile = profile_src;
2446         }
2447       }
2448
2449       if (profile != NULL)
2450         gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
2451
2452       tier = get_tier_string (sps->profile_tier_level.tier_flag);
2453       if (tier != NULL)
2454         gst_caps_set_simple (caps, "tier", G_TYPE_STRING, tier, NULL);
2455
2456       level = get_level_string (sps->profile_tier_level.level_idc);
2457       if (level != NULL)
2458         gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
2459
2460       /* relax the profile constraint to find a suitable decoder */
2461       ensure_caps_profile (h265parse, caps, sps, p);
2462     }
2463
2464     if (s)
2465       mdi_str = gst_structure_get_string (s, "mastering-display-info");
2466     if (mdi_str) {
2467       gst_caps_set_simple (caps, "mastering-display-info", G_TYPE_STRING,
2468           mdi_str, NULL);
2469     } else if (h265parse->mastering_display_info_state !=
2470         GST_H265_PARSE_SEI_EXPIRED &&
2471         !gst_video_mastering_display_info_add_to_caps
2472         (&h265parse->mastering_display_info, caps)) {
2473       GST_WARNING_OBJECT (h265parse,
2474           "Couldn't set mastering display info to caps");
2475     }
2476
2477     if (s)
2478       cll_str = gst_structure_get_string (s, "content-light-level");
2479     if (cll_str) {
2480       gst_caps_set_simple (caps, "content-light-level", G_TYPE_STRING, cll_str,
2481           NULL);
2482     } else if (h265parse->content_light_level_state !=
2483         GST_H265_PARSE_SEI_EXPIRED &&
2484         !gst_video_content_light_level_add_to_caps
2485         (&h265parse->content_light_level, caps)) {
2486       GST_WARNING_OBJECT (h265parse,
2487           "Couldn't set content light level to caps");
2488     }
2489
2490     src_caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (h265parse));
2491
2492     if (src_caps) {
2493       GstStructure *src_caps_str = gst_caps_get_structure (src_caps, 0);
2494
2495       /* use codec data from old caps for comparison if we have pushed frame for now.
2496        * we don't want to resend caps if everything is same except codec data.
2497        * However, if the updated sps/pps is not in bitstream, we should put
2498        * it on bitstream */
2499       if (gst_structure_has_field (src_caps_str, "codec_data")) {
2500         const GValue *codec_data_value =
2501             gst_structure_get_value (src_caps_str, "codec_data");
2502
2503         if (!GST_VALUE_HOLDS_BUFFER (codec_data_value)) {
2504           GST_WARNING_OBJECT (h265parse, "codec_data does not hold buffer");
2505         } else if (!h265parse->first_frame) {
2506           /* If there is no pushed frame before, we can update caps without worry.
2507            * But updating codec_data in the middle of frames
2508            * (especially on non-keyframe) might make downstream be confused.
2509            * Therefore we are setting old codec data
2510            * (i.e., was pushed to downstream previously) to new caps candidate
2511            * here for gst_caps_is_strictly_equal() to be returned TRUE if only
2512            * the codec_data is different, and to avoid re-sending caps it
2513            * that case.
2514            */
2515           gst_caps_set_value (caps, "codec_data", codec_data_value);
2516
2517           /* check for codec_data update to re-send sps/pps inband data if
2518            * current frame has no sps/pps but upstream codec_data was updated.
2519            * Note that have_vps_in_frame is skipped here since it's optional  */
2520           if ((!h265parse->have_sps_in_frame || !h265parse->have_pps_in_frame)
2521               && buf) {
2522             GstBuffer *codec_data_buf = gst_value_get_buffer (codec_data_value);
2523             GstMapInfo map;
2524
2525             gst_buffer_map (buf, &map, GST_MAP_READ);
2526             if (map.size != gst_buffer_get_size (codec_data_buf) ||
2527                 gst_buffer_memcmp (codec_data_buf, 0, map.data, map.size)) {
2528               codec_data_modified = TRUE;
2529             }
2530
2531             gst_buffer_unmap (buf, &map);
2532           }
2533         }
2534       } else if (!buf) {
2535         GstStructure *s;
2536         /* remove any left-over codec-data hanging around */
2537         s = gst_caps_get_structure (caps, 0);
2538         gst_structure_remove_field (s, "codec_data");
2539       }
2540     }
2541
2542     if (!(src_caps && gst_caps_is_strictly_equal (src_caps, caps))) {
2543       /* update codec data to new value */
2544       if (buf) {
2545         gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
2546         gst_buffer_replace (&h265parse->codec_data, buf);
2547         gst_buffer_unref (buf);
2548         buf = NULL;
2549       } else {
2550         GstStructure *s;
2551         /* remove any left-over codec-data hanging around */
2552         s = gst_caps_get_structure (caps, 0);
2553         gst_structure_remove_field (s, "codec_data");
2554         gst_buffer_replace (&h265parse->codec_data, NULL);
2555       }
2556
2557       gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (h265parse), caps);
2558     } else if (codec_data_modified) {
2559       GST_DEBUG_OBJECT (h265parse,
2560           "Only codec_data is different, need inband vps/sps/pps update");
2561
2562       /* this will insert updated codec_data with next idr */
2563       h265parse->push_codec = TRUE;
2564     }
2565
2566     if (src_caps)
2567       gst_caps_unref (src_caps);
2568     gst_caps_unref (caps);
2569   }
2570
2571   gst_caps_unref (sink_caps);
2572   if (buf)
2573     gst_buffer_unref (buf);
2574
2575 }
2576
2577 static GstFlowReturn
2578 gst_h265_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
2579 {
2580   GstH265Parse *h265parse;
2581   GstBuffer *buffer;
2582   guint av;
2583
2584   h265parse = GST_H265_PARSE (parse);
2585   buffer = frame->buffer;
2586
2587   gst_h265_parse_update_src_caps (h265parse, NULL);
2588
2589   if (h265parse->fps_num > 0 && h265parse->fps_den > 0) {
2590     GstClockTime val =
2591         gst_h265_parse_is_field_interlaced (h265parse) ? GST_SECOND /
2592         2 : GST_SECOND;
2593
2594     GST_BUFFER_DURATION (buffer) = gst_util_uint64_scale (val,
2595         h265parse->fps_den, h265parse->fps_num);
2596   }
2597
2598   if (h265parse->keyframe)
2599     GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2600   else
2601     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2602
2603   if (h265parse->discard_bidirectional && h265parse->bidirectional)
2604     goto discard;
2605
2606
2607   if (h265parse->header)
2608     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_HEADER);
2609   else
2610     GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_HEADER);
2611
2612   if (h265parse->discont) {
2613     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
2614     h265parse->discont = FALSE;
2615   }
2616
2617   if (h265parse->marker) {
2618     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_MARKER);
2619     h265parse->marker = FALSE;
2620   } else {
2621     GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_MARKER);
2622   }
2623
2624   /* replace with transformed HEVC output if applicable */
2625   av = gst_adapter_available (h265parse->frame_out);
2626   if (av) {
2627     GstBuffer *buf;
2628
2629     buf = gst_adapter_take_buffer (h265parse->frame_out, av);
2630     gst_buffer_copy_into (buf, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
2631     gst_buffer_replace (&frame->out_buffer, buf);
2632     gst_buffer_unref (buf);
2633   }
2634
2635 done:
2636   return GST_FLOW_OK;
2637
2638 discard:
2639   GST_DEBUG_OBJECT (h265parse, "Discarding bidirectional frame");
2640   frame->flags |= GST_BASE_PARSE_FRAME_FLAG_DROP;
2641   gst_h265_parse_reset_frame (h265parse);
2642   goto done;
2643
2644 }
2645
2646 /* sends a codec NAL downstream, decorating and transforming as needed.
2647  * No ownership is taken of @nal */
2648 static GstFlowReturn
2649 gst_h265_parse_push_codec_buffer (GstH265Parse * h265parse, GstBuffer * nal,
2650     GstBuffer * buffer)
2651 {
2652   GstMapInfo map;
2653
2654   gst_buffer_map (nal, &map, GST_MAP_READ);
2655   nal = gst_h265_parse_wrap_nal (h265parse, h265parse->format,
2656       map.data, map.size);
2657   gst_buffer_unmap (nal, &map);
2658
2659   if (h265parse->discont) {
2660     GST_BUFFER_FLAG_SET (nal, GST_BUFFER_FLAG_DISCONT);
2661     h265parse->discont = FALSE;
2662   }
2663
2664   GST_BUFFER_PTS (nal) = GST_BUFFER_PTS (buffer);
2665   GST_BUFFER_DTS (nal) = GST_BUFFER_DTS (buffer);
2666   GST_BUFFER_DURATION (nal) = 0;
2667
2668   return gst_pad_push (GST_BASE_PARSE_SRC_PAD (h265parse), nal);
2669 }
2670
2671 static GstEvent *
2672 check_pending_key_unit_event (GstEvent * pending_event, GstSegment * segment,
2673     GstClockTime timestamp, guint flags, GstClockTime pending_key_unit_ts)
2674 {
2675   GstClockTime running_time, stream_time;
2676   gboolean all_headers;
2677   guint count;
2678   GstEvent *event = NULL;
2679
2680   g_return_val_if_fail (segment != NULL, NULL);
2681
2682   if (pending_event == NULL)
2683     goto out;
2684
2685   if (GST_CLOCK_TIME_IS_VALID (pending_key_unit_ts) &&
2686       timestamp == GST_CLOCK_TIME_NONE)
2687     goto out;
2688
2689   running_time = gst_segment_to_running_time (segment,
2690       GST_FORMAT_TIME, timestamp);
2691
2692   GST_INFO ("now %" GST_TIME_FORMAT " wanted %" GST_TIME_FORMAT,
2693       GST_TIME_ARGS (running_time), GST_TIME_ARGS (pending_key_unit_ts));
2694   if (GST_CLOCK_TIME_IS_VALID (pending_key_unit_ts) &&
2695       running_time < pending_key_unit_ts)
2696     goto out;
2697
2698   if (flags & GST_BUFFER_FLAG_DELTA_UNIT) {
2699     GST_DEBUG ("pending force key unit, waiting for keyframe");
2700     goto out;
2701   }
2702
2703   stream_time = gst_segment_to_stream_time (segment,
2704       GST_FORMAT_TIME, timestamp);
2705
2706   if (!gst_video_event_parse_upstream_force_key_unit (pending_event,
2707           NULL, &all_headers, &count)) {
2708     gst_video_event_parse_downstream_force_key_unit (pending_event, NULL,
2709         NULL, NULL, &all_headers, &count);
2710   }
2711
2712   event =
2713       gst_video_event_new_downstream_force_key_unit (timestamp, stream_time,
2714       running_time, all_headers, count);
2715   gst_event_set_seqnum (event, gst_event_get_seqnum (pending_event));
2716
2717 out:
2718   return event;
2719 }
2720
2721 static void
2722 gst_h265_parse_prepare_key_unit (GstH265Parse * parse, GstEvent * event)
2723 {
2724   GstClockTime running_time;
2725   guint count;
2726 #ifndef GST_DISABLE_GST_DEBUG
2727   gboolean have_vps, have_sps, have_pps;
2728   gint i;
2729 #endif
2730
2731   parse->pending_key_unit_ts = GST_CLOCK_TIME_NONE;
2732   gst_event_replace (&parse->force_key_unit_event, NULL);
2733
2734   gst_video_event_parse_downstream_force_key_unit (event,
2735       NULL, NULL, &running_time, NULL, &count);
2736
2737   GST_INFO_OBJECT (parse, "pushing downstream force-key-unit event %d "
2738       "%" GST_TIME_FORMAT " count %d", gst_event_get_seqnum (event),
2739       GST_TIME_ARGS (running_time), count);
2740   gst_pad_push_event (GST_BASE_PARSE_SRC_PAD (parse), event);
2741
2742 #ifndef GST_DISABLE_GST_DEBUG
2743   have_vps = have_sps = have_pps = FALSE;
2744   for (i = 0; i < GST_H265_MAX_VPS_COUNT; i++) {
2745     if (parse->vps_nals[i] != NULL) {
2746       have_vps = TRUE;
2747       break;
2748     }
2749   }
2750   for (i = 0; i < GST_H265_MAX_SPS_COUNT; i++) {
2751     if (parse->sps_nals[i] != NULL) {
2752       have_sps = TRUE;
2753       break;
2754     }
2755   }
2756   for (i = 0; i < GST_H265_MAX_PPS_COUNT; i++) {
2757     if (parse->pps_nals[i] != NULL) {
2758       have_pps = TRUE;
2759       break;
2760     }
2761   }
2762
2763   GST_INFO_OBJECT (parse,
2764       "preparing key unit, have vps %d have sps %d have pps %d", have_vps,
2765       have_sps, have_pps);
2766 #endif
2767
2768   /* set push_codec to TRUE so that pre_push_frame sends VPS/SPS/PPS again */
2769   parse->push_codec = TRUE;
2770 }
2771
2772 static gboolean
2773 gst_h265_parse_handle_vps_sps_pps_nals (GstH265Parse * h265parse,
2774     GstBuffer * buffer, GstBaseParseFrame * frame)
2775 {
2776   GstBuffer *codec_nal;
2777   gint i;
2778   gboolean send_done = FALSE;
2779
2780   if (h265parse->have_vps_in_frame && h265parse->have_sps_in_frame
2781       && h265parse->have_pps_in_frame) {
2782     GST_DEBUG_OBJECT (h265parse, "VPS/SPS/PPS exist in frame, will not insert");
2783     return TRUE;
2784   }
2785
2786   if (h265parse->align == GST_H265_PARSE_ALIGN_NAL) {
2787     /* send separate config NAL buffers */
2788     GST_DEBUG_OBJECT (h265parse, "- sending VPS/SPS/PPS");
2789     for (i = 0; i < GST_H265_MAX_VPS_COUNT; i++) {
2790       if ((codec_nal = h265parse->vps_nals[i])) {
2791         GST_DEBUG_OBJECT (h265parse, "sending VPS nal");
2792         gst_h265_parse_push_codec_buffer (h265parse, codec_nal, buffer);
2793         send_done = TRUE;
2794       }
2795     }
2796     for (i = 0; i < GST_H265_MAX_SPS_COUNT; i++) {
2797       if ((codec_nal = h265parse->sps_nals[i])) {
2798         GST_DEBUG_OBJECT (h265parse, "sending SPS nal");
2799         gst_h265_parse_push_codec_buffer (h265parse, codec_nal, buffer);
2800         send_done = TRUE;
2801       }
2802     }
2803     for (i = 0; i < GST_H265_MAX_PPS_COUNT; i++) {
2804       if ((codec_nal = h265parse->pps_nals[i])) {
2805         GST_DEBUG_OBJECT (h265parse, "sending PPS nal");
2806         gst_h265_parse_push_codec_buffer (h265parse, codec_nal, buffer);
2807         send_done = TRUE;
2808       }
2809     }
2810   } else {
2811     /* insert config NALs into AU */
2812     GstByteWriter bw;
2813     GstBuffer *new_buf;
2814     const gboolean bs = h265parse->format == GST_H265_PARSE_FORMAT_BYTE;
2815     const gint nls = 4 - h265parse->nal_length_size;
2816     gboolean ok;
2817
2818     gst_byte_writer_init_with_size (&bw, gst_buffer_get_size (buffer), FALSE);
2819     ok = gst_byte_writer_put_buffer (&bw, buffer, 0, h265parse->idr_pos);
2820     GST_DEBUG_OBJECT (h265parse, "- inserting VPS/SPS/PPS");
2821     for (i = 0; i < GST_H265_MAX_VPS_COUNT; i++) {
2822       if ((codec_nal = h265parse->vps_nals[i])) {
2823         gsize nal_size = gst_buffer_get_size (codec_nal);
2824         GST_DEBUG_OBJECT (h265parse, "inserting VPS nal");
2825         if (bs) {
2826           ok &= gst_byte_writer_put_uint32_be (&bw, 1);
2827         } else {
2828           ok &= gst_byte_writer_put_uint32_be (&bw, (nal_size << (nls * 8)));
2829           ok &= gst_byte_writer_set_pos (&bw,
2830               gst_byte_writer_get_pos (&bw) - nls);
2831         }
2832
2833         ok &= gst_byte_writer_put_buffer (&bw, codec_nal, 0, nal_size);
2834         send_done = TRUE;
2835       }
2836     }
2837     for (i = 0; i < GST_H265_MAX_SPS_COUNT; i++) {
2838       if ((codec_nal = h265parse->sps_nals[i])) {
2839         gsize nal_size = gst_buffer_get_size (codec_nal);
2840         GST_DEBUG_OBJECT (h265parse, "inserting SPS nal");
2841         if (bs) {
2842           ok &= gst_byte_writer_put_uint32_be (&bw, 1);
2843         } else {
2844           ok &= gst_byte_writer_put_uint32_be (&bw, (nal_size << (nls * 8)));
2845           ok &= gst_byte_writer_set_pos (&bw,
2846               gst_byte_writer_get_pos (&bw) - nls);
2847         }
2848
2849         ok &= gst_byte_writer_put_buffer (&bw, codec_nal, 0, nal_size);
2850         send_done = TRUE;
2851       }
2852     }
2853     for (i = 0; i < GST_H265_MAX_PPS_COUNT; i++) {
2854       if ((codec_nal = h265parse->pps_nals[i])) {
2855         gsize nal_size = gst_buffer_get_size (codec_nal);
2856         GST_DEBUG_OBJECT (h265parse, "inserting PPS nal");
2857         if (bs) {
2858           ok &= gst_byte_writer_put_uint32_be (&bw, 1);
2859         } else {
2860           ok &= gst_byte_writer_put_uint32_be (&bw, (nal_size << (nls * 8)));
2861           ok &= gst_byte_writer_set_pos (&bw,
2862               gst_byte_writer_get_pos (&bw) - nls);
2863         }
2864         ok &= gst_byte_writer_put_buffer (&bw, codec_nal, 0, nal_size);
2865         send_done = TRUE;
2866       }
2867     }
2868     ok &= gst_byte_writer_put_buffer (&bw, buffer, h265parse->idr_pos, -1);
2869     /* collect result and push */
2870     new_buf = gst_byte_writer_reset_and_get_buffer (&bw);
2871     gst_buffer_copy_into (new_buf, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
2872     /* should already be keyframe/IDR, but it may not have been,
2873      * so mark it as such to avoid being discarded by picky decoder */
2874     GST_BUFFER_FLAG_UNSET (new_buf, GST_BUFFER_FLAG_DELTA_UNIT);
2875     gst_buffer_replace (&frame->out_buffer, new_buf);
2876     gst_buffer_unref (new_buf);
2877     /* some result checking seems to make some compilers happy */
2878     if (G_UNLIKELY (!ok)) {
2879       GST_ERROR_OBJECT (h265parse, "failed to insert SPS/PPS");
2880     }
2881   }
2882
2883   return send_done;
2884 }
2885
2886 static GstFlowReturn
2887 gst_h265_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
2888 {
2889   GstH265Parse *h265parse;
2890   GstBuffer *buffer;
2891   GstEvent *event;
2892   GstBuffer *parse_buffer = NULL;
2893
2894   h265parse = GST_H265_PARSE (parse);
2895
2896   if (h265parse->first_frame) {
2897     GstTagList *taglist;
2898     GstCaps *caps;
2899
2900     /* codec tag */
2901     caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
2902     if (G_UNLIKELY (caps == NULL)) {
2903       if (GST_PAD_IS_FLUSHING (GST_BASE_PARSE_SRC_PAD (parse))) {
2904         GST_INFO_OBJECT (parse, "Src pad is flushing");
2905         return GST_FLOW_FLUSHING;
2906       } else {
2907         GST_INFO_OBJECT (parse, "Src pad is not negotiated!");
2908         return GST_FLOW_NOT_NEGOTIATED;
2909       }
2910     }
2911
2912     taglist = gst_tag_list_new_empty ();
2913     gst_pb_utils_add_codec_description_to_tag_list (taglist,
2914         GST_TAG_VIDEO_CODEC, caps);
2915     gst_caps_unref (caps);
2916
2917     gst_base_parse_merge_tags (parse, taglist, GST_TAG_MERGE_REPLACE);
2918     gst_tag_list_unref (taglist);
2919
2920     /* also signals the end of first-frame processing */
2921     h265parse->first_frame = FALSE;
2922   }
2923
2924   buffer = frame->buffer;
2925
2926   if ((event = check_pending_key_unit_event (h265parse->force_key_unit_event,
2927               &parse->segment, GST_BUFFER_TIMESTAMP (buffer),
2928               GST_BUFFER_FLAGS (buffer), h265parse->pending_key_unit_ts))) {
2929     gst_h265_parse_prepare_key_unit (h265parse, event);
2930   }
2931
2932   /* periodic VPS/SPS/PPS sending */
2933   if (h265parse->interval > 0 || h265parse->push_codec) {
2934     GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer);
2935     guint64 diff;
2936     gboolean initial_frame = FALSE;
2937
2938     /* init */
2939     if (!GST_CLOCK_TIME_IS_VALID (h265parse->last_report)) {
2940       h265parse->last_report = timestamp;
2941       initial_frame = TRUE;
2942     }
2943
2944     if (h265parse->idr_pos >= 0) {
2945       GST_LOG_OBJECT (h265parse, "IDR nal at offset %d", h265parse->idr_pos);
2946
2947       if (timestamp > h265parse->last_report)
2948         diff = timestamp - h265parse->last_report;
2949       else
2950         diff = 0;
2951
2952       GST_LOG_OBJECT (h265parse,
2953           "now %" GST_TIME_FORMAT ", last VPS/SPS/PPS %" GST_TIME_FORMAT,
2954           GST_TIME_ARGS (timestamp), GST_TIME_ARGS (h265parse->last_report));
2955
2956       GST_DEBUG_OBJECT (h265parse,
2957           "interval since last VPS/SPS/PPS %" GST_TIME_FORMAT,
2958           GST_TIME_ARGS (diff));
2959
2960       if (GST_TIME_AS_SECONDS (diff) >= h265parse->interval ||
2961           initial_frame || h265parse->push_codec) {
2962         GstClockTime new_ts;
2963
2964         /* avoid overwriting a perfectly fine timestamp */
2965         new_ts = GST_CLOCK_TIME_IS_VALID (timestamp) ? timestamp :
2966             h265parse->last_report;
2967
2968         if (gst_h265_parse_handle_vps_sps_pps_nals (h265parse, buffer, frame)) {
2969           h265parse->last_report = new_ts;
2970         }
2971       }
2972
2973       /* we pushed whatever we had */
2974       h265parse->push_codec = FALSE;
2975       h265parse->have_vps = FALSE;
2976       h265parse->have_sps = FALSE;
2977       h265parse->have_pps = FALSE;
2978       h265parse->state &= GST_H265_PARSE_STATE_VALID_PICTURE_HEADERS;
2979     }
2980   } else if (h265parse->interval == -1) {
2981     if (h265parse->idr_pos >= 0) {
2982       GST_LOG_OBJECT (h265parse, "IDR nal at offset %d", h265parse->idr_pos);
2983
2984       gst_h265_parse_handle_vps_sps_pps_nals (h265parse, buffer, frame);
2985
2986       /* we pushed whatever we had */
2987       h265parse->push_codec = FALSE;
2988       h265parse->have_vps = FALSE;
2989       h265parse->have_sps = FALSE;
2990       h265parse->have_pps = FALSE;
2991       h265parse->state &= GST_H265_PARSE_STATE_VALID_PICTURE_HEADERS;
2992     }
2993   }
2994
2995   if (frame->out_buffer) {
2996     parse_buffer = frame->out_buffer =
2997         gst_buffer_make_writable (frame->out_buffer);
2998   } else {
2999     parse_buffer = frame->buffer = gst_buffer_make_writable (frame->buffer);
3000   }
3001
3002   /* see section D.3.3 of the spec */
3003   switch (h265parse->sei_pic_struct) {
3004     case GST_H265_SEI_PIC_STRUCT_TOP_BOTTOM:
3005     case GST_H265_SEI_PIC_STRUCT_BOTTOM_TOP:
3006     case GST_H265_SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
3007     case GST_H265_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
3008       GST_BUFFER_FLAG_SET (parse_buffer, GST_VIDEO_BUFFER_FLAG_INTERLACED);
3009       break;
3010     case GST_H265_SEI_PIC_STRUCT_TOP_FIELD:
3011     case GST_H265_SEI_PIC_STRUCT_TOP_PAIRED_NEXT_BOTTOM:
3012     case GST_H265_SEI_PIC_STRUCT_TOP_PAIRED_PREVIOUS_BOTTOM:
3013       GST_BUFFER_FLAG_SET (parse_buffer, GST_VIDEO_BUFFER_FLAG_INTERLACED);
3014       GST_BUFFER_FLAG_SET (parse_buffer, GST_VIDEO_BUFFER_FLAG_TOP_FIELD);
3015       break;
3016     case GST_H265_SEI_PIC_STRUCT_BOTTOM_FIELD:
3017     case GST_H265_SEI_PIC_STRUCT_BOTTOM_PAIRED_PREVIOUS_TOP:
3018     case GST_H265_SEI_PIC_STRUCT_BOTTOM_PAIRED_NEXT_TOP:
3019       GST_BUFFER_FLAG_SET (parse_buffer, GST_VIDEO_BUFFER_FLAG_INTERLACED);
3020       GST_BUFFER_FLAG_SET (parse_buffer, GST_VIDEO_BUFFER_FLAG_BOTTOM_FIELD);
3021       break;
3022     default:
3023       break;
3024   }
3025
3026   {
3027     guint i = 0;
3028
3029     for (i = 0; i < h265parse->time_code.num_clock_ts; i++) {
3030       gint field_count = -1;
3031       guint n_frames;
3032       GstVideoTimeCodeFlags flags = 0;
3033
3034       if (!h265parse->time_code.clock_timestamp_flag[i])
3035         break;
3036
3037       h265parse->time_code.clock_timestamp_flag[i] = 0;
3038
3039       /* Table D.2 */
3040       switch (h265parse->sei_pic_struct) {
3041         case GST_H265_SEI_PIC_STRUCT_FRAME:
3042         case GST_H265_SEI_PIC_STRUCT_TOP_FIELD:
3043         case GST_H265_SEI_PIC_STRUCT_BOTTOM_FIELD:
3044           field_count = h265parse->sei_pic_struct;
3045           break;
3046         case GST_H265_SEI_PIC_STRUCT_TOP_BOTTOM:
3047         case GST_H265_SEI_PIC_STRUCT_TOP_PAIRED_PREVIOUS_BOTTOM:
3048         case GST_H265_SEI_PIC_STRUCT_TOP_PAIRED_NEXT_BOTTOM:
3049           field_count = i + 1;
3050           break;
3051         case GST_H265_SEI_PIC_STRUCT_BOTTOM_TOP:
3052         case GST_H265_SEI_PIC_STRUCT_BOTTOM_PAIRED_PREVIOUS_TOP:
3053         case GST_H265_SEI_PIC_STRUCT_BOTTOM_PAIRED_NEXT_TOP:
3054           field_count = 2 - i;
3055           break;
3056         case GST_H265_SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
3057           field_count = i % 2 ? 2 : 1;
3058           break;
3059         case GST_H265_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
3060           field_count = i % 2 ? 1 : 2;
3061           break;
3062         case GST_H265_SEI_PIC_STRUCT_FRAME_DOUBLING:
3063         case GST_H265_SEI_PIC_STRUCT_FRAME_TRIPLING:
3064           field_count = 0;
3065           break;
3066       }
3067
3068       if (field_count == -1) {
3069         GST_WARNING_OBJECT (parse,
3070             "failed to determine field count for timecode");
3071         field_count = 0;
3072       }
3073
3074       /* Dropping of the two lowest (value 0 and 1) n_frames[ i ] counts when
3075        * seconds_value[ i ] is equal to 0 and minutes_value[ i ] is not an integer
3076        * multiple of 10 */
3077       if (h265parse->time_code.counting_type[i] == 4)
3078         flags |= GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME;
3079
3080       if (h265parse->sei_pic_struct != GST_H265_SEI_PIC_STRUCT_FRAME)
3081         flags |= GST_VIDEO_TIME_CODE_FLAGS_INTERLACED;
3082
3083       n_frames =
3084           gst_util_uint64_scale_int (h265parse->time_code.n_frames[i], 1,
3085           2 - h265parse->time_code.units_field_based_flag[i]);
3086
3087       gst_buffer_add_video_time_code_meta_full (parse_buffer,
3088           h265parse->parsed_fps_n,
3089           h265parse->parsed_fps_d,
3090           NULL,
3091           flags,
3092           h265parse->time_code.hours_flag[i] ? h265parse->time_code.
3093           hours_value[i] : 0,
3094           h265parse->time_code.minutes_flag[i] ? h265parse->time_code.
3095           minutes_value[i] : 0,
3096           h265parse->time_code.seconds_flag[i] ? h265parse->time_code.
3097           seconds_value[i] : 0, n_frames, field_count);
3098     }
3099   }
3100
3101   gst_video_push_user_data ((GstElement *) h265parse, &h265parse->user_data,
3102       parse_buffer);
3103
3104   gst_h265_parse_reset_frame (h265parse);
3105
3106   return GST_FLOW_OK;
3107 }
3108
3109 static gboolean
3110 gst_h265_parse_set_caps (GstBaseParse * parse, GstCaps * caps)
3111 {
3112   GstH265Parse *h265parse;
3113   GstStructure *str;
3114   const GValue *value;
3115   GstBuffer *codec_data = NULL;
3116   gsize off, size;
3117   guint format, align;
3118   guint num_nals, i, j;
3119   GstH265NalUnit nalu;
3120   GstH265ParserResult parseres;
3121   GstCaps *old_caps;
3122
3123   h265parse = GST_H265_PARSE (parse);
3124
3125   /* reset */
3126   h265parse->push_codec = FALSE;
3127
3128   old_caps = gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (parse));
3129   if (old_caps) {
3130     if (!gst_caps_is_equal (old_caps, caps))
3131       gst_h265_parse_reset_stream_info (h265parse);
3132     gst_caps_unref (old_caps);
3133   }
3134
3135   str = gst_caps_get_structure (caps, 0);
3136
3137   /* accept upstream info if provided */
3138   gst_structure_get_int (str, "width", &h265parse->width);
3139   gst_structure_get_int (str, "height", &h265parse->height);
3140   gst_structure_get_fraction (str, "framerate", &h265parse->fps_num,
3141       &h265parse->fps_den);
3142   gst_structure_get_fraction (str, "pixel-aspect-ratio",
3143       &h265parse->upstream_par_n, &h265parse->upstream_par_d);
3144
3145   /* get upstream format and align from caps */
3146   gst_h265_parse_format_from_caps (caps, &format, &align);
3147
3148   /* packetized video has a codec_data */
3149   if (format != GST_H265_PARSE_FORMAT_BYTE &&
3150       (value = gst_structure_get_value (str, "codec_data"))) {
3151     GstMapInfo map;
3152     guint8 *data;
3153     guint num_nal_arrays;
3154
3155     GST_DEBUG_OBJECT (h265parse, "have packetized h265");
3156     /* make note for optional split processing */
3157     h265parse->packetized = TRUE;
3158
3159     codec_data = gst_value_get_buffer (value);
3160     if (!codec_data)
3161       goto wrong_type;
3162     gst_buffer_map (codec_data, &map, GST_MAP_READ);
3163     data = map.data;
3164     size = map.size;
3165
3166     /* parse the hvcC data */
3167     if (size < 23) {
3168       gst_buffer_unmap (codec_data, &map);
3169       goto hvcc_too_small;
3170     }
3171     /* parse the version, this must be one but
3172      * is zero until the spec is finalized */
3173     if (data[0] != 0 && data[0] != 1) {
3174       gst_buffer_unmap (codec_data, &map);
3175       goto wrong_version;
3176     }
3177
3178     h265parse->nal_length_size = (data[21] & 0x03) + 1;
3179     GST_DEBUG_OBJECT (h265parse, "nal length size %u",
3180         h265parse->nal_length_size);
3181
3182     num_nal_arrays = data[22];
3183     off = 23;
3184
3185     for (i = 0; i < num_nal_arrays; i++) {
3186       if (off + 3 >= size) {
3187         gst_buffer_unmap (codec_data, &map);
3188         goto hvcc_too_small;
3189       }
3190
3191       num_nals = GST_READ_UINT16_BE (data + off + 1);
3192       off += 3;
3193       for (j = 0; j < num_nals; j++) {
3194         parseres = gst_h265_parser_identify_nalu_hevc (h265parse->nalparser,
3195             data, off, size, 2, &nalu);
3196
3197         if (parseres != GST_H265_PARSER_OK) {
3198           gst_buffer_unmap (codec_data, &map);
3199           goto hvcc_too_small;
3200         }
3201
3202         gst_h265_parse_process_nal (h265parse, &nalu);
3203         off = nalu.offset + nalu.size;
3204       }
3205     }
3206     gst_buffer_unmap (codec_data, &map);
3207
3208     /* don't confuse codec_data with inband vps/sps/pps */
3209     h265parse->have_vps_in_frame = FALSE;
3210     h265parse->have_sps_in_frame = FALSE;
3211     h265parse->have_pps_in_frame = FALSE;
3212   } else {
3213     GST_DEBUG_OBJECT (h265parse, "have bytestream h265");
3214     /* nothing to pre-process */
3215     h265parse->packetized = FALSE;
3216     /* we have 4 sync bytes */
3217     h265parse->nal_length_size = 4;
3218
3219     if (format == GST_H265_PARSE_FORMAT_NONE) {
3220       format = GST_H265_PARSE_FORMAT_BYTE;
3221       align = GST_H265_PARSE_ALIGN_AU;
3222     }
3223   }
3224
3225   {
3226     GstCaps *in_caps;
3227
3228     /* prefer input type determined above */
3229     in_caps = gst_caps_new_simple ("video/x-h265",
3230         "parsed", G_TYPE_BOOLEAN, TRUE,
3231         "stream-format", G_TYPE_STRING,
3232         gst_h265_parse_get_string (h265parse, TRUE, format),
3233         "alignment", G_TYPE_STRING,
3234         gst_h265_parse_get_string (h265parse, FALSE, align), NULL);
3235     /* negotiate with downstream, sets ->format and ->align */
3236     gst_h265_parse_negotiate (h265parse, format, in_caps);
3237     gst_caps_unref (in_caps);
3238   }
3239
3240   if (format == h265parse->format && align == h265parse->align) {
3241     /* do not set CAPS and passthrough mode if SPS/PPS have not been parsed */
3242     if (h265parse->have_sps && h265parse->have_pps) {
3243       /* Don't enable passthrough here. This element will parse various
3244        * SEI messages which would be very important/useful for downstream
3245        * (HDR, timecode for example)
3246        */
3247 #if 0
3248       gst_base_parse_set_passthrough (parse, TRUE);
3249 #endif
3250
3251       /* we did parse codec-data and might supplement src caps */
3252       gst_h265_parse_update_src_caps (h265parse, caps);
3253     }
3254   } else if (format == GST_H265_PARSE_FORMAT_HVC1
3255       || format == GST_H265_PARSE_FORMAT_HEV1) {
3256     /* if input != output, and input is hevc, must split before anything else */
3257     /* arrange to insert codec-data in-stream if needed.
3258      * src caps are only arranged for later on */
3259     h265parse->push_codec = TRUE;
3260     h265parse->have_vps = FALSE;
3261     h265parse->have_sps = FALSE;
3262     h265parse->have_pps = FALSE;
3263     if (h265parse->align == GST_H265_PARSE_ALIGN_NAL)
3264       h265parse->split_packetized = TRUE;
3265     h265parse->packetized = TRUE;
3266   }
3267
3268   h265parse->in_align = align;
3269
3270   return TRUE;
3271
3272   /* ERRORS */
3273 hvcc_too_small:
3274   {
3275     GST_DEBUG_OBJECT (h265parse, "hvcC size %" G_GSIZE_FORMAT " < 23", size);
3276     goto refuse_caps;
3277   }
3278 wrong_version:
3279   {
3280     GST_DEBUG_OBJECT (h265parse, "wrong hvcC version");
3281     goto refuse_caps;
3282   }
3283 wrong_type:
3284   {
3285     GST_DEBUG_OBJECT (h265parse, "wrong codec-data type");
3286     goto refuse_caps;
3287   }
3288 refuse_caps:
3289   {
3290     GST_WARNING_OBJECT (h265parse, "refused caps %" GST_PTR_FORMAT, caps);
3291     return FALSE;
3292   }
3293 }
3294
3295 static void
3296 remove_fields (GstCaps * caps, gboolean all)
3297 {
3298   guint i, n;
3299
3300   n = gst_caps_get_size (caps);
3301   for (i = 0; i < n; i++) {
3302     GstStructure *s = gst_caps_get_structure (caps, i);
3303
3304     if (all) {
3305       gst_structure_remove_field (s, "alignment");
3306       gst_structure_remove_field (s, "stream-format");
3307     }
3308     gst_structure_remove_field (s, "parsed");
3309   }
3310 }
3311
3312 static GstCaps *
3313 gst_h265_parse_get_caps (GstBaseParse * parse, GstCaps * filter)
3314 {
3315   GstCaps *peercaps, *templ;
3316   GstCaps *res, *tmp, *pcopy;
3317
3318   templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
3319   if (filter) {
3320     GstCaps *fcopy = gst_caps_copy (filter);
3321     /* Remove the fields we convert */
3322     remove_fields (fcopy, TRUE);
3323     peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), fcopy);
3324     gst_caps_unref (fcopy);
3325   } else
3326     peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), NULL);
3327
3328   pcopy = gst_caps_copy (peercaps);
3329   remove_fields (pcopy, TRUE);
3330
3331   res = gst_caps_intersect_full (pcopy, templ, GST_CAPS_INTERSECT_FIRST);
3332   gst_caps_unref (pcopy);
3333   gst_caps_unref (templ);
3334
3335   if (filter) {
3336     GstCaps *tmp = gst_caps_intersect_full (res, filter,
3337         GST_CAPS_INTERSECT_FIRST);
3338     gst_caps_unref (res);
3339     res = tmp;
3340   }
3341
3342   /* Try if we can put the downstream caps first */
3343   pcopy = gst_caps_copy (peercaps);
3344   remove_fields (pcopy, FALSE);
3345   tmp = gst_caps_intersect_full (pcopy, res, GST_CAPS_INTERSECT_FIRST);
3346   gst_caps_unref (pcopy);
3347   if (!gst_caps_is_empty (tmp))
3348     res = gst_caps_merge (tmp, res);
3349   else
3350     gst_caps_unref (tmp);
3351
3352   gst_caps_unref (peercaps);
3353   return res;
3354 }
3355
3356 static gboolean
3357 gst_h265_parse_event (GstBaseParse * parse, GstEvent * event)
3358 {
3359   gboolean res;
3360   GstH265Parse *h265parse = GST_H265_PARSE (parse);
3361
3362   switch (GST_EVENT_TYPE (event)) {
3363     case GST_EVENT_CUSTOM_DOWNSTREAM:
3364     {
3365       GstClockTime timestamp, stream_time, running_time;
3366       gboolean all_headers;
3367       guint count;
3368
3369       if (gst_video_event_is_force_key_unit (event)) {
3370         gst_video_event_parse_downstream_force_key_unit (event,
3371             &timestamp, &stream_time, &running_time, &all_headers, &count);
3372
3373         GST_INFO_OBJECT (h265parse, "received downstream force key unit event, "
3374             "seqnum %d running_time %" GST_TIME_FORMAT
3375             " all_headers %d count %d", gst_event_get_seqnum (event),
3376             GST_TIME_ARGS (running_time), all_headers, count);
3377         if (h265parse->force_key_unit_event) {
3378           GST_INFO_OBJECT (h265parse, "ignoring force key unit event "
3379               "as one is already queued");
3380         } else {
3381           h265parse->pending_key_unit_ts = running_time;
3382           gst_event_replace (&h265parse->force_key_unit_event, event);
3383         }
3384         gst_event_unref (event);
3385         res = TRUE;
3386       } else {
3387         res = GST_BASE_PARSE_CLASS (parent_class)->sink_event (parse, event);
3388         break;
3389       }
3390       break;
3391     }
3392     case GST_EVENT_FLUSH_STOP:
3393     case GST_EVENT_SEGMENT_DONE:
3394       h265parse->push_codec = TRUE;
3395       res = GST_BASE_PARSE_CLASS (parent_class)->sink_event (parse, event);
3396       break;
3397     case GST_EVENT_SEGMENT:
3398     {
3399       const GstSegment *segment = NULL;
3400
3401       gst_event_parse_segment (event, &segment);
3402
3403       h265parse->last_report = GST_CLOCK_TIME_NONE;
3404
3405       if (segment->flags & GST_SEEK_FLAG_TRICKMODE_FORWARD_PREDICTED) {
3406         GST_DEBUG_OBJECT (h265parse, "Will discard bidirectional frames");
3407         h265parse->discard_bidirectional = TRUE;
3408       }
3409
3410       res = GST_BASE_PARSE_CLASS (parent_class)->sink_event (parse, event);
3411       break;
3412     }
3413     default:
3414       res = GST_BASE_PARSE_CLASS (parent_class)->sink_event (parse, event);
3415       break;
3416   }
3417   return res;
3418 }
3419
3420 static gboolean
3421 gst_h265_parse_src_event (GstBaseParse * parse, GstEvent * event)
3422 {
3423   gboolean res;
3424   GstH265Parse *h265parse = GST_H265_PARSE (parse);
3425
3426   switch (GST_EVENT_TYPE (event)) {
3427     case GST_EVENT_CUSTOM_UPSTREAM:
3428     {
3429       GstClockTime running_time;
3430       gboolean all_headers;
3431       guint count;
3432
3433       if (gst_video_event_is_force_key_unit (event)) {
3434         gst_video_event_parse_upstream_force_key_unit (event,
3435             &running_time, &all_headers, &count);
3436
3437         GST_INFO_OBJECT (h265parse, "received upstream force-key-unit event, "
3438             "seqnum %d running_time %" GST_TIME_FORMAT
3439             " all_headers %d count %d", gst_event_get_seqnum (event),
3440             GST_TIME_ARGS (running_time), all_headers, count);
3441
3442         if (all_headers) {
3443           h265parse->pending_key_unit_ts = running_time;
3444           gst_event_replace (&h265parse->force_key_unit_event, event);
3445         }
3446       }
3447       res = GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
3448       break;
3449     }
3450     default:
3451       res = GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
3452       break;
3453   }
3454
3455   return res;
3456 }
3457
3458 static void
3459 gst_h265_parse_set_property (GObject * object, guint prop_id,
3460     const GValue * value, GParamSpec * pspec)
3461 {
3462   GstH265Parse *parse;
3463   parse = GST_H265_PARSE (object);
3464
3465   switch (prop_id) {
3466     case PROP_CONFIG_INTERVAL:
3467       parse->interval = g_value_get_int (value);
3468       break;
3469     default:
3470       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3471       break;
3472   }
3473 }
3474
3475 static void
3476 gst_h265_parse_get_property (GObject * object, guint prop_id, GValue * value,
3477     GParamSpec * pspec)
3478 {
3479   GstH265Parse *parse;
3480   parse = GST_H265_PARSE (object);
3481
3482   switch (prop_id) {
3483     case PROP_CONFIG_INTERVAL:
3484       g_value_set_int (value, parse->interval);
3485       break;
3486     default:
3487       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3488       break;
3489   }
3490 }