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