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