29968df1282253b9555a673c526bbfa7d919253b
[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 void
1933 gst_h265_parse_update_src_caps (GstH265Parse * h265parse, GstCaps * caps)
1934 {
1935   GstH265SPS *sps = NULL;
1936   GstCaps *sink_caps, *src_caps;
1937   gboolean modified = FALSE;
1938   GstBuffer *buf = NULL;
1939   GstStructure *s = NULL;
1940
1941   if (G_UNLIKELY (!gst_pad_has_current_caps (GST_BASE_PARSE_SRC_PAD
1942               (h265parse))))
1943     modified = TRUE;
1944   else if (G_UNLIKELY (!h265parse->update_caps))
1945     return;
1946
1947   /* if this is being called from the first _setcaps call, caps on the sinkpad
1948    * aren't set yet and so they need to be passed as an argument */
1949   if (caps)
1950     sink_caps = gst_caps_ref (caps);
1951   else
1952     sink_caps = gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (h265parse));
1953
1954   /* carry over input caps as much as possible; override with our own stuff */
1955   if (!sink_caps)
1956     sink_caps = gst_caps_new_empty_simple ("video/x-h265");
1957   else
1958     s = gst_caps_get_structure (sink_caps, 0);
1959
1960   sps = h265parse->nalparser->last_sps;
1961   GST_DEBUG_OBJECT (h265parse, "sps: %p", sps);
1962
1963   /* only codec-data for nice-and-clean au aligned packetized hevc format */
1964   if ((h265parse->format == GST_H265_PARSE_FORMAT_HVC1
1965           || h265parse->format == GST_H265_PARSE_FORMAT_HEV1)
1966       && h265parse->align == GST_H265_PARSE_ALIGN_AU) {
1967     buf = gst_h265_parse_make_codec_data (h265parse);
1968     if (buf && h265parse->codec_data) {
1969       GstMapInfo map;
1970
1971       gst_buffer_map (buf, &map, GST_MAP_READ);
1972       if (map.size != gst_buffer_get_size (h265parse->codec_data) ||
1973           gst_buffer_memcmp (h265parse->codec_data, 0, map.data, map.size))
1974         modified = TRUE;
1975
1976       gst_buffer_unmap (buf, &map);
1977     } else {
1978       if (!buf && h265parse->codec_data_in)
1979         buf = gst_buffer_ref (h265parse->codec_data_in);
1980       modified = TRUE;
1981     }
1982   }
1983
1984   caps = NULL;
1985   if (G_UNLIKELY (!sps)) {
1986     caps = gst_caps_copy (sink_caps);
1987   } else {
1988     gint crop_width, crop_height;
1989     const gchar *chroma_format = NULL;
1990     guint bit_depth_chroma;
1991     GstH265VPS *vps = sps->vps;
1992     GstH265VUIParams *vui = &sps->vui_params;
1993     gchar *colorimetry = NULL;
1994
1995     GST_DEBUG_OBJECT (h265parse, "vps: %p", vps);
1996
1997     if (sps->conformance_window_flag) {
1998       crop_width = sps->crop_rect_width;
1999       crop_height = sps->crop_rect_height;
2000     } else {
2001       crop_width = sps->width;
2002       crop_height = sps->height;
2003     }
2004
2005     if (G_UNLIKELY (h265parse->width != crop_width ||
2006             h265parse->height != crop_height)) {
2007       h265parse->width = crop_width;
2008       h265parse->height = sps->profile_tier_level.interlaced_source_flag ?
2009           crop_height * 2 : crop_height;
2010       GST_INFO_OBJECT (h265parse, "resolution changed %dx%d",
2011           h265parse->width, h265parse->height);
2012       modified = TRUE;
2013     }
2014
2015     /* 0/1 is set as the default in the codec parser */
2016     if (vui->timing_info_present_flag) {
2017       gint fps_num = 0, fps_den = 1;
2018
2019       if (!(sps->fps_num == 0 && sps->fps_den == 1)) {
2020         fps_num = sps->fps_num;
2021         fps_den = sps->fps_den;
2022       } else if (!(sps->vui_params.time_scale == 0 &&
2023               sps->vui_params.num_units_in_tick == 1)) {
2024         fps_num = sps->vui_params.time_scale;
2025         fps_den = sps->vui_params.num_units_in_tick;
2026
2027         if (sps->profile_tier_level.interlaced_source_flag)
2028           fps_num /= 2;
2029       }
2030
2031       if (G_UNLIKELY (h265parse->fps_num != fps_num
2032               || h265parse->fps_den != fps_den)) {
2033         GST_INFO_OBJECT (h265parse, "framerate changed %d/%d",
2034             fps_num, fps_den);
2035         h265parse->fps_num = fps_num;
2036         h265parse->fps_den = fps_den;
2037         modified = TRUE;
2038       }
2039     }
2040
2041     if (vui->aspect_ratio_info_present_flag) {
2042       if (G_UNLIKELY ((h265parse->parsed_par_n != vui->par_n)
2043               && (h265parse->parsed_par_d != sps->vui_params.par_d))) {
2044         h265parse->parsed_par_n = vui->par_n;
2045         h265parse->parsed_par_d = vui->par_d;
2046         GST_INFO_OBJECT (h265parse, "pixel aspect ratio has been changed %d/%d",
2047             h265parse->parsed_par_n, h265parse->parsed_par_d);
2048         modified = TRUE;
2049       }
2050
2051     }
2052
2053     if (vui->video_signal_type_present_flag &&
2054         vui->colour_description_present_flag) {
2055       GstVideoColorimetry ci = { 0, };
2056       gchar *old_colorimetry = NULL;
2057
2058       if (vui->video_full_range_flag)
2059         ci.range = GST_VIDEO_COLOR_RANGE_0_255;
2060       else
2061         ci.range = GST_VIDEO_COLOR_RANGE_16_235;
2062
2063       ci.matrix = gst_video_color_matrix_from_iso (vui->matrix_coefficients);
2064       ci.transfer =
2065           gst_video_transfer_function_from_iso (vui->transfer_characteristics);
2066       ci.primaries = gst_video_color_primaries_from_iso (vui->colour_primaries);
2067
2068       old_colorimetry =
2069           gst_video_colorimetry_to_string (&h265parse->parsed_colorimetry);
2070       colorimetry = gst_video_colorimetry_to_string (&ci);
2071
2072       if (colorimetry && g_strcmp0 (old_colorimetry, colorimetry)) {
2073         GST_INFO_OBJECT (h265parse,
2074             "colorimetry has been changed from %s to %s",
2075             GST_STR_NULL (old_colorimetry), colorimetry);
2076         h265parse->parsed_colorimetry = ci;
2077         modified = TRUE;
2078       }
2079
2080       g_free (old_colorimetry);
2081     }
2082
2083     if (G_UNLIKELY (modified || h265parse->update_caps)) {
2084       gint fps_num = h265parse->fps_num;
2085       gint fps_den = h265parse->fps_den;
2086       gint width, height;
2087       GstClockTime latency = 0;
2088
2089       caps = gst_caps_copy (sink_caps);
2090
2091       /* sps should give this but upstream overrides */
2092       if (s && gst_structure_has_field (s, "width"))
2093         gst_structure_get_int (s, "width", &width);
2094       else
2095         width = h265parse->width;
2096
2097       if (s && gst_structure_has_field (s, "height"))
2098         gst_structure_get_int (s, "height", &height);
2099       else
2100         height = h265parse->height;
2101
2102       gst_caps_set_simple (caps, "width", G_TYPE_INT, width,
2103           "height", G_TYPE_INT, height, NULL);
2104
2105       h265parse->parsed_framerate = FALSE;
2106       /* upstream overrides */
2107       if (s && gst_structure_has_field (s, "framerate"))
2108         gst_structure_get_fraction (s, "framerate", &fps_num, &fps_den);
2109
2110       /* but not necessarily or reliably this */
2111       if (fps_den > 0) {
2112         GstStructure *s2;
2113         GstClockTime val;
2114
2115         GST_INFO_OBJECT (h265parse, "setting framerate in caps");
2116         gst_caps_set_simple (caps, "framerate",
2117             GST_TYPE_FRACTION, fps_num, fps_den, NULL);
2118         s2 = gst_caps_get_structure (caps, 0);
2119         gst_structure_get_fraction (s2, "framerate", &h265parse->parsed_fps_n,
2120             &h265parse->parsed_fps_d);
2121         gst_base_parse_set_frame_rate (GST_BASE_PARSE (h265parse),
2122             fps_num, fps_den, 0, 0);
2123         val = sps->profile_tier_level.interlaced_source_flag ? GST_SECOND / 2 :
2124             GST_SECOND;
2125         h265parse->parsed_framerate = TRUE;
2126
2127         /* If we know the frame duration, and if we are not in one of the zero
2128          * latency pattern, add one frame of latency */
2129         if (fps_num > 0 &&
2130             h265parse->in_align != GST_H265_PARSE_ALIGN_AU &&
2131             !(h265parse->in_align == GST_H265_PARSE_ALIGN_NAL &&
2132                 h265parse->align == GST_H265_PARSE_ALIGN_NAL))
2133           latency = gst_util_uint64_scale (val, fps_den, fps_num);
2134
2135         gst_base_parse_set_latency (GST_BASE_PARSE (h265parse), latency,
2136             latency);
2137       }
2138
2139       bit_depth_chroma = sps->bit_depth_chroma_minus8 + 8;
2140
2141       switch (sps->chroma_format_idc) {
2142         case 0:
2143           chroma_format = "4:0:0";
2144           bit_depth_chroma = 0;
2145           break;
2146         case 1:
2147           chroma_format = "4:2:0";
2148           break;
2149         case 2:
2150           chroma_format = "4:2:2";
2151           break;
2152         case 3:
2153           chroma_format = "4:4:4";
2154           break;
2155         default:
2156           break;
2157       }
2158
2159       if (chroma_format)
2160         gst_caps_set_simple (caps, "chroma-format", G_TYPE_STRING,
2161             chroma_format, "bit-depth-luma", G_TYPE_UINT,
2162             sps->bit_depth_luma_minus8 + 8, "bit-depth-chroma", G_TYPE_UINT,
2163             bit_depth_chroma, NULL);
2164
2165       if (colorimetry && (!s || !gst_structure_has_field (s, "colorimetry"))) {
2166         gst_caps_set_simple (caps, "colorimetry", G_TYPE_STRING, colorimetry,
2167             NULL);
2168       }
2169     }
2170
2171     g_free (colorimetry);
2172   }
2173
2174   if (caps) {
2175     gint par_n, par_d;
2176     const gchar *mdi_str = NULL;
2177     const gchar *cll_str = NULL;
2178     gboolean codec_data_modified = FALSE;
2179
2180     gst_caps_set_simple (caps, "parsed", G_TYPE_BOOLEAN, TRUE,
2181         "stream-format", G_TYPE_STRING,
2182         gst_h265_parse_get_string (h265parse, TRUE, h265parse->format),
2183         "alignment", G_TYPE_STRING,
2184         gst_h265_parse_get_string (h265parse, FALSE, h265parse->align), NULL);
2185
2186     gst_h265_parse_get_par (h265parse, &par_n, &par_d);
2187     if (par_n != 0 && par_d != 0 &&
2188         (!s || !gst_structure_has_field (s, "pixel-aspect-ratio"))) {
2189       GST_INFO_OBJECT (h265parse, "PAR %d/%d", par_n, par_d);
2190       gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION,
2191           par_n, par_d, NULL);
2192     }
2193
2194     /* set profile and level in caps */
2195     if (sps) {
2196       const gchar *profile, *tier, *level;
2197       GstH265Profile p;
2198
2199       p = gst_h265_get_profile_from_sps (sps);
2200
2201       profile = gst_h265_profile_to_string (p);
2202       if (profile != NULL)
2203         gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
2204
2205       tier = get_tier_string (sps->profile_tier_level.tier_flag);
2206       if (tier != NULL)
2207         gst_caps_set_simple (caps, "tier", G_TYPE_STRING, tier, NULL);
2208
2209       level = get_level_string (sps->profile_tier_level.level_idc);
2210       if (level != NULL)
2211         gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
2212
2213       /* relax the profile constraint to find a suitable decoder */
2214       ensure_caps_profile (h265parse, caps, sps, p);
2215     }
2216
2217     if (s)
2218       mdi_str = gst_structure_get_string (s, "mastering-display-info");
2219     if (mdi_str) {
2220       gst_caps_set_simple (caps, "mastering-display-info", G_TYPE_STRING,
2221           mdi_str, NULL);
2222     } else if (h265parse->mastering_display_info_state !=
2223         GST_H265_PARSE_SEI_EXPIRED &&
2224         !gst_video_mastering_display_info_add_to_caps
2225         (&h265parse->mastering_display_info, caps)) {
2226       GST_WARNING_OBJECT (h265parse,
2227           "Couldn't set mastering display info to caps");
2228     }
2229
2230     if (s)
2231       cll_str = gst_structure_get_string (s, "content-light-level");
2232     if (cll_str) {
2233       gst_caps_set_simple (caps, "content-light-level", G_TYPE_STRING, cll_str,
2234           NULL);
2235     } else if (h265parse->content_light_level_state !=
2236         GST_H265_PARSE_SEI_EXPIRED &&
2237         !gst_video_content_light_level_add_to_caps
2238         (&h265parse->content_light_level, caps)) {
2239       GST_WARNING_OBJECT (h265parse,
2240           "Couldn't set content light level to caps");
2241     }
2242
2243     src_caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (h265parse));
2244
2245     if (src_caps) {
2246       GstStructure *src_caps_str = gst_caps_get_structure (src_caps, 0);
2247
2248       /* use codec data from old caps for comparison if we have pushed frame for now.
2249        * we don't want to resend caps if everything is same except codec data.
2250        * However, if the updated sps/pps is not in bitstream, we should put
2251        * it on bitstream */
2252       if (gst_structure_has_field (src_caps_str, "codec_data")) {
2253         const GValue *codec_data_value =
2254             gst_structure_get_value (src_caps_str, "codec_data");
2255
2256         if (!GST_VALUE_HOLDS_BUFFER (codec_data_value)) {
2257           GST_WARNING_OBJECT (h265parse, "codec_data does not hold buffer");
2258         } else if (!h265parse->first_frame) {
2259           /* If there is no pushed frame before, we can update caps without worry.
2260            * But updating codec_data in the middle of frames
2261            * (especially on non-keyframe) might make downstream be confused.
2262            * Therefore we are setting old codec data
2263            * (i.e., was pushed to downstream previously) to new caps candidate
2264            * here for gst_caps_is_strictly_equal() to be returned TRUE if only
2265            * the codec_data is different, and to avoid re-sending caps it
2266            * that case.
2267            */
2268           gst_caps_set_value (caps, "codec_data", codec_data_value);
2269
2270           /* check for codec_data update to re-send sps/pps inband data if
2271            * current frame has no sps/pps but upstream codec_data was updated.
2272            * Note that have_vps_in_frame is skipped here since it's optional  */
2273           if ((!h265parse->have_sps_in_frame || !h265parse->have_pps_in_frame)
2274               && buf) {
2275             GstBuffer *codec_data_buf = gst_value_get_buffer (codec_data_value);
2276             GstMapInfo map;
2277
2278             gst_buffer_map (buf, &map, GST_MAP_READ);
2279             if (map.size != gst_buffer_get_size (codec_data_buf) ||
2280                 gst_buffer_memcmp (codec_data_buf, 0, map.data, map.size)) {
2281               codec_data_modified = TRUE;
2282             }
2283
2284             gst_buffer_unmap (buf, &map);
2285           }
2286         }
2287       } else if (!buf) {
2288         GstStructure *s;
2289         /* remove any left-over codec-data hanging around */
2290         s = gst_caps_get_structure (caps, 0);
2291         gst_structure_remove_field (s, "codec_data");
2292       }
2293     }
2294
2295     if (!(src_caps && gst_caps_is_strictly_equal (src_caps, caps))) {
2296       /* update codec data to new value */
2297       if (buf) {
2298         gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
2299         gst_buffer_replace (&h265parse->codec_data, buf);
2300         gst_buffer_unref (buf);
2301         buf = NULL;
2302       } else {
2303         GstStructure *s;
2304         /* remove any left-over codec-data hanging around */
2305         s = gst_caps_get_structure (caps, 0);
2306         gst_structure_remove_field (s, "codec_data");
2307         gst_buffer_replace (&h265parse->codec_data, NULL);
2308       }
2309
2310       gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (h265parse), caps);
2311     } else if (codec_data_modified) {
2312       GST_DEBUG_OBJECT (h265parse,
2313           "Only codec_data is different, need inband vps/sps/pps update");
2314
2315       /* this will insert updated codec_data with next idr */
2316       h265parse->push_codec = TRUE;
2317     }
2318
2319     if (src_caps)
2320       gst_caps_unref (src_caps);
2321     gst_caps_unref (caps);
2322   }
2323
2324   gst_caps_unref (sink_caps);
2325   if (buf)
2326     gst_buffer_unref (buf);
2327
2328 }
2329
2330 static GstFlowReturn
2331 gst_h265_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
2332 {
2333   GstH265Parse *h265parse;
2334   GstBuffer *buffer;
2335   guint av;
2336
2337   h265parse = GST_H265_PARSE (parse);
2338   buffer = frame->buffer;
2339
2340   gst_h265_parse_update_src_caps (h265parse, NULL);
2341
2342   if (h265parse->fps_num > 0 && h265parse->fps_den > 0) {
2343     GstH265SPS *sps = h265parse->nalparser->last_sps;
2344     GstClockTime val;
2345
2346     val = (sps != NULL && sps->profile_tier_level.interlaced_source_flag) ?
2347         GST_SECOND / 2 : GST_SECOND;
2348     GST_BUFFER_DURATION (buffer) = gst_util_uint64_scale (val,
2349         h265parse->fps_den, h265parse->fps_num);
2350   }
2351
2352   if (h265parse->keyframe)
2353     GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2354   else
2355     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2356
2357   if (h265parse->discard_bidirectional && h265parse->bidirectional)
2358     goto discard;
2359
2360
2361   if (h265parse->header)
2362     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_HEADER);
2363   else
2364     GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_HEADER);
2365
2366   if (h265parse->discont) {
2367     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
2368     h265parse->discont = FALSE;
2369   }
2370
2371   if (h265parse->marker) {
2372     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_MARKER);
2373     h265parse->marker = FALSE;
2374   } else {
2375     GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_MARKER);
2376   }
2377
2378   /* replace with transformed HEVC output if applicable */
2379   av = gst_adapter_available (h265parse->frame_out);
2380   if (av) {
2381     GstBuffer *buf;
2382
2383     buf = gst_adapter_take_buffer (h265parse->frame_out, av);
2384     gst_buffer_copy_into (buf, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
2385     gst_buffer_replace (&frame->out_buffer, buf);
2386     gst_buffer_unref (buf);
2387   }
2388
2389 done:
2390   return GST_FLOW_OK;
2391
2392 discard:
2393   GST_DEBUG_OBJECT (h265parse, "Discarding bidirectional frame");
2394   frame->flags |= GST_BASE_PARSE_FRAME_FLAG_DROP;
2395   gst_h265_parse_reset_frame (h265parse);
2396   goto done;
2397
2398 }
2399
2400 /* sends a codec NAL downstream, decorating and transforming as needed.
2401  * No ownership is taken of @nal */
2402 static GstFlowReturn
2403 gst_h265_parse_push_codec_buffer (GstH265Parse * h265parse, GstBuffer * nal,
2404     GstBuffer * buffer)
2405 {
2406   GstMapInfo map;
2407
2408   gst_buffer_map (nal, &map, GST_MAP_READ);
2409   nal = gst_h265_parse_wrap_nal (h265parse, h265parse->format,
2410       map.data, map.size);
2411   gst_buffer_unmap (nal, &map);
2412
2413   if (h265parse->discont) {
2414     GST_BUFFER_FLAG_SET (nal, GST_BUFFER_FLAG_DISCONT);
2415     h265parse->discont = FALSE;
2416   }
2417
2418   GST_BUFFER_PTS (nal) = GST_BUFFER_PTS (buffer);
2419   GST_BUFFER_DTS (nal) = GST_BUFFER_DTS (buffer);
2420   GST_BUFFER_DURATION (nal) = 0;
2421
2422   return gst_pad_push (GST_BASE_PARSE_SRC_PAD (h265parse), nal);
2423 }
2424
2425 static GstEvent *
2426 check_pending_key_unit_event (GstEvent * pending_event, GstSegment * segment,
2427     GstClockTime timestamp, guint flags, GstClockTime pending_key_unit_ts)
2428 {
2429   GstClockTime running_time, stream_time;
2430   gboolean all_headers;
2431   guint count;
2432   GstEvent *event = NULL;
2433
2434   g_return_val_if_fail (segment != NULL, NULL);
2435
2436   if (pending_event == NULL)
2437     goto out;
2438
2439   if (GST_CLOCK_TIME_IS_VALID (pending_key_unit_ts) &&
2440       timestamp == GST_CLOCK_TIME_NONE)
2441     goto out;
2442
2443   running_time = gst_segment_to_running_time (segment,
2444       GST_FORMAT_TIME, timestamp);
2445
2446   GST_INFO ("now %" GST_TIME_FORMAT " wanted %" GST_TIME_FORMAT,
2447       GST_TIME_ARGS (running_time), GST_TIME_ARGS (pending_key_unit_ts));
2448   if (GST_CLOCK_TIME_IS_VALID (pending_key_unit_ts) &&
2449       running_time < pending_key_unit_ts)
2450     goto out;
2451
2452   if (flags & GST_BUFFER_FLAG_DELTA_UNIT) {
2453     GST_DEBUG ("pending force key unit, waiting for keyframe");
2454     goto out;
2455   }
2456
2457   stream_time = gst_segment_to_stream_time (segment,
2458       GST_FORMAT_TIME, timestamp);
2459
2460   if (!gst_video_event_parse_upstream_force_key_unit (pending_event,
2461           NULL, &all_headers, &count)) {
2462     gst_video_event_parse_downstream_force_key_unit (pending_event, NULL,
2463         NULL, NULL, &all_headers, &count);
2464   }
2465
2466   event =
2467       gst_video_event_new_downstream_force_key_unit (timestamp, stream_time,
2468       running_time, all_headers, count);
2469   gst_event_set_seqnum (event, gst_event_get_seqnum (pending_event));
2470
2471 out:
2472   return event;
2473 }
2474
2475 static void
2476 gst_h265_parse_prepare_key_unit (GstH265Parse * parse, GstEvent * event)
2477 {
2478   GstClockTime running_time;
2479   guint count;
2480 #ifndef GST_DISABLE_GST_DEBUG
2481   gboolean have_vps, have_sps, have_pps;
2482   gint i;
2483 #endif
2484
2485   parse->pending_key_unit_ts = GST_CLOCK_TIME_NONE;
2486   gst_event_replace (&parse->force_key_unit_event, NULL);
2487
2488   gst_video_event_parse_downstream_force_key_unit (event,
2489       NULL, NULL, &running_time, NULL, &count);
2490
2491   GST_INFO_OBJECT (parse, "pushing downstream force-key-unit event %d "
2492       "%" GST_TIME_FORMAT " count %d", gst_event_get_seqnum (event),
2493       GST_TIME_ARGS (running_time), count);
2494   gst_pad_push_event (GST_BASE_PARSE_SRC_PAD (parse), event);
2495
2496 #ifndef GST_DISABLE_GST_DEBUG
2497   have_vps = have_sps = have_pps = FALSE;
2498   for (i = 0; i < GST_H265_MAX_VPS_COUNT; i++) {
2499     if (parse->vps_nals[i] != NULL) {
2500       have_vps = TRUE;
2501       break;
2502     }
2503   }
2504   for (i = 0; i < GST_H265_MAX_SPS_COUNT; i++) {
2505     if (parse->sps_nals[i] != NULL) {
2506       have_sps = TRUE;
2507       break;
2508     }
2509   }
2510   for (i = 0; i < GST_H265_MAX_PPS_COUNT; i++) {
2511     if (parse->pps_nals[i] != NULL) {
2512       have_pps = TRUE;
2513       break;
2514     }
2515   }
2516
2517   GST_INFO_OBJECT (parse,
2518       "preparing key unit, have vps %d have sps %d have pps %d", have_vps,
2519       have_sps, have_pps);
2520 #endif
2521
2522   /* set push_codec to TRUE so that pre_push_frame sends VPS/SPS/PPS again */
2523   parse->push_codec = TRUE;
2524 }
2525
2526 static gboolean
2527 gst_h265_parse_handle_vps_sps_pps_nals (GstH265Parse * h265parse,
2528     GstBuffer * buffer, GstBaseParseFrame * frame)
2529 {
2530   GstBuffer *codec_nal;
2531   gint i;
2532   gboolean send_done = FALSE;
2533
2534   if (h265parse->have_vps_in_frame && h265parse->have_sps_in_frame
2535       && h265parse->have_pps_in_frame) {
2536     GST_DEBUG_OBJECT (h265parse, "VPS/SPS/PPS exist in frame, will not insert");
2537     return TRUE;
2538   }
2539
2540   if (h265parse->align == GST_H265_PARSE_ALIGN_NAL) {
2541     /* send separate config NAL buffers */
2542     GST_DEBUG_OBJECT (h265parse, "- sending VPS/SPS/PPS");
2543     for (i = 0; i < GST_H265_MAX_VPS_COUNT; i++) {
2544       if ((codec_nal = h265parse->vps_nals[i])) {
2545         GST_DEBUG_OBJECT (h265parse, "sending VPS nal");
2546         gst_h265_parse_push_codec_buffer (h265parse, codec_nal, buffer);
2547         send_done = TRUE;
2548       }
2549     }
2550     for (i = 0; i < GST_H265_MAX_SPS_COUNT; i++) {
2551       if ((codec_nal = h265parse->sps_nals[i])) {
2552         GST_DEBUG_OBJECT (h265parse, "sending SPS nal");
2553         gst_h265_parse_push_codec_buffer (h265parse, codec_nal, buffer);
2554         send_done = TRUE;
2555       }
2556     }
2557     for (i = 0; i < GST_H265_MAX_PPS_COUNT; i++) {
2558       if ((codec_nal = h265parse->pps_nals[i])) {
2559         GST_DEBUG_OBJECT (h265parse, "sending PPS nal");
2560         gst_h265_parse_push_codec_buffer (h265parse, codec_nal, buffer);
2561         send_done = TRUE;
2562       }
2563     }
2564   } else {
2565     /* insert config NALs into AU */
2566     GstByteWriter bw;
2567     GstBuffer *new_buf;
2568     const gboolean bs = h265parse->format == GST_H265_PARSE_FORMAT_BYTE;
2569     const gint nls = 4 - h265parse->nal_length_size;
2570     gboolean ok;
2571
2572     gst_byte_writer_init_with_size (&bw, gst_buffer_get_size (buffer), FALSE);
2573     ok = gst_byte_writer_put_buffer (&bw, buffer, 0, h265parse->idr_pos);
2574     GST_DEBUG_OBJECT (h265parse, "- inserting VPS/SPS/PPS");
2575     for (i = 0; i < GST_H265_MAX_VPS_COUNT; i++) {
2576       if ((codec_nal = h265parse->vps_nals[i])) {
2577         gsize nal_size = gst_buffer_get_size (codec_nal);
2578         GST_DEBUG_OBJECT (h265parse, "inserting VPS nal");
2579         if (bs) {
2580           ok &= gst_byte_writer_put_uint32_be (&bw, 1);
2581         } else {
2582           ok &= gst_byte_writer_put_uint32_be (&bw, (nal_size << (nls * 8)));
2583           ok &= gst_byte_writer_set_pos (&bw,
2584               gst_byte_writer_get_pos (&bw) - nls);
2585         }
2586
2587         ok &= gst_byte_writer_put_buffer (&bw, codec_nal, 0, nal_size);
2588         send_done = TRUE;
2589       }
2590     }
2591     for (i = 0; i < GST_H265_MAX_SPS_COUNT; i++) {
2592       if ((codec_nal = h265parse->sps_nals[i])) {
2593         gsize nal_size = gst_buffer_get_size (codec_nal);
2594         GST_DEBUG_OBJECT (h265parse, "inserting SPS nal");
2595         if (bs) {
2596           ok &= gst_byte_writer_put_uint32_be (&bw, 1);
2597         } else {
2598           ok &= gst_byte_writer_put_uint32_be (&bw, (nal_size << (nls * 8)));
2599           ok &= gst_byte_writer_set_pos (&bw,
2600               gst_byte_writer_get_pos (&bw) - nls);
2601         }
2602
2603         ok &= gst_byte_writer_put_buffer (&bw, codec_nal, 0, nal_size);
2604         send_done = TRUE;
2605       }
2606     }
2607     for (i = 0; i < GST_H265_MAX_PPS_COUNT; i++) {
2608       if ((codec_nal = h265parse->pps_nals[i])) {
2609         gsize nal_size = gst_buffer_get_size (codec_nal);
2610         GST_DEBUG_OBJECT (h265parse, "inserting PPS 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         ok &= gst_byte_writer_put_buffer (&bw, codec_nal, 0, nal_size);
2619         send_done = TRUE;
2620       }
2621     }
2622     ok &= gst_byte_writer_put_buffer (&bw, buffer, h265parse->idr_pos, -1);
2623     /* collect result and push */
2624     new_buf = gst_byte_writer_reset_and_get_buffer (&bw);
2625     gst_buffer_copy_into (new_buf, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
2626     /* should already be keyframe/IDR, but it may not have been,
2627      * so mark it as such to avoid being discarded by picky decoder */
2628     GST_BUFFER_FLAG_UNSET (new_buf, GST_BUFFER_FLAG_DELTA_UNIT);
2629     gst_buffer_replace (&frame->out_buffer, new_buf);
2630     gst_buffer_unref (new_buf);
2631     /* some result checking seems to make some compilers happy */
2632     if (G_UNLIKELY (!ok)) {
2633       GST_ERROR_OBJECT (h265parse, "failed to insert SPS/PPS");
2634     }
2635   }
2636
2637   return send_done;
2638 }
2639
2640 static GstFlowReturn
2641 gst_h265_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
2642 {
2643   GstH265Parse *h265parse;
2644   GstBuffer *buffer;
2645   GstEvent *event;
2646   GstBuffer *parse_buffer = NULL;
2647
2648   h265parse = GST_H265_PARSE (parse);
2649
2650   if (h265parse->first_frame) {
2651     GstTagList *taglist;
2652     GstCaps *caps;
2653
2654     /* codec tag */
2655     caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
2656     if (G_UNLIKELY (caps == NULL)) {
2657       if (GST_PAD_IS_FLUSHING (GST_BASE_PARSE_SRC_PAD (parse))) {
2658         GST_INFO_OBJECT (parse, "Src pad is flushing");
2659         return GST_FLOW_FLUSHING;
2660       } else {
2661         GST_INFO_OBJECT (parse, "Src pad is not negotiated!");
2662         return GST_FLOW_NOT_NEGOTIATED;
2663       }
2664     }
2665
2666     taglist = gst_tag_list_new_empty ();
2667     gst_pb_utils_add_codec_description_to_tag_list (taglist,
2668         GST_TAG_VIDEO_CODEC, caps);
2669     gst_caps_unref (caps);
2670
2671     gst_base_parse_merge_tags (parse, taglist, GST_TAG_MERGE_REPLACE);
2672     gst_tag_list_unref (taglist);
2673
2674     /* also signals the end of first-frame processing */
2675     h265parse->first_frame = FALSE;
2676   }
2677
2678   buffer = frame->buffer;
2679
2680   if ((event = check_pending_key_unit_event (h265parse->force_key_unit_event,
2681               &parse->segment, GST_BUFFER_TIMESTAMP (buffer),
2682               GST_BUFFER_FLAGS (buffer), h265parse->pending_key_unit_ts))) {
2683     gst_h265_parse_prepare_key_unit (h265parse, event);
2684   }
2685
2686   /* periodic VPS/SPS/PPS sending */
2687   if (h265parse->interval > 0 || h265parse->push_codec) {
2688     GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer);
2689     guint64 diff;
2690     gboolean initial_frame = FALSE;
2691
2692     /* init */
2693     if (!GST_CLOCK_TIME_IS_VALID (h265parse->last_report)) {
2694       h265parse->last_report = timestamp;
2695       initial_frame = TRUE;
2696     }
2697
2698     if (h265parse->idr_pos >= 0) {
2699       GST_LOG_OBJECT (h265parse, "IDR nal at offset %d", h265parse->idr_pos);
2700
2701       if (timestamp > h265parse->last_report)
2702         diff = timestamp - h265parse->last_report;
2703       else
2704         diff = 0;
2705
2706       GST_LOG_OBJECT (h265parse,
2707           "now %" GST_TIME_FORMAT ", last VPS/SPS/PPS %" GST_TIME_FORMAT,
2708           GST_TIME_ARGS (timestamp), GST_TIME_ARGS (h265parse->last_report));
2709
2710       GST_DEBUG_OBJECT (h265parse,
2711           "interval since last VPS/SPS/PPS %" GST_TIME_FORMAT,
2712           GST_TIME_ARGS (diff));
2713
2714       if (GST_TIME_AS_SECONDS (diff) >= h265parse->interval ||
2715           initial_frame || h265parse->push_codec) {
2716         GstClockTime new_ts;
2717
2718         /* avoid overwriting a perfectly fine timestamp */
2719         new_ts = GST_CLOCK_TIME_IS_VALID (timestamp) ? timestamp :
2720             h265parse->last_report;
2721
2722         if (gst_h265_parse_handle_vps_sps_pps_nals (h265parse, buffer, frame)) {
2723           h265parse->last_report = new_ts;
2724         }
2725       }
2726
2727       /* we pushed whatever we had */
2728       h265parse->push_codec = FALSE;
2729       h265parse->have_vps = FALSE;
2730       h265parse->have_sps = FALSE;
2731       h265parse->have_pps = FALSE;
2732       h265parse->state &= GST_H265_PARSE_STATE_VALID_PICTURE_HEADERS;
2733     }
2734   } else if (h265parse->interval == -1) {
2735     if (h265parse->idr_pos >= 0) {
2736       GST_LOG_OBJECT (h265parse, "IDR nal at offset %d", h265parse->idr_pos);
2737
2738       gst_h265_parse_handle_vps_sps_pps_nals (h265parse, buffer, frame);
2739
2740       /* we pushed whatever we had */
2741       h265parse->push_codec = FALSE;
2742       h265parse->have_vps = FALSE;
2743       h265parse->have_sps = FALSE;
2744       h265parse->have_pps = FALSE;
2745       h265parse->state &= GST_H265_PARSE_STATE_VALID_PICTURE_HEADERS;
2746     }
2747   }
2748
2749   if (frame->out_buffer) {
2750     parse_buffer = frame->out_buffer =
2751         gst_buffer_make_writable (frame->out_buffer);
2752   } else {
2753     parse_buffer = frame->buffer = gst_buffer_make_writable (frame->buffer);
2754   }
2755
2756   if (h265parse->sei_pic_struct != GST_H265_SEI_PIC_STRUCT_FRAME) {
2757     if (h265parse->parsed_framerate) {
2758       /* If the frame rate doesn't come from upstream (e.g. a muxer), it means
2759        * we must double it, because it's now fields per second */
2760       gint new_fps_n, new_fps_d;
2761
2762       gst_util_fraction_multiply (h265parse->fps_num, h265parse->fps_den, 2, 1,
2763           &new_fps_n, &new_fps_d);
2764       h265parse->fps_num = new_fps_n;
2765       h265parse->fps_den = new_fps_d;
2766       h265parse->parsed_framerate = FALSE;
2767       /* We need to fix the duration of the first frame */
2768       GST_BUFFER_DURATION (parse_buffer) /= 2;
2769     }
2770     GST_BUFFER_FLAG_SET (parse_buffer, GST_VIDEO_BUFFER_FLAG_INTERLACED);
2771     /* h265 doesn't support interleaved */
2772     switch (h265parse->sei_pic_struct) {
2773       case GST_H265_SEI_PIC_STRUCT_TOP_FIELD:
2774       case GST_H265_SEI_PIC_STRUCT_TOP_PAIRED_NEXT_BOTTOM:
2775       case GST_H265_SEI_PIC_STRUCT_TOP_PAIRED_PREVIOUS_BOTTOM:
2776         GST_BUFFER_FLAG_SET (parse_buffer, GST_VIDEO_BUFFER_FLAG_TOP_FIELD);
2777         break;
2778       case GST_H265_SEI_PIC_STRUCT_BOTTOM_FIELD:
2779       case GST_H265_SEI_PIC_STRUCT_BOTTOM_PAIRED_PREVIOUS_TOP:
2780       case GST_H265_SEI_PIC_STRUCT_BOTTOM_PAIRED_NEXT_TOP:
2781         GST_BUFFER_FLAG_SET (parse_buffer, GST_VIDEO_BUFFER_FLAG_BOTTOM_FIELD);
2782         break;
2783       default:
2784         break;
2785     }
2786   }
2787
2788   {
2789     guint i = 0;
2790
2791     for (i = 0; i < h265parse->time_code.num_clock_ts; i++) {
2792       gint field_count = -1;
2793       guint n_frames;
2794       GstVideoTimeCodeFlags flags = 0;
2795
2796       if (!h265parse->time_code.clock_timestamp_flag[i])
2797         break;
2798
2799       h265parse->time_code.clock_timestamp_flag[i] = 0;
2800
2801       /* Table D.2 */
2802       switch (h265parse->sei_pic_struct) {
2803         case GST_H265_SEI_PIC_STRUCT_FRAME:
2804         case GST_H265_SEI_PIC_STRUCT_TOP_FIELD:
2805         case GST_H265_SEI_PIC_STRUCT_BOTTOM_FIELD:
2806           field_count = h265parse->sei_pic_struct;
2807           break;
2808         case GST_H265_SEI_PIC_STRUCT_TOP_BOTTOM:
2809         case GST_H265_SEI_PIC_STRUCT_TOP_PAIRED_PREVIOUS_BOTTOM:
2810         case GST_H265_SEI_PIC_STRUCT_TOP_PAIRED_NEXT_BOTTOM:
2811           field_count = i + 1;
2812           break;
2813         case GST_H265_SEI_PIC_STRUCT_BOTTOM_TOP:
2814         case GST_H265_SEI_PIC_STRUCT_BOTTOM_PAIRED_PREVIOUS_TOP:
2815         case GST_H265_SEI_PIC_STRUCT_BOTTOM_PAIRED_NEXT_TOP:
2816           field_count = 2 - i;
2817           break;
2818         case GST_H265_SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
2819           field_count = i % 2 ? 2 : 1;
2820           break;
2821         case GST_H265_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
2822           field_count = i % 2 ? 1 : 2;
2823           break;
2824         case GST_H265_SEI_PIC_STRUCT_FRAME_DOUBLING:
2825         case GST_H265_SEI_PIC_STRUCT_FRAME_TRIPLING:
2826           field_count = 0;
2827           break;
2828       }
2829
2830       if (field_count == -1) {
2831         GST_WARNING_OBJECT (parse,
2832             "failed to determine field count for timecode");
2833         field_count = 0;
2834       }
2835
2836       /* Dropping of the two lowest (value 0 and 1) n_frames[ i ] counts when
2837        * seconds_value[ i ] is equal to 0 and minutes_value[ i ] is not an integer
2838        * multiple of 10 */
2839       if (h265parse->time_code.counting_type[i] == 4)
2840         flags |= GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME;
2841
2842       if (h265parse->sei_pic_struct != GST_H265_SEI_PIC_STRUCT_FRAME)
2843         flags |= GST_VIDEO_TIME_CODE_FLAGS_INTERLACED;
2844
2845       n_frames =
2846           gst_util_uint64_scale_int (h265parse->time_code.n_frames[i], 1,
2847           2 - h265parse->time_code.units_field_based_flag[i]);
2848
2849       gst_buffer_add_video_time_code_meta_full (parse_buffer,
2850           h265parse->parsed_fps_n,
2851           h265parse->parsed_fps_d,
2852           NULL,
2853           flags,
2854           h265parse->time_code.hours_flag[i] ? h265parse->time_code.
2855           hours_value[i] : 0,
2856           h265parse->time_code.minutes_flag[i] ? h265parse->time_code.
2857           minutes_value[i] : 0,
2858           h265parse->time_code.seconds_flag[i] ? h265parse->time_code.
2859           seconds_value[i] : 0, n_frames, field_count);
2860     }
2861   }
2862
2863   if (h265parse->sei_pic_struct != GST_H265_SEI_PIC_STRUCT_FRAME) {
2864     GST_BUFFER_FLAG_SET (parse_buffer, GST_VIDEO_BUFFER_FLAG_INTERLACED);
2865     if (h265parse->sei_pic_struct == GST_H265_SEI_PIC_STRUCT_TOP_FIELD)
2866       GST_BUFFER_FLAG_SET (parse_buffer, GST_VIDEO_BUFFER_FLAG_TFF);
2867   }
2868
2869   gst_video_push_user_data ((GstElement *) h265parse, &h265parse->user_data,
2870       parse_buffer);
2871
2872   gst_h265_parse_reset_frame (h265parse);
2873
2874   return GST_FLOW_OK;
2875 }
2876
2877 static gboolean
2878 gst_h265_parse_set_caps (GstBaseParse * parse, GstCaps * caps)
2879 {
2880   GstH265Parse *h265parse;
2881   GstStructure *str;
2882   const GValue *value;
2883   GstBuffer *codec_data = NULL;
2884   gsize off, size;
2885   guint format, align;
2886   guint num_nals, i, j;
2887   GstH265NalUnit nalu;
2888   GstH265ParserResult parseres;
2889   GstCaps *old_caps;
2890
2891   h265parse = GST_H265_PARSE (parse);
2892
2893   /* reset */
2894   h265parse->push_codec = FALSE;
2895
2896   old_caps = gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (parse));
2897   if (old_caps) {
2898     if (!gst_caps_is_equal (old_caps, caps))
2899       gst_h265_parse_reset_stream_info (h265parse);
2900     gst_caps_unref (old_caps);
2901   }
2902
2903   str = gst_caps_get_structure (caps, 0);
2904
2905   /* accept upstream info if provided */
2906   gst_structure_get_int (str, "width", &h265parse->width);
2907   gst_structure_get_int (str, "height", &h265parse->height);
2908   gst_structure_get_fraction (str, "framerate", &h265parse->fps_num,
2909       &h265parse->fps_den);
2910   gst_structure_get_fraction (str, "pixel-aspect-ratio",
2911       &h265parse->upstream_par_n, &h265parse->upstream_par_d);
2912
2913   /* get upstream format and align from caps */
2914   gst_h265_parse_format_from_caps (caps, &format, &align);
2915
2916   /* packetized video has a codec_data */
2917   if (format != GST_H265_PARSE_FORMAT_BYTE &&
2918       (value = gst_structure_get_value (str, "codec_data"))) {
2919     GstMapInfo map;
2920     guint8 *data;
2921     guint num_nal_arrays;
2922
2923     GST_DEBUG_OBJECT (h265parse, "have packetized h265");
2924     /* make note for optional split processing */
2925     h265parse->packetized = TRUE;
2926
2927     codec_data = gst_value_get_buffer (value);
2928     if (!codec_data)
2929       goto wrong_type;
2930     gst_buffer_map (codec_data, &map, GST_MAP_READ);
2931     data = map.data;
2932     size = map.size;
2933
2934     /* parse the hvcC data */
2935     if (size < 23) {
2936       gst_buffer_unmap (codec_data, &map);
2937       goto hvcc_too_small;
2938     }
2939     /* parse the version, this must be one but
2940      * is zero until the spec is finalized */
2941     if (data[0] != 0 && data[0] != 1) {
2942       gst_buffer_unmap (codec_data, &map);
2943       goto wrong_version;
2944     }
2945
2946     h265parse->nal_length_size = (data[21] & 0x03) + 1;
2947     GST_DEBUG_OBJECT (h265parse, "nal length size %u",
2948         h265parse->nal_length_size);
2949
2950     num_nal_arrays = data[22];
2951     off = 23;
2952
2953     for (i = 0; i < num_nal_arrays; i++) {
2954       if (off + 3 >= size) {
2955         gst_buffer_unmap (codec_data, &map);
2956         goto hvcc_too_small;
2957       }
2958
2959       num_nals = GST_READ_UINT16_BE (data + off + 1);
2960       off += 3;
2961       for (j = 0; j < num_nals; j++) {
2962         parseres = gst_h265_parser_identify_nalu_hevc (h265parse->nalparser,
2963             data, off, size, 2, &nalu);
2964
2965         if (parseres != GST_H265_PARSER_OK) {
2966           gst_buffer_unmap (codec_data, &map);
2967           goto hvcc_too_small;
2968         }
2969
2970         gst_h265_parse_process_nal (h265parse, &nalu);
2971         off = nalu.offset + nalu.size;
2972       }
2973     }
2974     gst_buffer_unmap (codec_data, &map);
2975
2976     /* don't confuse codec_data with inband vps/sps/pps */
2977     h265parse->have_vps_in_frame = FALSE;
2978     h265parse->have_sps_in_frame = FALSE;
2979     h265parse->have_pps_in_frame = FALSE;
2980   } else {
2981     GST_DEBUG_OBJECT (h265parse, "have bytestream h265");
2982     /* nothing to pre-process */
2983     h265parse->packetized = FALSE;
2984     /* we have 4 sync bytes */
2985     h265parse->nal_length_size = 4;
2986
2987     if (format == GST_H265_PARSE_FORMAT_NONE) {
2988       format = GST_H265_PARSE_FORMAT_BYTE;
2989       align = GST_H265_PARSE_ALIGN_AU;
2990     }
2991   }
2992
2993   {
2994     GstCaps *in_caps;
2995
2996     /* prefer input type determined above */
2997     in_caps = gst_caps_new_simple ("video/x-h265",
2998         "parsed", G_TYPE_BOOLEAN, TRUE,
2999         "stream-format", G_TYPE_STRING,
3000         gst_h265_parse_get_string (h265parse, TRUE, format),
3001         "alignment", G_TYPE_STRING,
3002         gst_h265_parse_get_string (h265parse, FALSE, align), NULL);
3003     /* negotiate with downstream, sets ->format and ->align */
3004     gst_h265_parse_negotiate (h265parse, format, in_caps);
3005     gst_caps_unref (in_caps);
3006   }
3007
3008   if (format == h265parse->format && align == h265parse->align) {
3009     /* do not set CAPS and passthrough mode if SPS/PPS have not been parsed */
3010     if (h265parse->have_sps && h265parse->have_pps) {
3011       /* Don't enable passthrough here. This element will parse various
3012        * SEI messages which would be very important/useful for downstream
3013        * (HDR, timecode for example)
3014        */
3015 #if 0
3016       gst_base_parse_set_passthrough (parse, TRUE);
3017 #endif
3018
3019       /* we did parse codec-data and might supplement src caps */
3020       gst_h265_parse_update_src_caps (h265parse, caps);
3021     }
3022   } else if (format == GST_H265_PARSE_FORMAT_HVC1
3023       || format == GST_H265_PARSE_FORMAT_HEV1) {
3024     /* if input != output, and input is hevc, must split before anything else */
3025     /* arrange to insert codec-data in-stream if needed.
3026      * src caps are only arranged for later on */
3027     h265parse->push_codec = TRUE;
3028     h265parse->have_vps = FALSE;
3029     h265parse->have_sps = FALSE;
3030     h265parse->have_pps = FALSE;
3031     if (h265parse->align == GST_H265_PARSE_ALIGN_NAL)
3032       h265parse->split_packetized = TRUE;
3033     h265parse->packetized = TRUE;
3034   }
3035
3036   h265parse->in_align = align;
3037
3038   return TRUE;
3039
3040   /* ERRORS */
3041 hvcc_too_small:
3042   {
3043     GST_DEBUG_OBJECT (h265parse, "hvcC size %" G_GSIZE_FORMAT " < 23", size);
3044     goto refuse_caps;
3045   }
3046 wrong_version:
3047   {
3048     GST_DEBUG_OBJECT (h265parse, "wrong hvcC version");
3049     goto refuse_caps;
3050   }
3051 wrong_type:
3052   {
3053     GST_DEBUG_OBJECT (h265parse, "wrong codec-data type");
3054     goto refuse_caps;
3055   }
3056 refuse_caps:
3057   {
3058     GST_WARNING_OBJECT (h265parse, "refused caps %" GST_PTR_FORMAT, caps);
3059     return FALSE;
3060   }
3061 }
3062
3063 static void
3064 remove_fields (GstCaps * caps, gboolean all)
3065 {
3066   guint i, n;
3067
3068   n = gst_caps_get_size (caps);
3069   for (i = 0; i < n; i++) {
3070     GstStructure *s = gst_caps_get_structure (caps, i);
3071
3072     if (all) {
3073       gst_structure_remove_field (s, "alignment");
3074       gst_structure_remove_field (s, "stream-format");
3075     }
3076     gst_structure_remove_field (s, "parsed");
3077   }
3078 }
3079
3080 static GstCaps *
3081 gst_h265_parse_get_caps (GstBaseParse * parse, GstCaps * filter)
3082 {
3083   GstCaps *peercaps, *templ;
3084   GstCaps *res, *tmp, *pcopy;
3085
3086   templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
3087   if (filter) {
3088     GstCaps *fcopy = gst_caps_copy (filter);
3089     /* Remove the fields we convert */
3090     remove_fields (fcopy, TRUE);
3091     peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), fcopy);
3092     gst_caps_unref (fcopy);
3093   } else
3094     peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), NULL);
3095
3096   pcopy = gst_caps_copy (peercaps);
3097   remove_fields (pcopy, TRUE);
3098
3099   res = gst_caps_intersect_full (pcopy, templ, GST_CAPS_INTERSECT_FIRST);
3100   gst_caps_unref (pcopy);
3101   gst_caps_unref (templ);
3102
3103   if (filter) {
3104     GstCaps *tmp = gst_caps_intersect_full (res, filter,
3105         GST_CAPS_INTERSECT_FIRST);
3106     gst_caps_unref (res);
3107     res = tmp;
3108   }
3109
3110   /* Try if we can put the downstream caps first */
3111   pcopy = gst_caps_copy (peercaps);
3112   remove_fields (pcopy, FALSE);
3113   tmp = gst_caps_intersect_full (pcopy, res, GST_CAPS_INTERSECT_FIRST);
3114   gst_caps_unref (pcopy);
3115   if (!gst_caps_is_empty (tmp))
3116     res = gst_caps_merge (tmp, res);
3117   else
3118     gst_caps_unref (tmp);
3119
3120   gst_caps_unref (peercaps);
3121   return res;
3122 }
3123
3124 static gboolean
3125 gst_h265_parse_event (GstBaseParse * parse, GstEvent * event)
3126 {
3127   gboolean res;
3128   GstH265Parse *h265parse = GST_H265_PARSE (parse);
3129
3130   switch (GST_EVENT_TYPE (event)) {
3131     case GST_EVENT_CUSTOM_DOWNSTREAM:
3132     {
3133       GstClockTime timestamp, stream_time, running_time;
3134       gboolean all_headers;
3135       guint count;
3136
3137       if (gst_video_event_is_force_key_unit (event)) {
3138         gst_video_event_parse_downstream_force_key_unit (event,
3139             &timestamp, &stream_time, &running_time, &all_headers, &count);
3140
3141         GST_INFO_OBJECT (h265parse, "received downstream force key unit event, "
3142             "seqnum %d running_time %" GST_TIME_FORMAT
3143             " all_headers %d count %d", gst_event_get_seqnum (event),
3144             GST_TIME_ARGS (running_time), all_headers, count);
3145         if (h265parse->force_key_unit_event) {
3146           GST_INFO_OBJECT (h265parse, "ignoring force key unit event "
3147               "as one is already queued");
3148         } else {
3149           h265parse->pending_key_unit_ts = running_time;
3150           gst_event_replace (&h265parse->force_key_unit_event, event);
3151         }
3152         gst_event_unref (event);
3153         res = TRUE;
3154       } else {
3155         res = GST_BASE_PARSE_CLASS (parent_class)->sink_event (parse, event);
3156         break;
3157       }
3158       break;
3159     }
3160     case GST_EVENT_FLUSH_STOP:
3161       h265parse->push_codec = TRUE;
3162       res = GST_BASE_PARSE_CLASS (parent_class)->sink_event (parse, event);
3163       break;
3164     case GST_EVENT_SEGMENT:
3165     {
3166       const GstSegment *segment = NULL;
3167
3168       gst_event_parse_segment (event, &segment);
3169
3170       h265parse->last_report = GST_CLOCK_TIME_NONE;
3171
3172       if (segment->flags & GST_SEEK_FLAG_TRICKMODE_FORWARD_PREDICTED) {
3173         GST_DEBUG_OBJECT (h265parse, "Will discard bidirectional frames");
3174         h265parse->discard_bidirectional = TRUE;
3175       }
3176
3177       res = GST_BASE_PARSE_CLASS (parent_class)->sink_event (parse, event);
3178       break;
3179     }
3180     default:
3181       res = GST_BASE_PARSE_CLASS (parent_class)->sink_event (parse, event);
3182       break;
3183   }
3184   return res;
3185 }
3186
3187 static gboolean
3188 gst_h265_parse_src_event (GstBaseParse * parse, GstEvent * event)
3189 {
3190   gboolean res;
3191   GstH265Parse *h265parse = GST_H265_PARSE (parse);
3192
3193   switch (GST_EVENT_TYPE (event)) {
3194     case GST_EVENT_CUSTOM_UPSTREAM:
3195     {
3196       GstClockTime running_time;
3197       gboolean all_headers;
3198       guint count;
3199
3200       if (gst_video_event_is_force_key_unit (event)) {
3201         gst_video_event_parse_upstream_force_key_unit (event,
3202             &running_time, &all_headers, &count);
3203
3204         GST_INFO_OBJECT (h265parse, "received upstream force-key-unit event, "
3205             "seqnum %d running_time %" GST_TIME_FORMAT
3206             " all_headers %d count %d", gst_event_get_seqnum (event),
3207             GST_TIME_ARGS (running_time), all_headers, count);
3208
3209         if (all_headers) {
3210           h265parse->pending_key_unit_ts = running_time;
3211           gst_event_replace (&h265parse->force_key_unit_event, event);
3212         }
3213       }
3214       res = GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
3215       break;
3216     }
3217     default:
3218       res = GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
3219       break;
3220   }
3221
3222   return res;
3223 }
3224
3225 static void
3226 gst_h265_parse_set_property (GObject * object, guint prop_id,
3227     const GValue * value, GParamSpec * pspec)
3228 {
3229   GstH265Parse *parse;
3230   parse = GST_H265_PARSE (object);
3231
3232   switch (prop_id) {
3233     case PROP_CONFIG_INTERVAL:
3234       parse->interval = g_value_get_int (value);
3235       break;
3236     default:
3237       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3238       break;
3239   }
3240 }
3241
3242 static void
3243 gst_h265_parse_get_property (GObject * object, guint prop_id, GValue * value,
3244     GParamSpec * pspec)
3245 {
3246   GstH265Parse *parse;
3247   parse = GST_H265_PARSE (object);
3248
3249   switch (prop_id) {
3250     case PROP_CONFIG_INTERVAL:
3251       g_value_set_int (value, parse->interval);
3252       break;
3253     default:
3254       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3255       break;
3256   }
3257 }