2 * gstvaapidecoder_h265.c - H.265 decoder
4 * Copyright (C) 2015 Intel Corporation
5 * Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
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.
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.
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
24 * SECTION:gstvaapidecoder_h265
25 * @short_description: H.265 decoder
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"
42 #include "gstvaapidebug.h"
44 /* Defined to 1 if strict ordering of DPB is needed. Only useful for debug */
45 #define USE_STRICT_DPB_ORDERING 0
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;
54 static gboolean nal_is_slice (guint8 nal_type);
56 /* ------------------------------------------------------------------------- */
57 /* --- H.265 Parser Info --- */
58 /* ------------------------------------------------------------------------- */
61 * Extended decoder unit flags:
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.
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),
72 GST_VAAPI_DECODER_UNIT_FLAGS_AU = (GST_VAAPI_DECODER_UNIT_FLAG_AU_START |
73 GST_VAAPI_DECODER_UNIT_FLAG_AU_END),
76 #define GST_VAAPI_PARSER_INFO_H265(obj) \
77 ((GstVaapiParserInfoH265 *)(obj))
79 struct _GstVaapiParserInfoH265
81 GstVaapiMiniObject parent_instance;
88 /* Fix SEI parsing in codecparser, have to use GArray like h264parser */
89 GstH265SEIMessage sei;
90 GstH265SliceHdr slice_hdr;
93 guint flags; // Same as decoder unit flags (persistent)
97 gst_vaapi_parser_info_h265_finalize (GstVaapiParserInfoH265 * pi)
99 if (nal_is_slice (pi->nalu.type))
100 gst_h265_slice_hdr_free (&pi->data.slice_hdr);
102 switch (pi->nalu.type) {
103 case GST_H265_NAL_VPS:
104 case GST_H265_NAL_SPS:
105 case GST_H265_NAL_PPS:
107 case GST_H265_NAL_PREFIX_SEI:
108 case GST_H265_NAL_SUFFIX_SEI:
109 gst_h265_sei_free (&pi->data.sei);
115 static inline const GstVaapiMiniObjectClass *
116 gst_vaapi_parser_info_h265_class (void)
118 static const GstVaapiMiniObjectClass GstVaapiParserInfoH265Class = {
119 .size = sizeof (GstVaapiParserInfoH265),
120 .finalize = (GDestroyNotify) gst_vaapi_parser_info_h265_finalize
122 return &GstVaapiParserInfoH265Class;
125 static inline GstVaapiParserInfoH265 *
126 gst_vaapi_parser_info_h265_new (void)
128 return (GstVaapiParserInfoH265 *)
129 gst_vaapi_mini_object_new (gst_vaapi_parser_info_h265_class ());
132 #define gst_vaapi_parser_info_h265_ref(pi) \
133 gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(pi))
135 #define gst_vaapi_parser_info_h265_unref(pi) \
136 gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(pi))
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))
142 /* ------------------------------------------------------------------------- */
143 /* --- H.265 Pictures --- */
144 /* ------------------------------------------------------------------------- */
147 * Extended picture flags:
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
152 * @GST_VAAPI_PICTURE_FLAG_AU_END: flag that marks the end of an
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)
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),
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),
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),
200 #define GST_VAAPI_PICTURE_IS_IDR(picture) \
201 (GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR))
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)
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)
213 #define GST_VAAPI_PICTURE_H265(picture) \
214 ((GstVaapiPictureH265 *)(picture))
216 struct _GstVaapiPictureH265
218 GstVaapiPicture base;
219 GstH265SliceHdr *last_slice_hdr;
221 gint32 poc; // PicOrderCntVal (8.3.1)
222 gint32 poc_lsb; // slice_pic_order_cnt_lsb
223 guint32 pic_latency_cnt; // PicLatencyCount
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)
232 GST_VAAPI_CODEC_DEFINE_TYPE (GstVaapiPictureH265, gst_vaapi_picture_h265);
235 gst_vaapi_picture_h265_destroy (GstVaapiPictureH265 * picture)
237 gst_vaapi_picture_destroy (GST_VAAPI_PICTURE (picture));
241 gst_vaapi_picture_h265_create (GstVaapiPictureH265 * picture,
242 const GstVaapiCodecObjectConstructorArgs * args)
244 if (!gst_vaapi_picture_create (GST_VAAPI_PICTURE (picture), args))
247 picture->structure = picture->base.structure;
248 picture->poc = G_MAXINT32;
249 picture->output_needed = FALSE;
253 static inline GstVaapiPictureH265 *
254 gst_vaapi_picture_h265_new (GstVaapiDecoderH265 * decoder)
256 return (GstVaapiPictureH265 *)
257 gst_vaapi_codec_object_new (&GstVaapiPictureH265Class,
258 GST_VAAPI_CODEC_BASE (decoder), NULL,
259 sizeof (VAPictureParameterBufferHEVC), NULL, 0, 0);
263 gst_vaapi_picture_h265_set_reference (GstVaapiPictureH265 * picture,
264 guint reference_flags)
268 GST_VAAPI_PICTURE_FLAG_UNSET (picture,
269 GST_VAAPI_PICTURE_FLAGS_RPS_ST | GST_VAAPI_PICTURE_FLAGS_RPS_LT);
270 GST_VAAPI_PICTURE_FLAG_UNSET (picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE);
271 GST_VAAPI_PICTURE_FLAG_SET (picture, reference_flags);
274 /* ------------------------------------------------------------------------- */
275 /* --- Frame Buffers (DPB) --- */
276 /* ------------------------------------------------------------------------- */
278 struct _GstVaapiFrameStore
281 GstVaapiMiniObject parent_instance;
283 GstVaapiPictureH265 *buffer;
287 gst_vaapi_frame_store_finalize (gpointer object)
289 GstVaapiFrameStore *const fs = object;
291 gst_vaapi_picture_replace (&fs->buffer, NULL);
294 static GstVaapiFrameStore *
295 gst_vaapi_frame_store_new (GstVaapiPictureH265 * picture)
297 GstVaapiFrameStore *fs;
299 static const GstVaapiMiniObjectClass GstVaapiFrameStoreClass = {
300 sizeof (GstVaapiFrameStore),
301 gst_vaapi_frame_store_finalize
304 fs = (GstVaapiFrameStore *)
305 gst_vaapi_mini_object_new (&GstVaapiFrameStoreClass);
309 fs->buffer = gst_vaapi_picture_ref (picture);
314 static inline gboolean
315 gst_vaapi_frame_store_has_reference (GstVaapiFrameStore * fs)
317 if (GST_VAAPI_PICTURE_IS_REFERENCE (fs->buffer))
322 #define gst_vaapi_frame_store_ref(fs) \
323 gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(fs))
325 #define gst_vaapi_frame_store_unref(fs) \
326 gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(fs))
328 #define gst_vaapi_frame_store_replace(old_fs_p, new_fs) \
329 gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_fs_p), \
330 (GstVaapiMiniObject *)(new_fs))
332 /* ------------------------------------------------------------------------- */
333 /* --- H.265 Decoder --- */
334 /* ------------------------------------------------------------------------- */
336 #define GST_VAAPI_DECODER_H265_CAST(decoder) \
337 ((GstVaapiDecoderH265 *)(decoder))
341 GST_H265_VIDEO_STATE_GOT_VPS = 1 << 0,
342 GST_H265_VIDEO_STATE_GOT_SPS = 1 << 1,
343 GST_H265_VIDEO_STATE_GOT_PPS = 1 << 2,
344 GST_H265_VIDEO_STATE_GOT_SLICE = 1 << 3,
346 GST_H265_VIDEO_STATE_VALID_PICTURE_HEADERS =
347 (GST_H265_VIDEO_STATE_GOT_SPS | GST_H265_VIDEO_STATE_GOT_PPS),
348 GST_H265_VIDEO_STATE_VALID_PICTURE =
349 (GST_H265_VIDEO_STATE_VALID_PICTURE_HEADERS |
350 GST_H265_VIDEO_STATE_GOT_SLICE)
353 struct _GstVaapiDecoderH265Private
355 GstH265Parser *parser;
358 GstVaapiStreamAlignH265 stream_alignment;
359 GstVaapiPictureH265 *current_picture;
360 GstVaapiParserInfoH265 *vps[GST_H265_MAX_VPS_COUNT];
361 GstVaapiParserInfoH265 *active_vps;
362 GstVaapiParserInfoH265 *sps[GST_H265_MAX_SPS_COUNT];
363 GstVaapiParserInfoH265 *active_sps;
364 GstVaapiParserInfoH265 *pps[GST_H265_MAX_PPS_COUNT];
365 GstVaapiParserInfoH265 *active_pps;
366 GstVaapiParserInfoH265 *prev_pi;
367 GstVaapiParserInfoH265 *prev_slice_pi;
368 GstVaapiParserInfoH265 *prev_independent_slice_pi;
369 GstVaapiFrameStore **dpb;
373 GstVaapiProfile profile;
374 GstVaapiEntrypoint entrypoint;
375 GstVaapiChromaType chroma_type;
377 GstVaapiPictureH265 *RefPicSetStCurrBefore[16];
378 GstVaapiPictureH265 *RefPicSetStCurrAfter[16];
379 GstVaapiPictureH265 *RefPicSetStFoll[16];
380 GstVaapiPictureH265 *RefPicSetLtCurr[16];
381 GstVaapiPictureH265 *RefPicSetLtFoll[16];
383 GstVaapiPictureH265 *RefPicList0[16];
384 guint RefPicList0_count;
385 GstVaapiPictureH265 *RefPicList1[16];
386 guint RefPicList1_count;
388 guint32 SpsMaxLatencyPictures;
390 guint nal_length_size;
392 guint pic_width_in_luma_samples; //sps->pic_width_in_luma_samples
393 guint pic_height_in_luma_samples; //sps->pic_height_in_luma_samples
394 guint pic_structure; // pic_struct (from SEI pic_timing() or inferred)
395 gint32 poc; // PicOrderCntVal
396 gint32 poc_msb; // PicOrderCntMsb
397 gint32 poc_lsb; // pic_order_cnt_lsb (from slice_header())
398 gint32 prev_poc_msb; // prevPicOrderCntMsb
399 gint32 prev_poc_lsb; // prevPicOrderCntLsb
400 gint32 prev_tid0pic_poc_lsb;
401 gint32 prev_tid0pic_poc_msb;
402 gint32 PocStCurrBefore[16];
403 gint32 PocStCurrAfter[16];
404 gint32 PocStFoll[16];
405 gint32 PocLtCurr[16];
406 gint32 PocLtFoll[16];
407 guint NumPocStCurrBefore;
408 guint NumPocStCurrAfter;
412 guint NumPocTotalCurr;
416 guint progressive_sequence:1;
417 guint new_bitstream:1;
418 guint prev_nal_is_eos:1; /*previous nal type is EOS */
419 guint associated_irap_NoRaslOutputFlag:1;
423 * GstVaapiDecoderH265:
425 * A decoder based on H265.
427 struct _GstVaapiDecoderH265
430 GstVaapiDecoder parent_instance;
431 GstVaapiDecoderH265Private priv;
435 * GstVaapiDecoderH265Class:
437 * A decoder class based on H265.
439 struct _GstVaapiDecoderH265Class
442 GstVaapiDecoderClass parent_class;
445 #define RSV_VCL_N10 10
446 #define RSV_VCL_N12 12
447 #define RSV_VCL_N14 14
450 nal_is_idr (guint8 nal_type)
452 if ((nal_type == GST_H265_NAL_SLICE_IDR_W_RADL) ||
453 (nal_type == GST_H265_NAL_SLICE_IDR_N_LP))
459 nal_is_irap (guint8 nal_type)
461 if ((nal_type >= GST_H265_NAL_SLICE_BLA_W_LP) &&
462 (nal_type <= RESERVED_IRAP_NAL_TYPE_MAX))
468 nal_is_bla (guint8 nal_type)
470 if ((nal_type >= GST_H265_NAL_SLICE_BLA_W_LP) &&
471 (nal_type <= GST_H265_NAL_SLICE_BLA_N_LP))
477 nal_is_cra (guint8 nal_type)
479 if (nal_type == GST_H265_NAL_SLICE_CRA_NUT)
485 nal_is_radl (guint8 nal_type)
487 if ((nal_type >= GST_H265_NAL_SLICE_RADL_N) &&
488 (nal_type <= GST_H265_NAL_SLICE_RADL_R))
494 nal_is_rasl (guint8 nal_type)
496 if ((nal_type >= GST_H265_NAL_SLICE_RASL_N) &&
497 (nal_type <= GST_H265_NAL_SLICE_RASL_R))
503 nal_is_slice (guint8 nal_type)
505 if ((nal_type >= GST_H265_NAL_SLICE_TRAIL_N) &&
506 (nal_type <= GST_H265_NAL_SLICE_CRA_NUT))
512 nal_is_ref (guint8 nal_type)
514 gboolean ret = FALSE;
516 case GST_H265_NAL_SLICE_TRAIL_N:
517 case GST_H265_NAL_SLICE_TSA_N:
518 case GST_H265_NAL_SLICE_STSA_N:
519 case GST_H265_NAL_SLICE_RADL_N:
520 case GST_H265_NAL_SLICE_RASL_N:
533 /* Activates the supplied PPS */
535 ensure_pps (GstVaapiDecoderH265 * decoder, GstH265PPS * pps)
537 GstVaapiDecoderH265Private *const priv = &decoder->priv;
538 GstVaapiParserInfoH265 *const pi = priv->pps[pps->id];
540 gst_vaapi_parser_info_h265_replace (&priv->active_pps, pi);
541 return pi ? &pi->data.pps : NULL;
544 /* Returns the active PPS */
545 static inline GstH265PPS *
546 get_pps (GstVaapiDecoderH265 * decoder)
548 GstVaapiParserInfoH265 *const pi = decoder->priv.active_pps;
550 return pi ? &pi->data.pps : NULL;
553 /* Activate the supplied SPS */
555 ensure_sps (GstVaapiDecoderH265 * decoder, GstH265SPS * sps)
557 GstVaapiDecoderH265Private *const priv = &decoder->priv;
558 GstVaapiParserInfoH265 *const pi = priv->sps[sps->id];
560 gst_vaapi_parser_info_h265_replace (&priv->active_sps, pi);
561 return pi ? &pi->data.sps : NULL;
564 /* Returns the active SPS */
565 static inline GstH265SPS *
566 get_sps (GstVaapiDecoderH265 * decoder)
568 GstVaapiParserInfoH265 *const pi = decoder->priv.active_sps;
570 return pi ? &pi->data.sps : NULL;
573 /* Activate the supplied VPS */
575 ensure_vps (GstVaapiDecoderH265 * decoder, GstH265VPS * vps)
577 GstVaapiDecoderH265Private *const priv = &decoder->priv;
578 GstVaapiParserInfoH265 *const pi = priv->vps[vps->id];
580 gst_vaapi_parser_info_h265_replace (&priv->active_vps, pi);
581 return pi ? &pi->data.vps : NULL;
584 /* Returns the active VPS */
585 static inline GstH265VPS *
586 get_vps (GstVaapiDecoderH265 * decoder)
588 GstVaapiParserInfoH265 *const pi = decoder->priv.active_vps;
589 return pi ? &pi->data.vps : NULL;
592 /* Get number of reference frames to use */
594 get_max_dec_frame_buffering (GstH265SPS * sps)
596 guint max_dec_frame_buffering;
597 GstVaapiLevelH265 level;
598 const GstVaapiH265LevelLimits *level_limits;
600 level = gst_vaapi_utils_h265_get_level (sps->profile_tier_level.level_idc);
601 level_limits = gst_vaapi_utils_h265_get_level_limits (level);
602 if (G_UNLIKELY (!level_limits)) {
603 GST_FIXME ("unsupported level_idc value (%d)",
604 sps->profile_tier_level.level_idc);
605 max_dec_frame_buffering = 16;
607 /* Fixme: Add limit check based on Annex A */
608 return MAX (1, (sps->max_dec_pic_buffering_minus1[0] + 1));
612 dpb_remove_index (GstVaapiDecoderH265 * decoder, gint index)
614 GstVaapiDecoderH265Private *const priv = &decoder->priv;
615 guint i, num_frames = --priv->dpb_count;
617 if (USE_STRICT_DPB_ORDERING) {
618 for (i = index; i < num_frames; i++)
619 gst_vaapi_frame_store_replace (&priv->dpb[i], priv->dpb[i + 1]);
620 } else if (index != num_frames)
621 gst_vaapi_frame_store_replace (&priv->dpb[index], priv->dpb[num_frames]);
622 gst_vaapi_frame_store_replace (&priv->dpb[num_frames], NULL);
626 dpb_output (GstVaapiDecoderH265 * decoder, GstVaapiFrameStore * fs)
628 GstVaapiPictureH265 *picture;
630 g_return_val_if_fail (fs != NULL, FALSE);
632 picture = fs->buffer;
633 g_return_val_if_fail (picture != NULL, FALSE);
635 picture->output_needed = FALSE;
636 return gst_vaapi_picture_output (GST_VAAPI_PICTURE_CAST (picture));
639 /* Get the dpb picture having the specifed poc or poc_lsb */
640 static GstVaapiPictureH265 *
641 dpb_get_picture (GstVaapiDecoderH265 * decoder, gint poc, gboolean match_lsb)
643 GstVaapiDecoderH265Private *const priv = &decoder->priv;
646 for (i = 0; i < priv->dpb_count; i++) {
647 GstVaapiPictureH265 *const picture = priv->dpb[i]->buffer;
649 if (picture && GST_VAAPI_PICTURE_FLAG_IS_SET (picture,
650 GST_VAAPI_PICTURE_FLAGS_REFERENCE)) {
652 if (picture->poc_lsb == poc)
655 if (picture->poc == poc)
663 /* Get the dpb picture having the specifed poc and shor/long ref flags */
664 static GstVaapiPictureH265 *
665 dpb_get_ref_picture (GstVaapiDecoderH265 * decoder, gint poc, gboolean is_short)
667 GstVaapiDecoderH265Private *const priv = &decoder->priv;
670 for (i = 0; i < priv->dpb_count; i++) {
671 GstVaapiPictureH265 *const picture = priv->dpb[i]->buffer;
673 if (picture && picture->poc == poc) {
674 if (is_short && GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE (picture))
676 else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE (picture))
684 /* Finds the picture with the lowest POC that needs to be output */
686 dpb_find_lowest_poc (GstVaapiDecoderH265 * decoder,
687 GstVaapiPictureH265 ** found_picture_ptr)
689 GstVaapiDecoderH265Private *const priv = &decoder->priv;
690 GstVaapiPictureH265 *found_picture = NULL;
691 guint i, found_index;
693 for (i = 0; i < priv->dpb_count; i++) {
694 GstVaapiPictureH265 *const picture = priv->dpb[i]->buffer;
695 if (picture && !picture->output_needed)
697 if (!found_picture || found_picture->poc > picture->poc)
698 found_picture = picture, found_index = i;
701 if (found_picture_ptr)
702 *found_picture_ptr = found_picture;
703 return found_picture ? found_index : -1;
707 dpb_bump (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture)
709 GstVaapiDecoderH265Private *const priv = &decoder->priv;
710 GstVaapiPictureH265 *found_picture;
714 found_index = dpb_find_lowest_poc (decoder, &found_picture);
718 success = dpb_output (decoder, priv->dpb[found_index]);
720 if (!gst_vaapi_frame_store_has_reference (priv->dpb[found_index]))
721 dpb_remove_index (decoder, found_index);
727 dpb_clear (GstVaapiDecoderH265 * decoder, gboolean hard_flush)
729 GstVaapiDecoderH265Private *const priv = &decoder->priv;
730 GstVaapiPictureH265 *pic;
734 for (i = 0; i < priv->dpb_count; i++)
735 dpb_remove_index (decoder, i);
738 /* Remove unused pictures from DPB */
740 while (i < priv->dpb_count) {
741 GstVaapiFrameStore *const fs = priv->dpb[i];
743 if (!pic->output_needed && !gst_vaapi_frame_store_has_reference (fs))
744 dpb_remove_index (decoder, i);
752 dpb_flush (GstVaapiDecoderH265 * decoder)
754 /* Output any frame remaining in DPB */
755 while (dpb_bump (decoder, NULL));
756 dpb_clear (decoder, TRUE);
760 dpb_get_num_need_output (GstVaapiDecoderH265 * decoder)
762 GstVaapiDecoderH265Private *const priv = &decoder->priv;
763 guint i = 0, n_output_needed = 0;
765 while (i < priv->dpb_count) {
766 GstVaapiFrameStore *const fs = priv->dpb[i];
767 if (fs->buffer->output_needed)
772 return n_output_needed;
776 check_latency_cnt (GstVaapiDecoderH265 * decoder)
778 GstVaapiDecoderH265Private *const priv = &decoder->priv;
779 GstVaapiPictureH265 *tmp_pic;
782 while (i < priv->dpb_count) {
783 GstVaapiFrameStore *const fs = priv->dpb[i];
784 tmp_pic = fs->buffer;
785 if (tmp_pic->output_needed) {
786 if (tmp_pic->pic_latency_cnt >= priv->SpsMaxLatencyPictures)
796 dpb_add (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture)
798 GstVaapiDecoderH265Private *const priv = &decoder->priv;
799 GstH265SPS *const sps = get_sps (decoder);
800 GstVaapiFrameStore *fs;
801 GstVaapiPictureH265 *tmp_pic;
805 while (i < priv->dpb_count) {
806 GstVaapiFrameStore *const fs = priv->dpb[i];
807 tmp_pic = fs->buffer;
808 if (tmp_pic->output_needed)
809 tmp_pic->pic_latency_cnt += 1;
813 if (picture->output_flag) {
814 picture->output_needed = 1;
815 picture->pic_latency_cnt = 0;
817 picture->output_needed = 0;
819 /* set pic as short_term_ref */
820 gst_vaapi_picture_h265_set_reference (picture,
821 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE);
823 /* C.5.2.4 "Bumping" process */
824 while ((dpb_get_num_need_output (decoder) >
825 sps->max_num_reorder_pics[sps->max_sub_layers_minus1])
826 || (sps->max_latency_increase_plus1[sps->max_sub_layers_minus1]
827 && check_latency_cnt (decoder)))
828 dpb_bump (decoder, picture);
830 /* Create new frame store */
831 fs = gst_vaapi_frame_store_new (picture);
834 gst_vaapi_frame_store_replace (&priv->dpb[priv->dpb_count++], fs);
835 gst_vaapi_frame_store_unref (fs);
843 dpb_init (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture,
844 GstVaapiParserInfoH265 * pi)
846 GstVaapiDecoderH265Private *const priv = &decoder->priv;
847 GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr;
848 GstH265SPS *const sps = get_sps (decoder);
850 if (nal_is_irap (pi->nalu.type)
851 && picture->NoRaslOutputFlag && !priv->new_bitstream) {
853 if (pi->nalu.type == GST_H265_NAL_SLICE_CRA_NUT)
854 picture->NoOutputOfPriorPicsFlag = 1;
856 picture->NoOutputOfPriorPicsFlag =
857 slice_hdr->no_output_of_prior_pics_flag;
859 if (picture->NoOutputOfPriorPicsFlag)
860 dpb_clear (decoder, TRUE);
862 dpb_clear (decoder, FALSE);
863 while (dpb_bump (decoder, NULL));
866 dpb_clear (decoder, FALSE);
867 while ((dpb_get_num_need_output (decoder) >
868 sps->max_num_reorder_pics[sps->max_sub_layers_minus1])
869 || (sps->max_latency_increase_plus1[sps->max_sub_layers_minus1]
870 && check_latency_cnt (decoder))
871 || (priv->dpb_count >=
872 (sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1] +
874 dpb_bump (decoder, picture);
882 dpb_reset (GstVaapiDecoderH265 * decoder, guint dpb_size)
884 GstVaapiDecoderH265Private *const priv = &decoder->priv;
886 if (dpb_size > priv->dpb_size_max) {
887 priv->dpb = g_try_realloc_n (priv->dpb, dpb_size, sizeof (*priv->dpb));
890 memset (&priv->dpb[priv->dpb_size_max], 0,
891 (dpb_size - priv->dpb_size_max) * sizeof (*priv->dpb));
892 priv->dpb_size_max = dpb_size;
894 priv->dpb_size = dpb_size;
895 GST_DEBUG ("DPB size %u", priv->dpb_size);
899 static GstVaapiDecoderStatus
900 get_status (GstH265ParserResult result)
902 GstVaapiDecoderStatus status;
905 case GST_H265_PARSER_OK:
906 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
908 case GST_H265_PARSER_NO_NAL_END:
909 status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
911 case GST_H265_PARSER_ERROR:
912 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
915 status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
922 gst_vaapi_decoder_h265_close (GstVaapiDecoderH265 * decoder)
924 GstVaapiDecoderH265Private *const priv = &decoder->priv;
926 gst_vaapi_picture_replace (&priv->current_picture, NULL);
927 gst_vaapi_parser_info_h265_replace (&priv->prev_slice_pi, NULL);
928 gst_vaapi_parser_info_h265_replace (&priv->prev_independent_slice_pi, NULL);
929 gst_vaapi_parser_info_h265_replace (&priv->prev_pi, NULL);
931 dpb_clear (decoder, TRUE);
934 gst_h265_parser_free (priv->parser);
940 gst_vaapi_decoder_h265_open (GstVaapiDecoderH265 * decoder)
942 GstVaapiDecoderH265Private *const priv = &decoder->priv;
944 gst_vaapi_decoder_h265_close (decoder);
945 priv->parser = gst_h265_parser_new ();
952 gst_vaapi_decoder_h265_destroy (GstVaapiDecoder * base_decoder)
954 GstVaapiDecoderH265 *const decoder =
955 GST_VAAPI_DECODER_H265_CAST (base_decoder);
956 GstVaapiDecoderH265Private *const priv = &decoder->priv;
959 gst_vaapi_decoder_h265_close (decoder);
963 for (i = 0; i < G_N_ELEMENTS (priv->pps); i++)
964 gst_vaapi_parser_info_h265_replace (&priv->pps[i], NULL);
965 gst_vaapi_parser_info_h265_replace (&priv->active_pps, NULL);
966 for (i = 0; i < G_N_ELEMENTS (priv->sps); i++)
967 gst_vaapi_parser_info_h265_replace (&priv->sps[i], NULL);
968 gst_vaapi_parser_info_h265_replace (&priv->active_sps, NULL);
969 for (i = 0; i < G_N_ELEMENTS (priv->vps); i++)
970 gst_vaapi_parser_info_h265_replace (&priv->vps[i], NULL);
971 gst_vaapi_parser_info_h265_replace (&priv->active_vps, NULL);
975 gst_vaapi_decoder_h265_create (GstVaapiDecoder * base_decoder)
977 GstVaapiDecoderH265 *const decoder =
978 GST_VAAPI_DECODER_H265_CAST (base_decoder);
979 GstVaapiDecoderH265Private *const priv = &decoder->priv;
981 priv->profile = GST_VAAPI_PROFILE_UNKNOWN;
982 priv->entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
983 priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
984 priv->progressive_sequence = TRUE;
985 priv->new_bitstream = TRUE;
986 priv->prev_nal_is_eos = FALSE;
992 fill_profiles (GstVaapiProfile profiles[16], guint * n_profiles_ptr,
993 GstVaapiProfile profile)
995 guint n_profiles = *n_profiles_ptr;
997 profiles[n_profiles++] = profile;
999 case GST_VAAPI_PROFILE_H265_MAIN:
1000 profiles[n_profiles++] = GST_VAAPI_PROFILE_H265_MAIN10;
1002 case GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE:
1003 profiles[n_profiles++] = GST_VAAPI_PROFILE_H265_MAIN;
1004 profiles[n_profiles++] = GST_VAAPI_PROFILE_H265_MAIN10;
1009 *n_profiles_ptr = n_profiles;
1012 static GstVaapiProfile
1013 get_profile (GstVaapiDecoderH265 * decoder, GstH265SPS * sps, guint dpb_size)
1015 GstVaapiDecoderH265Private *const priv = &decoder->priv;
1016 GstVaapiDisplay *const display = GST_VAAPI_DECODER_DISPLAY (decoder);
1017 GstVaapiProfile profile, profiles[3];
1018 guint i, n_profiles = 0;
1021 gst_vaapi_utils_h265_get_profile (sps->profile_tier_level.profile_idc);
1023 return GST_VAAPI_PROFILE_UNKNOWN;
1024 fill_profiles (profiles, &n_profiles, profile);
1026 case GST_VAAPI_PROFILE_H265_MAIN10:
1027 if (sps->profile_tier_level.profile_compatibility_flag[1]) { // A.2.3.2 (main profile)
1028 fill_profiles (profiles, &n_profiles, GST_VAAPI_PROFILE_H265_MAIN);
1035 /* If the preferred profile (profiles[0]) matches one that we already
1036 found, then just return it now instead of searching for it again */
1037 if (profiles[0] == priv->profile)
1038 return priv->profile;
1039 for (i = 0; i < n_profiles; i++) {
1040 if (gst_vaapi_display_has_decoder (display, profiles[i], priv->entrypoint))
1043 return GST_VAAPI_PROFILE_UNKNOWN;
1046 static GstVaapiDecoderStatus
1047 ensure_context (GstVaapiDecoderH265 * decoder, GstH265SPS * sps)
1049 GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER_CAST (decoder);
1050 GstVaapiDecoderH265Private *const priv = &decoder->priv;
1051 GstVaapiContextInfo info;
1052 GstVaapiProfile profile;
1053 GstVaapiChromaType chroma_type;
1054 gboolean reset_context = FALSE;
1057 dpb_size = get_max_dec_frame_buffering (sps);
1058 if (priv->dpb_size < dpb_size) {
1059 GST_DEBUG ("DPB size increased");
1060 reset_context = TRUE;
1063 profile = get_profile (decoder, sps, dpb_size);
1065 GST_ERROR ("unsupported profile_idc %u",
1066 sps->profile_tier_level.profile_idc);
1067 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1070 if (!priv->profile || (priv->profile != profile)) {
1071 GST_DEBUG ("profile changed");
1072 reset_context = TRUE;
1073 priv->profile = profile;
1076 chroma_type = gst_vaapi_utils_h265_get_chroma_type (sps->chroma_format_idc);
1078 GST_ERROR ("unsupported chroma_format_idc %u", sps->chroma_format_idc);
1079 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
1082 if (priv->chroma_type != chroma_type) {
1083 GST_DEBUG ("chroma format changed");
1084 reset_context = TRUE;
1085 priv->chroma_type = chroma_type;
1088 if (priv->pic_width_in_luma_samples != sps->pic_width_in_luma_samples ||
1089 priv->pic_height_in_luma_samples != sps->pic_height_in_luma_samples) {
1090 GST_DEBUG ("size changed");
1091 reset_context = TRUE;
1092 priv->pic_width_in_luma_samples = sps->pic_width_in_luma_samples;
1093 priv->pic_height_in_luma_samples = sps->pic_height_in_luma_samples;
1096 priv->progressive_sequence = 1; /*Fixme */
1097 gst_vaapi_decoder_set_interlaced (base_decoder, !priv->progressive_sequence);
1098 gst_vaapi_decoder_set_pixel_aspect_ratio (base_decoder,
1099 sps->vui_params.par_n, sps->vui_params.par_d);
1100 if (!reset_context && priv->has_context)
1101 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1103 /* XXX: fix surface size when cropping is implemented */
1104 info.profile = priv->profile;
1105 info.entrypoint = priv->entrypoint;
1106 info.chroma_type = priv->chroma_type;
1107 info.width = sps->width;
1108 info.height = sps->height;
1109 info.ref_frames = dpb_size;
1111 if (!gst_vaapi_decoder_ensure_context (GST_VAAPI_DECODER (decoder), &info))
1112 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
1113 priv->has_context = TRUE;
1116 if (!dpb_reset (decoder, dpb_size))
1117 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
1119 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1123 fill_iq_matrix_4x4 (VAIQMatrixBufferHEVC * iq_matrix,
1124 GstH265ScalingList * scaling_list)
1128 g_assert (G_N_ELEMENTS (iq_matrix->ScalingList4x4) == 6);
1129 g_assert (G_N_ELEMENTS (iq_matrix->ScalingList4x4[0]) == 16);
1130 for (i = 0; i < G_N_ELEMENTS (iq_matrix->ScalingList4x4); i++) {
1131 gst_h265_quant_matrix_4x4_get_raster_from_zigzag (iq_matrix->ScalingList4x4
1132 [i], scaling_list->scaling_lists_4x4[i]);
1137 fill_iq_matrix_8x8 (VAIQMatrixBufferHEVC * iq_matrix,
1138 GstH265ScalingList * scaling_list)
1142 g_assert (G_N_ELEMENTS (iq_matrix->ScalingList8x8) == 6);
1143 g_assert (G_N_ELEMENTS (iq_matrix->ScalingList8x8[0]) == 64);
1144 for (i = 0; i < G_N_ELEMENTS (iq_matrix->ScalingList8x8); i++) {
1145 gst_h265_quant_matrix_8x8_get_raster_from_zigzag (iq_matrix->ScalingList8x8
1146 [i], scaling_list->scaling_lists_8x8[i]);
1151 fill_iq_matrix_16x16 (VAIQMatrixBufferHEVC * iq_matrix,
1152 GstH265ScalingList * scaling_list)
1156 g_assert (G_N_ELEMENTS (iq_matrix->ScalingList16x16) == 6);
1157 g_assert (G_N_ELEMENTS (iq_matrix->ScalingList16x16[0]) == 64);
1158 for (i = 0; i < G_N_ELEMENTS (iq_matrix->ScalingList16x16); i++) {
1159 gst_h265_quant_matrix_16x16_get_raster_from_zigzag
1160 (iq_matrix->ScalingList16x16[i], scaling_list->scaling_lists_16x16[i]);
1165 fill_iq_matrix_32x32 (VAIQMatrixBufferHEVC * iq_matrix,
1166 GstH265ScalingList * scaling_list)
1170 g_assert (G_N_ELEMENTS (iq_matrix->ScalingList32x32) == 2);
1171 g_assert (G_N_ELEMENTS (iq_matrix->ScalingList32x32[0]) == 64);
1172 for (i = 0; i < G_N_ELEMENTS (iq_matrix->ScalingList32x32); i++) {
1173 gst_h265_quant_matrix_32x32_get_raster_from_zigzag
1174 (iq_matrix->ScalingList32x32[i], scaling_list->scaling_lists_32x32[i]);
1179 fill_iq_matrix_dc_16x16 (VAIQMatrixBufferHEVC * iq_matrix,
1180 GstH265ScalingList * scaling_list)
1184 for (i = 0; i < 6; i++)
1185 iq_matrix->ScalingListDC16x16[i] =
1186 scaling_list->scaling_list_dc_coef_minus8_16x16[i] + 8;
1190 fill_iq_matrix_dc_32x32 (VAIQMatrixBufferHEVC * iq_matrix,
1191 GstH265ScalingList * scaling_list)
1195 for (i = 0; i < 2; i++)
1196 iq_matrix->ScalingListDC32x32[i] =
1197 scaling_list->scaling_list_dc_coef_minus8_32x32[i] + 8;
1200 static GstVaapiDecoderStatus
1201 ensure_quant_matrix (GstVaapiDecoderH265 * decoder,
1202 GstVaapiPictureH265 * picture)
1204 GstVaapiPicture *const base_picture = &picture->base;
1205 GstH265PPS *const pps = get_pps (decoder);
1206 GstH265SPS *const sps = get_sps (decoder);
1207 GstH265ScalingList *scaling_list = NULL;
1208 VAIQMatrixBufferHEVC *iq_matrix;
1211 (pps->scaling_list_data_present_flag ||
1212 (sps->scaling_list_enabled_flag
1213 && !sps->scaling_list_data_present_flag)))
1214 scaling_list = &pps->scaling_list;
1215 else if (sps && sps->scaling_list_enabled_flag
1216 && sps->scaling_list_data_present_flag)
1217 scaling_list = &sps->scaling_list;
1219 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1221 base_picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW (HEVC, decoder);
1222 if (!base_picture->iq_matrix) {
1223 GST_ERROR ("failed to allocate IQ matrix");
1224 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
1226 iq_matrix = base_picture->iq_matrix->param;
1228 /* Only supporting 4:2:0 */
1229 if (sps->chroma_format_idc != 1)
1230 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
1232 fill_iq_matrix_4x4 (iq_matrix, scaling_list);
1233 fill_iq_matrix_8x8 (iq_matrix, scaling_list);
1234 fill_iq_matrix_16x16 (iq_matrix, scaling_list);
1235 fill_iq_matrix_32x32 (iq_matrix, scaling_list);
1236 fill_iq_matrix_dc_16x16 (iq_matrix, scaling_list);
1237 fill_iq_matrix_dc_32x32 (iq_matrix, scaling_list);
1239 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1242 static inline gboolean
1243 is_valid_state (guint state, guint ref_state)
1245 return (state & ref_state) == ref_state;
1248 static GstVaapiDecoderStatus
1249 decode_current_picture (GstVaapiDecoderH265 * decoder)
1251 GstVaapiDecoderH265Private *const priv = &decoder->priv;
1252 GstVaapiPictureH265 *const picture = priv->current_picture;
1254 if (!is_valid_state (priv->decoder_state, GST_H265_VIDEO_STATE_VALID_PICTURE)) {
1258 priv->decoder_state = 0;
1259 /*Fixme: Use SEI header values */
1260 priv->pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
1263 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1265 if (!gst_vaapi_picture_decode (GST_VAAPI_PICTURE_CAST (picture)))
1268 if (!dpb_add (decoder, picture))
1271 gst_vaapi_picture_replace (&priv->current_picture, NULL);
1272 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1275 gst_vaapi_picture_replace (&priv->current_picture, NULL);
1276 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
1278 priv->decoder_state = 0;
1279 priv->pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
1280 return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME;
1283 static GstVaapiDecoderStatus
1284 parse_vps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
1286 GstVaapiDecoderH265Private *const priv = &decoder->priv;
1287 GstVaapiParserInfoH265 *const pi = unit->parsed_info;
1288 GstH265VPS *const vps = &pi->data.vps;
1289 GstH265ParserResult result;
1291 GST_DEBUG ("parse VPS");
1292 priv->parser_state = 0;
1294 memset (vps, 0, sizeof (GstH265VPS));
1296 result = gst_h265_parser_parse_vps (priv->parser, &pi->nalu, vps);
1297 if (result != GST_H265_PARSER_OK)
1298 return get_status (result);
1300 priv->parser_state |= GST_H265_VIDEO_STATE_GOT_VPS;
1301 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1304 static GstVaapiDecoderStatus
1305 parse_sps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
1307 GstVaapiDecoderH265Private *const priv = &decoder->priv;
1308 GstVaapiParserInfoH265 *const pi = unit->parsed_info;
1309 GstH265SPS *const sps = &pi->data.sps;
1310 GstH265ParserResult result;
1312 GST_DEBUG ("parse SPS");
1313 priv->parser_state = 0;
1315 memset (sps, 0, sizeof (GstH265SPS));
1317 result = gst_h265_parser_parse_sps (priv->parser, &pi->nalu, sps, TRUE);
1318 if (result != GST_H265_PARSER_OK)
1319 return get_status (result);
1321 priv->parser_state |= GST_H265_VIDEO_STATE_GOT_SPS;
1322 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1326 get_pic_width_height_in_ctbs (GstH265PPS * pps,
1327 guint * PicWidthInCtbsY, guint * PicHeightInCtbsY)
1329 gint MinCbLog2SizeY, CtbLog2SizeY, MinCbSizeY, CtbSizeY;
1330 GstH265SPS *sps = pps->sps;
1332 MinCbLog2SizeY = sps->log2_min_luma_coding_block_size_minus3 + 3;
1333 CtbLog2SizeY = MinCbLog2SizeY + sps->log2_diff_max_min_luma_coding_block_size;
1334 MinCbSizeY = 1 << MinCbLog2SizeY;
1335 CtbSizeY = 1 << CtbLog2SizeY;
1338 ceil ((double) sps->pic_width_in_luma_samples / (double) CtbSizeY);
1340 ceil ((double) sps->pic_height_in_luma_samples / (double) CtbSizeY);
1343 static GstVaapiDecoderStatus
1344 parse_pps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
1346 GstVaapiDecoderH265Private *const priv = &decoder->priv;
1347 GstVaapiParserInfoH265 *const pi = unit->parsed_info;
1348 GstH265PPS *const pps = &pi->data.pps;
1349 GstH265ParserResult result;
1350 guint col_width[19], row_height[21];
1352 GST_DEBUG ("parse PPS");
1353 priv->parser_state &= GST_H265_VIDEO_STATE_GOT_SPS;
1355 memset (col_width, 0, sizeof (col_width));
1356 memset (row_height, 0, sizeof (row_height));
1358 memset (pps, 0, sizeof (GstH265PPS));
1360 result = gst_h265_parser_parse_pps (priv->parser, &pi->nalu, pps);
1361 if (result != GST_H265_PARSER_OK)
1362 return get_status (result);
1364 if (pps->tiles_enabled_flag) {
1366 guint PicWidthInCtbsY, PicHeightInCtbsY;
1368 get_pic_width_height_in_ctbs (pps, &PicWidthInCtbsY, &PicHeightInCtbsY);
1369 GST_DEBUG ("PicWidthInCtbsY %d PicHeightInCtbsY %d", PicWidthInCtbsY,
1372 /* Tile Scanning Conversion 6-3 and 6-4 */
1373 if (pps->uniform_spacing_flag) {
1375 for (i = 0; i <= pps->num_tile_columns_minus1; i++)
1377 ((i + 1) * PicWidthInCtbsY) / (pps->num_tile_columns_minus1 + 1) -
1378 (i * PicWidthInCtbsY) / (pps->num_tile_columns_minus1 + 1);
1380 for (i = 0; i <= pps->num_tile_rows_minus1; i++)
1382 ((i + 1) * PicHeightInCtbsY) / (pps->num_tile_rows_minus1 + 1) -
1383 (i * PicHeightInCtbsY) / (pps->num_tile_rows_minus1 + 1);
1387 col_width[pps->num_tile_columns_minus1] = PicWidthInCtbsY;
1388 for (i = 0; i < pps->num_tile_columns_minus1; i++) {
1389 col_width[i] = pps->column_width_minus1[i] + 1;
1390 col_width[pps->num_tile_columns_minus1] -= col_width[i];
1393 row_height[pps->num_tile_rows_minus1] = PicHeightInCtbsY;
1394 for (i = 0; i < pps->num_tile_rows_minus1; i++) {
1395 row_height[i] = pps->row_height_minus1[i] + 1;
1396 row_height[pps->num_tile_rows_minus1] -= row_height[i];
1399 for (i = 0; i <= pps->num_tile_columns_minus1; i++)
1400 pps->column_width_minus1[i] = col_width[i] - 1;
1401 for (i = 0; i <= pps->num_tile_rows_minus1; i++)
1402 pps->row_height_minus1[i] = row_height[i] - 1;
1405 priv->parser_state |= GST_H265_VIDEO_STATE_GOT_PPS;
1406 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1409 static GstVaapiDecoderStatus
1410 parse_sei (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
1412 GST_FIXME ("Parse SEI, Not implemented !");
1414 GstVaapiDecoderH265Private *const priv = &decoder->priv;
1415 GstVaapiParserInfoH265 *const pi = unit->parsed_info;
1416 GstH265SEIMessage *sei = &pi->data.sei;
1417 GstH265ParserResult result;
1418 GST_DEBUG ("parse SEI");
1419 result = gst_h265_parser_parse_sei (priv->parser, &pi->nalu, sei);
1420 if (result != GST_H265_PARSER_OK) {
1421 GST_WARNING ("failed to parse SEI messages");
1422 return get_status (result);
1425 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1428 static GstVaapiDecoderStatus
1429 parse_slice (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
1431 GstVaapiDecoderH265Private *const priv = &decoder->priv;
1432 GstVaapiParserInfoH265 *const pi = unit->parsed_info;
1433 GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr;
1434 GstH265ParserResult result;
1436 GST_DEBUG ("parse slice");
1437 priv->parser_state &= (GST_H265_VIDEO_STATE_GOT_SPS |
1438 GST_H265_VIDEO_STATE_GOT_PPS);
1440 slice_hdr->short_term_ref_pic_set_idx = 0;
1442 memset (slice_hdr, 0, sizeof (GstH265SliceHdr));
1444 result = gst_h265_parser_parse_slice_hdr (priv->parser, &pi->nalu, slice_hdr);
1445 if (result != GST_H265_PARSER_OK)
1446 return get_status (result);
1448 priv->parser_state |= GST_H265_VIDEO_STATE_GOT_SLICE;
1449 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1452 static GstVaapiDecoderStatus
1453 decode_vps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
1455 GstVaapiDecoderH265Private *const priv = &decoder->priv;
1456 GstVaapiParserInfoH265 *const pi = unit->parsed_info;
1457 GstH265VPS *const vps = &pi->data.vps;
1459 GST_DEBUG ("decode VPS");
1461 gst_vaapi_parser_info_h265_replace (&priv->vps[vps->id], pi);
1463 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1466 static GstVaapiDecoderStatus
1467 decode_sps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
1469 GstVaapiDecoderH265Private *const priv = &decoder->priv;
1470 GstVaapiParserInfoH265 *const pi = unit->parsed_info;
1471 GstH265SPS *const sps = &pi->data.sps;
1473 GST_DEBUG ("decode SPS");
1475 if (sps->max_latency_increase_plus1[sps->max_sub_layers_minus1])
1476 priv->SpsMaxLatencyPictures =
1477 sps->max_num_reorder_pics[sps->max_sub_layers_minus1] +
1478 sps->max_latency_increase_plus1[sps->max_sub_layers_minus1] - 1;
1480 gst_vaapi_parser_info_h265_replace (&priv->sps[sps->id], pi);
1482 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1485 static GstVaapiDecoderStatus
1486 decode_pps (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
1488 GstVaapiDecoderH265Private *const priv = &decoder->priv;
1489 GstVaapiParserInfoH265 *const pi = unit->parsed_info;
1490 GstH265PPS *const pps = &pi->data.pps;
1492 GST_DEBUG ("decode PPS");
1494 gst_vaapi_parser_info_h265_replace (&priv->pps[pps->id], pi);
1496 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1499 static GstVaapiDecoderStatus
1500 decode_sei (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
1502 GST_FIXME ("Decode SEI, Not implemented!");
1504 GstVaapiDecoderH265Private *const priv = &decoder->priv;
1505 GstVaapiParserInfoH265 *const pi = unit->parsed_info;
1506 GstH265SEIMessage *sei = &pi->data.sei;
1508 GST_DEBUG ("decode SEI messages");
1509 switch (sei->payloadType) {
1510 case GST_H265_SEI_PIC_TIMING:{
1511 GstH265PicTiming *pic_timing = &sei->payload.pic_timing;
1512 /* Fix: only if vps->frame_field_info_present_flag */
1513 priv->pic_structure = pic_timing->pic_struct;
1520 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1523 static GstVaapiDecoderStatus
1524 decode_sequence_end (GstVaapiDecoderH265 * decoder)
1526 GstVaapiDecoderStatus status;
1528 GST_DEBUG ("decode sequence-end");
1530 status = decode_current_picture (decoder);
1531 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1534 dpb_flush (decoder);
1535 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1538 /* 8.3.1 - Decoding process for picture order count */
1540 init_picture_poc (GstVaapiDecoderH265 * decoder,
1541 GstVaapiPictureH265 * picture, GstVaapiParserInfoH265 * pi)
1543 GstVaapiDecoderH265Private *const priv = &decoder->priv;
1544 GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr;
1545 GstH265SPS *const sps = get_sps (decoder);
1546 const gint32 MaxPicOrderCntLsb =
1547 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1548 guint8 nal_type = pi->nalu.type;
1549 guint8 temporal_id = pi->nalu.temporal_id_plus1 - 1;
1551 GST_DEBUG ("decode PicOrderCntVal");
1553 priv->prev_poc_lsb = priv->poc_lsb;
1554 priv->prev_poc_msb = priv->poc_msb;
1556 if (!(nal_is_irap (nal_type) && picture->NoRaslOutputFlag)) {
1557 priv->prev_poc_lsb = priv->prev_tid0pic_poc_lsb;
1558 priv->prev_poc_msb = priv->prev_tid0pic_poc_msb;
1561 /* Finding PicOrderCntMsb */
1562 if (nal_is_irap (nal_type) && picture->NoRaslOutputFlag)
1566 if ((slice_hdr->pic_order_cnt_lsb < priv->prev_poc_lsb) &&
1567 ((priv->prev_poc_lsb - slice_hdr->pic_order_cnt_lsb) >=
1568 (MaxPicOrderCntLsb / 2)))
1569 priv->poc_msb = priv->prev_poc_msb + MaxPicOrderCntLsb;
1571 else if ((slice_hdr->pic_order_cnt_lsb > priv->prev_poc_lsb) &&
1572 ((slice_hdr->pic_order_cnt_lsb - priv->prev_poc_lsb) >
1573 (MaxPicOrderCntLsb / 2)))
1574 priv->poc_msb = priv->prev_poc_msb - MaxPicOrderCntLsb;
1577 priv->poc_msb = priv->prev_poc_msb;
1581 priv->poc = picture->poc = priv->poc_msb + slice_hdr->pic_order_cnt_lsb;
1582 priv->poc_lsb = picture->poc_lsb = slice_hdr->pic_order_cnt_lsb;
1584 if (nal_is_idr (nal_type)) {
1586 picture->poc_lsb = 0;
1589 priv->prev_poc_lsb = 0;
1590 priv->prev_poc_msb = 0;
1591 priv->prev_tid0pic_poc_lsb = 0;
1592 priv->prev_tid0pic_poc_msb = 0;
1595 picture->base.poc = picture->poc;
1596 GST_DEBUG ("PicOrderCntVal %d", picture->base.poc);
1598 if (!temporal_id && !nal_is_rasl (nal_type) &&
1599 !nal_is_radl (nal_type) && nal_is_ref (nal_type)) {
1600 priv->prev_tid0pic_poc_lsb = slice_hdr->pic_order_cnt_lsb;
1601 priv->prev_tid0pic_poc_msb = priv->poc_msb;
1606 init_picture_refs (GstVaapiDecoderH265 * decoder,
1607 GstVaapiPictureH265 * picture, GstH265SliceHdr * slice_hdr)
1609 GstVaapiDecoderH265Private *const priv = &decoder->priv;
1610 guint32 NumRpsCurrTempList0 = 0, NumRpsCurrTempList1 = 0;
1611 GstVaapiPictureH265 *RefPicListTemp0[16] = { NULL, }, *RefPicListTemp1[16] = {
1614 guint num_ref_idx_l0_active_minus1 = 0;
1615 guint num_ref_idx_l1_active_minus1 = 0;
1616 GstH265RefPicListModification *ref_pic_list_modification;
1619 memset (priv->RefPicList0, 0, sizeof (GstVaapiPictureH265 *) * 16);
1620 memset (priv->RefPicList1, 0, sizeof (GstVaapiPictureH265 *) * 16);
1621 priv->RefPicList0_count = priv->RefPicList1_count = 0;
1623 if (slice_hdr->dependent_slice_segment_flag) {
1624 GstH265SliceHdr *tmp = &priv->prev_independent_slice_pi->data.slice_hdr;
1625 num_ref_idx_l0_active_minus1 = tmp->num_ref_idx_l0_active_minus1;
1626 num_ref_idx_l1_active_minus1 = tmp->num_ref_idx_l1_active_minus1;
1627 ref_pic_list_modification = &tmp->ref_pic_list_modification;
1630 num_ref_idx_l0_active_minus1 = slice_hdr->num_ref_idx_l0_active_minus1;
1631 num_ref_idx_l1_active_minus1 = slice_hdr->num_ref_idx_l1_active_minus1;
1632 ref_pic_list_modification = &slice_hdr->ref_pic_list_modification;
1633 type = slice_hdr->type;
1636 /* decoding process for reference picture list construction needs to be
1637 * invoked only for P and B slice */
1638 if (type == GST_H265_I_SLICE)
1641 NumRpsCurrTempList0 =
1642 MAX ((num_ref_idx_l0_active_minus1 + 1), priv->NumPocTotalCurr);
1643 NumRpsCurrTempList1 =
1644 MAX ((num_ref_idx_l1_active_minus1 + 1), priv->NumPocTotalCurr);
1647 while (rIdx < NumRpsCurrTempList0) {
1648 for (i = 0; i < priv->NumPocStCurrBefore && rIdx < NumRpsCurrTempList0;
1650 RefPicListTemp0[rIdx] = priv->RefPicSetStCurrBefore[i];
1651 for (i = 0; i < priv->NumPocStCurrAfter && rIdx < NumRpsCurrTempList0;
1653 RefPicListTemp0[rIdx] = priv->RefPicSetStCurrAfter[i];
1654 for (i = 0; i < priv->NumPocLtCurr && rIdx < NumRpsCurrTempList0;
1656 RefPicListTemp0[rIdx] = priv->RefPicSetLtCurr[i];
1659 /* construct RefPicList0 (8-9) */
1660 for (rIdx = 0; rIdx <= num_ref_idx_l0_active_minus1; rIdx++)
1661 priv->RefPicList0[rIdx] =
1662 ref_pic_list_modification->ref_pic_list_modification_flag_l0 ?
1663 RefPicListTemp0[ref_pic_list_modification->list_entry_l0[rIdx]] :
1664 RefPicListTemp0[rIdx];
1665 priv->RefPicList0_count = rIdx;
1667 if (type == GST_H265_B_SLICE) {
1671 while (rIdx < NumRpsCurrTempList1) {
1672 for (i = 0; i < priv->NumPocStCurrAfter && rIdx < NumRpsCurrTempList1;
1674 RefPicListTemp1[rIdx] = priv->RefPicSetStCurrAfter[i];
1675 for (i = 0; i < priv->NumPocStCurrBefore && rIdx < NumRpsCurrTempList1;
1677 RefPicListTemp1[rIdx] = priv->RefPicSetStCurrBefore[i];
1678 for (i = 0; i < priv->NumPocLtCurr && rIdx < NumRpsCurrTempList1;
1680 RefPicListTemp1[rIdx] = priv->RefPicSetLtCurr[i];
1683 /* construct RefPicList1 (8-10) */
1684 for (rIdx = 0; rIdx <= num_ref_idx_l1_active_minus1; rIdx++)
1685 priv->RefPicList1[rIdx] =
1686 ref_pic_list_modification->ref_pic_list_modification_flag_l1 ?
1687 RefPicListTemp1[ref_pic_list_modification->list_entry_l1
1688 [rIdx]] : RefPicListTemp1[rIdx];
1689 priv->RefPicList1_count = rIdx;
1694 init_picture (GstVaapiDecoderH265 * decoder,
1695 GstVaapiPictureH265 * picture, GstVaapiParserInfoH265 * pi)
1697 GstVaapiDecoderH265Private *const priv = &decoder->priv;
1698 GstVaapiPicture *const base_picture = &picture->base;
1699 GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr;
1701 base_picture->pts = GST_VAAPI_DECODER_CODEC_FRAME (decoder)->pts;
1702 base_picture->type = GST_VAAPI_PICTURE_TYPE_NONE;
1704 if (nal_is_idr (pi->nalu.type)) {
1705 GST_DEBUG ("<IDR>");
1706 GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_IDR);
1709 if (pi->nalu.type >= GST_H265_NAL_SLICE_BLA_W_LP &&
1710 pi->nalu.type <= GST_H265_NAL_SLICE_CRA_NUT)
1711 picture->RapPicFlag = TRUE;
1713 /*Fixme: Use SEI header values */
1714 base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
1715 picture->structure = base_picture->structure;
1717 /*NoRaslOutputFlag ==1 if the current picture is
1720 3) a CRA picture that is the first access unit in the bitstream
1721 4) first picture that follows an end of sequence NAL unit in decoding order
1722 5) has HandleCraAsBlaFlag == 1 (set by external means, so not considering )
1724 if (nal_is_idr (pi->nalu.type) || nal_is_bla (pi->nalu.type) ||
1725 (nal_is_cra (pi->nalu.type) && priv->new_bitstream)
1726 || priv->prev_nal_is_eos) {
1727 picture->NoRaslOutputFlag = 1;
1730 if (nal_is_irap (pi->nalu.type)) {
1731 picture->IntraPicFlag = TRUE;
1732 priv->associated_irap_NoRaslOutputFlag = picture->NoRaslOutputFlag;
1735 if (nal_is_rasl (pi->nalu.type) && priv->associated_irap_NoRaslOutputFlag)
1736 picture->output_flag = FALSE;
1738 picture->output_flag = slice_hdr->pic_output_flag;
1740 init_picture_poc (decoder, picture, pi);
1746 vaapi_init_picture (VAPictureHEVC * pic)
1748 pic->picture_id = VA_INVALID_SURFACE;
1749 pic->pic_order_cnt = 0;
1750 pic->flags = VA_PICTURE_HEVC_INVALID;
1754 vaapi_fill_picture (VAPictureHEVC * pic, GstVaapiPictureH265 * picture,
1755 guint picture_structure)
1758 if (!picture_structure)
1759 picture_structure = picture->structure;
1761 pic->picture_id = picture->base.surface_id;
1762 pic->pic_order_cnt = picture->poc;
1765 /* Set the VAPictureHEVC flags */
1766 if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE (picture))
1767 pic->flags |= VA_PICTURE_HEVC_LONG_TERM_REFERENCE;
1769 if (GST_VAAPI_PICTURE_FLAG_IS_SET (picture,
1770 GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_BEFORE))
1771 pic->flags |= VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE;
1773 else if (GST_VAAPI_PICTURE_FLAG_IS_SET (picture,
1774 GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_AFTER))
1775 pic->flags |= VA_PICTURE_HEVC_RPS_ST_CURR_AFTER;
1777 else if (GST_VAAPI_PICTURE_FLAG_IS_SET (picture,
1778 GST_VAAPI_PICTURE_FLAG_RPS_LT_CURR))
1779 pic->flags |= VA_PICTURE_HEVC_RPS_LT_CURR;
1781 switch (picture_structure) {
1782 case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
1784 case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
1785 pic->flags |= VA_PICTURE_HEVC_FIELD_PIC;
1787 case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
1788 pic->flags |= VA_PICTURE_HEVC_FIELD_PIC;
1789 pic->flags |= VA_PICTURE_HEVC_BOTTOM_FIELD;
1797 get_index_for_RefPicListX (VAPictureHEVC * ReferenceFrames,
1798 GstVaapiPictureH265 * pic)
1802 for (i = 0; i < 15; i++) {
1803 if ((ReferenceFrames[i].picture_id != VA_INVALID_ID) && pic) {
1804 if ((ReferenceFrames[i].pic_order_cnt == pic->poc) &&
1805 (ReferenceFrames[i].picture_id == pic->base.surface_id)) {
1814 fill_picture (GstVaapiDecoderH265 * decoder, GstVaapiPictureH265 * picture)
1816 GstVaapiDecoderH265Private *const priv = &decoder->priv;
1817 GstVaapiPicture *const base_picture = &picture->base;
1818 GstH265PPS *const pps = get_pps (decoder);
1819 GstH265SPS *const sps = get_sps (decoder);
1820 VAPictureParameterBufferHEVC *const pic_param = base_picture->param;
1823 pic_param->pic_fields.value = 0;
1824 pic_param->slice_parsing_fields.value = 0;
1826 /* Fill in VAPictureHEVC */
1827 vaapi_fill_picture (&pic_param->CurrPic, picture, 0);
1828 /* Fill in ReferenceFrames */
1829 for (i = 0, n = 0; i < priv->dpb_count; i++) {
1830 GstVaapiFrameStore *const fs = priv->dpb[i];
1831 if ((gst_vaapi_frame_store_has_reference (fs)))
1832 vaapi_fill_picture (&pic_param->ReferenceFrames[n++], fs->buffer,
1833 fs->buffer->structure);
1834 if (n >= G_N_ELEMENTS (pic_param->ReferenceFrames))
1837 for (; n < G_N_ELEMENTS (pic_param->ReferenceFrames); n++)
1838 vaapi_init_picture (&pic_param->ReferenceFrames[n]);
1841 #define COPY_FIELD(s, f) \
1842 pic_param->f = (s)->f
1843 #define COPY_BFM(a, s, f) \
1844 pic_param->a.bits.f = (s)->f
1846 COPY_FIELD (sps, pic_width_in_luma_samples);
1847 COPY_FIELD (sps, pic_height_in_luma_samples);
1848 COPY_BFM (pic_fields, sps, chroma_format_idc);
1849 COPY_BFM (pic_fields, sps, separate_colour_plane_flag);
1850 COPY_BFM (pic_fields, sps, pcm_enabled_flag);
1851 COPY_BFM (pic_fields, sps, scaling_list_enabled_flag);
1852 COPY_BFM (pic_fields, pps, transform_skip_enabled_flag);
1853 COPY_BFM (pic_fields, sps, amp_enabled_flag);
1854 COPY_BFM (pic_fields, sps, strong_intra_smoothing_enabled_flag);
1855 COPY_BFM (pic_fields, pps, sign_data_hiding_enabled_flag);
1856 COPY_BFM (pic_fields, pps, constrained_intra_pred_flag);
1857 COPY_BFM (pic_fields, pps, cu_qp_delta_enabled_flag);
1858 COPY_BFM (pic_fields, pps, weighted_pred_flag);
1859 COPY_BFM (pic_fields, pps, weighted_bipred_flag);
1860 COPY_BFM (pic_fields, pps, transquant_bypass_enabled_flag);
1861 COPY_BFM (pic_fields, pps, tiles_enabled_flag);
1862 COPY_BFM (pic_fields, pps, entropy_coding_sync_enabled_flag);
1863 pic_param->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag =
1864 pps->loop_filter_across_slices_enabled_flag;
1865 COPY_BFM (pic_fields, pps, loop_filter_across_tiles_enabled_flag);
1866 COPY_BFM (pic_fields, sps, pcm_loop_filter_disabled_flag);
1867 /* Fix: Assign value based on sps_max_num_reorder_pics */
1868 pic_param->pic_fields.bits.NoPicReorderingFlag = 0;
1869 /* Fix: Enable if picture has no B slices */
1870 pic_param->pic_fields.bits.NoBiPredFlag = 0;
1872 pic_param->sps_max_dec_pic_buffering_minus1 =
1873 sps->max_dec_pic_buffering_minus1[0];
1874 COPY_FIELD (sps, bit_depth_luma_minus8);
1875 COPY_FIELD (sps, bit_depth_chroma_minus8);
1876 COPY_FIELD (sps, pcm_sample_bit_depth_luma_minus1);
1877 COPY_FIELD (sps, pcm_sample_bit_depth_chroma_minus1);
1878 COPY_FIELD (sps, log2_min_luma_coding_block_size_minus3);
1879 COPY_FIELD (sps, log2_diff_max_min_luma_coding_block_size);
1880 COPY_FIELD (sps, log2_min_transform_block_size_minus2);
1881 COPY_FIELD (sps, log2_diff_max_min_transform_block_size);
1882 COPY_FIELD (sps, log2_min_pcm_luma_coding_block_size_minus3);
1883 COPY_FIELD (sps, log2_diff_max_min_pcm_luma_coding_block_size);
1884 COPY_FIELD (sps, max_transform_hierarchy_depth_intra);
1885 COPY_FIELD (sps, max_transform_hierarchy_depth_inter);
1886 COPY_FIELD (pps, init_qp_minus26);
1887 COPY_FIELD (pps, diff_cu_qp_delta_depth);
1888 pic_param->pps_cb_qp_offset = pps->cb_qp_offset;
1889 pic_param->pps_cr_qp_offset = pps->cr_qp_offset;
1890 COPY_FIELD (pps, log2_parallel_merge_level_minus2);
1891 COPY_FIELD (pps, num_tile_columns_minus1);
1892 COPY_FIELD (pps, num_tile_rows_minus1);
1893 for (i = 0; i <= pps->num_tile_columns_minus1; i++)
1894 pic_param->column_width_minus1[i] = pps->column_width_minus1[i];
1896 pic_param->column_width_minus1[i] = 0;
1897 for (i = 0; i <= pps->num_tile_rows_minus1; i++)
1898 pic_param->row_height_minus1[i] = pps->row_height_minus1[i];
1900 pic_param->row_height_minus1[i] = 0;
1902 COPY_BFM (slice_parsing_fields, pps, lists_modification_present_flag);
1903 COPY_BFM (slice_parsing_fields, sps, long_term_ref_pics_present_flag);
1904 pic_param->slice_parsing_fields.bits.sps_temporal_mvp_enabled_flag =
1905 sps->temporal_mvp_enabled_flag;
1906 COPY_BFM (slice_parsing_fields, pps, cabac_init_present_flag);
1907 COPY_BFM (slice_parsing_fields, pps, output_flag_present_flag);
1908 COPY_BFM (slice_parsing_fields, pps, dependent_slice_segments_enabled_flag);
1909 pic_param->slice_parsing_fields.
1910 bits.pps_slice_chroma_qp_offsets_present_flag =
1911 pps->slice_chroma_qp_offsets_present_flag;
1912 COPY_BFM (slice_parsing_fields, sps, sample_adaptive_offset_enabled_flag);
1913 COPY_BFM (slice_parsing_fields, pps, deblocking_filter_override_enabled_flag);
1914 pic_param->slice_parsing_fields.bits.pps_disable_deblocking_filter_flag =
1915 pps->deblocking_filter_disabled_flag;
1916 COPY_BFM (slice_parsing_fields, pps,
1917 slice_segment_header_extension_present_flag);
1918 pic_param->slice_parsing_fields.bits.RapPicFlag = picture->RapPicFlag;
1919 pic_param->slice_parsing_fields.bits.IdrPicFlag =
1920 GST_VAAPI_PICTURE_FLAG_IS_SET (picture, GST_VAAPI_PICTURE_FLAG_IDR);
1921 pic_param->slice_parsing_fields.bits.IntraPicFlag = picture->IntraPicFlag;
1923 COPY_FIELD (sps, log2_max_pic_order_cnt_lsb_minus4);
1924 COPY_FIELD (sps, num_short_term_ref_pic_sets);
1925 pic_param->num_long_term_ref_pic_sps = sps->num_long_term_ref_pics_sps;
1926 COPY_FIELD (pps, num_ref_idx_l0_default_active_minus1);
1927 COPY_FIELD (pps, num_ref_idx_l1_default_active_minus1);
1928 pic_param->pps_beta_offset_div2 = pps->beta_offset_div2;
1929 pic_param->pps_tc_offset_div2 = pps->tc_offset_div2;
1930 COPY_FIELD (pps, num_extra_slice_header_bits);
1932 /*Fixme: Set correct value as mentioned in va_dec_hevc.h */
1933 pic_param->st_rps_bits = 0;
1937 /* Detection of the first VCL NAL unit of a coded picture (7.4.2.4.5 ) */
1939 is_new_picture (GstVaapiParserInfoH265 * pi, GstVaapiParserInfoH265 * prev_pi)
1941 GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr;
1946 if (slice_hdr->first_slice_segment_in_pic_flag)
1952 /* Detection of a new access unit, assuming we are already in presence
1954 static inline gboolean
1955 is_new_access_unit (GstVaapiParserInfoH265 * pi,
1956 GstVaapiParserInfoH265 * prev_pi)
1965 has_entry_in_rps (GstVaapiPictureH265 * dpb_pic,
1966 GstVaapiPictureH265 ** rps_list, guint rps_list_length)
1970 if (!dpb_pic || !rps_list || !rps_list_length)
1973 for (i = 0; i < rps_list_length; i++) {
1974 if (rps_list[i] && rps_list[i]->poc == dpb_pic->poc)
1980 /* the derivation process for the RPS and the picture marking */
1982 derive_and_mark_rps (GstVaapiDecoderH265 * decoder,
1983 GstVaapiPictureH265 * picture, GstVaapiParserInfoH265 * pi,
1984 gint32 * CurrDeltaPocMsbPresentFlag, gint32 * FollDeltaPocMsbPresentFlag)
1986 GstVaapiDecoderH265Private *const priv = &decoder->priv;
1987 GstVaapiPictureH265 *dpb_pic = NULL;
1990 memset (priv->RefPicSetLtCurr, 0, sizeof (GstVaapiPictureH265 *) * 16);
1991 memset (priv->RefPicSetLtFoll, 0, sizeof (GstVaapiPictureH265 *) * 16);
1992 memset (priv->RefPicSetStCurrBefore, 0, sizeof (GstVaapiPictureH265 *) * 16);
1993 memset (priv->RefPicSetStCurrAfter, 0, sizeof (GstVaapiPictureH265 *) * 16);
1994 memset (priv->RefPicSetStFoll, 0, sizeof (GstVaapiPictureH265 *) * 16);
1997 for (i = 0; i < priv->NumPocLtCurr; i++) {
1998 if (!CurrDeltaPocMsbPresentFlag[i]) {
1999 dpb_pic = dpb_get_picture (decoder, priv->PocLtCurr[i], TRUE);
2001 priv->RefPicSetLtCurr[i] = dpb_pic;
2003 priv->RefPicSetLtCurr[i] = NULL;
2005 dpb_pic = dpb_get_picture (decoder, priv->PocLtCurr[i], FALSE);
2007 priv->RefPicSetLtCurr[i] = dpb_pic;
2009 priv->RefPicSetLtCurr[i] = NULL;
2013 priv->RefPicSetLtCurr[i] = NULL;
2015 for (i = 0; i < priv->NumPocLtFoll; i++) {
2016 if (!FollDeltaPocMsbPresentFlag[i]) {
2017 dpb_pic = dpb_get_picture (decoder, priv->PocLtFoll[i], TRUE);
2019 priv->RefPicSetLtFoll[i] = dpb_pic;
2021 priv->RefPicSetLtFoll[i] = NULL;
2023 dpb_pic = dpb_get_picture (decoder, priv->PocLtFoll[i], FALSE);
2025 priv->RefPicSetLtFoll[i] = dpb_pic;
2027 priv->RefPicSetLtFoll[i] = NULL;
2031 priv->RefPicSetLtFoll[i] = NULL;
2033 /* Mark all ref pics in RefPicSetLtCurr and RefPicSetLtFol as long_term_refs */
2034 for (i = 0; i < priv->NumPocLtCurr; i++) {
2035 if (priv->RefPicSetLtCurr[i])
2036 gst_vaapi_picture_h265_set_reference (priv->RefPicSetLtCurr[i],
2037 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE |
2038 GST_VAAPI_PICTURE_FLAG_RPS_LT_CURR);
2040 for (i = 0; i < priv->NumPocLtFoll; i++) {
2041 if (priv->RefPicSetLtFoll[i])
2042 gst_vaapi_picture_h265_set_reference (priv->RefPicSetLtFoll[i],
2043 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE |
2044 GST_VAAPI_PICTURE_FLAG_RPS_LT_FOLL);
2048 for (i = 0; i < priv->NumPocStCurrBefore; i++) {
2049 dpb_pic = dpb_get_ref_picture (decoder, priv->PocStCurrBefore[i], TRUE);
2051 gst_vaapi_picture_h265_set_reference (dpb_pic,
2052 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE |
2053 GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_BEFORE);
2054 priv->RefPicSetStCurrBefore[i] = dpb_pic;
2056 priv->RefPicSetStCurrBefore[i] = NULL;
2059 priv->RefPicSetStCurrBefore[i] = NULL;
2061 for (i = 0; i < priv->NumPocStCurrAfter; i++) {
2062 dpb_pic = dpb_get_ref_picture (decoder, priv->PocStCurrAfter[i], TRUE);
2064 gst_vaapi_picture_h265_set_reference (dpb_pic,
2065 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE |
2066 GST_VAAPI_PICTURE_FLAG_RPS_ST_CURR_AFTER);
2067 priv->RefPicSetStCurrAfter[i] = dpb_pic;
2069 priv->RefPicSetStCurrAfter[i] = NULL;
2072 priv->RefPicSetStCurrAfter[i] = NULL;
2074 for (i = 0; i < priv->NumPocStFoll; i++) {
2075 dpb_pic = dpb_get_ref_picture (decoder, priv->PocStFoll[i], TRUE);
2077 gst_vaapi_picture_h265_set_reference (dpb_pic,
2078 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE |
2079 GST_VAAPI_PICTURE_FLAG_RPS_ST_FOLL);
2080 priv->RefPicSetStFoll[i] = dpb_pic;
2082 priv->RefPicSetStFoll[i] = NULL;
2085 priv->RefPicSetStFoll[i] = NULL;
2087 /* Mark all dpb pics not beloging to RefPicSet*[] as unused for ref */
2088 for (i = 0; i < priv->dpb_count; i++) {
2089 dpb_pic = priv->dpb[i]->buffer;
2091 !has_entry_in_rps (dpb_pic, priv->RefPicSetLtCurr, priv->NumPocLtCurr)
2092 && !has_entry_in_rps (dpb_pic, priv->RefPicSetLtFoll,
2094 && !has_entry_in_rps (dpb_pic, priv->RefPicSetStCurrAfter,
2095 priv->NumPocStCurrAfter)
2096 && !has_entry_in_rps (dpb_pic, priv->RefPicSetStCurrBefore,
2097 priv->NumPocStCurrBefore)
2098 && !has_entry_in_rps (dpb_pic, priv->RefPicSetStFoll,
2099 priv->NumPocStFoll))
2100 gst_vaapi_picture_h265_set_reference (dpb_pic, 0);
2105 /* Decoding process for reference picture set (8.3.2) */
2107 decode_ref_pic_set (GstVaapiDecoderH265 * decoder,
2108 GstVaapiPictureH265 * picture, GstVaapiParserInfoH265 * pi)
2111 gint32 CurrDeltaPocMsbPresentFlag[16] = { 0, };
2112 gint32 FollDeltaPocMsbPresentFlag[16] = { 0, };
2113 GstVaapiDecoderH265Private *const priv = &decoder->priv;
2114 GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr;
2115 GstH265SPS *const sps = get_sps (decoder);
2116 const gint32 MaxPicOrderCntLsb =
2117 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
2119 /* if it is an irap pic, set all ref pics in dpb as unused for ref */
2120 if (nal_is_irap (pi->nalu.type) && picture->NoRaslOutputFlag) {
2121 for (i = 0; i < priv->dpb_count; i++) {
2122 GstVaapiFrameStore *const fs = priv->dpb[i];
2123 gst_vaapi_picture_h265_set_reference (fs->buffer, 0);
2127 /* Reset everything for IDR */
2128 if (nal_is_idr (pi->nalu.type)) {
2129 memset (priv->PocStCurrBefore, 0, sizeof (guint) * 16);
2130 memset (priv->PocStCurrAfter, 0, sizeof (guint) * 16);
2131 memset (priv->PocStFoll, 0, sizeof (guint) * 16);
2132 memset (priv->PocLtCurr, 0, sizeof (guint) * 16);
2133 memset (priv->PocLtFoll, 0, sizeof (guint) * 16);
2134 priv->NumPocStCurrBefore = priv->NumPocStCurrAfter = priv->NumPocStFoll = 0;
2135 priv->NumPocLtCurr = priv->NumPocLtFoll = 0;
2137 GstH265ShortTermRefPicSet *stRefPic = NULL;
2138 gint32 num_lt_pics, pocLt, PocLsbLt[16] = { 0, }
2139 , UsedByCurrPicLt[16] = {
2141 gint32 DeltaPocMsbCycleLt[16] = { 0, };
2142 gint numtotalcurr = 0;
2144 /* this is based on CurrRpsIdx described in spec */
2145 if (!slice_hdr->short_term_ref_pic_set_sps_flag)
2146 stRefPic = &slice_hdr->short_term_ref_pic_sets;
2147 else if (sps->num_short_term_ref_pic_sets)
2149 &sps->short_term_ref_pic_set[slice_hdr->short_term_ref_pic_set_idx];
2151 g_assert (stRefPic != NULL);
2153 for (i = 0, j = 0, k = 0; i < stRefPic->NumNegativePics; i++) {
2154 if (stRefPic->UsedByCurrPicS0[i]) {
2155 priv->PocStCurrBefore[j++] = picture->poc + stRefPic->DeltaPocS0[i];
2158 priv->PocStFoll[k++] = picture->poc + stRefPic->DeltaPocS0[i];
2160 priv->NumPocStCurrBefore = j;
2161 for (i = 0, j = 0; i < stRefPic->NumPositivePics; i++) {
2162 if (stRefPic->UsedByCurrPicS1[i]) {
2163 priv->PocStCurrAfter[j++] = picture->poc + stRefPic->DeltaPocS1[i];
2166 priv->PocStFoll[k++] = picture->poc + stRefPic->DeltaPocS1[i];
2168 priv->NumPocStCurrAfter = j;
2169 priv->NumPocStFoll = k;
2170 num_lt_pics = slice_hdr->num_long_term_sps + slice_hdr->num_long_term_pics;
2171 /* The variables PocLsbLt[i] and UsedByCurrPicLt[i] are derived as follows: */
2172 for (i = 0; i < num_lt_pics; i++) {
2173 if (i < slice_hdr->num_long_term_sps) {
2174 PocLsbLt[i] = sps->lt_ref_pic_poc_lsb_sps[slice_hdr->lt_idx_sps[i]];
2175 UsedByCurrPicLt[i] =
2176 sps->used_by_curr_pic_lt_sps_flag[slice_hdr->lt_idx_sps[i]];
2178 PocLsbLt[i] = slice_hdr->poc_lsb_lt[i];
2179 UsedByCurrPicLt[i] = slice_hdr->used_by_curr_pic_lt_flag[i];
2181 if (UsedByCurrPicLt[i])
2185 priv->NumPocTotalCurr = numtotalcurr;
2187 /* The variable DeltaPocMsbCycleLt[i] is derived as follows: (7-38) */
2188 for (i = 0; i < num_lt_pics; i++) {
2189 if (i == 0 || i == slice_hdr->num_long_term_sps)
2190 DeltaPocMsbCycleLt[i] = slice_hdr->delta_poc_msb_cycle_lt[i];
2192 DeltaPocMsbCycleLt[i] =
2193 slice_hdr->delta_poc_msb_cycle_lt[i] + DeltaPocMsbCycleLt[i - 1];
2197 for (i = 0, j = 0, k = 0; i < num_lt_pics; i++) {
2198 pocLt = PocLsbLt[i];
2199 if (slice_hdr->delta_poc_msb_present_flag[i])
2201 picture->poc - DeltaPocMsbCycleLt[i] * MaxPicOrderCntLsb -
2202 slice_hdr->pic_order_cnt_lsb;
2203 if (UsedByCurrPicLt[i]) {
2204 priv->PocLtCurr[j] = pocLt;
2205 CurrDeltaPocMsbPresentFlag[j++] =
2206 slice_hdr->delta_poc_msb_present_flag[i];
2208 priv->PocLtFoll[k] = pocLt;
2209 FollDeltaPocMsbPresentFlag[k++] =
2210 slice_hdr->delta_poc_msb_present_flag[i];
2213 priv->NumPocLtCurr = j;
2214 priv->NumPocLtFoll = k;
2218 /* the derivation process for the RPS and the picture marking */
2219 derive_and_mark_rps (decoder, picture, pi, CurrDeltaPocMsbPresentFlag,
2220 FollDeltaPocMsbPresentFlag);
2225 static GstVaapiDecoderStatus
2226 decode_picture (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
2228 GstVaapiDecoderH265Private *const priv = &decoder->priv;
2229 GstVaapiParserInfoH265 *pi = unit->parsed_info;
2230 GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr;
2231 GstH265PPS *const pps = ensure_pps (decoder, slice_hdr->pps);
2232 GstH265SPS *const sps = ensure_sps (decoder, slice_hdr->pps->sps);
2233 GstVaapiPictureH265 *picture;
2234 GstVaapiDecoderStatus status;
2236 g_return_val_if_fail (pps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN);
2237 g_return_val_if_fail (sps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN);
2239 status = ensure_context (decoder, sps);
2240 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2243 priv->decoder_state = 0;
2245 /* Create new picture */
2246 picture = gst_vaapi_picture_h265_new (decoder);
2248 GST_ERROR ("failed to allocate picture");
2249 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2252 gst_vaapi_picture_replace (&priv->current_picture, picture);
2253 gst_vaapi_picture_unref (picture);
2255 /* Update cropping rectangle */
2256 if (sps->conformance_window_flag) {
2257 GstVaapiRectangle crop_rect;
2258 crop_rect.x = sps->crop_rect_x;
2259 crop_rect.y = sps->crop_rect_y;
2260 crop_rect.width = sps->crop_rect_width;
2261 crop_rect.height = sps->crop_rect_height;
2262 gst_vaapi_picture_set_crop_rect (&picture->base, &crop_rect);
2265 status = ensure_quant_matrix (decoder, picture);
2266 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
2267 GST_ERROR ("failed to reset quantizer matrix");
2271 if (!init_picture (decoder, picture, pi))
2272 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2274 /* Drop all RASL pictures having NoRaslOutputFlag is TRUE for the
2275 * associated IRAP picture */
2276 if (nal_is_rasl (pi->nalu.type) && priv->associated_irap_NoRaslOutputFlag) {
2277 gst_vaapi_picture_replace (&priv->current_picture, NULL);
2278 return (GstVaapiDecoderStatus) GST_VAAPI_DECODER_STATUS_DROP_FRAME;
2281 if (!decode_ref_pic_set (decoder, picture, pi))
2282 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2284 if (!dpb_init (decoder, picture, pi))
2285 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2287 if (!fill_picture (decoder, picture))
2288 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2290 priv->decoder_state = pi->state;
2291 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2295 get_slice_data_byte_offset (GstH265SliceHdr * slice_hdr, guint nal_header_bytes)
2299 epb_count = slice_hdr->n_emulation_prevention_bytes;
2300 return nal_header_bytes + (slice_hdr->header_size + 7) / 8 - epb_count;
2304 fill_pred_weight_table (GstVaapiDecoderH265 * decoder,
2305 GstVaapiSlice * slice, GstH265SliceHdr * slice_hdr)
2307 VASliceParameterBufferHEVC *const slice_param = slice->param;
2308 GstH265PPS *const pps = get_pps (decoder);
2309 GstH265SPS *const sps = get_sps (decoder);
2310 GstH265PredWeightTable *const w = &slice_hdr->pred_weight_table;
2311 gint chroma_weight, chroma_log2_weight_denom;
2314 slice_param->luma_log2_weight_denom = 0;
2315 slice_param->delta_chroma_log2_weight_denom = 0;
2317 if ((pps->weighted_pred_flag && GST_H265_IS_P_SLICE (slice_hdr)) ||
2318 (pps->weighted_bipred_flag && GST_H265_IS_B_SLICE (slice_hdr))) {
2320 slice_param->luma_log2_weight_denom = w->luma_log2_weight_denom;
2321 if (!sps->chroma_format_idc)
2322 slice_param->delta_chroma_log2_weight_denom =
2323 w->delta_chroma_log2_weight_denom;
2325 chroma_log2_weight_denom =
2326 slice_param->luma_log2_weight_denom +
2327 slice_param->delta_chroma_log2_weight_denom;
2329 for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) {
2330 if (slice_hdr->pred_weight_table.luma_weight_l0_flag[i]) {
2331 slice_param->delta_luma_weight_l0[i] = w->delta_luma_weight_l0[i];
2332 slice_param->luma_offset_l0[i] = w->luma_offset_l0[i];
2334 if (slice_hdr->pred_weight_table.chroma_weight_l0_flag[i]) {
2335 for (j = 0; j < 2; j++) {
2336 slice_param->delta_chroma_weight_l0[i][j] =
2337 w->delta_chroma_weight_l0[i][j];
2338 /* Find ChromaWeightL0 */
2340 (1 << chroma_log2_weight_denom) + w->delta_chroma_weight_l0[i][j];
2342 slice_param->ChromaOffsetL0[i][j] = CLAMP (
2343 (w->delta_chroma_offset_l0[i][j] -
2344 ((128 * chroma_weight) >> chroma_log2_weight_denom)), -128,
2350 if (GST_H265_IS_B_SLICE (slice_hdr)) {
2351 for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) {
2352 if (slice_hdr->pred_weight_table.luma_weight_l1_flag[i]) {
2353 slice_param->delta_luma_weight_l1[i] = w->delta_luma_weight_l1[i];
2354 slice_param->luma_offset_l1[i] = w->luma_offset_l1[i];
2356 if (slice_hdr->pred_weight_table.chroma_weight_l1_flag[i]) {
2357 for (j = 0; j < 2; j++) {
2358 slice_param->delta_chroma_weight_l1[i][j] =
2359 w->delta_chroma_weight_l1[i][j];
2360 /* Find ChromaWeightL1 */
2362 (1 << chroma_log2_weight_denom) +
2363 w->delta_chroma_weight_l1[i][j];
2364 slice_param->ChromaOffsetL1[i][j] =
2365 CLAMP ((w->delta_chroma_offset_l1[i][j] -
2366 ((128 * chroma_weight) >> chroma_log2_weight_denom)), -128,
2373 /* Fixme: Optimize */
2375 for (i = 0; i < 15; i++) {
2376 slice_param->delta_luma_weight_l0[i] = 0;
2377 slice_param->luma_offset_l0[i] = 0;
2378 slice_param->delta_luma_weight_l1[i] = 0;
2379 slice_param->luma_offset_l1[i] = 0;
2381 for (i = 0; i < 15; i++) {
2382 for (j = 0; j < 2; j++) {
2383 slice_param->delta_chroma_weight_l0[i][j] = 0;
2384 slice_param->ChromaOffsetL0[i][j] = 0;
2385 slice_param->delta_chroma_weight_l1[i][j] = 0;
2386 slice_param->ChromaOffsetL1[i][j] = 0;
2394 fill_RefPicList (GstVaapiDecoderH265 * decoder,
2395 GstVaapiPictureH265 * picture, GstVaapiSlice * slice,
2396 GstH265SliceHdr * slice_hdr)
2398 GstVaapiDecoderH265Private *const priv = &decoder->priv;
2399 VASliceParameterBufferHEVC *const slice_param = slice->param;
2400 GstVaapiPicture *const base_picture = &picture->base;
2401 VAPictureParameterBufferHEVC *const pic_param = base_picture->param;
2402 guint i, num_ref_lists = 0, j;
2404 slice_param->num_ref_idx_l0_active_minus1 = 0;
2405 slice_param->num_ref_idx_l1_active_minus1 = 0;
2406 for (j = 0; j < 2; j++)
2407 for (i = 0; i < 15; i++)
2408 slice_param->RefPicList[j][i] = 0xFF;
2410 if (GST_H265_IS_B_SLICE (slice_hdr))
2412 else if (GST_H265_IS_I_SLICE (slice_hdr))
2417 if (num_ref_lists < 1)
2420 slice_param->num_ref_idx_l0_active_minus1 =
2421 slice_hdr->num_ref_idx_l0_active_minus1;
2422 slice_param->num_ref_idx_l1_active_minus1 =
2423 slice_hdr->num_ref_idx_l1_active_minus1;
2425 for (i = 0; i < priv->RefPicList0_count; i++)
2426 slice_param->RefPicList[0][i] =
2427 get_index_for_RefPicListX (pic_param->ReferenceFrames,
2428 priv->RefPicList0[i]);
2430 slice_param->RefPicList[0][i] = 0xFF;
2432 if (num_ref_lists < 2)
2435 for (i = 0; i < priv->RefPicList1_count; i++)
2436 slice_param->RefPicList[1][i] =
2437 get_index_for_RefPicListX (pic_param->ReferenceFrames,
2438 priv->RefPicList1[i]);
2440 slice_param->RefPicList[1][i] = 0xFF;
2446 fill_slice (GstVaapiDecoderH265 * decoder,
2447 GstVaapiPictureH265 * picture, GstVaapiSlice * slice,
2448 GstVaapiParserInfoH265 * pi, GstVaapiDecoderUnit * unit)
2450 GstVaapiDecoderH265Private *const priv = &decoder->priv;
2451 VASliceParameterBufferHEVC *const slice_param = slice->param;
2452 GstH265SliceHdr *slice_hdr = &pi->data.slice_hdr;
2454 /* Fill in VASliceParameterBufferH265 */
2455 slice_param->LongSliceFlags.value = 0;
2456 slice_param->slice_data_byte_offset =
2457 get_slice_data_byte_offset (slice_hdr, pi->nalu.header_bytes);
2459 slice_param->slice_segment_address = slice_hdr->segment_address;
2461 #define COPY_LFF(f) \
2462 slice_param->LongSliceFlags.fields.f = (slice_hdr)->f
2464 if (GST_VAAPI_PICTURE_FLAG_IS_SET (picture, GST_VAAPI_PICTURE_FLAG_AU_END))
2465 slice_param->LongSliceFlags.fields.LastSliceOfPic = 1;
2467 slice_param->LongSliceFlags.fields.LastSliceOfPic = 0;
2469 COPY_LFF (dependent_slice_segment_flag);
2471 /* use most recent independent slice segment header syntax elements
2472 * for filling the missing fields in dependent slice segment header */
2473 if (slice_hdr->dependent_slice_segment_flag)
2474 slice_hdr = &priv->prev_independent_slice_pi->data.slice_hdr;
2476 COPY_LFF (mvd_l1_zero_flag);
2477 COPY_LFF (cabac_init_flag);
2478 COPY_LFF (collocated_from_l0_flag);
2479 slice_param->LongSliceFlags.fields.color_plane_id =
2480 slice_hdr->colour_plane_id;
2481 slice_param->LongSliceFlags.fields.slice_type = slice_hdr->type;
2482 slice_param->LongSliceFlags.fields.slice_sao_luma_flag =
2483 slice_hdr->sao_luma_flag;
2484 slice_param->LongSliceFlags.fields.slice_sao_chroma_flag =
2485 slice_hdr->sao_chroma_flag;
2486 slice_param->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag =
2487 slice_hdr->temporal_mvp_enabled_flag;
2488 slice_param->LongSliceFlags.fields.slice_deblocking_filter_disabled_flag =
2489 slice_hdr->deblocking_filter_disabled_flag;
2490 slice_param->LongSliceFlags.
2491 fields.slice_loop_filter_across_slices_enabled_flag =
2492 slice_hdr->loop_filter_across_slices_enabled_flag;
2494 if (!slice_hdr->temporal_mvp_enabled_flag)
2495 slice_param->collocated_ref_idx = 0xFF;
2497 slice_param->collocated_ref_idx = slice_hdr->collocated_ref_idx;
2499 slice_param->num_ref_idx_l0_active_minus1 =
2500 slice_hdr->num_ref_idx_l0_active_minus1;
2501 slice_param->num_ref_idx_l1_active_minus1 =
2502 slice_hdr->num_ref_idx_l1_active_minus1;
2503 slice_param->slice_qp_delta = slice_hdr->qp_delta;
2504 slice_param->slice_cb_qp_offset = slice_hdr->cb_qp_offset;
2505 slice_param->slice_cr_qp_offset = slice_hdr->cr_qp_offset;
2506 slice_param->slice_beta_offset_div2 = slice_hdr->beta_offset_div2;
2507 slice_param->slice_tc_offset_div2 = slice_hdr->tc_offset_div2;
2508 slice_param->five_minus_max_num_merge_cand =
2509 slice_hdr->five_minus_max_num_merge_cand;
2511 if (!fill_RefPicList (decoder, picture, slice, slice_hdr))
2514 if (!fill_pred_weight_table (decoder, slice, slice_hdr))
2520 static GstVaapiDecoderStatus
2521 decode_slice (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
2523 GstVaapiDecoderH265Private *const priv = &decoder->priv;
2524 GstVaapiParserInfoH265 *const pi = unit->parsed_info;
2525 GstVaapiPictureH265 *const picture = priv->current_picture;
2526 GstH265SliceHdr *const slice_hdr = &pi->data.slice_hdr;
2527 GstVaapiSlice *slice;
2528 GstBuffer *const buffer =
2529 GST_VAAPI_DECODER_CODEC_FRAME (decoder)->input_buffer;
2530 GstMapInfo map_info;
2532 GST_DEBUG ("slice (%u bytes)", pi->nalu.size);
2533 if (!is_valid_state (pi->state, GST_H265_VIDEO_STATE_VALID_PICTURE_HEADERS)) {
2534 GST_WARNING ("failed to receive enough headers to decode slice");
2535 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2538 if (!ensure_pps (decoder, slice_hdr->pps)) {
2539 GST_ERROR ("failed to activate PPS");
2540 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2543 if (!ensure_sps (decoder, slice_hdr->pps->sps)) {
2544 GST_ERROR ("failed to activate SPS");
2545 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2548 if (!gst_buffer_map (buffer, &map_info, GST_MAP_READ)) {
2549 GST_ERROR ("failed to map buffer");
2550 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2553 /* Check wether this is the first/last slice in the current access unit */
2554 if (pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_START)
2555 GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_AU_START);
2557 if (pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_END)
2558 GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_AU_END);
2560 slice = GST_VAAPI_SLICE_NEW (HEVC, decoder,
2561 (map_info.data + unit->offset + pi->nalu.offset), pi->nalu.size);
2563 gst_buffer_unmap (buffer, &map_info);
2565 GST_ERROR ("failed to allocate slice");
2566 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2569 init_picture_refs (decoder, picture, slice_hdr);
2571 if (!fill_slice (decoder, picture, slice, pi, unit)) {
2572 gst_vaapi_mini_object_unref (GST_VAAPI_MINI_OBJECT (slice));
2573 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2576 gst_vaapi_picture_add_slice (GST_VAAPI_PICTURE_CAST (picture), slice);
2577 picture->last_slice_hdr = slice_hdr;
2578 priv->decoder_state |= GST_H265_VIDEO_STATE_GOT_SLICE;
2579 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2583 scan_for_start_code (GstAdapter * adapter, guint ofs, guint size, guint32 * scp)
2585 return (gint) gst_adapter_masked_scan_uint32_peek (adapter,
2586 0xffffff00, 0x00000100, ofs, size, scp);
2589 static GstVaapiDecoderStatus
2590 decode_unit (GstVaapiDecoderH265 * decoder, GstVaapiDecoderUnit * unit)
2592 GstVaapiDecoderH265Private *const priv = &decoder->priv;
2593 GstVaapiParserInfoH265 *const pi = unit->parsed_info;
2594 GstVaapiDecoderStatus status;
2595 priv->decoder_state |= pi->state;
2596 switch (pi->nalu.type) {
2597 case GST_H265_NAL_VPS:
2598 status = decode_vps (decoder, unit);
2600 case GST_H265_NAL_SPS:
2601 status = decode_sps (decoder, unit);
2603 case GST_H265_NAL_PPS:
2604 status = decode_pps (decoder, unit);
2606 case GST_H265_NAL_SLICE_TRAIL_N:
2607 case GST_H265_NAL_SLICE_TRAIL_R:
2608 case GST_H265_NAL_SLICE_TSA_N:
2609 case GST_H265_NAL_SLICE_TSA_R:
2610 case GST_H265_NAL_SLICE_STSA_N:
2611 case GST_H265_NAL_SLICE_STSA_R:
2612 case GST_H265_NAL_SLICE_RADL_N:
2613 case GST_H265_NAL_SLICE_RADL_R:
2614 case GST_H265_NAL_SLICE_RASL_N:
2615 case GST_H265_NAL_SLICE_RASL_R:
2616 case GST_H265_NAL_SLICE_BLA_W_LP:
2617 case GST_H265_NAL_SLICE_BLA_W_RADL:
2618 case GST_H265_NAL_SLICE_BLA_N_LP:
2619 case GST_H265_NAL_SLICE_IDR_W_RADL:
2620 case GST_H265_NAL_SLICE_IDR_N_LP:
2621 case GST_H265_NAL_SLICE_CRA_NUT:
2622 /* slice decoding will get started only after completing all the
2623 initialization routines for each picture which is hanlding in
2624 start_frame() call back, so the new_bitstream and prev_nal_is_eos
2625 flags will have effects starting from the next frame onwards */
2626 priv->new_bitstream = FALSE;
2627 priv->prev_nal_is_eos = FALSE;
2628 status = decode_slice (decoder, unit);
2630 case GST_H265_NAL_EOB:
2631 priv->new_bitstream = TRUE;
2633 ("Next AU(if there is any) will be the begining of new bitstream");
2634 status = decode_sequence_end (decoder);
2636 case GST_H265_NAL_EOS:
2637 priv->prev_nal_is_eos = TRUE;
2638 status = decode_sequence_end (decoder);
2640 case GST_H265_NAL_SUFFIX_SEI:
2641 case GST_H265_NAL_PREFIX_SEI:
2642 status = decode_sei (decoder, unit);
2645 GST_WARNING ("unsupported NAL unit type %d", pi->nalu.type);
2646 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
2652 static GstVaapiDecoderStatus
2653 gst_vaapi_decoder_h265_decode_codec_data (GstVaapiDecoder *
2654 base_decoder, const guchar * buf, guint buf_size)
2656 GstVaapiDecoderH265 *const decoder =
2657 GST_VAAPI_DECODER_H265_CAST (base_decoder);
2658 GstVaapiDecoderH265Private *const priv = &decoder->priv;
2659 GstVaapiDecoderStatus status;
2660 GstVaapiDecoderUnit unit;
2661 GstVaapiParserInfoH265 *pi = NULL;
2662 GstH265ParserResult result;
2663 guint num_nal_arrays, num_nals;
2666 unit.parsed_info = NULL;
2668 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2670 GST_ERROR ("failed to decode codec-data, not in hvcC format");
2671 return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
2674 priv->nal_length_size = (buf[21] & 0x03) + 1;
2675 GST_DEBUG ("nal length size %u", priv->nal_length_size);
2676 num_nal_arrays = buf[22];
2678 for (i = 0; i < num_nal_arrays; i++) {
2679 num_nals = GST_READ_UINT16_BE (buf + ofs + 1);
2680 for (j = 0; j < num_nals; j++) {
2681 pi = gst_vaapi_parser_info_h265_new ();
2683 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2684 unit.parsed_info = pi;
2685 result = gst_h265_parser_identify_nalu_hevc (priv->parser,
2686 buf, ofs + 3, buf_size, 2, &pi->nalu);
2687 if (result != GST_H265_PARSER_OK) {
2688 status = get_status (result);
2692 switch (pi->nalu.type) {
2693 case GST_H265_NAL_VPS:
2694 status = parse_vps (decoder, &unit);
2695 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2697 status = decode_vps (decoder, &unit);
2698 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2701 case GST_H265_NAL_SPS:
2702 status = parse_sps (decoder, &unit);
2703 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2705 status = decode_sps (decoder, &unit);
2706 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2709 case GST_H265_NAL_PPS:
2710 status = parse_pps (decoder, &unit);
2711 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2713 status = decode_pps (decoder, &unit);
2714 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2718 gst_vaapi_parser_info_h265_replace (&pi, NULL);
2722 priv->is_hvcC = TRUE;
2723 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2725 gst_vaapi_parser_info_h265_replace (&pi, NULL);
2729 static GstVaapiDecoderStatus
2730 ensure_decoder (GstVaapiDecoderH265 * decoder)
2732 GstVaapiDecoderH265Private *const priv = &decoder->priv;
2733 GstVaapiDecoderStatus status;
2735 if (!priv->is_opened) {
2736 priv->is_opened = gst_vaapi_decoder_h265_open (decoder);
2737 if (!priv->is_opened)
2738 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
2740 gst_vaapi_decoder_decode_codec_data (GST_VAAPI_DECODER_CAST (decoder));
2741 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2744 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2747 static GstVaapiDecoderStatus
2748 gst_vaapi_decoder_h265_parse (GstVaapiDecoder * base_decoder,
2749 GstAdapter * adapter, gboolean at_eos, GstVaapiDecoderUnit * unit)
2751 GstVaapiDecoderH265 *const decoder =
2752 GST_VAAPI_DECODER_H265_CAST (base_decoder);
2753 GstVaapiDecoderH265Private *const priv = &decoder->priv;
2754 GstVaapiParserState *const ps = GST_VAAPI_PARSER_STATE (base_decoder);
2755 GstVaapiParserInfoH265 *pi;
2756 GstVaapiDecoderStatus status;
2757 GstH265ParserResult result;
2759 guint i, size, buf_size, nalu_size, flags;
2762 gboolean at_au_end = FALSE;
2764 status = ensure_decoder (decoder);
2765 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2768 switch (priv->stream_alignment) {
2769 case GST_VAAPI_STREAM_ALIGN_H265_NALU:
2770 case GST_VAAPI_STREAM_ALIGN_H265_AU:
2771 size = gst_adapter_available_fast (adapter);
2774 size = gst_adapter_available (adapter);
2778 if (priv->is_hvcC) {
2779 if (size < priv->nal_length_size)
2780 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2781 buf = (guchar *) & start_code;
2782 g_assert (priv->nal_length_size <= sizeof (start_code));
2783 gst_adapter_copy (adapter, buf, 0, priv->nal_length_size);
2785 for (i = 0; i < priv->nal_length_size; i++)
2786 nalu_size = (nalu_size << 8) | buf[i];
2787 buf_size = priv->nal_length_size + nalu_size;
2788 if (size < buf_size)
2789 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2790 else if (priv->stream_alignment == GST_VAAPI_STREAM_ALIGN_H265_AU)
2791 at_au_end = (buf_size == size);
2794 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2795 if (priv->stream_alignment == GST_VAAPI_STREAM_ALIGN_H265_NALU)
2798 ofs = scan_for_start_code (adapter, 0, size, NULL);
2800 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2802 gst_adapter_flush (adapter, ofs);
2806 ofs2 = ps->input_offset2 - ofs - 4;
2809 ofs = G_UNLIKELY (size < ofs2 + 4) ? -1 :
2810 scan_for_start_code (adapter, ofs2, size - ofs2, NULL);
2812 // Assume the whole NAL unit is present if end-of-stream
2813 // or stream buffers aligned on access unit boundaries
2814 if (priv->stream_alignment == GST_VAAPI_STREAM_ALIGN_H265_AU)
2817 ps->input_offset2 = size;
2818 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2825 ps->input_offset2 = 0;
2826 buf = (guchar *) gst_adapter_map (adapter, buf_size);
2828 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2829 unit->size = buf_size;
2830 pi = gst_vaapi_parser_info_h265_new ();
2832 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2833 gst_vaapi_decoder_unit_set_parsed_info (unit,
2834 pi, (GDestroyNotify) gst_vaapi_mini_object_unref);
2836 result = gst_h265_parser_identify_nalu_hevc (priv->parser,
2837 buf, 0, buf_size, priv->nal_length_size, &pi->nalu);
2839 result = gst_h265_parser_identify_nalu_unchecked (priv->parser,
2840 buf, 0, buf_size, &pi->nalu);
2841 status = get_status (result);
2842 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2844 switch (pi->nalu.type) {
2845 case GST_H265_NAL_VPS:
2846 status = parse_vps (decoder, unit);
2848 case GST_H265_NAL_SPS:
2849 status = parse_sps (decoder, unit);
2851 case GST_H265_NAL_PPS:
2852 status = parse_pps (decoder, unit);
2854 case GST_H265_NAL_PREFIX_SEI:
2855 case GST_H265_NAL_SUFFIX_SEI:
2856 status = parse_sei (decoder, unit);
2858 case GST_H265_NAL_SLICE_TRAIL_N:
2859 case GST_H265_NAL_SLICE_TRAIL_R:
2860 case GST_H265_NAL_SLICE_TSA_N:
2861 case GST_H265_NAL_SLICE_TSA_R:
2862 case GST_H265_NAL_SLICE_STSA_N:
2863 case GST_H265_NAL_SLICE_STSA_R:
2864 case GST_H265_NAL_SLICE_RADL_N:
2865 case GST_H265_NAL_SLICE_RADL_R:
2866 case GST_H265_NAL_SLICE_RASL_N:
2867 case GST_H265_NAL_SLICE_RASL_R:
2868 case GST_H265_NAL_SLICE_BLA_W_LP:
2869 case GST_H265_NAL_SLICE_BLA_W_RADL:
2870 case GST_H265_NAL_SLICE_BLA_N_LP:
2871 case GST_H265_NAL_SLICE_IDR_W_RADL:
2872 case GST_H265_NAL_SLICE_IDR_N_LP:
2873 case GST_H265_NAL_SLICE_CRA_NUT:
2874 status = parse_slice (decoder, unit);
2877 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2880 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2884 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END |
2885 GST_VAAPI_DECODER_UNIT_FLAG_AU_END;
2888 switch (pi->nalu.type) {
2889 case GST_H265_NAL_AUD:
2890 flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START;
2891 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
2893 case GST_H265_NAL_FD:
2894 flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP;
2896 case GST_H265_NAL_EOB:
2897 flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END;
2899 case GST_H265_NAL_SUFFIX_SEI:
2900 case GST_H265_NAL_EOS:
2901 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END;
2902 flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_END;
2904 case GST_H265_NAL_VPS:
2905 case GST_H265_NAL_SPS:
2906 case GST_H265_NAL_PPS:
2907 case GST_H265_NAL_PREFIX_SEI:
2908 flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START;
2909 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
2911 case GST_H265_NAL_SLICE_TRAIL_N:
2912 case GST_H265_NAL_SLICE_TRAIL_R:
2913 case GST_H265_NAL_SLICE_TSA_N:
2914 case GST_H265_NAL_SLICE_TSA_R:
2915 case GST_H265_NAL_SLICE_STSA_N:
2916 case GST_H265_NAL_SLICE_STSA_R:
2917 case GST_H265_NAL_SLICE_RADL_N:
2918 case GST_H265_NAL_SLICE_RADL_R:
2919 case GST_H265_NAL_SLICE_RASL_N:
2920 case GST_H265_NAL_SLICE_RASL_R:
2921 case GST_H265_NAL_SLICE_BLA_W_LP:
2922 case GST_H265_NAL_SLICE_BLA_W_RADL:
2923 case GST_H265_NAL_SLICE_BLA_N_LP:
2924 case GST_H265_NAL_SLICE_IDR_W_RADL:
2925 case GST_H265_NAL_SLICE_IDR_N_LP:
2926 case GST_H265_NAL_SLICE_CRA_NUT:
2927 flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE;
2928 if (priv->prev_pi &&
2929 (priv->prev_pi->flags & GST_VAAPI_DECODER_UNIT_FLAG_AU_END)) {
2930 flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START |
2931 GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
2932 } else if (is_new_picture (pi, priv->prev_slice_pi)) {
2933 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
2934 if (is_new_access_unit (pi, priv->prev_slice_pi))
2935 flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_START;
2937 gst_vaapi_parser_info_h265_replace (&priv->prev_slice_pi, pi);
2938 if (!pi->data.slice_hdr.dependent_slice_segment_flag)
2939 gst_vaapi_parser_info_h265_replace (&priv->prev_independent_slice_pi,
2946 if ((flags & GST_VAAPI_DECODER_UNIT_FLAGS_AU) && priv->prev_slice_pi)
2947 priv->prev_slice_pi->flags |= GST_VAAPI_DECODER_UNIT_FLAG_AU_END;
2948 GST_VAAPI_DECODER_UNIT_FLAG_SET (unit, flags);
2949 pi->nalu.data = NULL;
2950 pi->state = priv->parser_state;
2952 gst_vaapi_parser_info_h265_replace (&priv->prev_pi, pi);
2953 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2956 static GstVaapiDecoderStatus
2957 gst_vaapi_decoder_h265_decode (GstVaapiDecoder * base_decoder,
2958 GstVaapiDecoderUnit * unit)
2960 GstVaapiDecoderH265 *const decoder =
2961 GST_VAAPI_DECODER_H265_CAST (base_decoder);
2962 GstVaapiDecoderStatus status;
2964 status = ensure_decoder (decoder);
2965 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2967 return decode_unit (decoder, unit);
2970 static GstVaapiDecoderStatus
2971 gst_vaapi_decoder_h265_start_frame (GstVaapiDecoder * base_decoder,
2972 GstVaapiDecoderUnit * unit)
2974 GstVaapiDecoderH265 *const decoder =
2975 GST_VAAPI_DECODER_H265_CAST (base_decoder);
2977 return decode_picture (decoder, unit);
2980 static GstVaapiDecoderStatus
2981 gst_vaapi_decoder_h265_end_frame (GstVaapiDecoder * base_decoder)
2983 GstVaapiDecoderH265 *const decoder =
2984 GST_VAAPI_DECODER_H265_CAST (base_decoder);
2986 return decode_current_picture (decoder);
2989 static GstVaapiDecoderStatus
2990 gst_vaapi_decoder_h265_flush (GstVaapiDecoder * base_decoder)
2992 GstVaapiDecoderH265 *const decoder =
2993 GST_VAAPI_DECODER_H265_CAST (base_decoder);
2995 dpb_flush (decoder);
2996 return GST_VAAPI_DECODER_STATUS_SUCCESS;
3000 gst_vaapi_decoder_h265_class_init (GstVaapiDecoderH265Class * klass)
3002 GstVaapiMiniObjectClass *const object_class =
3003 GST_VAAPI_MINI_OBJECT_CLASS (klass);
3004 GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass);
3006 object_class->size = sizeof (GstVaapiDecoderH265);
3007 object_class->finalize = (GDestroyNotify) gst_vaapi_decoder_finalize;
3008 decoder_class->create = gst_vaapi_decoder_h265_create;
3009 decoder_class->destroy = gst_vaapi_decoder_h265_destroy;
3010 decoder_class->parse = gst_vaapi_decoder_h265_parse;
3011 decoder_class->decode = gst_vaapi_decoder_h265_decode;
3012 decoder_class->start_frame = gst_vaapi_decoder_h265_start_frame;
3013 decoder_class->end_frame = gst_vaapi_decoder_h265_end_frame;
3014 decoder_class->flush = gst_vaapi_decoder_h265_flush;
3015 decoder_class->decode_codec_data = gst_vaapi_decoder_h265_decode_codec_data;
3018 static inline const GstVaapiDecoderClass *
3019 gst_vaapi_decoder_h265_class (void)
3021 static GstVaapiDecoderH265Class g_class;
3022 static gsize g_class_init = FALSE;
3024 if (g_once_init_enter (&g_class_init)) {
3025 gst_vaapi_decoder_h265_class_init (&g_class);
3026 g_once_init_leave (&g_class_init, TRUE);
3028 return GST_VAAPI_DECODER_CLASS (&g_class);
3032 * gst_vaapi_decoder_h265_set_alignment:
3033 * @decoder: a #GstVaapiDecoderH265
3034 * @alignment: the #GstVaapiStreamAlignH265
3036 * Specifies how stream buffers are aligned / fed, i.e. the boundaries
3037 * of each buffer that is supplied to the decoder. This could be no
3038 * specific alignment, NAL unit boundaries, or access unit boundaries.
3041 gst_vaapi_decoder_h265_set_alignment (GstVaapiDecoderH265 * decoder,
3042 GstVaapiStreamAlignH265 alignment)
3044 g_return_if_fail (decoder != NULL);
3045 decoder->priv.stream_alignment = alignment;
3049 * gst_vaapi_decoder_h265_new:
3050 * @display: a #GstVaapiDisplay
3051 * @caps: a #GstCaps holding codec information
3053 * Creates a new #GstVaapiDecoder for MPEG-2 decoding. The @caps can
3054 * hold extra information like codec-data and pictured coded size.
3056 * Return value: the newly allocated #GstVaapiDecoder object
3059 gst_vaapi_decoder_h265_new (GstVaapiDisplay * display, GstCaps * caps)
3061 return gst_vaapi_decoder_new (gst_vaapi_decoder_h265_class (), display, caps);