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