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