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