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