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