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