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