decoder: hevc: Fix the value assigning for delta_chroma_log2_weight_denom
[platform/upstream/gstreamer.git] / gst-libs / gst / vaapi / gstvaapidecoder_h265.c
1 /*
2  *  gstvaapidecoder_h265.c - H.265 decoder
3  *
4  *  Copyright (C) 2015 Intel Corporation
5  *    Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
6  *
7  *  This library is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU Lesser General Public License
9  *  as published by the Free Software Foundation; either version 2.1
10  *  of the License, or (at your option) any later version.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *  Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public
18  *  License along with this library; if not, write to the Free
19  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  *  Boston, MA 02110-1301 USA
21  */
22
23 /**
24  * SECTION:gstvaapidecoder_h265
25  * @short_description: H.265 decoder
26  */
27
28 #include "sysdeps.h"
29 #include <string.h>
30 #include <math.h>
31 #include <gst/base/gstadapter.h>
32 #include <gst/codecparsers/gsth265parser.h>
33 #include "gstvaapicompat.h"
34 #include "gstvaapidecoder_h265.h"
35 #include "gstvaapidecoder_objects.h"
36 #include "gstvaapidecoder_priv.h"
37 #include "gstvaapidisplay_priv.h"
38 #include "gstvaapiobject_priv.h"
39 #include "gstvaapiutils_h265_priv.h"
40
41 #define DEBUG 1
42 #include "gstvaapidebug.h"
43
44 /* Defined to 1 if strict ordering of DPB is needed. Only useful for debug */
45 #define USE_STRICT_DPB_ORDERING 0
46
47 typedef struct _GstVaapiDecoderH265Private GstVaapiDecoderH265Private;
48 typedef struct _GstVaapiDecoderH265Class GstVaapiDecoderH265Class;
49 typedef struct _GstVaapiFrameStore GstVaapiFrameStore;
50 typedef struct _GstVaapiFrameStoreClass GstVaapiFrameStoreClass;
51 typedef struct _GstVaapiParserInfoH265 GstVaapiParserInfoH265;
52 typedef struct _GstVaapiPictureH265 GstVaapiPictureH265;
53
54 static gboolean nal_is_slice (guint8 nal_type);
55
56 /* ------------------------------------------------------------------------- */
57 /* --- H.265 Parser Info                                                 --- */
58 /* ------------------------------------------------------------------------- */
59
60 /*
61  * Extended decoder unit flags:
62  *
63  * @GST_VAAPI_DECODER_UNIT_AU_START: marks the start of an access unit.
64  * @GST_VAAPI_DECODER_UNIT_AU_END: marks the end of an access unit.
65  */
66 enum
67 {
68   GST_VAAPI_DECODER_UNIT_FLAG_AU_START =
69       (GST_VAAPI_DECODER_UNIT_FLAG_LAST << 0),
70   GST_VAAPI_DECODER_UNIT_FLAG_AU_END = (GST_VAAPI_DECODER_UNIT_FLAG_LAST << 1),
71
72   GST_VAAPI_DECODER_UNIT_FLAGS_AU = (GST_VAAPI_DECODER_UNIT_FLAG_AU_START |
73       GST_VAAPI_DECODER_UNIT_FLAG_AU_END),
74 };
75
76 #define GST_VAAPI_PARSER_INFO_H265(obj) \
77     ((GstVaapiParserInfoH265 *)(obj))
78
79 struct _GstVaapiParserInfoH265
80 {
81   GstVaapiMiniObject parent_instance;
82   GstH265NalUnit nalu;
83   union
84   {
85     GstH265VPS vps;
86     GstH265SPS sps;
87     GstH265PPS pps;
88     GArray *sei;
89     GstH265SliceHdr slice_hdr;
90   } data;
91   guint state;
92   guint flags;                  // Same as decoder unit flags (persistent)
93 };
94
95 static void
96 gst_vaapi_parser_info_h265_finalize (GstVaapiParserInfoH265 * pi)
97 {
98   if (nal_is_slice (pi->nalu.type))
99     gst_h265_slice_hdr_free (&pi->data.slice_hdr);
100   else {
101     switch (pi->nalu.type) {
102       case GST_H265_NAL_VPS:
103       case GST_H265_NAL_SPS:
104       case GST_H265_NAL_PPS:
105         break;
106       case GST_H265_NAL_PREFIX_SEI:
107       case GST_H265_NAL_SUFFIX_SEI:
108         if (pi->data.sei) {
109           g_array_unref (pi->data.sei);
110           pi->data.sei = NULL;
111         }
112         break;
113     }
114   }
115 }
116
117 static inline const GstVaapiMiniObjectClass *
118 gst_vaapi_parser_info_h265_class (void)
119 {
120   static const GstVaapiMiniObjectClass GstVaapiParserInfoH265Class = {
121     .size = sizeof (GstVaapiParserInfoH265),
122     .finalize = (GDestroyNotify) gst_vaapi_parser_info_h265_finalize
123   };
124   return &GstVaapiParserInfoH265Class;
125 }
126
127 static inline GstVaapiParserInfoH265 *
128 gst_vaapi_parser_info_h265_new (void)
129 {
130   return (GstVaapiParserInfoH265 *)
131       gst_vaapi_mini_object_new (gst_vaapi_parser_info_h265_class ());
132 }
133
134 #define gst_vaapi_parser_info_h265_ref(pi) \
135     gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(pi))
136
137 #define gst_vaapi_parser_info_h265_unref(pi) \
138     gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(pi))
139
140 #define gst_vaapi_parser_info_h265_replace(old_pi_ptr, new_pi)          \
141     gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_pi_ptr),  \
142         (GstVaapiMiniObject *)(new_pi))
143
144 /* ------------------------------------------------------------------------- */
145 /* --- H.265 Pictures                                                    --- */
146 /* ------------------------------------------------------------------------- */
147
148 /*
149  * Extended picture flags:
150  *
151  * @GST_VAAPI_PICTURE_FLAG_IDR: flag that specifies an IDR picture
152  * @GST_VAAPI_PICTURE_FLAG_AU_START: flag that marks the start of an
153  *   access unit (AU)
154  * @GST_VAAPI_PICTURE_FLAG_AU_END: flag that marks the end of an
155  *   access unit (AU)
156  * @GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_BEFORE: flag indicate the inclusion
157  *   of picture in RefPicSetStCurrBefore reference list
158  * @GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_AFTER: flag indicate the inclusion
159  *   of picture in RefPictSetStCurrAfter reference list
160  * @GST_VAAPI_PICTURE_FLAG_RPS_ST_FOLL: flag indicate the inclusion
161  *   of picture in RefPicSetStFoll reference list
162  * @GST_VAAPI_PICTURE_FLAG_RPS_LT_CURR: flag indicate the inclusion
163  *   of picture in RefPicSetLtCurr reference list
164  * @GST_VAAPI_PICTURE_FLAG_RPS_LT_FOLL: flag indicate the inclusion
165  *   of picture in RefPicSetLtFoll reference list
166  * @GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE: flag that specifies
167  *     "used for short-term reference"
168  * @GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE: flag that specifies
169  *     "used for long-term reference"
170  * @GST_VAAPI_PICTURE_FLAGS_REFERENCE: mask covering any kind of
171  *     reference picture (short-term reference or long-term reference)
172  */
173 enum
174 {
175   GST_VAAPI_PICTURE_FLAG_IDR = (GST_VAAPI_PICTURE_FLAG_LAST << 0),
176   GST_VAAPI_PICTURE_FLAG_REFERENCE2 = (GST_VAAPI_PICTURE_FLAG_LAST << 1),
177   GST_VAAPI_PICTURE_FLAG_AU_START = (GST_VAAPI_PICTURE_FLAG_LAST << 4),
178   GST_VAAPI_PICTURE_FLAG_AU_END = (GST_VAAPI_PICTURE_FLAG_LAST << 5),
179   GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_BEFORE =
180       (GST_VAAPI_PICTURE_FLAG_LAST << 6),
181   GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_AFTER = (GST_VAAPI_PICTURE_FLAG_LAST << 7),
182   GST_VAAPI_PICTURE_FLAG_RPS_ST_FOLL = (GST_VAAPI_PICTURE_FLAG_LAST << 8),
183   GST_VAAPI_PICTURE_FLAG_RPS_LT_CURR = (GST_VAAPI_PICTURE_FLAG_LAST << 9),
184   GST_VAAPI_PICTURE_FLAG_RPS_LT_FOLL = (GST_VAAPI_PICTURE_FLAG_LAST << 10),
185
186   GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE =
187       (GST_VAAPI_PICTURE_FLAG_REFERENCE),
188   GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE =
189       (GST_VAAPI_PICTURE_FLAG_REFERENCE | GST_VAAPI_PICTURE_FLAG_REFERENCE2),
190   GST_VAAPI_PICTURE_FLAGS_REFERENCE =
191       (GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE |
192       GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE),
193
194   GST_VAAPI_PICTURE_FLAGS_RPS_ST =
195       (GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_BEFORE |
196       GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_AFTER |
197       GST_VAAPI_PICTURE_FLAG_RPS_ST_FOLL),
198   GST_VAAPI_PICTURE_FLAGS_RPS_LT =
199       (GST_VAAPI_PICTURE_FLAG_RPS_LT_CURR | GST_VAAPI_PICTURE_FLAG_RPS_LT_FOLL),
200 };
201
202 #define GST_VAAPI_PICTURE_IS_IDR(picture) \
203     (GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR))
204
205 #define GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture)      \
206     ((GST_VAAPI_PICTURE_FLAGS(picture) &                        \
207       GST_VAAPI_PICTURE_FLAGS_REFERENCE) ==                     \
208      GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE)
209
210 #define GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture)       \
211     ((GST_VAAPI_PICTURE_FLAGS(picture) &                        \
212       GST_VAAPI_PICTURE_FLAGS_REFERENCE) ==                     \
213      GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE)
214
215 #define GST_VAAPI_PICTURE_H265(picture) \
216     ((GstVaapiPictureH265 *)(picture))
217
218 struct _GstVaapiPictureH265
219 {
220   GstVaapiPicture base;
221   GstH265SliceHdr *last_slice_hdr;
222   guint structure;
223   gint32 poc;                   // PicOrderCntVal (8.3.1) 
224   gint32 poc_lsb;               // slice_pic_order_cnt_lsb
225   guint32 pic_latency_cnt;      // PicLatencyCount
226   guint output_flag:1;
227   guint output_needed:1;
228   guint NoRaslOutputFlag:1;
229   guint NoOutputOfPriorPicsFlag:1;
230   guint RapPicFlag:1;           // nalu type between 16 and 21
231   guint IntraPicFlag:1;         // Intra pic (only Intra slices)
232 };
233
234 GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiPictureH265, gst_vaapi_picture_h265);
235
236 void
237 gst_vaapi_picture_h265_destroy (GstVaapiPictureH265 * picture)
238 {
239   gst_vaapi_picture_destroy (GST_VAAPI_PICTURE (picture));
240 }
241
242 gboolean
243 gst_vaapi_picture_h265_create (GstVaapiPictureH265 * picture,
244     const GstVaapiCodecObjectConstructorArgs * args)
245 {
246   if (!gst_vaapi_picture_create (GST_VAAPI_PICTURE (picture), args))
247     return FALSE;
248
249   picture->structure = picture->base.structure;
250   picture->poc = G_MAXINT32;
251   picture->output_needed = FALSE;
252   return TRUE;
253 }
254
255 static inline GstVaapiPictureH265 *
256 gst_vaapi_picture_h265_new (GstVaapiDecoderH265 * decoder)
257 {
258   return (GstVaapiPictureH265 *)
259       gst_vaapi_codec_object_new (&GstVaapiPictureH265Class,
260       GST_VAAPI_CODEC_BASE (decoder), NULL,
261       sizeof (VAPictureParameterBufferHEVC), NULL, 0, 0);
262 }
263
264 static inline void
265 gst_vaapi_picture_h265_set_reference (GstVaapiPictureH265 * picture,
266     guint reference_flags)
267 {
268   if (!picture)
269     return;
270   GST_VAAPI_PICTURE_FLAG_UNSET (picture,
271       GST_VAAPI_PICTURE_FLAGS_RPS_ST | GST_VAAPI_PICTURE_FLAGS_RPS_LT);
272   GST_VAAPI_PICTURE_FLAG_UNSET (picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE);
273   GST_VAAPI_PICTURE_FLAG_SET (picture, reference_flags);
274 }
275
276 /* ------------------------------------------------------------------------- */
277 /* --- Frame Buffers (DPB)                                               --- */
278 /* ------------------------------------------------------------------------- */
279
280 struct _GstVaapiFrameStore
281 {
282   /*< private > */
283   GstVaapiMiniObject parent_instance;
284
285   GstVaapiPictureH265 *buffer;
286 };
287
288 static void
289 gst_vaapi_frame_store_finalize (gpointer object)
290 {
291   GstVaapiFrameStore *const fs = object;
292
293   gst_vaapi_picture_replace (&fs->buffer, NULL);
294 }
295
296 static GstVaapiFrameStore *
297 gst_vaapi_frame_store_new (GstVaapiPictureH265 * picture)
298 {
299   GstVaapiFrameStore *fs;
300
301   static const GstVaapiMiniObjectClass GstVaapiFrameStoreClass = {
302     sizeof (GstVaapiFrameStore),
303     gst_vaapi_frame_store_finalize
304   };
305
306   fs = (GstVaapiFrameStore *)
307       gst_vaapi_mini_object_new (&GstVaapiFrameStoreClass);
308   if (!fs)
309     return NULL;
310
311   fs->buffer = gst_vaapi_picture_ref (picture);
312
313   return fs;
314 }
315
316 static inline gboolean
317 gst_vaapi_frame_store_has_reference (GstVaapiFrameStore * fs)
318 {
319   if (GST_VAAPI_PICTURE_IS_REFERENCE (fs->buffer))
320     return TRUE;
321   return FALSE;
322 }
323
324 #define gst_vaapi_frame_store_ref(fs) \
325     gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(fs))
326
327 #define gst_vaapi_frame_store_unref(fs) \
328     gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(fs))
329
330 #define gst_vaapi_frame_store_replace(old_fs_p, new_fs)                 \
331     gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_fs_p),    \
332         (GstVaapiMiniObject *)(new_fs))
333
334 /* ------------------------------------------------------------------------- */
335 /* --- H.265 Decoder                                                     --- */
336 /* ------------------------------------------------------------------------- */
337
338 #define GST_VAAPI_DECODER_H265_CAST(decoder) \
339     ((GstVaapiDecoderH265 *)(decoder))
340
341 typedef enum
342 {
343   GST_H265_VIDEO_STATE_GOT_VPS = 1 << 0,
344   GST_H265_VIDEO_STATE_GOT_SPS = 1 << 1,
345   GST_H265_VIDEO_STATE_GOT_PPS = 1 << 2,
346   GST_H265_VIDEO_STATE_GOT_SLICE = 1 << 3,
347
348   GST_H265_VIDEO_STATE_VALID_PICTURE_HEADERS =
349       (GST_H265_VIDEO_STATE_GOT_SPS | GST_H265_VIDEO_STATE_GOT_PPS),
350   GST_H265_VIDEO_STATE_VALID_PICTURE =
351       (GST_H265_VIDEO_STATE_VALID_PICTURE_HEADERS |
352       GST_H265_VIDEO_STATE_GOT_SLICE)
353 } GstH265VideoState;
354
355 struct _GstVaapiDecoderH265Private
356 {
357   GstH265Parser *parser;
358   guint parser_state;
359   guint decoder_state;
360   GstVaapiStreamAlignH265 stream_alignment;
361   GstVaapiPictureH265 *current_picture;
362   GstVaapiParserInfoH265 *vps[GST_H265_MAX_VPS_COUNT];
363   GstVaapiParserInfoH265 *active_vps;
364   GstVaapiParserInfoH265 *sps[GST_H265_MAX_SPS_COUNT];
365   GstVaapiParserInfoH265 *active_sps;
366   GstVaapiParserInfoH265 *pps[GST_H265_MAX_PPS_COUNT];
367   GstVaapiParserInfoH265 *active_pps;
368   GstVaapiParserInfoH265 *prev_pi;
369   GstVaapiParserInfoH265 *prev_slice_pi;
370   GstVaapiParserInfoH265 *prev_independent_slice_pi;
371   GstVaapiFrameStore **dpb;
372   guint dpb_count;
373   guint dpb_size;
374   guint dpb_size_max;
375   GstVaapiProfile profile;
376   GstVaapiEntrypoint entrypoint;
377   GstVaapiChromaType chroma_type;
378
379   GstVaapiPictureH265 *RefPicSetStCurrBefore[16];
380   GstVaapiPictureH265 *RefPicSetStCurrAfter[16];
381   GstVaapiPictureH265 *RefPicSetStFoll[16];
382   GstVaapiPictureH265 *RefPicSetLtCurr[16];
383   GstVaapiPictureH265 *RefPicSetLtFoll[16];
384
385   GstVaapiPictureH265 *RefPicList0[16];
386   guint RefPicList0_count;
387   GstVaapiPictureH265 *RefPicList1[16];
388   guint RefPicList1_count;
389
390   guint32 SpsMaxLatencyPictures;
391
392   guint nal_length_size;
393
394   guint pic_width_in_luma_samples;      //sps->pic_width_in_luma_samples
395   guint pic_height_in_luma_samples;     //sps->pic_height_in_luma_samples
396   guint pic_structure;          // pic_struct (from SEI pic_timing() or inferred)
397   gint32 poc;                   // PicOrderCntVal
398   gint32 poc_msb;               // PicOrderCntMsb
399   gint32 poc_lsb;               // pic_order_cnt_lsb (from slice_header())
400   gint32 prev_poc_msb;          // prevPicOrderCntMsb
401   gint32 prev_poc_lsb;          // prevPicOrderCntLsb
402   gint32 prev_tid0pic_poc_lsb;
403   gint32 prev_tid0pic_poc_msb;
404   gint32 PocStCurrBefore[16];
405   gint32 PocStCurrAfter[16];
406   gint32 PocStFoll[16];
407   gint32 PocLtCurr[16];
408   gint32 PocLtFoll[16];
409   guint NumPocStCurrBefore;
410   guint NumPocStCurrAfter;
411   guint NumPocStFoll;
412   guint NumPocLtCurr;
413   guint NumPocLtFoll;
414   guint NumPocTotalCurr;
415   guint is_opened:1;
416   guint is_hvcC:1;
417   guint has_context:1;
418   guint progressive_sequence:1;
419   guint new_bitstream:1;
420   guint prev_nal_is_eos:1;      /*previous nal type is EOS */
421   guint associated_irap_NoRaslOutputFlag:1;
422 };
423
424 /**
425  * GstVaapiDecoderH265:
426  *
427  * A decoder based on H265.
428  */
429 struct _GstVaapiDecoderH265
430 {
431   /*< private > */
432   GstVaapiDecoder parent_instance;
433   GstVaapiDecoderH265Private priv;
434 };
435
436 /**
437  * GstVaapiDecoderH265Class:
438  *
439  * A decoder class based on H265.
440  */
441 struct _GstVaapiDecoderH265Class
442 {
443   /*< private > */
444   GstVaapiDecoderClass parent_class;
445 };
446
447 #define RSV_VCL_N10 10
448 #define RSV_VCL_N12 12
449 #define RSV_VCL_N14 14
450
451 static gboolean
452 nal_is_idr (guint8 nal_type)
453 {
454   if ((nal_type == GST_H265_NAL_SLICE_IDR_W_RADL) ||
455       (nal_type == GST_H265_NAL_SLICE_IDR_N_LP))
456     return TRUE;
457   return FALSE;
458 }
459
460 static gboolean
461 nal_is_irap (guint8 nal_type)
462 {
463   if ((nal_type >= GST_H265_NAL_SLICE_BLA_W_LP) &&
464       (nal_type <= RESERVED_IRAP_NAL_TYPE_MAX))
465     return TRUE;
466   return FALSE;
467 }
468
469 static gboolean
470 nal_is_bla (guint8 nal_type)
471 {
472   if ((nal_type >= GST_H265_NAL_SLICE_BLA_W_LP) &&
473       (nal_type <= GST_H265_NAL_SLICE_BLA_N_LP))
474     return TRUE;
475   return FALSE;
476 }
477
478 static gboolean
479 nal_is_cra (guint8 nal_type)
480 {
481   if (nal_type == GST_H265_NAL_SLICE_CRA_NUT)
482     return TRUE;
483   return FALSE;
484 }
485
486 static gboolean
487 nal_is_radl (guint8 nal_type)
488 {
489   if ((nal_type >= GST_H265_NAL_SLICE_RADL_N) &&
490       (nal_type <= GST_H265_NAL_SLICE_RADL_R))
491     return TRUE;
492   return FALSE;
493 }
494
495 static gboolean
496 nal_is_rasl (guint8 nal_type)
497 {
498   if ((nal_type >= GST_H265_NAL_SLICE_RASL_N) &&
499       (nal_type <= GST_H265_NAL_SLICE_RASL_R))
500     return TRUE;
501   return FALSE;
502 }
503
504 static gboolean
505 nal_is_slice (guint8 nal_type)
506 {
507   if ((nal_type >= GST_H265_NAL_SLICE_TRAIL_N) &&
508       (nal_type <= GST_H265_NAL_SLICE_CRA_NUT))
509     return TRUE;
510   return FALSE;
511 }
512
513 static gboolean
514 nal_is_ref (guint8 nal_type)
515 {
516   gboolean ret = FALSE;
517   switch (nal_type) {
518     case GST_H265_NAL_SLICE_TRAIL_N:
519     case GST_H265_NAL_SLICE_TSA_N:
520     case GST_H265_NAL_SLICE_STSA_N:
521     case GST_H265_NAL_SLICE_RADL_N:
522     case GST_H265_NAL_SLICE_RASL_N:
523     case RSV_VCL_N10:
524     case RSV_VCL_N12:
525     case RSV_VCL_N14:
526       ret = FALSE;
527       break;
528     default:
529       ret = TRUE;
530       break;
531   }
532   return ret;
533 }
534
535 /* Activates the supplied PPS */
536 static GstH265PPS *
537 ensure_pps (GstVaapiDecoderH265 * decoder, GstH265PPS * pps)
538 {
539   GstVaapiDecoderH265Private *const priv = &decoder->priv;
540   GstVaapiParserInfoH265 *const pi = priv->pps[pps->id];
541
542   gst_vaapi_parser_info_h265_replace (&priv->active_pps, pi);
543   return pi ? &pi->data.pps : NULL;
544 }
545
546 /* Returns the active PPS */
547 static inline GstH265PPS *
548 get_pps (GstVaapiDecoderH265 * decoder)
549 {
550   GstVaapiParserInfoH265 *const pi = decoder->priv.active_pps;
551
552   return pi ? &pi->data.pps : NULL;
553 }
554
555 /* Activate the supplied SPS */
556 static GstH265SPS *
557 ensure_sps (GstVaapiDecoderH265 * decoder, GstH265SPS * sps)
558 {
559   GstVaapiDecoderH265Private *const priv = &decoder->priv;
560   GstVaapiParserInfoH265 *const pi = priv->sps[sps->id];
561
562   gst_vaapi_parser_info_h265_replace (&priv->active_sps, pi);
563   return pi ? &pi->data.sps : NULL;
564 }
565
566 /* Returns the active SPS */
567 static inline GstH265SPS *
568 get_sps (GstVaapiDecoderH265 * decoder)
569 {
570   GstVaapiParserInfoH265 *const pi = decoder->priv.active_sps;
571
572   return pi ? &pi->data.sps : NULL;
573 }
574
575 /* Activate the supplied VPS */
576 static GstH265VPS *
577 ensure_vps (GstVaapiDecoderH265 * decoder, GstH265VPS * vps)
578 {
579   GstVaapiDecoderH265Private *const priv = &decoder->priv;
580   GstVaapiParserInfoH265 *const pi = priv->vps[vps->id];
581
582   gst_vaapi_parser_info_h265_replace (&priv->active_vps, pi);
583   return pi ? &pi->data.vps : NULL;
584 }
585
586 /* Returns the active VPS */
587 static inline GstH265VPS *
588 get_vps (GstVaapiDecoderH265 * decoder)
589 {
590   GstVaapiParserInfoH265 *const pi = decoder->priv.active_vps;
591   return pi ? &pi->data.vps : NULL;
592 }
593
594 /* Get number of reference frames to use */
595 static guint
596 get_max_dec_frame_buffering (GstH265SPS * sps)
597 {
598   guint max_dec_frame_buffering;
599   GstVaapiLevelH265 level;
600   const GstVaapiH265LevelLimits *level_limits;
601
602   level = gst_vaapi_utils_h265_get_level (sps->profile_tier_level.level_idc);
603   level_limits = gst_vaapi_utils_h265_get_level_limits (level);
604   if (G_UNLIKELY (!level_limits)) {
605     GST_FIXME ("unsupported level_idc value (%d)",
606         sps->profile_tier_level.level_idc);
607     max_dec_frame_buffering = 16;
608   }
609
610   /* Fixme: Add limit check based on Annex A */
611
612   /* Assuming HighestTid as sps_max_sub_layers_minus1 */
613   return MAX (1,
614       (sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1] + 1));
615 }
616
617 static void
618 dpb_remove_index (GstVaapiDecoderH265 * decoder, gint index)
619 {
620   GstVaapiDecoderH265Private *const priv = &decoder->priv;
621   guint i, num_frames = --priv->dpb_count;
622
623   if (USE_STRICT_DPB_ORDERING) {
624     for (i = index; i < num_frames; i++)
625       gst_vaapi_frame_store_replace (&priv->dpb[i], priv->dpb[i + 1]);
626   } else if (index != num_frames)
627     gst_vaapi_frame_store_replace (&priv->dpb[index], priv->dpb[num_frames]);
628   gst_vaapi_frame_store_replace (&priv->dpb[num_frames], NULL);
629 }
630
631 static gboolean
632 dpb_output (GstVaapiDecoderH265 * decoder, GstVaapiFrameStore * fs)
633 {
634   GstVaapiPictureH265 *picture;
635
636   g_return_val_if_fail (fs != NULL, FALSE);
637
638   picture = fs->buffer;
639   g_return_val_if_fail (picture != NULL, FALSE);
640
641   picture->output_needed = FALSE;
642   return gst_vaapi_picture_output (GST_VAAPI_PICTURE_CAST (picture));
643 }
644
645 /* Get the dpb picture having the specifed poc or poc_lsb */
646 static GstVaapiPictureH265 *
647 dpb_get_picture (GstVaapiDecoderH265 * decoder, gint poc, gboolean match_lsb)
648 {
649   GstVaapiDecoderH265Private *const priv = &decoder->priv;
650   guint i;
651
652   for (i = 0; i < priv->dpb_count; i++) {
653     GstVaapiPictureH265 *const picture = priv->dpb[i]->buffer;
654
655     if (picture && GST_VAAPI_PICTURE_FLAG_IS_SET (picture,
656             GST_VAAPI_PICTURE_FLAGS_REFERENCE)) {
657       if (match_lsb) {
658         if (picture->poc_lsb == poc)
659           return picture;
660       } else {
661         if (picture->poc == poc)
662           return picture;
663       }
664     }
665   }
666   return NULL;
667 }
668
669 /* Get the dpb picture having the specifed poc and shor/long ref flags */
670 static GstVaapiPictureH265 *
671 dpb_get_ref_picture (GstVaapiDecoderH265 * decoder, gint poc, gboolean is_short)
672 {
673   GstVaapiDecoderH265Private *const priv = &decoder->priv;
674   guint i;
675
676   for (i = 0; i < priv->dpb_count; i++) {
677     GstVaapiPictureH265 *const picture = priv->dpb[i]->buffer;
678
679     if (picture && picture->poc == poc) {
680       if (is_short && GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE (picture))
681         return picture;
682       else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE (picture))
683         return picture;
684     }
685   }
686
687   return NULL;
688 }
689
690 /* Finds the picture with the lowest POC that needs to be output */
691 static gint
692 dpb_find_lowest_poc (GstVaapiDecoderH265 * decoder,
693     GstVaapiPictureH265 ** found_picture_ptr)
694 {
695   GstVaapiDecoderH265Private *const priv = &decoder->priv;
696   GstVaapiPictureH265 *found_picture = NULL;
697   guint i, found_index;
698
699   for (i = 0; i < priv->dpb_count; i++) {
700     GstVaapiPictureH265 *const picture = priv->dpb[i]->buffer;
701     if (picture && !picture->output_needed)
702       continue;
703     if (!found_picture || found_picture->poc > picture->poc)
704       found_picture = picture, found_index = i;
705   }
706
707   if (found_picture_ptr)
708     *found_picture_ptr = found_picture;
709   return found_picture ? found_index : -1;
710 }
711
712 static gboolean
713 dpb_bump (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture)
714 {
715   GstVaapiDecoderH265Private *const priv = &decoder->priv;
716   GstVaapiPictureH265 *found_picture;
717   gint found_index;
718   gboolean success;
719
720   found_index = dpb_find_lowest_poc (decoder, &found_picture);
721   if (found_index < 0)
722     return FALSE;
723
724   success = dpb_output (decoder, priv->dpb[found_index]);
725
726   if (!gst_vaapi_frame_store_has_reference (priv->dpb[found_index]))
727     dpb_remove_index (decoder, found_index);
728
729   return success;
730 }
731
732 static void
733 dpb_clear (GstVaapiDecoderH265 * decoder, gboolean hard_flush)
734 {
735   GstVaapiDecoderH265Private *const priv = &decoder->priv;
736   GstVaapiPictureH265 *pic;
737   guint i;
738
739   if (hard_flush) {
740     for (i = 0; i < priv->dpb_count; i++)
741       dpb_remove_index (decoder, i);
742     priv->dpb_count = 0;
743   } else {
744     /* Remove unused pictures from DPB */
745     i = 0;
746     while (i < priv->dpb_count) {
747       GstVaapiFrameStore *const fs = priv->dpb[i];
748       pic = fs->buffer;
749       if (!pic->output_needed && !gst_vaapi_frame_store_has_reference (fs))
750         dpb_remove_index (decoder, i);
751       else
752         i++;
753     }
754   }
755 }
756
757 static void
758 dpb_flush (GstVaapiDecoderH265 * decoder)
759 {
760   /* Output any frame remaining in DPB */
761   while (dpb_bump (decoder, NULL));
762   dpb_clear (decoder, TRUE);
763 }
764
765 static gint
766 dpb_get_num_need_output (GstVaapiDecoderH265 * decoder)
767 {
768   GstVaapiDecoderH265Private *const priv = &decoder->priv;
769   guint i = 0, n_output_needed = 0;
770
771   while (i < priv->dpb_count) {
772     GstVaapiFrameStore *const fs = priv->dpb[i];
773     if (fs->buffer->output_needed)
774       n_output_needed++;
775     i++;
776   }
777
778   return n_output_needed;
779 }
780
781 static gboolean
782 check_latency_cnt (GstVaapiDecoderH265 * decoder)
783 {
784   GstVaapiDecoderH265Private *const priv = &decoder->priv;
785   GstVaapiPictureH265 *tmp_pic;
786   guint i = 0;
787
788   while (i < priv->dpb_count) {
789     GstVaapiFrameStore *const fs = priv->dpb[i];
790     tmp_pic = fs->buffer;
791     if (tmp_pic->output_needed) {
792       if (tmp_pic->pic_latency_cnt >= priv->SpsMaxLatencyPictures)
793         return TRUE;
794     }
795     i++;
796   }
797
798   return FALSE;
799 }
800
801 static gboolean
802 dpb_add (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture)
803 {
804   GstVaapiDecoderH265Private *const priv = &decoder->priv;
805   GstH265SPS *const sps = get_sps (decoder);
806   GstVaapiFrameStore *fs;
807   GstVaapiPictureH265 *tmp_pic;
808   guint i = 0;
809
810   /* C.5.2.3 */
811   while (i < priv->dpb_count) {
812     GstVaapiFrameStore *const fs = priv->dpb[i];
813     tmp_pic = fs->buffer;
814     if (tmp_pic->output_needed)
815       tmp_pic->pic_latency_cnt += 1;
816     i++;
817   }
818
819   if (picture->output_flag) {
820     picture->output_needed = 1;
821     picture->pic_latency_cnt = 0;
822   } else
823     picture->output_needed = 0;
824
825   /* set pic as short_term_ref */
826   gst_vaapi_picture_h265_set_reference (picture,
827       GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE);
828
829   /* C.5.2.4 "Bumping" process */
830   while ((dpb_get_num_need_output (decoder) >
831           sps->max_num_reorder_pics[sps->max_sub_layers_minus1])
832       || (sps->max_latency_increase_plus1[sps->max_sub_layers_minus1]
833           && check_latency_cnt (decoder)))
834     dpb_bump (decoder, picture);
835
836   /* Create new frame store */
837   fs = gst_vaapi_frame_store_new (picture);
838   if (!fs)
839     return FALSE;
840   gst_vaapi_frame_store_replace (&priv->dpb[priv->dpb_count++], fs);
841   gst_vaapi_frame_store_unref (fs);
842
843   return TRUE;
844 }
845
846
847 /* C.5.2.2 */
848 static gboolean
849 dpb_init (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture,
850     GstVaapiParserInfoH265 * pi)
851 {
852   GstVaapiDecoderH265Private *const priv = &decoder->priv;
853   GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr;
854   GstH265SPS *const sps = get_sps (decoder);
855
856   if (nal_is_irap (pi->nalu.type)
857       && picture->NoRaslOutputFlag && !priv->new_bitstream) {
858
859     if (pi->nalu.type == GST_H265_NAL_SLICE_CRA_NUT)
860       picture->NoOutputOfPriorPicsFlag = 1;
861     else
862       picture->NoOutputOfPriorPicsFlag =
863           slice_hdr->no_output_of_prior_pics_flag;
864
865     if (picture->NoOutputOfPriorPicsFlag)
866       dpb_clear (decoder, TRUE);
867     else {
868       dpb_clear (decoder, FALSE);
869       while (dpb_bump (decoder, NULL));
870     }
871   } else {
872     dpb_clear (decoder, FALSE);
873     while ((dpb_get_num_need_output (decoder) >
874             sps->max_num_reorder_pics[sps->max_sub_layers_minus1])
875         || (sps->max_latency_increase_plus1[sps->max_sub_layers_minus1]
876             && check_latency_cnt (decoder))
877         || (priv->dpb_count >=
878             (sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1] +
879                 1))) {
880       dpb_bump (decoder, picture);
881     }
882   }
883
884   return TRUE;
885 }
886
887 static gboolean
888 dpb_reset (GstVaapiDecoderH265 * decoder, guint dpb_size)
889 {
890   GstVaapiDecoderH265Private *const priv = &decoder->priv;
891
892   if (dpb_size > priv->dpb_size_max) {
893     priv->dpb = g_try_realloc_n (priv->dpb, dpb_size, sizeof (*priv->dpb));
894     if (!priv->dpb)
895       return FALSE;
896     memset (&priv->dpb[priv->dpb_size_max], 0,
897         (dpb_size - priv->dpb_size_max) * sizeof (*priv->dpb));
898     priv->dpb_size_max = dpb_size;
899   }
900   priv->dpb_size = dpb_size;
901   GST_DEBUG ("DPB size %u", priv->dpb_size);
902   return TRUE;
903 }
904
905 static GstVaapiDecoderStatus
906 get_status (GstH265ParserResult result)
907 {
908   GstVaapiDecoderStatus status;
909
910   switch (result) {
911     case GST_H265_PARSER_OK:
912       status = GST_VAAPI_DECODER_STATUS_SUCCESS;
913       break;
914     case GST_H265_PARSER_NO_NAL_END:
915       status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
916       break;
917     case GST_H265_PARSER_ERROR:
918       status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
919       break;
920     default:
921       status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
922       break;
923   }
924   return status;
925 }
926
927 static void
928 gst_vaapi_decoder_h265_close (GstVaapiDecoderH265 * decoder)
929 {
930   GstVaapiDecoderH265Private *const priv = &decoder->priv;
931
932   gst_vaapi_picture_replace (&priv->current_picture, NULL);
933   gst_vaapi_parser_info_h265_replace (&priv->prev_slice_pi, NULL);
934   gst_vaapi_parser_info_h265_replace (&priv->prev_independent_slice_pi, NULL);
935   gst_vaapi_parser_info_h265_replace (&priv->prev_pi, NULL);
936
937   dpb_clear (decoder, TRUE);
938
939   if (priv->parser) {
940     gst_h265_parser_free (priv->parser);
941     priv->parser = NULL;
942   }
943 }
944
945 static gboolean
946 gst_vaapi_decoder_h265_open (GstVaapiDecoderH265 * decoder)
947 {
948   GstVaapiDecoderH265Private *const priv = &decoder->priv;
949
950   gst_vaapi_decoder_h265_close (decoder);
951   priv->parser = gst_h265_parser_new ();
952   if (!priv->parser)
953     return FALSE;
954   return TRUE;
955 }
956
957 static void
958 gst_vaapi_decoder_h265_destroy (GstVaapiDecoder * base_decoder)
959 {
960   GstVaapiDecoderH265 *const decoder =
961       GST_VAAPI_DECODER_H265_CAST (base_decoder);
962   GstVaapiDecoderH265Private *const priv = &decoder->priv;
963   guint i;
964
965   gst_vaapi_decoder_h265_close (decoder);
966   g_free (priv->dpb);
967   priv->dpb = NULL;
968   priv->dpb_size = 0;
969   for (i = 0; i < G_N_ELEMENTS (priv->pps); i++)
970     gst_vaapi_parser_info_h265_replace (&priv->pps[i], NULL);
971   gst_vaapi_parser_info_h265_replace (&priv->active_pps, NULL);
972   for (i = 0; i < G_N_ELEMENTS (priv->sps); i++)
973     gst_vaapi_parser_info_h265_replace (&priv->sps[i], NULL);
974   gst_vaapi_parser_info_h265_replace (&priv->active_sps, NULL);
975   for (i = 0; i < G_N_ELEMENTS (priv->vps); i++)
976     gst_vaapi_parser_info_h265_replace (&priv->vps[i], NULL);
977   gst_vaapi_parser_info_h265_replace (&priv->active_vps, NULL);
978 }
979
980 static gboolean
981 gst_vaapi_decoder_h265_create (GstVaapiDecoder * base_decoder)
982 {
983   GstVaapiDecoderH265 *const decoder =
984       GST_VAAPI_DECODER_H265_CAST (base_decoder);
985   GstVaapiDecoderH265Private *const priv = &decoder->priv;
986
987   priv->profile = GST_VAAPI_PROFILE_UNKNOWN;
988   priv->entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
989   priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
990   priv->progressive_sequence = TRUE;
991   priv->new_bitstream = TRUE;
992   priv->prev_nal_is_eos = FALSE;
993   return TRUE;
994 }
995
996
997 static void
998 fill_profiles (GstVaapiProfile profiles[16], guint * n_profiles_ptr,
999     GstVaapiProfile profile)
1000 {
1001   guint n_profiles = *n_profiles_ptr;
1002
1003   profiles[n_profiles++] = profile;
1004   switch (profile) {
1005     case GST_VAAPI_PROFILE_H265_MAIN:
1006       profiles[n_profiles++] = GST_VAAPI_PROFILE_H265_MAIN10;
1007       break;
1008     case GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE:
1009       profiles[n_profiles++] = GST_VAAPI_PROFILE_H265_MAIN;
1010       profiles[n_profiles++] = GST_VAAPI_PROFILE_H265_MAIN10;
1011       break;
1012     default:
1013       break;
1014   }
1015   *n_profiles_ptr = n_profiles;
1016 }
1017
1018 static GstVaapiProfile
1019 get_profile (GstVaapiDecoderH265 * decoder, GstH265SPS * sps, guint dpb_size)
1020 {
1021   GstVaapiDecoderH265Private *const priv = &decoder->priv;
1022   GstVaapiDisplay *const display = GST_VAAPI_DECODER_DISPLAY (decoder);
1023   GstVaapiProfile profile, profiles[3];
1024   guint i, n_profiles = 0;
1025
1026   profile =
1027       gst_vaapi_utils_h265_get_profile (sps->profile_tier_level.profile_idc);
1028   if (!profile) {
1029     /* HACK: This is a work-around to identify some main profile streams having wrong profile_idc.
1030      * There are some wrongly encoded main profile streams(eg: ENTP_C_LG_3.bin) which doesn't
1031      * have any of the profile_idc values mentioned in Annex-A, instead general_profile_idc
1032      * has been set as zero and having general_profile_compatibility_flag[general_profile_idc]
1033      * is TRUE. Assuming them as MAIN profile for now */
1034     if (sps->profile_tier_level.profile_space == 0 &&
1035         sps->profile_tier_level.profile_idc == 0 &&
1036         sps->profile_tier_level.profile_compatibility_flag[0] == 1) {
1037       GST_WARNING ("Wrong profile_idc, blindly setting it as main profile !!");
1038       profile = GST_VAAPI_PROFILE_H265_MAIN;
1039     } else
1040       return GST_VAAPI_PROFILE_UNKNOWN;
1041   }
1042
1043   fill_profiles (profiles, &n_profiles, profile);
1044   switch (profile) {
1045     case GST_VAAPI_PROFILE_H265_MAIN10:
1046       if (sps->profile_tier_level.profile_compatibility_flag[1]) {      // A.2.3.2 (main profile)
1047         fill_profiles (profiles, &n_profiles, GST_VAAPI_PROFILE_H265_MAIN);
1048       }
1049       break;
1050     default:
1051       break;
1052   }
1053
1054   /* If the preferred profile (profiles[0]) matches one that we already
1055      found, then just return it now instead of searching for it again */
1056   if (profiles[0] == priv->profile)
1057     return priv->profile;
1058   for (i = 0; i < n_profiles; i++) {
1059     if (gst_vaapi_display_has_decoder (display, profiles[i], priv->entrypoint))
1060       return profiles[i];
1061   }
1062   return GST_VAAPI_PROFILE_UNKNOWN;
1063 }
1064
1065 static GstVaapiDecoderStatus
1066 ensure_context (GstVaapiDecoderH265 * decoder, GstH265SPS * sps)
1067 {
1068   GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER_CAST (decoder);
1069   GstVaapiDecoderH265Private *const priv = &decoder->priv;
1070   GstVaapiContextInfo info;
1071   GstVaapiProfile profile;
1072   GstVaapiChromaType chroma_type;
1073   gboolean reset_context = FALSE;
1074   guint dpb_size;
1075
1076   dpb_size = get_max_dec_frame_buffering (sps);
1077   if (priv->dpb_size < dpb_size) {
1078     GST_DEBUG ("DPB size increased");
1079     reset_context = TRUE;
1080   }
1081
1082   profile = get_profile (decoder, sps, dpb_size);
1083   if (!profile) {
1084     GST_ERROR ("unsupported profile_idc %u",
1085         sps->profile_tier_level.profile_idc);
1086     return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1087   }
1088
1089   if (!priv->profile || (priv->profile != profile)) {
1090     GST_DEBUG ("profile changed");
1091     reset_context = TRUE;
1092     priv->profile = profile;
1093   }
1094
1095   chroma_type = gst_vaapi_utils_h265_get_chroma_type (sps->chroma_format_idc);
1096   if (!chroma_type) {
1097     GST_ERROR ("unsupported chroma_format_idc %u", sps->chroma_format_idc);
1098     return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
1099   }
1100
1101   if (priv->chroma_type != chroma_type) {
1102     GST_DEBUG ("chroma format changed");
1103     reset_context = TRUE;
1104     priv->chroma_type = chroma_type;
1105   }
1106
1107   if (priv->pic_width_in_luma_samples != sps->pic_width_in_luma_samples ||
1108       priv->pic_height_in_luma_samples != sps->pic_height_in_luma_samples) {
1109     GST_DEBUG ("size changed");
1110     reset_context = TRUE;
1111     priv->pic_width_in_luma_samples = sps->pic_width_in_luma_samples;
1112     priv->pic_height_in_luma_samples = sps->pic_height_in_luma_samples;
1113   }
1114
1115   priv->progressive_sequence = 1;       /*Fixme */
1116   gst_vaapi_decoder_set_interlaced (base_decoder, !priv->progressive_sequence);
1117   gst_vaapi_decoder_set_pixel_aspect_ratio (base_decoder,
1118       sps->vui_params.par_n, sps->vui_params.par_d);
1119   if (!reset_context && priv->has_context)
1120     return GST_VAAPI_DECODER_STATUS_SUCCESS;
1121
1122   /* XXX: fix surface size when cropping is implemented */
1123   info.profile = priv->profile;
1124   info.entrypoint = priv->entrypoint;
1125   info.chroma_type = priv->chroma_type;
1126   info.width = sps->width;
1127   info.height = sps->height;
1128   info.ref_frames = dpb_size;
1129
1130   if (!gst_vaapi_decoder_ensure_context (GST_VAAPI_DECODER (decoder), &info))
1131     return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
1132   priv->has_context = TRUE;
1133
1134   /* Reset DPB */
1135   if (!dpb_reset (decoder, dpb_size))
1136     return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
1137
1138   return GST_VAAPI_DECODER_STATUS_SUCCESS;
1139 }
1140
1141 static void
1142 fill_iq_matrix_4x4 (VAIQMatrixBufferHEVC * iq_matrix,
1143     GstH265ScalingList * scaling_list)
1144 {
1145   guint i;
1146
1147   g_assert (G_N_ELEMENTS (iq_matrix->ScalingList4x4) == 6);
1148   g_assert (G_N_ELEMENTS (iq_matrix->ScalingList4x4[0]) == 16);
1149   for (i = 0; i < G_N_ELEMENTS (iq_matrix->ScalingList4x4); i++) {
1150     gst_h265_quant_matrix_4x4_get_raster_from_zigzag (iq_matrix->ScalingList4x4
1151         [i], scaling_list->scaling_lists_4x4[i]);
1152   }
1153 }
1154
1155 static void
1156 fill_iq_matrix_8x8 (VAIQMatrixBufferHEVC * iq_matrix,
1157     GstH265ScalingList * scaling_list)
1158 {
1159   guint i;
1160
1161   g_assert (G_N_ELEMENTS (iq_matrix->ScalingList8x8) == 6);
1162   g_assert (G_N_ELEMENTS (iq_matrix->ScalingList8x8[0]) == 64);
1163   for (i = 0; i < G_N_ELEMENTS (iq_matrix->ScalingList8x8); i++) {
1164     gst_h265_quant_matrix_8x8_get_raster_from_zigzag (iq_matrix->ScalingList8x8
1165         [i], scaling_list->scaling_lists_8x8[i]);
1166   }
1167 }
1168
1169 static void
1170 fill_iq_matrix_16x16 (VAIQMatrixBufferHEVC * iq_matrix,
1171     GstH265ScalingList * scaling_list)
1172 {
1173   guint i;
1174
1175   g_assert (G_N_ELEMENTS (iq_matrix->ScalingList16x16) == 6);
1176   g_assert (G_N_ELEMENTS (iq_matrix->ScalingList16x16[0]) == 64);
1177   for (i = 0; i < G_N_ELEMENTS (iq_matrix->ScalingList16x16); i++) {
1178     gst_h265_quant_matrix_16x16_get_raster_from_zigzag
1179         (iq_matrix->ScalingList16x16[i], scaling_list->scaling_lists_16x16[i]);
1180   }
1181 }
1182
1183 static void
1184 fill_iq_matrix_32x32 (VAIQMatrixBufferHEVC * iq_matrix,
1185     GstH265ScalingList * scaling_list)
1186 {
1187   guint i;
1188
1189   g_assert (G_N_ELEMENTS (iq_matrix->ScalingList32x32) == 2);
1190   g_assert (G_N_ELEMENTS (iq_matrix->ScalingList32x32[0]) == 64);
1191   for (i = 0; i < G_N_ELEMENTS (iq_matrix->ScalingList32x32); i++) {
1192     gst_h265_quant_matrix_32x32_get_raster_from_zigzag
1193         (iq_matrix->ScalingList32x32[i], scaling_list->scaling_lists_32x32[i]);
1194   }
1195 }
1196
1197 static void
1198 fill_iq_matrix_dc_16x16 (VAIQMatrixBufferHEVC * iq_matrix,
1199     GstH265ScalingList * scaling_list)
1200 {
1201   guint i;
1202
1203   for (i = 0; i < 6; i++)
1204     iq_matrix->ScalingListDC16x16[i] =
1205         scaling_list->scaling_list_dc_coef_minus8_16x16[i] + 8;
1206 }
1207
1208 static void
1209 fill_iq_matrix_dc_32x32 (VAIQMatrixBufferHEVC * iq_matrix,
1210     GstH265ScalingList * scaling_list)
1211 {
1212   guint i;
1213
1214   for (i = 0; i < 2; i++)
1215     iq_matrix->ScalingListDC32x32[i] =
1216         scaling_list->scaling_list_dc_coef_minus8_32x32[i] + 8;
1217 }
1218
1219 static GstVaapiDecoderStatus
1220 ensure_quant_matrix (GstVaapiDecoderH265 * decoder,
1221     GstVaapiPictureH265 * picture)
1222 {
1223   GstVaapiPicture *const base_picture = &picture->base;
1224   GstH265PPS *const pps = get_pps (decoder);
1225   GstH265SPS *const sps = get_sps (decoder);
1226   GstH265ScalingList *scaling_list = NULL;
1227   VAIQMatrixBufferHEVC *iq_matrix;
1228
1229   if (pps &&
1230       (pps->scaling_list_data_present_flag ||
1231           (sps->scaling_list_enabled_flag
1232               && !sps->scaling_list_data_present_flag)))
1233     scaling_list = &pps->scaling_list;
1234   else if (sps && sps->scaling_list_enabled_flag
1235       && sps->scaling_list_data_present_flag)
1236     scaling_list = &sps->scaling_list;
1237   else
1238     return GST_VAAPI_DECODER_STATUS_SUCCESS;
1239
1240   base_picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW (HEVC, decoder);
1241   if (!base_picture->iq_matrix) {
1242     GST_ERROR ("failed to allocate IQ matrix");
1243     return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
1244   }
1245   iq_matrix = base_picture->iq_matrix->param;
1246
1247   /* Only supporting 4:2:0 */
1248   if (sps->chroma_format_idc != 1)
1249     return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
1250
1251   fill_iq_matrix_4x4 (iq_matrix, scaling_list);
1252   fill_iq_matrix_8x8 (iq_matrix, scaling_list);
1253   fill_iq_matrix_16x16 (iq_matrix, scaling_list);
1254   fill_iq_matrix_32x32 (iq_matrix, scaling_list);
1255   fill_iq_matrix_dc_16x16 (iq_matrix, scaling_list);
1256   fill_iq_matrix_dc_32x32 (iq_matrix, scaling_list);
1257
1258   return GST_VAAPI_DECODER_STATUS_SUCCESS;
1259 }
1260
1261 static inline gboolean
1262 is_valid_state (guint state, guint ref_state)
1263 {
1264   return (state & ref_state) == ref_state;
1265 }
1266
1267 static GstVaapiDecoderStatus
1268 decode_current_picture (GstVaapiDecoderH265 * decoder)
1269 {
1270   GstVaapiDecoderH265Private *const priv = &decoder->priv;
1271   GstVaapiPictureH265 *const picture = priv->current_picture;
1272
1273   if (!is_valid_state (priv->decoder_state, GST_H265_VIDEO_STATE_VALID_PICTURE)) {
1274     goto drop_frame;
1275   }
1276
1277   priv->decoder_state = 0;
1278   /*Fixme: Use SEI header values */
1279   priv->pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
1280
1281   if (!picture)
1282     return GST_VAAPI_DECODER_STATUS_SUCCESS;
1283
1284   if (!gst_vaapi_picture_decode (GST_VAAPI_PICTURE_CAST (picture)))
1285     goto error;
1286
1287   if (!dpb_add (decoder, picture))
1288     goto error;
1289
1290   gst_vaapi_picture_replace (&priv->current_picture, NULL);
1291   return GST_VAAPI_DECODER_STATUS_SUCCESS;
1292
1293 error:
1294   gst_vaapi_picture_replace (&priv->current_picture, NULL);
1295   return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
1296 drop_frame:
1297   priv->decoder_state = 0;
1298   priv->pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
1299   return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME;
1300 }
1301
1302 static GstVaapiDecoderStatus
1303 parse_vps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
1304 {
1305   GstVaapiDecoderH265Private *const priv = &decoder->priv;
1306   GstVaapiParserInfoH265 *const pi = unit->parsed_info;
1307   GstH265VPS *const vps = &pi->data.vps;
1308   GstH265ParserResult result;
1309
1310   GST_DEBUG ("parse VPS");
1311   priv->parser_state = 0;
1312
1313   memset (vps, 0, sizeof (GstH265VPS));
1314
1315   result = gst_h265_parser_parse_vps (priv->parser, &pi->nalu, vps);
1316   if (result != GST_H265_PARSER_OK)
1317     return get_status (result);
1318
1319   priv->parser_state |= GST_H265_VIDEO_STATE_GOT_VPS;
1320   return GST_VAAPI_DECODER_STATUS_SUCCESS;
1321 }
1322
1323 static GstVaapiDecoderStatus
1324 parse_sps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
1325 {
1326   GstVaapiDecoderH265Private *const priv = &decoder->priv;
1327   GstVaapiParserInfoH265 *const pi = unit->parsed_info;
1328   GstH265SPS *const sps = &pi->data.sps;
1329   GstH265ParserResult result;
1330
1331   GST_DEBUG ("parse SPS");
1332   priv->parser_state = 0;
1333
1334   memset (sps, 0, sizeof (GstH265SPS));
1335
1336   result = gst_h265_parser_parse_sps (priv->parser, &pi->nalu, sps, TRUE);
1337   if (result != GST_H265_PARSER_OK)
1338     return get_status (result);
1339
1340   priv->parser_state |= GST_H265_VIDEO_STATE_GOT_SPS;
1341   return GST_VAAPI_DECODER_STATUS_SUCCESS;
1342 }
1343
1344 static void
1345 get_pic_width_height_in_ctbs (GstH265PPS * pps,
1346     guint * PicWidthInCtbsY, guint * PicHeightInCtbsY)
1347 {
1348   gint MinCbLog2SizeY, CtbLog2SizeY, MinCbSizeY, CtbSizeY;
1349   GstH265SPS *sps = pps->sps;
1350
1351   MinCbLog2SizeY = sps->log2_min_luma_coding_block_size_minus3 + 3;
1352   CtbLog2SizeY = MinCbLog2SizeY + sps->log2_diff_max_min_luma_coding_block_size;
1353   MinCbSizeY = 1 << MinCbLog2SizeY;
1354   CtbSizeY = 1 << CtbLog2SizeY;
1355
1356   *PicWidthInCtbsY =
1357       ceil ((double) sps->pic_width_in_luma_samples / (double) CtbSizeY);
1358   *PicHeightInCtbsY =
1359       ceil ((double) sps->pic_height_in_luma_samples / (double) CtbSizeY);
1360 }
1361
1362 static GstVaapiDecoderStatus
1363 parse_pps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
1364 {
1365   GstVaapiDecoderH265Private *const priv = &decoder->priv;
1366   GstVaapiParserInfoH265 *const pi = unit->parsed_info;
1367   GstH265PPS *const pps = &pi->data.pps;
1368   GstH265ParserResult result;
1369   guint col_width[19], row_height[21];
1370
1371   GST_DEBUG ("parse PPS");
1372   priv->parser_state &= GST_H265_VIDEO_STATE_GOT_SPS;
1373
1374   memset (col_width, 0, sizeof (col_width));
1375   memset (row_height, 0, sizeof (row_height));
1376
1377   memset (pps, 0, sizeof (GstH265PPS));
1378
1379   result = gst_h265_parser_parse_pps (priv->parser, &pi->nalu, pps);
1380   if (result != GST_H265_PARSER_OK)
1381     return get_status (result);
1382
1383   if (pps->tiles_enabled_flag) {
1384     guint i;
1385     guint PicWidthInCtbsY, PicHeightInCtbsY;
1386
1387     get_pic_width_height_in_ctbs (pps, &PicWidthInCtbsY, &PicHeightInCtbsY);
1388     GST_DEBUG ("PicWidthInCtbsY %d PicHeightInCtbsY %d", PicWidthInCtbsY,
1389         PicHeightInCtbsY);
1390
1391     /* Tile Scanning Conversion 6-3 and 6-4 */
1392     if (pps->uniform_spacing_flag) {
1393
1394       for (i = 0; i <= pps->num_tile_columns_minus1; i++)
1395         col_width[i] =
1396             ((i + 1) * PicWidthInCtbsY) / (pps->num_tile_columns_minus1 + 1) -
1397             (i * PicWidthInCtbsY) / (pps->num_tile_columns_minus1 + 1);
1398
1399       for (i = 0; i <= pps->num_tile_rows_minus1; i++)
1400         row_height[i] =
1401             ((i + 1) * PicHeightInCtbsY) / (pps->num_tile_rows_minus1 + 1) -
1402             (i * PicHeightInCtbsY) / (pps->num_tile_rows_minus1 + 1);
1403
1404     } else {
1405
1406       col_width[pps->num_tile_columns_minus1] = PicWidthInCtbsY;
1407       for (i = 0; i < pps->num_tile_columns_minus1; i++) {
1408         col_width[i] = pps->column_width_minus1[i] + 1;
1409         col_width[pps->num_tile_columns_minus1] -= col_width[i];
1410       }
1411
1412       row_height[pps->num_tile_rows_minus1] = PicHeightInCtbsY;
1413       for (i = 0; i < pps->num_tile_rows_minus1; i++) {
1414         row_height[i] = pps->row_height_minus1[i] + 1;
1415         row_height[pps->num_tile_rows_minus1] -= row_height[i];
1416       }
1417     }
1418     for (i = 0; i <= pps->num_tile_columns_minus1; i++)
1419       pps->column_width_minus1[i] = col_width[i] - 1;
1420     for (i = 0; i <= pps->num_tile_rows_minus1; i++)
1421       pps->row_height_minus1[i] = row_height[i] - 1;
1422   }
1423
1424   priv->parser_state |= GST_H265_VIDEO_STATE_GOT_PPS;
1425   return GST_VAAPI_DECODER_STATUS_SUCCESS;
1426 }
1427
1428 static GstVaapiDecoderStatus
1429 parse_sei (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
1430 {
1431   GstVaapiDecoderH265Private *const priv = &decoder->priv;
1432   GstVaapiParserInfoH265 *const pi = unit->parsed_info;
1433   GArray **const sei_ptr = &pi->data.sei;
1434   GstH265ParserResult result;
1435
1436   GST_DEBUG ("parse SEI");
1437
1438   result = gst_h265_parser_parse_sei (priv->parser, &pi->nalu, sei_ptr);
1439   if (result != GST_H265_PARSER_OK) {
1440     GST_WARNING ("failed to parse SEI messages");
1441     return get_status (result);
1442   }
1443   return GST_VAAPI_DECODER_STATUS_SUCCESS;
1444 }
1445
1446 static GstVaapiDecoderStatus
1447 parse_slice (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
1448 {
1449   GstVaapiDecoderH265Private *const priv = &decoder->priv;
1450   GstVaapiParserInfoH265 *const pi = unit->parsed_info;
1451   GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr;
1452   GstH265ParserResult result;
1453
1454   GST_DEBUG ("parse slice");
1455   priv->parser_state &= (GST_H265_VIDEO_STATE_GOT_SPS |
1456       GST_H265_VIDEO_STATE_GOT_PPS);
1457
1458   slice_hdr->short_term_ref_pic_set_idx = 0;
1459
1460   memset (slice_hdr, 0, sizeof (GstH265SliceHdr));
1461
1462   result = gst_h265_parser_parse_slice_hdr (priv->parser, &pi->nalu, slice_hdr);
1463   if (result != GST_H265_PARSER_OK)
1464     return get_status (result);
1465
1466   priv->parser_state |= GST_H265_VIDEO_STATE_GOT_SLICE;
1467   return GST_VAAPI_DECODER_STATUS_SUCCESS;
1468 }
1469
1470 static GstVaapiDecoderStatus
1471 decode_vps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
1472 {
1473   GstVaapiDecoderH265Private *const priv = &decoder->priv;
1474   GstVaapiParserInfoH265 *const pi = unit->parsed_info;
1475   GstH265VPS *const vps = &pi->data.vps;
1476
1477   GST_DEBUG ("decode VPS");
1478
1479   gst_vaapi_parser_info_h265_replace (&priv->vps[vps->id], pi);
1480
1481   return GST_VAAPI_DECODER_STATUS_SUCCESS;
1482 }
1483
1484 static GstVaapiDecoderStatus
1485 decode_sps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
1486 {
1487   GstVaapiDecoderH265Private *const priv = &decoder->priv;
1488   GstVaapiParserInfoH265 *const pi = unit->parsed_info;
1489   GstH265SPS *const sps = &pi->data.sps;
1490
1491   GST_DEBUG ("decode SPS");
1492
1493   if (sps->max_latency_increase_plus1[sps->max_sub_layers_minus1])
1494     priv->SpsMaxLatencyPictures =
1495         sps->max_num_reorder_pics[sps->max_sub_layers_minus1] +
1496         sps->max_latency_increase_plus1[sps->max_sub_layers_minus1] - 1;
1497
1498   gst_vaapi_parser_info_h265_replace (&priv->sps[sps->id], pi);
1499
1500   return GST_VAAPI_DECODER_STATUS_SUCCESS;
1501 }
1502
1503 static GstVaapiDecoderStatus
1504 decode_pps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
1505 {
1506   GstVaapiDecoderH265Private *const priv = &decoder->priv;
1507   GstVaapiParserInfoH265 *const pi = unit->parsed_info;
1508   GstH265PPS *const pps = &pi->data.pps;
1509
1510   GST_DEBUG ("decode PPS");
1511
1512   gst_vaapi_parser_info_h265_replace (&priv->pps[pps->id], pi);
1513
1514   return GST_VAAPI_DECODER_STATUS_SUCCESS;
1515 }
1516
1517 static GstVaapiDecoderStatus
1518 decode_sei (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
1519 {
1520
1521   GstVaapiDecoderH265Private *const priv = &decoder->priv;
1522   GstVaapiParserInfoH265 *const pi = unit->parsed_info;
1523   guint i;
1524
1525   GST_DEBUG ("decode SEI messages");
1526
1527   for (i = 0; i < pi->data.sei->len; i++) {
1528     const GstH265SEIMessage *const sei =
1529         &g_array_index (pi->data.sei, GstH265SEIMessage, i);
1530
1531     switch (sei->payloadType) {
1532       case GST_H265_SEI_PIC_TIMING:{
1533         const GstH265PicTiming *const pic_timing = &sei->payload.pic_timing;
1534         priv->pic_structure = pic_timing->pic_struct;
1535         break;
1536       }
1537       default:
1538         break;
1539     }
1540   }
1541   return GST_VAAPI_DECODER_STATUS_SUCCESS;
1542 }
1543
1544 static GstVaapiDecoderStatus
1545 decode_sequence_end (GstVaapiDecoderH265 * decoder)
1546 {
1547   GstVaapiDecoderStatus status;
1548
1549   GST_DEBUG ("decode sequence-end");
1550
1551   status = decode_current_picture (decoder);
1552   if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1553     return status;
1554
1555   dpb_flush (decoder);
1556   return GST_VAAPI_DECODER_STATUS_SUCCESS;
1557 }
1558
1559 /* 8.3.1 - Decoding process for picture order count */
1560 static void
1561 init_picture_poc (GstVaapiDecoderH265 * decoder,
1562     GstVaapiPictureH265 * picture, GstVaapiParserInfoH265 * pi)
1563 {
1564   GstVaapiDecoderH265Private *const priv = &decoder->priv;
1565   GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr;
1566   GstH265SPS *const sps = get_sps (decoder);
1567   const gint32 MaxPicOrderCntLsb =
1568       1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1569   guint8 nal_type = pi->nalu.type;
1570   guint8 temporal_id = pi->nalu.temporal_id_plus1 - 1;
1571
1572   GST_DEBUG ("decode PicOrderCntVal");
1573
1574   priv->prev_poc_lsb = priv->poc_lsb;
1575   priv->prev_poc_msb = priv->poc_msb;
1576
1577   if (!(nal_is_irap (nal_type) && picture->NoRaslOutputFlag)) {
1578     priv->prev_poc_lsb = priv->prev_tid0pic_poc_lsb;
1579     priv->prev_poc_msb = priv->prev_tid0pic_poc_msb;
1580   }
1581
1582   /* Finding PicOrderCntMsb */
1583   if (nal_is_irap (nal_type) && picture->NoRaslOutputFlag)
1584     priv->poc_msb = 0;
1585   else {
1586     /* (8-1) */
1587     if ((slice_hdr->pic_order_cnt_lsb < priv->prev_poc_lsb) &&
1588         ((priv->prev_poc_lsb - slice_hdr->pic_order_cnt_lsb) >=
1589             (MaxPicOrderCntLsb / 2)))
1590       priv->poc_msb = priv->prev_poc_msb + MaxPicOrderCntLsb;
1591
1592     else if ((slice_hdr->pic_order_cnt_lsb > priv->prev_poc_lsb) &&
1593         ((slice_hdr->pic_order_cnt_lsb - priv->prev_poc_lsb) >
1594             (MaxPicOrderCntLsb / 2)))
1595       priv->poc_msb = priv->prev_poc_msb - MaxPicOrderCntLsb;
1596
1597     else
1598       priv->poc_msb = priv->prev_poc_msb;
1599   }
1600
1601   /* (8-2) */
1602   priv->poc = picture->poc = priv->poc_msb + slice_hdr->pic_order_cnt_lsb;
1603   priv->poc_lsb = picture->poc_lsb = slice_hdr->pic_order_cnt_lsb;
1604
1605   if (nal_is_idr (nal_type)) {
1606     picture->poc = 0;
1607     picture->poc_lsb = 0;
1608     priv->poc_lsb = 0;
1609     priv->poc_msb = 0;
1610     priv->prev_poc_lsb = 0;
1611     priv->prev_poc_msb = 0;
1612     priv->prev_tid0pic_poc_lsb = 0;
1613     priv->prev_tid0pic_poc_msb = 0;
1614   }
1615
1616   picture->base.poc = picture->poc;
1617   GST_DEBUG ("PicOrderCntVal %d", picture->base.poc);
1618
1619   if (!temporal_id && !nal_is_rasl (nal_type) &&
1620       !nal_is_radl (nal_type) && nal_is_ref (nal_type)) {
1621     priv->prev_tid0pic_poc_lsb = slice_hdr->pic_order_cnt_lsb;
1622     priv->prev_tid0pic_poc_msb = priv->poc_msb;
1623   }
1624 }
1625
1626 static void
1627 init_picture_refs (GstVaapiDecoderH265 * decoder,
1628     GstVaapiPictureH265 * picture, GstH265SliceHdr * slice_hdr)
1629 {
1630   GstVaapiDecoderH265Private *const priv = &decoder->priv;
1631   guint32 NumRpsCurrTempList0 = 0, NumRpsCurrTempList1 = 0;
1632   GstVaapiPictureH265 *RefPicListTemp0[16] = { NULL, }, *RefPicListTemp1[16] = {
1633   NULL,};
1634   guint i, rIdx = 0;
1635   guint num_ref_idx_l0_active_minus1 = 0;
1636   guint num_ref_idx_l1_active_minus1 = 0;
1637   GstH265RefPicListModification *ref_pic_list_modification;
1638   guint type;
1639
1640   memset (priv->RefPicList0, 0, sizeof (GstVaapiPictureH265 *) * 16);
1641   memset (priv->RefPicList1, 0, sizeof (GstVaapiPictureH265 *) * 16);
1642   priv->RefPicList0_count = priv->RefPicList1_count = 0;
1643
1644   if (slice_hdr->dependent_slice_segment_flag) {
1645     GstH265SliceHdr *tmp = &priv->prev_independent_slice_pi->data.slice_hdr;
1646     num_ref_idx_l0_active_minus1 = tmp->num_ref_idx_l0_active_minus1;
1647     num_ref_idx_l1_active_minus1 = tmp->num_ref_idx_l1_active_minus1;
1648     ref_pic_list_modification = &tmp->ref_pic_list_modification;
1649     type = tmp->type;
1650   } else {
1651     num_ref_idx_l0_active_minus1 = slice_hdr->num_ref_idx_l0_active_minus1;
1652     num_ref_idx_l1_active_minus1 = slice_hdr->num_ref_idx_l1_active_minus1;
1653     ref_pic_list_modification = &slice_hdr->ref_pic_list_modification;
1654     type = slice_hdr->type;
1655   }
1656
1657   /* decoding process for reference picture list construction needs to be
1658    * invoked only for P and B slice */
1659   if (type == GST_H265_I_SLICE)
1660     return;
1661
1662   NumRpsCurrTempList0 =
1663       MAX ((num_ref_idx_l0_active_minus1 + 1), priv->NumPocTotalCurr);
1664   NumRpsCurrTempList1 =
1665       MAX ((num_ref_idx_l1_active_minus1 + 1), priv->NumPocTotalCurr);
1666
1667   /* (8-8) */
1668   while (rIdx < NumRpsCurrTempList0) {
1669     for (i = 0; i < priv->NumPocStCurrBefore && rIdx < NumRpsCurrTempList0;
1670         rIdx++, i++)
1671       RefPicListTemp0[rIdx] = priv->RefPicSetStCurrBefore[i];
1672     for (i = 0; i < priv->NumPocStCurrAfter && rIdx < NumRpsCurrTempList0;
1673         rIdx++, i++)
1674       RefPicListTemp0[rIdx] = priv->RefPicSetStCurrAfter[i];
1675     for (i = 0; i < priv->NumPocLtCurr && rIdx < NumRpsCurrTempList0;
1676         rIdx++, i++)
1677       RefPicListTemp0[rIdx] = priv->RefPicSetLtCurr[i];
1678   }
1679
1680   /* construct RefPicList0 (8-9) */
1681   for (rIdx = 0; rIdx <= num_ref_idx_l0_active_minus1; rIdx++)
1682     priv->RefPicList0[rIdx] =
1683         ref_pic_list_modification->ref_pic_list_modification_flag_l0 ?
1684         RefPicListTemp0[ref_pic_list_modification->list_entry_l0[rIdx]] :
1685         RefPicListTemp0[rIdx];
1686   priv->RefPicList0_count = rIdx;
1687
1688   if (type == GST_H265_B_SLICE) {
1689     rIdx = 0;
1690
1691     /* (8-10) */
1692     while (rIdx < NumRpsCurrTempList1) {
1693       for (i = 0; i < priv->NumPocStCurrAfter && rIdx < NumRpsCurrTempList1;
1694           rIdx++, i++)
1695         RefPicListTemp1[rIdx] = priv->RefPicSetStCurrAfter[i];
1696       for (i = 0; i < priv->NumPocStCurrBefore && rIdx < NumRpsCurrTempList1;
1697           rIdx++, i++)
1698         RefPicListTemp1[rIdx] = priv->RefPicSetStCurrBefore[i];
1699       for (i = 0; i < priv->NumPocLtCurr && rIdx < NumRpsCurrTempList1;
1700           rIdx++, i++)
1701         RefPicListTemp1[rIdx] = priv->RefPicSetLtCurr[i];
1702     }
1703
1704     /* construct RefPicList1 (8-10) */
1705     for (rIdx = 0; rIdx <= num_ref_idx_l1_active_minus1; rIdx++)
1706       priv->RefPicList1[rIdx] =
1707           ref_pic_list_modification->ref_pic_list_modification_flag_l1 ?
1708           RefPicListTemp1[ref_pic_list_modification->list_entry_l1
1709           [rIdx]] : RefPicListTemp1[rIdx];
1710     priv->RefPicList1_count = rIdx;
1711   }
1712 }
1713
1714 static gboolean
1715 init_picture (GstVaapiDecoderH265 * decoder,
1716     GstVaapiPictureH265 * picture, GstVaapiParserInfoH265 * pi)
1717 {
1718   GstVaapiDecoderH265Private *const priv = &decoder->priv;
1719   GstVaapiPicture *const base_picture = &picture->base;
1720   GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr;
1721
1722   base_picture->pts = GST_VAAPI_DECODER_CODEC_FRAME (decoder)->pts;
1723   base_picture->type = GST_VAAPI_PICTURE_TYPE_NONE;
1724
1725   if (nal_is_idr (pi->nalu.type)) {
1726     GST_DEBUG ("<IDR>");
1727     GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_IDR);
1728   }
1729
1730   if (pi->nalu.type >= GST_H265_NAL_SLICE_BLA_W_LP &&
1731       pi->nalu.type <= GST_H265_NAL_SLICE_CRA_NUT)
1732     picture->RapPicFlag = TRUE;
1733
1734   /*Fixme: Use SEI header values */
1735   base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
1736   picture->structure = base_picture->structure;
1737
1738   /*NoRaslOutputFlag ==1 if the current picture is
1739      1) an IDR picture
1740      2) a BLA picture
1741      3) a CRA picture that is the first access unit in the bitstream
1742      4) first picture that follows an end of sequence NAL unit in decoding order
1743      5) has HandleCraAsBlaFlag == 1 (set by external means, so not considering )
1744    */
1745   if (nal_is_idr (pi->nalu.type) || nal_is_bla (pi->nalu.type) ||
1746       (nal_is_cra (pi->nalu.type) && priv->new_bitstream)
1747       || priv->prev_nal_is_eos) {
1748     picture->NoRaslOutputFlag = 1;
1749   }
1750
1751   if (nal_is_irap (pi->nalu.type)) {
1752     picture->IntraPicFlag = TRUE;
1753     priv->associated_irap_NoRaslOutputFlag = picture->NoRaslOutputFlag;
1754   }
1755
1756   if (nal_is_rasl (pi->nalu.type) && priv->associated_irap_NoRaslOutputFlag)
1757     picture->output_flag = FALSE;
1758   else
1759     picture->output_flag = slice_hdr->pic_output_flag;
1760
1761   init_picture_poc (decoder, picture, pi);
1762
1763   return TRUE;
1764 }
1765
1766 static void
1767 vaapi_init_picture (VAPictureHEVC * pic)
1768 {
1769   pic->picture_id = VA_INVALID_SURFACE;
1770   pic->pic_order_cnt = 0;
1771   pic->flags = VA_PICTURE_HEVC_INVALID;
1772 }
1773
1774 static void
1775 vaapi_fill_picture (VAPictureHEVC * pic, GstVaapiPictureH265 * picture,
1776     guint picture_structure)
1777 {
1778
1779   if (!picture_structure)
1780     picture_structure = picture->structure;
1781
1782   pic->picture_id = picture->base.surface_id;
1783   pic->pic_order_cnt = picture->poc;
1784   pic->flags = 0;
1785
1786   /* Set the VAPictureHEVC flags */
1787   if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE (picture))
1788     pic->flags |= VA_PICTURE_HEVC_LONG_TERM_REFERENCE;
1789
1790   if (GST_VAAPI_PICTURE_FLAG_IS_SET (picture,
1791           GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_BEFORE))
1792     pic->flags |= VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE;
1793
1794   else if (GST_VAAPI_PICTURE_FLAG_IS_SET (picture,
1795           GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_AFTER))
1796     pic->flags |= VA_PICTURE_HEVC_RPS_ST_CURR_AFTER;
1797
1798   else if (GST_VAAPI_PICTURE_FLAG_IS_SET (picture,
1799           GST_VAAPI_PICTURE_FLAG_RPS_LT_CURR))
1800     pic->flags |= VA_PICTURE_HEVC_RPS_LT_CURR;
1801
1802   switch (picture_structure) {
1803     case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
1804       break;
1805     case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
1806       pic->flags |= VA_PICTURE_HEVC_FIELD_PIC;
1807       break;
1808     case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
1809       pic->flags |= VA_PICTURE_HEVC_FIELD_PIC;
1810       pic->flags |= VA_PICTURE_HEVC_BOTTOM_FIELD;
1811       break;
1812     default:
1813       break;
1814   }
1815 }
1816
1817 static guint
1818 get_index_for_RefPicListX (VAPictureHEVC * ReferenceFrames,
1819     GstVaapiPictureH265 * pic)
1820 {
1821   gint i;
1822
1823   for (i = 0; i < 15; i++) {
1824     if ((ReferenceFrames[i].picture_id != VA_INVALID_ID) && pic) {
1825       if ((ReferenceFrames[i].pic_order_cnt == pic->poc) &&
1826           (ReferenceFrames[i].picture_id == pic->base.surface_id)) {
1827         return i;
1828       }
1829     }
1830   }
1831   return 0xff;
1832 }
1833
1834 static gboolean
1835 fill_picture (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture)
1836 {
1837   GstVaapiDecoderH265Private *const priv = &decoder->priv;
1838   GstVaapiPicture *const base_picture = &picture->base;
1839   GstH265PPS *const pps = get_pps (decoder);
1840   GstH265SPS *const sps = get_sps (decoder);
1841   VAPictureParameterBufferHEVC *const pic_param = base_picture->param;
1842   guint i, n;
1843
1844   pic_param->pic_fields.value = 0;
1845   pic_param->slice_parsing_fields.value = 0;
1846
1847   /* Fill in VAPictureHEVC */
1848   vaapi_fill_picture (&pic_param->CurrPic, picture, 0);
1849   /* Fill in ReferenceFrames */
1850   for (i = 0, n = 0; i < priv->dpb_count; i++) {
1851     GstVaapiFrameStore *const fs = priv->dpb[i];
1852     if ((gst_vaapi_frame_store_has_reference (fs)))
1853       vaapi_fill_picture (&pic_param->ReferenceFrames[n++], fs->buffer,
1854           fs->buffer->structure);
1855     if (n >= G_N_ELEMENTS (pic_param->ReferenceFrames))
1856       break;
1857   }
1858   for (; n < G_N_ELEMENTS (pic_param->ReferenceFrames); n++)
1859     vaapi_init_picture (&pic_param->ReferenceFrames[n]);
1860
1861
1862 #define COPY_FIELD(s, f) \
1863     pic_param->f = (s)->f
1864 #define COPY_BFM(a, s, f) \
1865     pic_param->a.bits.f = (s)->f
1866
1867   COPY_FIELD (sps, pic_width_in_luma_samples);
1868   COPY_FIELD (sps, pic_height_in_luma_samples);
1869   COPY_BFM (pic_fields, sps, chroma_format_idc);
1870   COPY_BFM (pic_fields, sps, separate_colour_plane_flag);
1871   COPY_BFM (pic_fields, sps, pcm_enabled_flag);
1872   COPY_BFM (pic_fields, sps, scaling_list_enabled_flag);
1873   COPY_BFM (pic_fields, pps, transform_skip_enabled_flag);
1874   COPY_BFM (pic_fields, sps, amp_enabled_flag);
1875   COPY_BFM (pic_fields, sps, strong_intra_smoothing_enabled_flag);
1876   COPY_BFM (pic_fields, pps, sign_data_hiding_enabled_flag);
1877   COPY_BFM (pic_fields, pps, constrained_intra_pred_flag);
1878   COPY_BFM (pic_fields, pps, cu_qp_delta_enabled_flag);
1879   COPY_BFM (pic_fields, pps, weighted_pred_flag);
1880   COPY_BFM (pic_fields, pps, weighted_bipred_flag);
1881   COPY_BFM (pic_fields, pps, transquant_bypass_enabled_flag);
1882   COPY_BFM (pic_fields, pps, tiles_enabled_flag);
1883   COPY_BFM (pic_fields, pps, entropy_coding_sync_enabled_flag);
1884   pic_param->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag =
1885       pps->loop_filter_across_slices_enabled_flag;
1886   COPY_BFM (pic_fields, pps, loop_filter_across_tiles_enabled_flag);
1887   COPY_BFM (pic_fields, sps, pcm_loop_filter_disabled_flag);
1888   /* Fix: Assign value based on sps_max_num_reorder_pics */
1889   pic_param->pic_fields.bits.NoPicReorderingFlag = 0;
1890   /* Fix: Enable if picture has no B slices */
1891   pic_param->pic_fields.bits.NoBiPredFlag = 0;
1892
1893   pic_param->sps_max_dec_pic_buffering_minus1 =
1894       sps->max_dec_pic_buffering_minus1[0];
1895   COPY_FIELD (sps, bit_depth_luma_minus8);
1896   COPY_FIELD (sps, bit_depth_chroma_minus8);
1897   COPY_FIELD (sps, pcm_sample_bit_depth_luma_minus1);
1898   COPY_FIELD (sps, pcm_sample_bit_depth_chroma_minus1);
1899   COPY_FIELD (sps, log2_min_luma_coding_block_size_minus3);
1900   COPY_FIELD (sps, log2_diff_max_min_luma_coding_block_size);
1901   COPY_FIELD (sps, log2_min_transform_block_size_minus2);
1902   COPY_FIELD (sps, log2_diff_max_min_transform_block_size);
1903   COPY_FIELD (sps, log2_min_pcm_luma_coding_block_size_minus3);
1904   COPY_FIELD (sps, log2_diff_max_min_pcm_luma_coding_block_size);
1905   COPY_FIELD (sps, max_transform_hierarchy_depth_intra);
1906   COPY_FIELD (sps, max_transform_hierarchy_depth_inter);
1907   COPY_FIELD (pps, init_qp_minus26);
1908   COPY_FIELD (pps, diff_cu_qp_delta_depth);
1909   pic_param->pps_cb_qp_offset = pps->cb_qp_offset;
1910   pic_param->pps_cr_qp_offset = pps->cr_qp_offset;
1911   COPY_FIELD (pps, log2_parallel_merge_level_minus2);
1912   COPY_FIELD (pps, num_tile_columns_minus1);
1913   COPY_FIELD (pps, num_tile_rows_minus1);
1914   for (i = 0; i <= pps->num_tile_columns_minus1; i++)
1915     pic_param->column_width_minus1[i] = pps->column_width_minus1[i];
1916   for (; i < 19; i++)
1917     pic_param->column_width_minus1[i] = 0;
1918   for (i = 0; i <= pps->num_tile_rows_minus1; i++)
1919     pic_param->row_height_minus1[i] = pps->row_height_minus1[i];
1920   for (; i < 21; i++)
1921     pic_param->row_height_minus1[i] = 0;
1922
1923   COPY_BFM (slice_parsing_fields, pps, lists_modification_present_flag);
1924   COPY_BFM (slice_parsing_fields, sps, long_term_ref_pics_present_flag);
1925   pic_param->slice_parsing_fields.bits.sps_temporal_mvp_enabled_flag =
1926       sps->temporal_mvp_enabled_flag;
1927   COPY_BFM (slice_parsing_fields, pps, cabac_init_present_flag);
1928   COPY_BFM (slice_parsing_fields, pps, output_flag_present_flag);
1929   COPY_BFM (slice_parsing_fields, pps, dependent_slice_segments_enabled_flag);
1930   pic_param->slice_parsing_fields.
1931       bits.pps_slice_chroma_qp_offsets_present_flag =
1932       pps->slice_chroma_qp_offsets_present_flag;
1933   COPY_BFM (slice_parsing_fields, sps, sample_adaptive_offset_enabled_flag);
1934   COPY_BFM (slice_parsing_fields, pps, deblocking_filter_override_enabled_flag);
1935   pic_param->slice_parsing_fields.bits.pps_disable_deblocking_filter_flag =
1936       pps->deblocking_filter_disabled_flag;
1937   COPY_BFM (slice_parsing_fields, pps,
1938       slice_segment_header_extension_present_flag);
1939   pic_param->slice_parsing_fields.bits.RapPicFlag = picture->RapPicFlag;
1940   pic_param->slice_parsing_fields.bits.IdrPicFlag =
1941       GST_VAAPI_PICTURE_FLAG_IS_SET (picture, GST_VAAPI_PICTURE_FLAG_IDR);
1942   pic_param->slice_parsing_fields.bits.IntraPicFlag = picture->IntraPicFlag;
1943
1944   COPY_FIELD (sps, log2_max_pic_order_cnt_lsb_minus4);
1945   COPY_FIELD (sps, num_short_term_ref_pic_sets);
1946   pic_param->num_long_term_ref_pic_sps = sps->num_long_term_ref_pics_sps;
1947   COPY_FIELD (pps, num_ref_idx_l0_default_active_minus1);
1948   COPY_FIELD (pps, num_ref_idx_l1_default_active_minus1);
1949   pic_param->pps_beta_offset_div2 = pps->beta_offset_div2;
1950   pic_param->pps_tc_offset_div2 = pps->tc_offset_div2;
1951   COPY_FIELD (pps, num_extra_slice_header_bits);
1952
1953   /*Fixme: Set correct value as mentioned in va_dec_hevc.h */
1954   pic_param->st_rps_bits = 0;
1955   return TRUE;
1956 }
1957
1958 /* Detection of the first VCL NAL unit of a coded picture (7.4.2.4.5 ) */
1959 static gboolean
1960 is_new_picture (GstVaapiParserInfoH265 * pi, GstVaapiParserInfoH265 * prev_pi)
1961 {
1962   GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr;
1963
1964   if (!prev_pi)
1965     return TRUE;
1966
1967   if (slice_hdr->first_slice_segment_in_pic_flag)
1968     return TRUE;
1969
1970   return FALSE;
1971 }
1972
1973 /* Detection of a new access unit, assuming we are already in presence
1974    of a new picture */
1975 static inline gboolean
1976 is_new_access_unit (GstVaapiParserInfoH265 * pi,
1977     GstVaapiParserInfoH265 * prev_pi)
1978 {
1979   if (!prev_pi)
1980     return TRUE;
1981
1982   return FALSE;
1983 }
1984
1985 static gboolean
1986 has_entry_in_rps (GstVaapiPictureH265 * dpb_pic,
1987     GstVaapiPictureH265 ** rps_list, guint rps_list_length)
1988 {
1989   guint i;
1990
1991   if (!dpb_pic || !rps_list || !rps_list_length)
1992     return FALSE;
1993
1994   for (i = 0; i < rps_list_length; i++) {
1995     if (rps_list[i] && rps_list[i]->poc == dpb_pic->poc)
1996       return TRUE;
1997   }
1998   return FALSE;
1999 }
2000
2001 /* the derivation process for the RPS and the picture marking */
2002 static void
2003 derive_and_mark_rps (GstVaapiDecoderH265 * decoder,
2004     GstVaapiPictureH265 * picture, GstVaapiParserInfoH265 * pi,
2005     gint32 * CurrDeltaPocMsbPresentFlag, gint32 * FollDeltaPocMsbPresentFlag)
2006 {
2007   GstVaapiDecoderH265Private *const priv = &decoder->priv;
2008   GstVaapiPictureH265 *dpb_pic = NULL;
2009   guint i;
2010
2011   memset (priv->RefPicSetLtCurr, 0, sizeof (GstVaapiPictureH265 *) * 16);
2012   memset (priv->RefPicSetLtFoll, 0, sizeof (GstVaapiPictureH265 *) * 16);
2013   memset (priv->RefPicSetStCurrBefore, 0, sizeof (GstVaapiPictureH265 *) * 16);
2014   memset (priv->RefPicSetStCurrAfter, 0, sizeof (GstVaapiPictureH265 *) * 16);
2015   memset (priv->RefPicSetStFoll, 0, sizeof (GstVaapiPictureH265 *) * 16);
2016
2017   /* (8-6) */
2018   for (i = 0; i < priv->NumPocLtCurr; i++) {
2019     if (!CurrDeltaPocMsbPresentFlag[i]) {
2020       dpb_pic = dpb_get_picture (decoder, priv->PocLtCurr[i], TRUE);
2021       if (dpb_pic)
2022         priv->RefPicSetLtCurr[i] = dpb_pic;
2023       else
2024         priv->RefPicSetLtCurr[i] = NULL;
2025     } else {
2026       dpb_pic = dpb_get_picture (decoder, priv->PocLtCurr[i], FALSE);
2027       if (dpb_pic)
2028         priv->RefPicSetLtCurr[i] = dpb_pic;
2029       else
2030         priv->RefPicSetLtCurr[i] = NULL;
2031     }
2032   }
2033   for (; i < 16; i++)
2034     priv->RefPicSetLtCurr[i] = NULL;
2035
2036   for (i = 0; i < priv->NumPocLtFoll; i++) {
2037     if (!FollDeltaPocMsbPresentFlag[i]) {
2038       dpb_pic = dpb_get_picture (decoder, priv->PocLtFoll[i], TRUE);
2039       if (dpb_pic)
2040         priv->RefPicSetLtFoll[i] = dpb_pic;
2041       else
2042         priv->RefPicSetLtFoll[i] = NULL;
2043     } else {
2044       dpb_pic = dpb_get_picture (decoder, priv->PocLtFoll[i], FALSE);
2045       if (dpb_pic)
2046         priv->RefPicSetLtFoll[i] = dpb_pic;
2047       else
2048         priv->RefPicSetLtFoll[i] = NULL;
2049     }
2050   }
2051   for (; i < 16; i++)
2052     priv->RefPicSetLtFoll[i] = NULL;
2053
2054   /* Mark all ref pics in RefPicSetLtCurr and RefPicSetLtFol as long_term_refs */
2055   for (i = 0; i < priv->NumPocLtCurr; i++) {
2056     if (priv->RefPicSetLtCurr[i])
2057       gst_vaapi_picture_h265_set_reference (priv->RefPicSetLtCurr[i],
2058           GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE |
2059           GST_VAAPI_PICTURE_FLAG_RPS_LT_CURR);
2060   }
2061   for (i = 0; i < priv->NumPocLtFoll; i++) {
2062     if (priv->RefPicSetLtFoll[i])
2063       gst_vaapi_picture_h265_set_reference (priv->RefPicSetLtFoll[i],
2064           GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE |
2065           GST_VAAPI_PICTURE_FLAG_RPS_LT_FOLL);
2066   }
2067
2068   /* (8-7) */
2069   for (i = 0; i < priv->NumPocStCurrBefore; i++) {
2070     dpb_pic = dpb_get_ref_picture (decoder, priv->PocStCurrBefore[i], TRUE);
2071     if (dpb_pic) {
2072       gst_vaapi_picture_h265_set_reference (dpb_pic,
2073           GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE |
2074           GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_BEFORE);
2075       priv->RefPicSetStCurrBefore[i] = dpb_pic;
2076     } else
2077       priv->RefPicSetStCurrBefore[i] = NULL;
2078   }
2079   for (; i < 16; i++)
2080     priv->RefPicSetStCurrBefore[i] = NULL;
2081
2082   for (i = 0; i < priv->NumPocStCurrAfter; i++) {
2083     dpb_pic = dpb_get_ref_picture (decoder, priv->PocStCurrAfter[i], TRUE);
2084     if (dpb_pic) {
2085       gst_vaapi_picture_h265_set_reference (dpb_pic,
2086           GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE |
2087           GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_AFTER);
2088       priv->RefPicSetStCurrAfter[i] = dpb_pic;
2089     } else
2090       priv->RefPicSetStCurrAfter[i] = NULL;
2091   }
2092   for (; i < 16; i++)
2093     priv->RefPicSetStCurrAfter[i] = NULL;
2094
2095   for (i = 0; i < priv->NumPocStFoll; i++) {
2096     dpb_pic = dpb_get_ref_picture (decoder, priv->PocStFoll[i], TRUE);
2097     if (dpb_pic) {
2098       gst_vaapi_picture_h265_set_reference (dpb_pic,
2099           GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE |
2100           GST_VAAPI_PICTURE_FLAG_RPS_ST_FOLL);
2101       priv->RefPicSetStFoll[i] = dpb_pic;
2102     } else
2103       priv->RefPicSetStFoll[i] = NULL;
2104   }
2105   for (; i < 16; i++)
2106     priv->RefPicSetStFoll[i] = NULL;
2107
2108   /* Mark all dpb pics not beloging to RefPicSet*[] as unused for ref */
2109   for (i = 0; i < priv->dpb_count; i++) {
2110     dpb_pic = priv->dpb[i]->buffer;
2111     if (dpb_pic &&
2112         !has_entry_in_rps (dpb_pic, priv->RefPicSetLtCurr, priv->NumPocLtCurr)
2113         && !has_entry_in_rps (dpb_pic, priv->RefPicSetLtFoll,
2114             priv->NumPocLtFoll)
2115         && !has_entry_in_rps (dpb_pic, priv->RefPicSetStCurrAfter,
2116             priv->NumPocStCurrAfter)
2117         && !has_entry_in_rps (dpb_pic, priv->RefPicSetStCurrBefore,
2118             priv->NumPocStCurrBefore)
2119         && !has_entry_in_rps (dpb_pic, priv->RefPicSetStFoll,
2120             priv->NumPocStFoll))
2121       gst_vaapi_picture_h265_set_reference (dpb_pic, 0);
2122   }
2123
2124 }
2125
2126 /* Decoding process for reference picture set (8.3.2) */
2127 static gboolean
2128 decode_ref_pic_set (GstVaapiDecoderH265 * decoder,
2129     GstVaapiPictureH265 * picture, GstVaapiParserInfoH265 * pi)
2130 {
2131   guint i, j, k;
2132   gint32 CurrDeltaPocMsbPresentFlag[16] = { 0, };
2133   gint32 FollDeltaPocMsbPresentFlag[16] = { 0, };
2134   GstVaapiDecoderH265Private *const priv = &decoder->priv;
2135   GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr;
2136   GstH265SPS *const sps = get_sps (decoder);
2137   const gint32 MaxPicOrderCntLsb =
2138       1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
2139
2140   /* if it is an irap pic, set all ref pics in dpb as unused for ref */
2141   if (nal_is_irap (pi->nalu.type) && picture->NoRaslOutputFlag) {
2142     for (i = 0; i < priv->dpb_count; i++) {
2143       GstVaapiFrameStore *const fs = priv->dpb[i];
2144       gst_vaapi_picture_h265_set_reference (fs->buffer, 0);
2145     }
2146   }
2147
2148   /* Reset everything for IDR */
2149   if (nal_is_idr (pi->nalu.type)) {
2150     memset (priv->PocStCurrBefore, 0, sizeof (guint) * 16);
2151     memset (priv->PocStCurrAfter, 0, sizeof (guint) * 16);
2152     memset (priv->PocStFoll, 0, sizeof (guint) * 16);
2153     memset (priv->PocLtCurr, 0, sizeof (guint) * 16);
2154     memset (priv->PocLtFoll, 0, sizeof (guint) * 16);
2155     priv->NumPocStCurrBefore = priv->NumPocStCurrAfter = priv->NumPocStFoll = 0;
2156     priv->NumPocLtCurr = priv->NumPocLtFoll = 0;
2157   } else {
2158     GstH265ShortTermRefPicSet *stRefPic = NULL;
2159     gint32 num_lt_pics, pocLt, PocLsbLt[16] = { 0, }
2160     , UsedByCurrPicLt[16] = {
2161     0,};
2162     gint32 DeltaPocMsbCycleLt[16] = { 0, };
2163     gint numtotalcurr = 0;
2164
2165     /* this is based on CurrRpsIdx described in spec */
2166     if (!slice_hdr->short_term_ref_pic_set_sps_flag)
2167       stRefPic = &slice_hdr->short_term_ref_pic_sets;
2168     else if (sps->num_short_term_ref_pic_sets)
2169       stRefPic =
2170           &sps->short_term_ref_pic_set[slice_hdr->short_term_ref_pic_set_idx];
2171
2172     g_assert (stRefPic != NULL);
2173
2174     for (i = 0, j = 0, k = 0; i < stRefPic->NumNegativePics; i++) {
2175       if (stRefPic->UsedByCurrPicS0[i]) {
2176         priv->PocStCurrBefore[j++] = picture->poc + stRefPic->DeltaPocS0[i];
2177         numtotalcurr++;
2178       } else
2179         priv->PocStFoll[k++] = picture->poc + stRefPic->DeltaPocS0[i];
2180     }
2181     priv->NumPocStCurrBefore = j;
2182     for (i = 0, j = 0; i < stRefPic->NumPositivePics; i++) {
2183       if (stRefPic->UsedByCurrPicS1[i]) {
2184         priv->PocStCurrAfter[j++] = picture->poc + stRefPic->DeltaPocS1[i];
2185         numtotalcurr++;
2186       } else
2187         priv->PocStFoll[k++] = picture->poc + stRefPic->DeltaPocS1[i];
2188     }
2189     priv->NumPocStCurrAfter = j;
2190     priv->NumPocStFoll = k;
2191     num_lt_pics = slice_hdr->num_long_term_sps + slice_hdr->num_long_term_pics;
2192     /* The variables PocLsbLt[i] and UsedByCurrPicLt[i] are derived as follows: */
2193     for (i = 0; i < num_lt_pics; i++) {
2194       if (i < slice_hdr->num_long_term_sps) {
2195         PocLsbLt[i] = sps->lt_ref_pic_poc_lsb_sps[slice_hdr->lt_idx_sps[i]];
2196         UsedByCurrPicLt[i] =
2197             sps->used_by_curr_pic_lt_sps_flag[slice_hdr->lt_idx_sps[i]];
2198       } else {
2199         PocLsbLt[i] = slice_hdr->poc_lsb_lt[i];
2200         UsedByCurrPicLt[i] = slice_hdr->used_by_curr_pic_lt_flag[i];
2201       }
2202       if (UsedByCurrPicLt[i])
2203         numtotalcurr++;
2204     }
2205
2206     priv->NumPocTotalCurr = numtotalcurr;
2207
2208     /* The variable DeltaPocMsbCycleLt[i] is derived as follows: (7-38) */
2209     for (i = 0; i < num_lt_pics; i++) {
2210       if (i == 0 || i == slice_hdr->num_long_term_sps)
2211         DeltaPocMsbCycleLt[i] = slice_hdr->delta_poc_msb_cycle_lt[i];
2212       else
2213         DeltaPocMsbCycleLt[i] =
2214             slice_hdr->delta_poc_msb_cycle_lt[i] + DeltaPocMsbCycleLt[i - 1];
2215     }
2216
2217     /* (8-5) */
2218     for (i = 0, j = 0, k = 0; i < num_lt_pics; i++) {
2219       pocLt = PocLsbLt[i];
2220       if (slice_hdr->delta_poc_msb_present_flag[i])
2221         pocLt +=
2222             picture->poc - DeltaPocMsbCycleLt[i] * MaxPicOrderCntLsb -
2223             slice_hdr->pic_order_cnt_lsb;
2224       if (UsedByCurrPicLt[i]) {
2225         priv->PocLtCurr[j] = pocLt;
2226         CurrDeltaPocMsbPresentFlag[j++] =
2227             slice_hdr->delta_poc_msb_present_flag[i];
2228       } else {
2229         priv->PocLtFoll[k] = pocLt;
2230         FollDeltaPocMsbPresentFlag[k++] =
2231             slice_hdr->delta_poc_msb_present_flag[i];
2232       }
2233     }
2234     priv->NumPocLtCurr = j;
2235     priv->NumPocLtFoll = k;
2236
2237   }
2238
2239   /* the derivation process for the RPS and the picture marking */
2240   derive_and_mark_rps (decoder, picture, pi, CurrDeltaPocMsbPresentFlag,
2241       FollDeltaPocMsbPresentFlag);
2242
2243   return TRUE;
2244 }
2245
2246 static GstVaapiDecoderStatus
2247 decode_picture (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
2248 {
2249   GstVaapiDecoderH265Private *const priv = &decoder->priv;
2250   GstVaapiParserInfoH265 *pi = unit->parsed_info;
2251   GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr;
2252   GstH265PPS *const pps = ensure_pps (decoder, slice_hdr->pps);
2253   GstH265SPS *const sps = ensure_sps (decoder, slice_hdr->pps->sps);
2254   GstVaapiPictureH265 *picture;
2255   GstVaapiDecoderStatus status;
2256
2257   g_return_val_if_fail (pps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN);
2258   g_return_val_if_fail (sps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN);
2259
2260   status = ensure_context (decoder, sps);
2261   if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2262     return status;
2263
2264   priv->decoder_state = 0;
2265
2266   /* Create new picture */
2267   picture = gst_vaapi_picture_h265_new (decoder);
2268   if (!picture) {
2269     GST_ERROR ("failed to allocate picture");
2270     return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2271   }
2272
2273   gst_vaapi_picture_replace (&priv->current_picture, picture);
2274   gst_vaapi_picture_unref (picture);
2275
2276   /* Update cropping rectangle */
2277   if (sps->conformance_window_flag) {
2278     GstVaapiRectangle crop_rect;
2279     crop_rect.x = sps->crop_rect_x;
2280     crop_rect.y = sps->crop_rect_y;
2281     crop_rect.width = sps->crop_rect_width;
2282     crop_rect.height = sps->crop_rect_height;
2283     gst_vaapi_picture_set_crop_rect (&picture->base, &crop_rect);
2284   }
2285
2286   status = ensure_quant_matrix (decoder, picture);
2287   if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
2288     GST_ERROR ("failed to reset quantizer matrix");
2289     return status;
2290   }
2291
2292   if (!init_picture (decoder, picture, pi))
2293     return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2294
2295   /* Drop all RASL pictures having NoRaslOutputFlag is TRUE for the
2296    * associated IRAP picture */
2297   if (nal_is_rasl (pi->nalu.type) && priv->associated_irap_NoRaslOutputFlag) {
2298     gst_vaapi_picture_replace (&priv->current_picture, NULL);
2299     return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME;
2300   }
2301
2302   if (!decode_ref_pic_set (decoder, picture, pi))
2303     return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2304
2305   if (!dpb_init (decoder, picture, pi))
2306     return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2307
2308   if (!fill_picture (decoder, picture))
2309     return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2310
2311   priv->decoder_state = pi->state;
2312   return GST_VAAPI_DECODER_STATUS_SUCCESS;
2313 }
2314
2315 static inline guint
2316 get_slice_data_byte_offset (GstH265SliceHdr * slice_hdr, guint nal_header_bytes)
2317 {
2318   guint epb_count;
2319
2320   epb_count = slice_hdr->n_emulation_prevention_bytes;
2321   return nal_header_bytes + (slice_hdr->header_size + 7) / 8 - epb_count;
2322 }
2323
2324 static gboolean
2325 fill_pred_weight_table (GstVaapiDecoderH265 * decoder,
2326     GstVaapiSlice * slice, GstH265SliceHdr * slice_hdr)
2327 {
2328   VASliceParameterBufferHEVC *const slice_param = slice->param;
2329   GstH265PPS *const pps = get_pps (decoder);
2330   GstH265SPS *const sps = get_sps (decoder);
2331   GstH265PredWeightTable *const w = &slice_hdr->pred_weight_table;
2332   gint chroma_weight, chroma_log2_weight_denom;
2333   gint i, j;
2334
2335   slice_param->luma_log2_weight_denom = 0;
2336   slice_param->delta_chroma_log2_weight_denom = 0;
2337
2338   if ((pps->weighted_pred_flag && GST_H265_IS_P_SLICE (slice_hdr)) ||
2339       (pps->weighted_bipred_flag && GST_H265_IS_B_SLICE (slice_hdr))) {
2340
2341     slice_param->luma_log2_weight_denom = w->luma_log2_weight_denom;
2342     if (sps->chroma_array_type != 0)
2343       slice_param->delta_chroma_log2_weight_denom =
2344           w->delta_chroma_log2_weight_denom;
2345
2346     chroma_log2_weight_denom =
2347         slice_param->luma_log2_weight_denom +
2348         slice_param->delta_chroma_log2_weight_denom;
2349
2350     for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) {
2351       if (slice_hdr->pred_weight_table.luma_weight_l0_flag[i]) {
2352         slice_param->delta_luma_weight_l0[i] = w->delta_luma_weight_l0[i];
2353         slice_param->luma_offset_l0[i] = w->luma_offset_l0[i];
2354       }
2355       if (slice_hdr->pred_weight_table.chroma_weight_l0_flag[i]) {
2356         for (j = 0; j < 2; j++) {
2357           slice_param->delta_chroma_weight_l0[i][j] =
2358               w->delta_chroma_weight_l0[i][j];
2359           /* Find  ChromaWeightL0 */
2360           chroma_weight =
2361               (1 << chroma_log2_weight_denom) + w->delta_chroma_weight_l0[i][j];
2362           /* 7-44 */
2363           slice_param->ChromaOffsetL0[i][j] = CLAMP (
2364               (w->delta_chroma_offset_l0[i][j] -
2365                   ((128 * chroma_weight) >> chroma_log2_weight_denom)), -128,
2366               127);
2367         }
2368       }
2369     }
2370
2371     if (GST_H265_IS_B_SLICE (slice_hdr)) {
2372       for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) {
2373         if (slice_hdr->pred_weight_table.luma_weight_l1_flag[i]) {
2374           slice_param->delta_luma_weight_l1[i] = w->delta_luma_weight_l1[i];
2375           slice_param->luma_offset_l1[i] = w->luma_offset_l1[i];
2376         }
2377         if (slice_hdr->pred_weight_table.chroma_weight_l1_flag[i]) {
2378           for (j = 0; j < 2; j++) {
2379             slice_param->delta_chroma_weight_l1[i][j] =
2380                 w->delta_chroma_weight_l1[i][j];
2381             /* Find  ChromaWeightL1 */
2382             chroma_weight =
2383                 (1 << chroma_log2_weight_denom) +
2384                 w->delta_chroma_weight_l1[i][j];
2385             slice_param->ChromaOffsetL1[i][j] =
2386                 CLAMP ((w->delta_chroma_offset_l1[i][j] -
2387                     ((128 * chroma_weight) >> chroma_log2_weight_denom)), -128,
2388                 127);
2389           }
2390         }
2391       }
2392     }
2393   }
2394   /* Fixme: Optimize */
2395   else {
2396     for (i = 0; i < 15; i++) {
2397       slice_param->delta_luma_weight_l0[i] = 0;
2398       slice_param->luma_offset_l0[i] = 0;
2399       slice_param->delta_luma_weight_l1[i] = 0;
2400       slice_param->luma_offset_l1[i] = 0;
2401     }
2402     for (i = 0; i < 15; i++) {
2403       for (j = 0; j < 2; j++) {
2404         slice_param->delta_chroma_weight_l0[i][j] = 0;
2405         slice_param->ChromaOffsetL0[i][j] = 0;
2406         slice_param->delta_chroma_weight_l1[i][j] = 0;
2407         slice_param->ChromaOffsetL1[i][j] = 0;
2408       }
2409     }
2410   }
2411   return TRUE;
2412 }
2413
2414 static gboolean
2415 fill_RefPicList (GstVaapiDecoderH265 * decoder,
2416     GstVaapiPictureH265 * picture, GstVaapiSlice * slice,
2417     GstH265SliceHdr * slice_hdr)
2418 {
2419   GstVaapiDecoderH265Private *const priv = &decoder->priv;
2420   VASliceParameterBufferHEVC *const slice_param = slice->param;
2421   GstVaapiPicture *const base_picture = &picture->base;
2422   VAPictureParameterBufferHEVC *const pic_param = base_picture->param;
2423   guint i, num_ref_lists = 0, j;
2424
2425   slice_param->num_ref_idx_l0_active_minus1 = 0;
2426   slice_param->num_ref_idx_l1_active_minus1 = 0;
2427   for (j = 0; j < 2; j++)
2428     for (i = 0; i < 15; i++)
2429       slice_param->RefPicList[j][i] = 0xFF;
2430
2431   if (GST_H265_IS_B_SLICE (slice_hdr))
2432     num_ref_lists = 2;
2433   else if (GST_H265_IS_I_SLICE (slice_hdr))
2434     num_ref_lists = 0;
2435   else
2436     num_ref_lists = 1;
2437
2438   if (num_ref_lists < 1)
2439     return TRUE;
2440
2441   slice_param->num_ref_idx_l0_active_minus1 =
2442       slice_hdr->num_ref_idx_l0_active_minus1;
2443   slice_param->num_ref_idx_l1_active_minus1 =
2444       slice_hdr->num_ref_idx_l1_active_minus1;
2445
2446   for (i = 0; i < priv->RefPicList0_count; i++)
2447     slice_param->RefPicList[0][i] =
2448         get_index_for_RefPicListX (pic_param->ReferenceFrames,
2449         priv->RefPicList0[i]);
2450   for (; i < 15; i++)
2451     slice_param->RefPicList[0][i] = 0xFF;
2452
2453   if (num_ref_lists < 2)
2454     return TRUE;
2455
2456   for (i = 0; i < priv->RefPicList1_count; i++)
2457     slice_param->RefPicList[1][i] =
2458         get_index_for_RefPicListX (pic_param->ReferenceFrames,
2459         priv->RefPicList1[i]);
2460   for (; i < 15; i++)
2461     slice_param->RefPicList[1][i] = 0xFF;
2462
2463   return TRUE;
2464 }
2465
2466 static gboolean
2467 fill_slice (GstVaapiDecoderH265 * decoder,
2468     GstVaapiPictureH265 * picture, GstVaapiSlice * slice,
2469     GstVaapiParserInfoH265 * pi, GstVaapiDecoderUnit * unit)
2470 {
2471   GstVaapiDecoderH265Private *const priv = &decoder->priv;
2472   VASliceParameterBufferHEVC *const slice_param = slice->param;
2473   GstH265SliceHdr *slice_hdr = &pi->data.slice_hdr;
2474
2475   /* Fill in VASliceParameterBufferH265 */
2476   slice_param->LongSliceFlags.value = 0;
2477   slice_param->slice_data_byte_offset =
2478       get_slice_data_byte_offset (slice_hdr, pi->nalu.header_bytes);
2479
2480   slice_param->slice_segment_address = slice_hdr->segment_address;
2481
2482 #define COPY_LFF(f) \
2483     slice_param->LongSliceFlags.fields.f = (slice_hdr)->f
2484
2485   if (GST_VAAPI_PICTURE_FLAG_IS_SET (picture, GST_VAAPI_PICTURE_FLAG_AU_END))
2486     slice_param->LongSliceFlags.fields.LastSliceOfPic = 1;
2487   else
2488     slice_param->LongSliceFlags.fields.LastSliceOfPic = 0;
2489
2490   COPY_LFF (dependent_slice_segment_flag);
2491
2492   /* use most recent independent slice segment header syntax elements
2493    * for filling the missing fields in dependent slice segment header */
2494   if (slice_hdr->dependent_slice_segment_flag)
2495     slice_hdr = &priv->prev_independent_slice_pi->data.slice_hdr;
2496
2497   COPY_LFF (mvd_l1_zero_flag);
2498   COPY_LFF (cabac_init_flag);
2499   COPY_LFF (collocated_from_l0_flag);
2500   slice_param->LongSliceFlags.fields.color_plane_id =
2501       slice_hdr->colour_plane_id;
2502   slice_param->LongSliceFlags.fields.slice_type = slice_hdr->type;
2503   slice_param->LongSliceFlags.fields.slice_sao_luma_flag =
2504       slice_hdr->sao_luma_flag;
2505   slice_param->LongSliceFlags.fields.slice_sao_chroma_flag =
2506       slice_hdr->sao_chroma_flag;
2507   slice_param->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag =
2508       slice_hdr->temporal_mvp_enabled_flag;
2509   slice_param->LongSliceFlags.fields.slice_deblocking_filter_disabled_flag =
2510       slice_hdr->deblocking_filter_disabled_flag;
2511   slice_param->LongSliceFlags.
2512       fields.slice_loop_filter_across_slices_enabled_flag =
2513       slice_hdr->loop_filter_across_slices_enabled_flag;
2514
2515   if (!slice_hdr->temporal_mvp_enabled_flag)
2516     slice_param->collocated_ref_idx = 0xFF;
2517   else
2518     slice_param->collocated_ref_idx = slice_hdr->collocated_ref_idx;
2519
2520   slice_param->num_ref_idx_l0_active_minus1 =
2521       slice_hdr->num_ref_idx_l0_active_minus1;
2522   slice_param->num_ref_idx_l1_active_minus1 =
2523       slice_hdr->num_ref_idx_l1_active_minus1;
2524   slice_param->slice_qp_delta = slice_hdr->qp_delta;
2525   slice_param->slice_cb_qp_offset = slice_hdr->cb_qp_offset;
2526   slice_param->slice_cr_qp_offset = slice_hdr->cr_qp_offset;
2527   slice_param->slice_beta_offset_div2 = slice_hdr->beta_offset_div2;
2528   slice_param->slice_tc_offset_div2 = slice_hdr->tc_offset_div2;
2529   slice_param->five_minus_max_num_merge_cand =
2530       slice_hdr->five_minus_max_num_merge_cand;
2531
2532   if (!fill_RefPicList (decoder, picture, slice, slice_hdr))
2533     return FALSE;
2534
2535   if (!fill_pred_weight_table (decoder, slice, slice_hdr))
2536     return FALSE;
2537
2538   return TRUE;
2539 }
2540
2541 static GstVaapiDecoderStatus
2542 decode_slice (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
2543 {
2544   GstVaapiDecoderH265Private *const priv = &decoder->priv;
2545   GstVaapiParserInfoH265 *const pi = unit->parsed_info;
2546   GstVaapiPictureH265 *const picture = priv->current_picture;
2547   GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr;
2548   GstVaapiSlice *slice;
2549   GstBuffer *const buffer =
2550       GST_VAAPI_DECODER_CODEC_FRAME (decoder)->input_buffer;
2551   GstMapInfo map_info;
2552
2553   GST_DEBUG ("slice (%u bytes)", pi->nalu.size);
2554   if (!is_valid_state (pi->state, GST_H265_VIDEO_STATE_VALID_PICTURE_HEADERS)) {
2555     GST_WARNING ("failed to receive enough headers to decode slice");
2556     return GST_VAAPI_DECODER_STATUS_SUCCESS;
2557   }
2558
2559   if (!ensure_pps (decoder, slice_hdr->pps)) {
2560     GST_ERROR ("failed to activate PPS");
2561     return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2562   }
2563
2564   if (!ensure_sps (decoder, slice_hdr->pps->sps)) {
2565     GST_ERROR ("failed to activate SPS");
2566     return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2567   }
2568
2569   if (!gst_buffer_map (buffer, &map_info, GST_MAP_READ)) {
2570     GST_ERROR ("failed to map buffer");
2571     return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2572   }
2573
2574   /* Check wether this is the first/last slice in the current access unit */
2575   if (pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_START)
2576     GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_AU_START);
2577
2578   if (pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_END)
2579     GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_AU_END);
2580
2581   slice = GST_VAAPI_SLICE_NEW (HEVC, decoder,
2582       (map_info.data + unit->offset + pi->nalu.offset), pi->nalu.size);
2583
2584   gst_buffer_unmap (buffer, &map_info);
2585   if (!slice) {
2586     GST_ERROR ("failed to allocate slice");
2587     return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2588   }
2589
2590   init_picture_refs (decoder, picture, slice_hdr);
2591
2592   if (!fill_slice (decoder, picture, slice, pi, unit)) {
2593     gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (slice));
2594     return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2595   }
2596
2597   gst_vaapi_picture_add_slice (GST_VAAPI_PICTURE_CAST (picture), slice);
2598   picture->last_slice_hdr = slice_hdr;
2599   priv->decoder_state |= GST_H265_VIDEO_STATE_GOT_SLICE;
2600   return GST_VAAPI_DECODER_STATUS_SUCCESS;
2601 }
2602
2603 static inline gint
2604 scan_for_start_code (GstAdapter * adapter, guint ofs, guint size, guint32 * scp)
2605 {
2606   return (gint) gst_adapter_masked_scan_uint32_peek (adapter,
2607       0xffffff00, 0x00000100, ofs, size, scp);
2608 }
2609
2610 static GstVaapiDecoderStatus
2611 decode_unit (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
2612 {
2613   GstVaapiDecoderH265Private *const priv = &decoder->priv;
2614   GstVaapiParserInfoH265 *const pi = unit->parsed_info;
2615   GstVaapiDecoderStatus status;
2616   priv->decoder_state |= pi->state;
2617   switch (pi->nalu.type) {
2618     case GST_H265_NAL_VPS:
2619       status = decode_vps (decoder, unit);
2620       break;
2621     case GST_H265_NAL_SPS:
2622       status = decode_sps (decoder, unit);
2623       break;
2624     case GST_H265_NAL_PPS:
2625       status = decode_pps (decoder, unit);
2626       break;
2627     case GST_H265_NAL_SLICE_TRAIL_N:
2628     case GST_H265_NAL_SLICE_TRAIL_R:
2629     case GST_H265_NAL_SLICE_TSA_N:
2630     case GST_H265_NAL_SLICE_TSA_R:
2631     case GST_H265_NAL_SLICE_STSA_N:
2632     case GST_H265_NAL_SLICE_STSA_R:
2633     case GST_H265_NAL_SLICE_RADL_N:
2634     case GST_H265_NAL_SLICE_RADL_R:
2635     case GST_H265_NAL_SLICE_RASL_N:
2636     case GST_H265_NAL_SLICE_RASL_R:
2637     case GST_H265_NAL_SLICE_BLA_W_LP:
2638     case GST_H265_NAL_SLICE_BLA_W_RADL:
2639     case GST_H265_NAL_SLICE_BLA_N_LP:
2640     case GST_H265_NAL_SLICE_IDR_W_RADL:
2641     case GST_H265_NAL_SLICE_IDR_N_LP:
2642     case GST_H265_NAL_SLICE_CRA_NUT:
2643       /* slice decoding will get started only after completing all the
2644          initialization routines for each picture which is hanlding in
2645          start_frame() call back, so the new_bitstream and prev_nal_is_eos
2646          flags will have effects starting from the next frame onwards */
2647       priv->new_bitstream = FALSE;
2648       priv->prev_nal_is_eos = FALSE;
2649       status = decode_slice (decoder, unit);
2650       break;
2651     case GST_H265_NAL_EOB:
2652       priv->new_bitstream = TRUE;
2653       GST_DEBUG
2654           ("Next AU(if there is any) will be the begining of new bitstream");
2655       status = decode_sequence_end (decoder);
2656       break;
2657     case GST_H265_NAL_EOS:
2658       priv->prev_nal_is_eos = TRUE;
2659       status = decode_sequence_end (decoder);
2660       break;
2661     case GST_H265_NAL_SUFFIX_SEI:
2662     case GST_H265_NAL_PREFIX_SEI:
2663       status = decode_sei (decoder, unit);
2664       break;
2665     default:
2666       GST_WARNING ("unsupported NAL unit type %d", pi->nalu.type);
2667       status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
2668       break;
2669   }
2670   return status;
2671 }
2672
2673 static GstVaapiDecoderStatus
2674 gst_vaapi_decoder_h265_decode_codec_data (GstVaapiDecoder *
2675     base_decoder, const guchar * buf, guint buf_size)
2676 {
2677   GstVaapiDecoderH265 *const decoder =
2678       GST_VAAPI_DECODER_H265_CAST (base_decoder);
2679   GstVaapiDecoderH265Private *const priv = &decoder->priv;
2680   GstVaapiDecoderStatus status;
2681   GstVaapiDecoderUnit unit;
2682   GstVaapiParserInfoH265 *pi = NULL;
2683   GstH265ParserResult result;
2684   guint num_nal_arrays, num_nals;
2685   guint i, j, ofs;
2686
2687   unit.parsed_info = NULL;
2688   if (buf_size < 23)
2689     return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2690   if (buf[0] != 1) {
2691     GST_ERROR ("failed to decode codec-data, not in hvcC format");
2692     return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
2693   }
2694
2695   priv->nal_length_size = (buf[21] & 0x03) + 1;
2696   GST_DEBUG ("nal length size %u", priv->nal_length_size);
2697   num_nal_arrays = buf[22];
2698   ofs = 23;
2699   for (i = 0; i < num_nal_arrays; i++) {
2700     num_nals = GST_READ_UINT16_BE (buf + ofs + 1);
2701     for (j = 0; j < num_nals; j++) {
2702       pi = gst_vaapi_parser_info_h265_new ();
2703       if (!pi)
2704         return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2705       unit.parsed_info = pi;
2706       result = gst_h265_parser_identify_nalu_hevc (priv->parser,
2707           buf, ofs + 3, buf_size, 2, &pi->nalu);
2708       if (result != GST_H265_PARSER_OK) {
2709         status = get_status (result);
2710         goto cleanup;
2711       }
2712
2713       switch (pi->nalu.type) {
2714         case GST_H265_NAL_VPS:
2715           status = parse_vps (decoder, &unit);
2716           if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2717             goto cleanup;
2718           status = decode_vps (decoder, &unit);
2719           if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2720             goto cleanup;
2721           break;
2722         case GST_H265_NAL_SPS:
2723           status = parse_sps (decoder, &unit);
2724           if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2725             goto cleanup;
2726           status = decode_sps (decoder, &unit);
2727           if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2728             goto cleanup;
2729           break;
2730         case GST_H265_NAL_PPS:
2731           status = parse_pps (decoder, &unit);
2732           if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2733             goto cleanup;
2734           status = decode_pps (decoder, &unit);
2735           if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2736             goto cleanup;
2737           break;
2738       }
2739       gst_vaapi_parser_info_h265_replace (&pi, NULL);
2740     }
2741   }
2742
2743   priv->is_hvcC = TRUE;
2744   status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2745 cleanup:
2746   gst_vaapi_parser_info_h265_replace (&pi, NULL);
2747   return status;
2748 }
2749
2750 static GstVaapiDecoderStatus
2751 ensure_decoder (GstVaapiDecoderH265 * decoder)
2752 {
2753   GstVaapiDecoderH265Private *const priv = &decoder->priv;
2754   GstVaapiDecoderStatus status;
2755
2756   if (!priv->is_opened) {
2757     priv->is_opened = gst_vaapi_decoder_h265_open (decoder);
2758     if (!priv->is_opened)
2759       return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
2760     status =
2761         gst_vaapi_decoder_decode_codec_data (GST_VAAPI_DECODER_CAST (decoder));
2762     if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2763       return status;
2764   }
2765   return GST_VAAPI_DECODER_STATUS_SUCCESS;
2766 }
2767
2768 static GstVaapiDecoderStatus
2769 gst_vaapi_decoder_h265_parse (GstVaapiDecoder * base_decoder,
2770     GstAdapter * adapter, gboolean at_eos, GstVaapiDecoderUnit * unit)
2771 {
2772   GstVaapiDecoderH265 *const decoder =
2773       GST_VAAPI_DECODER_H265_CAST (base_decoder);
2774   GstVaapiDecoderH265Private *const priv = &decoder->priv;
2775   GstVaapiParserState *const ps = GST_VAAPI_PARSER_STATE (base_decoder);
2776   GstVaapiParserInfoH265 *pi;
2777   GstVaapiDecoderStatus status;
2778   GstH265ParserResult result;
2779   guchar *buf;
2780   guint i, size, buf_size, nalu_size, flags;
2781   guint32 start_code;
2782   gint ofs, ofs2;
2783   gboolean at_au_end = FALSE;
2784
2785   status = ensure_decoder (decoder);
2786   if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2787     return status;
2788
2789   switch (priv->stream_alignment) {
2790     case GST_VAAPI_STREAM_ALIGN_H265_NALU:
2791     case GST_VAAPI_STREAM_ALIGN_H265_AU:
2792       size = gst_adapter_available_fast (adapter);
2793       break;
2794     default:
2795       size = gst_adapter_available (adapter);
2796       break;
2797   }
2798
2799   if (priv->is_hvcC) {
2800     if (size < priv->nal_length_size)
2801       return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2802     buf = (guchar *) & start_code;
2803     g_assert (priv->nal_length_size <= sizeof (start_code));
2804     gst_adapter_copy (adapter, buf, 0, priv->nal_length_size);
2805     nalu_size = 0;
2806     for (i = 0; i < priv->nal_length_size; i++)
2807       nalu_size = (nalu_size << 8) | buf[i];
2808     buf_size = priv->nal_length_size + nalu_size;
2809     if (size < buf_size)
2810       return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2811     else if (priv->stream_alignment == GST_VAAPI_STREAM_ALIGN_H265_AU)
2812       at_au_end = (buf_size == size);
2813   } else {
2814     if (size < 4)
2815       return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2816     if (priv->stream_alignment == GST_VAAPI_STREAM_ALIGN_H265_NALU)
2817       buf_size = size;
2818     else {
2819       ofs = scan_for_start_code (adapter, 0, size, NULL);
2820       if (ofs < 0)
2821         return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2822       if (ofs > 0) {
2823         gst_adapter_flush (adapter, ofs);
2824         size -= ofs;
2825       }
2826
2827       ofs2 = ps->input_offset2 - ofs - 4;
2828       if (ofs2 < 4)
2829         ofs2 = 4;
2830       ofs = G_UNLIKELY (size < ofs2 + 4) ? -1 :
2831           scan_for_start_code (adapter, ofs2, size - ofs2, NULL);
2832       if (ofs < 0) {
2833         // Assume the whole NAL unit is present if end-of-stream
2834         // or stream buffers aligned on access unit boundaries
2835         if (priv->stream_alignment == GST_VAAPI_STREAM_ALIGN_H265_AU)
2836           at_au_end = TRUE;
2837         else if (!at_eos) {
2838           ps->input_offset2 = size;
2839           return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2840         }
2841         ofs = size;
2842       }
2843       buf_size = ofs;
2844     }
2845   }
2846   ps->input_offset2 = 0;
2847   buf = (guchar *) gst_adapter_map (adapter, buf_size);
2848   if (!buf)
2849     return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2850   unit->size = buf_size;
2851   pi = gst_vaapi_parser_info_h265_new ();
2852   if (!pi)
2853     return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2854   gst_vaapi_decoder_unit_set_parsed_info (unit,
2855       pi, (GDestroyNotify) gst_vaapi_mini_object_unref);
2856   if (priv->is_hvcC)
2857     result = gst_h265_parser_identify_nalu_hevc (priv->parser,
2858         buf, 0, buf_size, priv->nal_length_size, &pi->nalu);
2859   else
2860     result = gst_h265_parser_identify_nalu_unchecked (priv->parser,
2861         buf, 0, buf_size, &pi->nalu);
2862   status = get_status (result);
2863   if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2864     return status;
2865   switch (pi->nalu.type) {
2866     case GST_H265_NAL_VPS:
2867       status = parse_vps (decoder, unit);
2868       break;
2869     case GST_H265_NAL_SPS:
2870       status = parse_sps (decoder, unit);
2871       break;
2872     case GST_H265_NAL_PPS:
2873       status = parse_pps (decoder, unit);
2874       break;
2875     case GST_H265_NAL_PREFIX_SEI:
2876     case GST_H265_NAL_SUFFIX_SEI:
2877       status = parse_sei (decoder, unit);
2878       break;
2879     case GST_H265_NAL_SLICE_TRAIL_N:
2880     case GST_H265_NAL_SLICE_TRAIL_R:
2881     case GST_H265_NAL_SLICE_TSA_N:
2882     case GST_H265_NAL_SLICE_TSA_R:
2883     case GST_H265_NAL_SLICE_STSA_N:
2884     case GST_H265_NAL_SLICE_STSA_R:
2885     case GST_H265_NAL_SLICE_RADL_N:
2886     case GST_H265_NAL_SLICE_RADL_R:
2887     case GST_H265_NAL_SLICE_RASL_N:
2888     case GST_H265_NAL_SLICE_RASL_R:
2889     case GST_H265_NAL_SLICE_BLA_W_LP:
2890     case GST_H265_NAL_SLICE_BLA_W_RADL:
2891     case GST_H265_NAL_SLICE_BLA_N_LP:
2892     case GST_H265_NAL_SLICE_IDR_W_RADL:
2893     case GST_H265_NAL_SLICE_IDR_N_LP:
2894     case GST_H265_NAL_SLICE_CRA_NUT:
2895       status = parse_slice (decoder, unit);
2896       break;
2897     default:
2898       status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2899       break;
2900   }
2901   if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2902     return status;
2903   flags = 0;
2904   if (at_au_end) {
2905     flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END |
2906         GST_VAAPI_DECODER_UNIT_FLAG_AU_END;
2907   }
2908
2909   switch (pi->nalu.type) {
2910     case GST_H265_NAL_AUD:
2911       flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START;
2912       flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
2913       /* fall-through */
2914     case GST_H265_NAL_FD:
2915       flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP;
2916       break;
2917     case GST_H265_NAL_EOB:
2918       flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END;
2919       /* fall-through */
2920     case GST_H265_NAL_SUFFIX_SEI:
2921     case GST_H265_NAL_EOS:
2922       flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END;
2923       flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_END;
2924       break;
2925     case GST_H265_NAL_VPS:
2926     case GST_H265_NAL_SPS:
2927     case GST_H265_NAL_PPS:
2928     case GST_H265_NAL_PREFIX_SEI:
2929       flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START;
2930       flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
2931       break;
2932     case GST_H265_NAL_SLICE_TRAIL_N:
2933     case GST_H265_NAL_SLICE_TRAIL_R:
2934     case GST_H265_NAL_SLICE_TSA_N:
2935     case GST_H265_NAL_SLICE_TSA_R:
2936     case GST_H265_NAL_SLICE_STSA_N:
2937     case GST_H265_NAL_SLICE_STSA_R:
2938     case GST_H265_NAL_SLICE_RADL_N:
2939     case GST_H265_NAL_SLICE_RADL_R:
2940     case GST_H265_NAL_SLICE_RASL_N:
2941     case GST_H265_NAL_SLICE_RASL_R:
2942     case GST_H265_NAL_SLICE_BLA_W_LP:
2943     case GST_H265_NAL_SLICE_BLA_W_RADL:
2944     case GST_H265_NAL_SLICE_BLA_N_LP:
2945     case GST_H265_NAL_SLICE_IDR_W_RADL:
2946     case GST_H265_NAL_SLICE_IDR_N_LP:
2947     case GST_H265_NAL_SLICE_CRA_NUT:
2948       flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE;
2949       if (priv->prev_pi &&
2950           (priv->prev_pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_END)) {
2951         flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START |
2952             GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
2953       } else if (is_new_picture (pi, priv->prev_slice_pi)) {
2954         flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
2955         if (is_new_access_unit (pi, priv->prev_slice_pi))
2956           flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START;
2957       }
2958       gst_vaapi_parser_info_h265_replace (&priv->prev_slice_pi, pi);
2959       if (!pi->data.slice_hdr.dependent_slice_segment_flag)
2960         gst_vaapi_parser_info_h265_replace (&priv->prev_independent_slice_pi,
2961             pi);
2962       break;
2963     default:
2964       /* Fix */
2965       break;
2966   }
2967   if ((flags & GST_VAAPI_DECODER_UNIT_FLAGS_AU) && priv->prev_slice_pi)
2968     priv->prev_slice_pi->flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_END;
2969   GST_VAAPI_DECODER_UNIT_FLAG_SET (unit, flags);
2970   pi->nalu.data = NULL;
2971   pi->state = priv->parser_state;
2972   pi->flags = flags;
2973   gst_vaapi_parser_info_h265_replace (&priv->prev_pi, pi);
2974   return GST_VAAPI_DECODER_STATUS_SUCCESS;
2975 }
2976
2977 static GstVaapiDecoderStatus
2978 gst_vaapi_decoder_h265_decode (GstVaapiDecoder * base_decoder,
2979     GstVaapiDecoderUnit * unit)
2980 {
2981   GstVaapiDecoderH265 *const decoder =
2982       GST_VAAPI_DECODER_H265_CAST (base_decoder);
2983   GstVaapiDecoderStatus status;
2984
2985   status = ensure_decoder (decoder);
2986   if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2987     return status;
2988   return decode_unit (decoder, unit);
2989 }
2990
2991 static GstVaapiDecoderStatus
2992 gst_vaapi_decoder_h265_start_frame (GstVaapiDecoder * base_decoder,
2993     GstVaapiDecoderUnit * unit)
2994 {
2995   GstVaapiDecoderH265 *const decoder =
2996       GST_VAAPI_DECODER_H265_CAST (base_decoder);
2997
2998   return decode_picture (decoder, unit);
2999 }
3000
3001 static GstVaapiDecoderStatus
3002 gst_vaapi_decoder_h265_end_frame (GstVaapiDecoder * base_decoder)
3003 {
3004   GstVaapiDecoderH265 *const decoder =
3005       GST_VAAPI_DECODER_H265_CAST (base_decoder);
3006
3007   return decode_current_picture (decoder);
3008 }
3009
3010 static GstVaapiDecoderStatus
3011 gst_vaapi_decoder_h265_flush (GstVaapiDecoder * base_decoder)
3012 {
3013   GstVaapiDecoderH265 *const decoder =
3014       GST_VAAPI_DECODER_H265_CAST (base_decoder);
3015
3016   dpb_flush (decoder);
3017   return GST_VAAPI_DECODER_STATUS_SUCCESS;
3018 }
3019
3020 static void
3021 gst_vaapi_decoder_h265_class_init (GstVaapiDecoderH265Class * klass)
3022 {
3023   GstVaapiMiniObjectClass *const object_class =
3024       GST_VAAPI_MINI_OBJECT_CLASS (klass);
3025   GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass);
3026
3027   object_class->size = sizeof (GstVaapiDecoderH265);
3028   object_class->finalize = (GDestroyNotify) gst_vaapi_decoder_finalize;
3029   decoder_class->create = gst_vaapi_decoder_h265_create;
3030   decoder_class->destroy = gst_vaapi_decoder_h265_destroy;
3031   decoder_class->parse = gst_vaapi_decoder_h265_parse;
3032   decoder_class->decode = gst_vaapi_decoder_h265_decode;
3033   decoder_class->start_frame = gst_vaapi_decoder_h265_start_frame;
3034   decoder_class->end_frame = gst_vaapi_decoder_h265_end_frame;
3035   decoder_class->flush = gst_vaapi_decoder_h265_flush;
3036   decoder_class->decode_codec_data = gst_vaapi_decoder_h265_decode_codec_data;
3037 }
3038
3039 static inline const GstVaapiDecoderClass *
3040 gst_vaapi_decoder_h265_class (void)
3041 {
3042   static GstVaapiDecoderH265Class g_class;
3043   static gsize g_class_init = FALSE;
3044
3045   if (g_once_init_enter (&g_class_init)) {
3046     gst_vaapi_decoder_h265_class_init (&g_class);
3047     g_once_init_leave (&g_class_init, TRUE);
3048   }
3049   return GST_VAAPI_DECODER_CLASS (&g_class);
3050 }
3051
3052 /**
3053  * gst_vaapi_decoder_h265_set_alignment:
3054  * @decoder: a #GstVaapiDecoderH265
3055  * @alignment: the #GstVaapiStreamAlignH265
3056  *
3057  * Specifies how stream buffers are aligned / fed, i.e. the boundaries
3058  * of each buffer that is supplied to the decoder. This could be no
3059  * specific alignment, NAL unit boundaries, or access unit boundaries.
3060  */
3061 void
3062 gst_vaapi_decoder_h265_set_alignment (GstVaapiDecoderH265 * decoder,
3063     GstVaapiStreamAlignH265 alignment)
3064 {
3065   g_return_if_fail (decoder != NULL);
3066   decoder->priv.stream_alignment = alignment;
3067 }
3068
3069 /**
3070  * gst_vaapi_decoder_h265_new:
3071  * @display: a #GstVaapiDisplay
3072  * @caps: a #GstCaps holding codec information
3073  *
3074  * Creates a new #GstVaapiDecoder for MPEG-2 decoding.  The @caps can
3075  * hold extra information like codec-data and pictured coded size.
3076  *
3077  * Return value: the newly allocated #GstVaapiDecoder object
3078  */
3079 GstVaapiDecoder *
3080 gst_vaapi_decoder_h265_new (GstVaapiDisplay * display, GstCaps * caps)
3081 {
3082   return gst_vaapi_decoder_new (gst_vaapi_decoder_h265_class (), display, caps);
3083 }