va: Move common variable need_negotiation to GstBaseDec.
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-bad / sys / va / gstvah265dec.c
1 /* GStreamer
2  * Copyright (C) 2020 Igalia, S.L.
3  *     Author: Víctor Jáquez <vjaquez@igalia.com>
4  * Copyright (C) 2020 Collabora
5  *     Author: Nicolas Dufresne <nicolas.dufresne@collabora.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the0
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 /**
24  * SECTION:element-vah265dec
25  * @title: vah265dec
26  * @short_description: A VA-API based H265 video decoder
27  *
28  * vah265dec decodes H265 bitstreams to VA surfaces using the
29  * installed and chosen [VA-API](https://01.org/linuxmedia/vaapi)
30  * driver.
31  *
32  * The decoding surfaces can be mapped onto main memory as video
33  * frames.
34  *
35  * ## Example launch line
36  * ```
37  * gst-launch-1.0 filesrc location=big_buck_bunny.mov ! parsebin ! vah265dec ! autovideosink
38  * ```
39  *
40  * Since: 1.20
41  *
42  */
43
44 /* ToDo:
45  *
46  * + interlaced streams
47  * + mutiview and stereo profiles
48  * + SCC extension buffer
49  * + Add 10bit support
50  */
51
52 #ifdef HAVE_CONFIG_H
53 #include "config.h"
54 #endif
55
56 #include "gstvah265dec.h"
57
58 #include "gstvabasedec.h"
59
60 GST_DEBUG_CATEGORY_STATIC (gst_va_h265dec_debug);
61 #ifndef GST_DISABLE_GST_DEBUG
62 #define GST_CAT_DEFAULT gst_va_h265dec_debug
63 #else
64 #define GST_CAT_DEFAULT NULL
65 #endif
66
67 #define GST_VA_H265_DEC(obj)           ((GstVaH265Dec *) obj)
68 #define GST_VA_H265_DEC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_FROM_INSTANCE (obj), GstVaH265DecClass))
69 #define GST_VA_H265_DEC_CLASS(klass)   ((GstVaH265DecClass *) klass)
70
71 struct slice
72 {
73   guint8 *data;
74   guint size;
75
76   VASliceParameterBufferHEVCExtension param;
77 };
78
79 typedef struct _GstVaH265Dec GstVaH265Dec;
80 typedef struct _GstVaH265DecClass GstVaH265DecClass;
81
82 struct _GstVaH265DecClass
83 {
84   GstVaBaseDecClass parent_class;
85 };
86
87 struct _GstVaH265Dec
88 {
89   GstVaBaseDec parent;
90
91   GstFlowReturn last_ret;
92
93   gint coded_width;
94   gint coded_height;
95   gint dpb_size;
96
97   VAPictureParameterBufferHEVCExtension pic_param;
98
99   gint32 WpOffsetHalfRangeC;
100
101   struct slice prev_slice;
102 };
103
104 static GstElementClass *parent_class = NULL;
105
106 /* *INDENT-OFF* */
107 static const gchar *src_caps_str =
108     GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VA,
109         "{ NV12, P010_10LE }") " ;"
110     GST_VIDEO_CAPS_MAKE ("{ NV12, P010_10LE }");
111 /* *INDENT-ON* */
112
113 static const gchar *sink_caps_str = "video/x-h265";
114
115 static gboolean
116 _is_range_extension_profile (VAProfile profile)
117 {
118   if (profile == VAProfileHEVCMain422_10
119       || profile == VAProfileHEVCMain444
120       || profile == VAProfileHEVCMain444_10
121       || profile == VAProfileHEVCMain12
122       || profile == VAProfileHEVCMain444_12
123       || profile == VAProfileHEVCMain422_12)
124     return TRUE;
125   return FALSE;
126 }
127
128 static gboolean
129 _is_screen_content_ext_profile (VAProfile profile)
130 {
131   if (profile == VAProfileHEVCSccMain
132       || profile == VAProfileHEVCSccMain10
133       || profile == VAProfileHEVCSccMain444)
134     return TRUE;
135
136   return FALSE;
137 }
138
139 static inline void
140 _set_last_slice_flag (GstVaH265Dec * self)
141 {
142   self->prev_slice.param.base.LongSliceFlags.fields.LastSliceOfPic = 1;
143 }
144
145 static void
146 _replace_previous_slice (GstVaH265Dec * self, guint8 * data, guint size)
147 {
148   struct slice *slice = &self->prev_slice;
149   gboolean do_reset = (slice->size < size);
150
151   if (!data || do_reset) {
152     g_clear_pointer (&slice->data, g_free);
153     slice->size = 0;
154   }
155
156   if (!data)
157     return;
158
159   if (do_reset) {
160     GST_LOG_OBJECT (self, "allocating slice data %u", size);
161     slice->data = g_malloc (size);
162   }
163
164   memcpy (slice->data, data, size);
165   slice->size = size;
166 }
167
168 static gboolean
169 _submit_previous_slice (GstVaBaseDec * base, GstVaDecodePicture * va_pic)
170 {
171   GstVaH265Dec *self = GST_VA_H265_DEC (base);
172   struct slice *slice;
173   gboolean ret;
174   gsize param_size;
175
176   slice = &self->prev_slice;
177   if (!slice->data && slice->size == 0)
178     return TRUE;
179   if (!slice->data || slice->size == 0)
180     return FALSE;
181
182   param_size = _is_range_extension_profile (self->parent.profile)
183       || _is_screen_content_ext_profile (self->parent.profile) ?
184       sizeof (slice->param) : sizeof (slice->param.base);
185   ret = gst_va_decoder_add_slice_buffer (base->decoder, va_pic, &slice->param,
186       param_size, slice->data, slice->size);
187
188   return ret;
189 }
190
191 static GstFlowReturn
192 gst_va_h265_dec_end_picture (GstH265Decoder * decoder, GstH265Picture * picture)
193 {
194   GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
195   GstVaH265Dec *self = GST_VA_H265_DEC (decoder);
196   GstVaDecodePicture *va_pic;
197   gboolean ret;
198
199   GST_LOG_OBJECT (base, "end picture %p, (poc %d)",
200       picture, picture->pic_order_cnt);
201
202   va_pic = gst_h265_picture_get_user_data (picture);
203
204   _set_last_slice_flag (self);
205   ret = _submit_previous_slice (base, va_pic);
206
207   /* TODO(victor): optimization: this could be done at decoder's
208    * stop() vmethod */
209   _replace_previous_slice (self, NULL, 0);
210
211   if (!ret) {
212     GST_ERROR_OBJECT (self, "Failed to submit the previous slice");
213     return GST_FLOW_ERROR;
214   }
215
216   ret = gst_va_decoder_decode (base->decoder, va_pic);
217   if (!ret) {
218     GST_ERROR_OBJECT (self, "Failed at end picture %p, (poc %d)",
219         picture, picture->pic_order_cnt);
220     return GST_FLOW_ERROR;
221   }
222
223   return GST_FLOW_OK;
224 }
225
226 static GstFlowReturn
227 gst_va_h265_dec_output_picture (GstH265Decoder * decoder,
228     GstVideoCodecFrame * frame, GstH265Picture * picture)
229 {
230   GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
231   GstVaH265Dec *self = GST_VA_H265_DEC (decoder);
232   GstVaDecodePicture *va_pic;
233
234   va_pic = gst_h265_picture_get_user_data (picture);
235   g_assert (va_pic->gstbuffer);
236
237   GST_LOG_OBJECT (self,
238       "Outputting picture %p (poc %d)", picture, picture->pic_order_cnt);
239
240   if (self->last_ret != GST_FLOW_OK) {
241     gst_h265_picture_unref (picture);
242     _replace_previous_slice (self, NULL, 0);
243     gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);
244     return self->last_ret;
245   }
246
247   gst_buffer_replace (&frame->output_buffer, va_pic->gstbuffer);
248
249   if (base->copy_frames)
250     gst_va_base_dec_copy_output_buffer (base, frame);
251
252   gst_h265_picture_unref (picture);
253
254   return gst_video_decoder_finish_frame (GST_VIDEO_DECODER (self), frame);
255 }
256
257 static void
258 _init_vaapi_pic (VAPictureHEVC * va_picture)
259 {
260   va_picture->picture_id = VA_INVALID_ID;
261   va_picture->flags = VA_PICTURE_HEVC_INVALID;
262   va_picture->pic_order_cnt = 0;
263 }
264
265 static gint
266 _find_frame_rps_type (GstH265Decoder * decoder, GstH265Picture * ref_pic)
267 {
268   gint i;
269
270   for (i = 0; i < G_N_ELEMENTS (decoder->RefPicSetStCurrBefore); i++) {
271     if (ref_pic == decoder->RefPicSetStCurrBefore[i])
272       return VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE;
273   }
274
275   for (i = 0; i < G_N_ELEMENTS (decoder->RefPicSetStCurrAfter); i++) {
276     if (ref_pic == decoder->RefPicSetStCurrAfter[i])
277       return VA_PICTURE_HEVC_RPS_ST_CURR_AFTER;
278   }
279
280   for (i = 0; i < G_N_ELEMENTS (decoder->RefPicSetLtCurr); i++) {
281     if (ref_pic == decoder->RefPicSetLtCurr[i])
282       return VA_PICTURE_HEVC_RPS_LT_CURR;
283   }
284
285   return 0;
286 }
287
288
289 static void
290 _fill_vaapi_pic (GstH265Decoder * decoder, VAPictureHEVC * va_picture,
291     GstH265Picture * picture)
292 {
293   GstVaDecodePicture *va_pic;
294
295   va_pic = gst_h265_picture_get_user_data (picture);
296
297   if (!va_pic) {
298     _init_vaapi_pic (va_picture);
299     return;
300   }
301
302   va_picture->picture_id = gst_va_decode_picture_get_surface (va_pic);
303   va_picture->pic_order_cnt = picture->pic_order_cnt;
304   va_picture->flags = 0;
305
306   if (picture->ref && picture->long_term)
307     va_picture->flags |= VA_PICTURE_HEVC_LONG_TERM_REFERENCE;
308
309   va_picture->flags |= _find_frame_rps_type (decoder, picture);
310 }
311
312 static guint8
313 _get_reference_index (GstH265Decoder * decoder, GstH265Picture * picture)
314 {
315   GstVaH265Dec *self = GST_VA_H265_DEC (decoder);
316   guint8 i;
317
318   for (i = 0; i < 15; i++) {
319     VAPictureHEVC *ref_va_pic = &self->pic_param.base.ReferenceFrames[i];
320
321     if (ref_va_pic->picture_id == VA_INVALID_ID)
322       break;
323
324     if (ref_va_pic->pic_order_cnt == picture->pic_order_cnt)
325       return i;
326   }
327
328   return 0xFF;
329 }
330
331 /* fill the VA API reference picture lists from the GstCodec reference
332  * picture list */
333 static void
334 _fill_ref_pic_list (GstH265Decoder * decoder, GstH265Picture * cur_pic,
335     guint8 va_reflist[15], GArray * reflist)
336 {
337   guint i;
338
339   for (i = 0; i < reflist->len && i < 15; i++) {
340     GstH265Picture *picture = g_array_index (reflist, GstH265Picture *, i);
341     va_reflist[i] = _get_reference_index (decoder, picture);
342   }
343
344   for (; i < 15; i++)
345     va_reflist[i] = 0xFF;
346 }
347
348 static void
349 _fill_pred_weight_table (GstVaH265Dec * self, GstH265SliceHdr * header,
350     VASliceParameterBufferHEVCExtension * slice_param)
351 {
352   gint chroma_weight, chroma_log2_weight_denom;
353   gint i, j;
354   GstH265PPS *pps = header->pps;
355   gboolean is_rext = _is_range_extension_profile (self->parent.profile);
356
357   if (GST_H265_IS_I_SLICE (header) ||
358       (!pps->weighted_pred_flag && GST_H265_IS_P_SLICE (header)) ||
359       (!pps->weighted_bipred_flag && GST_H265_IS_B_SLICE (header)))
360     return;
361
362   slice_param->base.luma_log2_weight_denom =
363       header->pred_weight_table.luma_log2_weight_denom;
364
365   if (pps->sps->chroma_array_type != 0)
366     slice_param->base.delta_chroma_log2_weight_denom =
367         header->pred_weight_table.delta_chroma_log2_weight_denom;
368
369   for (i = 0; i <= header->num_ref_idx_l0_active_minus1; i++) {
370     if (!header->pred_weight_table.luma_weight_l0_flag[i])
371       continue;
372
373     slice_param->base.delta_luma_weight_l0[i] =
374         header->pred_weight_table.delta_luma_weight_l0[i];
375     slice_param->base.luma_offset_l0[i] =
376         header->pred_weight_table.luma_offset_l0[i];
377
378     if (is_rext) {
379       slice_param->rext.luma_offset_l0[i] =
380           header->pred_weight_table.luma_offset_l0[i];
381     }
382   }
383
384   chroma_log2_weight_denom = slice_param->base.luma_log2_weight_denom +
385       slice_param->base.delta_chroma_log2_weight_denom;
386
387   for (i = 0; i <= header->num_ref_idx_l0_active_minus1; i++) {
388     if (!header->pred_weight_table.chroma_weight_l0_flag[i])
389       continue;
390
391     for (j = 0; j < 2; j++) {
392       gint16 delta_chroma_offset_l0 =
393           header->pred_weight_table.delta_chroma_offset_l0[i][j];
394       gint chroma_offset;
395
396       slice_param->base.delta_chroma_weight_l0[i][j] =
397           header->pred_weight_table.delta_chroma_weight_l0[i][j];
398
399       /* Find  ChromaWeightL0 */
400       chroma_weight = (1 << chroma_log2_weight_denom) +
401           header->pred_weight_table.delta_chroma_weight_l0[i][j];
402       chroma_offset = self->WpOffsetHalfRangeC + delta_chroma_offset_l0
403           - ((self->WpOffsetHalfRangeC * chroma_weight)
404           >> chroma_log2_weight_denom);
405
406       /* 7-56 */
407       slice_param->base.ChromaOffsetL0[i][j] = CLAMP (chroma_offset,
408           -self->WpOffsetHalfRangeC, self->WpOffsetHalfRangeC - 1);
409
410       if (is_rext) {
411         slice_param->rext.ChromaOffsetL0[i][j] =
412             slice_param->base.ChromaOffsetL0[i][j];
413       }
414     }
415   }
416
417   /* Skip l1 if this is not a B-Frame. */
418   if (!GST_H265_IS_B_SLICE (header))
419     return;
420
421   for (i = 0; i <= header->num_ref_idx_l1_active_minus1; i++) {
422     if (!header->pred_weight_table.luma_weight_l1_flag[i])
423       continue;
424
425     slice_param->base.delta_luma_weight_l1[i] =
426         header->pred_weight_table.delta_luma_weight_l1[i];
427     slice_param->base.luma_offset_l1[i] =
428         header->pred_weight_table.luma_offset_l1[i];
429
430     if (is_rext) {
431       slice_param->rext.luma_offset_l1[i] =
432           header->pred_weight_table.luma_offset_l1[i];
433     }
434   }
435
436   for (i = 0; i <= header->num_ref_idx_l1_active_minus1; i++) {
437     if (!header->pred_weight_table.chroma_weight_l1_flag[i])
438       continue;
439
440     for (j = 0; j < 2; j++) {
441       gint16 delta_chroma_offset_l1 =
442           header->pred_weight_table.delta_chroma_offset_l1[i][j];
443       gint chroma_offset;
444
445       slice_param->base.delta_chroma_weight_l1[i][j] =
446           header->pred_weight_table.delta_chroma_weight_l1[i][j];
447
448       /* Find  ChromaWeightL1 */
449       chroma_weight = (1 << chroma_log2_weight_denom) +
450           header->pred_weight_table.delta_chroma_weight_l1[i][j];
451
452       chroma_offset = self->WpOffsetHalfRangeC + delta_chroma_offset_l1
453           - ((self->WpOffsetHalfRangeC * chroma_weight)
454           >> chroma_log2_weight_denom);
455
456       /* 7-56 */
457       slice_param->base.ChromaOffsetL1[i][j] = CLAMP (chroma_offset,
458           -self->WpOffsetHalfRangeC, self->WpOffsetHalfRangeC - 1);
459
460       if (is_rext) {
461         slice_param->rext.ChromaOffsetL1[i][j] =
462             slice_param->base.ChromaOffsetL1[i][j];
463       }
464     }
465   }
466 }
467
468 static inline guint
469 _get_slice_data_byte_offset (GstH265SliceHdr * slice_hdr,
470     guint nal_header_bytes)
471 {
472   guint epb_count;
473
474   epb_count = slice_hdr->n_emulation_prevention_bytes;
475   return nal_header_bytes + (slice_hdr->header_size + 7) / 8 - epb_count;
476 }
477
478 static GstFlowReturn
479 gst_va_h265_dec_decode_slice (GstH265Decoder * decoder,
480     GstH265Picture * picture, GstH265Slice * slice, GArray * ref_pic_list0,
481     GArray * ref_pic_list1)
482 {
483   GstH265SliceHdr *header = &slice->header;
484   GstH265NalUnit *nalu = &slice->nalu;
485   GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
486   GstVaH265Dec *self = GST_VA_H265_DEC (decoder);
487   GstVaDecodePicture *va_pic;
488   VASliceParameterBufferHEVCExtension *slice_param;
489
490   va_pic = gst_h265_picture_get_user_data (picture);
491   if (!_submit_previous_slice (base, va_pic)) {
492     _replace_previous_slice (self, NULL, 0);
493     GST_ERROR_OBJECT (base, "Failed to submit previous slice buffers");
494     return GST_FLOW_ERROR;
495   }
496
497   slice_param = &self->prev_slice.param;
498
499   /* *INDENT-OFF* */
500   slice_param->base = (VASliceParameterBufferHEVC) {
501     .slice_data_size = nalu->size,
502     .slice_data_offset = 0,
503     .slice_data_flag = VA_SLICE_DATA_FLAG_ALL,
504     .slice_data_byte_offset = _get_slice_data_byte_offset (header, nalu->header_bytes),
505     .slice_segment_address = header->segment_address,
506     .collocated_ref_idx = header->temporal_mvp_enabled_flag ? header->collocated_ref_idx : 0xFF,
507     .num_ref_idx_l0_active_minus1 = header->num_ref_idx_l0_active_minus1,
508     .num_ref_idx_l1_active_minus1 = header->num_ref_idx_l1_active_minus1,
509     .slice_qp_delta = header->qp_delta,
510     .slice_cb_qp_offset = header->cb_qp_offset,
511     .slice_cr_qp_offset = header->cr_qp_offset,
512     .slice_beta_offset_div2 = header->beta_offset_div2,
513     .slice_tc_offset_div2 = header->tc_offset_div2,
514     .five_minus_max_num_merge_cand = header->five_minus_max_num_merge_cand,
515     .num_entry_point_offsets = header->num_entry_point_offsets,
516     .entry_offset_to_subset_array = 0, /* does not exist in spec */
517     .slice_data_num_emu_prevn_bytes = header->n_emulation_prevention_bytes,
518     .LongSliceFlags.fields = {
519       .LastSliceOfPic = 0, /* the last one will be set on end_picture() */
520       .dependent_slice_segment_flag = header->dependent_slice_segment_flag,
521       .slice_type = header->type,
522       .color_plane_id = header->colour_plane_id,
523       .slice_sao_luma_flag = header->sao_luma_flag,
524       .slice_sao_chroma_flag = header->sao_chroma_flag,
525       .mvd_l1_zero_flag = header->mvd_l1_zero_flag,
526       .cabac_init_flag = header->cabac_init_flag,
527       .slice_temporal_mvp_enabled_flag = header->temporal_mvp_enabled_flag,
528       .slice_deblocking_filter_disabled_flag =
529           header->deblocking_filter_disabled_flag,
530       .collocated_from_l0_flag = header->collocated_from_l0_flag,
531       .slice_loop_filter_across_slices_enabled_flag =
532           header->loop_filter_across_slices_enabled_flag,
533     },
534   };
535   /* *INDENT-ON* */
536
537   if (_is_range_extension_profile (base->profile)
538       || _is_screen_content_ext_profile (base->profile)) {
539     /* *INDENT-OFF* */
540     slice_param->rext = (VASliceParameterBufferHEVCRext) {
541       .slice_ext_flags.bits = {
542         .cu_chroma_qp_offset_enabled_flag = header->cu_chroma_qp_offset_enabled_flag,
543         .use_integer_mv_flag = header->use_integer_mv_flag,
544       },
545       .slice_act_y_qp_offset = header->slice_act_y_qp_offset,
546       .slice_act_cb_qp_offset = header->slice_act_cb_qp_offset,
547       .slice_act_cr_qp_offset = header->slice_act_cr_qp_offset,
548     };
549     /* *INDENT-ON* */
550   }
551
552   _fill_ref_pic_list (decoder, picture, slice_param->base.RefPicList[0],
553       ref_pic_list0);
554   _fill_ref_pic_list (decoder, picture, slice_param->base.RefPicList[1],
555       ref_pic_list1);
556
557   _fill_pred_weight_table (GST_VA_H265_DEC (decoder), header, slice_param);
558
559   _replace_previous_slice (self, slice->nalu.data + slice->nalu.offset,
560       slice->nalu.size);
561
562   return GST_FLOW_OK;
563 }
564
565 static void
566 _fill_picture_range_ext_parameter (GstVaH265Dec * decoder,
567     GstH265SPS * sps, GstH265PPS * pps)
568 {
569   VAPictureParameterBufferHEVCRext *pic_param = &decoder->pic_param.rext;
570
571   GstH265SPSExtensionParams *sps_ext = &sps->sps_extnsion_params;
572   GstH265PPSExtensionParams *pps_ext = &pps->pps_extension_params;
573
574   /* *INDENT-OFF* */
575   *pic_param = (VAPictureParameterBufferHEVCRext) {
576     .range_extension_pic_fields.bits = {
577       .transform_skip_rotation_enabled_flag = sps_ext->transform_skip_rotation_enabled_flag,
578       .transform_skip_context_enabled_flag = sps_ext->transform_skip_context_enabled_flag,
579       .implicit_rdpcm_enabled_flag = sps_ext->implicit_rdpcm_enabled_flag,
580       .explicit_rdpcm_enabled_flag = sps_ext->explicit_rdpcm_enabled_flag,
581       .extended_precision_processing_flag = sps_ext->extended_precision_processing_flag,
582       .intra_smoothing_disabled_flag = sps_ext->intra_smoothing_disabled_flag,
583       .high_precision_offsets_enabled_flag = sps_ext->high_precision_offsets_enabled_flag,
584       .persistent_rice_adaptation_enabled_flag = sps_ext->persistent_rice_adaptation_enabled_flag,
585       .cabac_bypass_alignment_enabled_flag = sps_ext->cabac_bypass_alignment_enabled_flag,
586       .cross_component_prediction_enabled_flag = pps_ext->cross_component_prediction_enabled_flag,
587       .chroma_qp_offset_list_enabled_flag = pps_ext->chroma_qp_offset_list_enabled_flag,
588     },
589     .diff_cu_chroma_qp_offset_depth = pps_ext->diff_cu_chroma_qp_offset_depth,
590     .chroma_qp_offset_list_len_minus1 = pps_ext->chroma_qp_offset_list_len_minus1,
591     .log2_sao_offset_scale_luma = pps_ext->log2_sao_offset_scale_luma,
592     .log2_sao_offset_scale_chroma = pps_ext->log2_sao_offset_scale_chroma,
593     .log2_max_transform_skip_block_size_minus2 = pps_ext->log2_max_transform_skip_block_size_minus2,
594   };
595   /* *INDENT-ON* */
596
597   memcpy (pic_param->cb_qp_offset_list, pps_ext->cb_qp_offset_list,
598       sizeof (pic_param->cb_qp_offset_list));
599   memcpy (pic_param->cr_qp_offset_list, pps_ext->cr_qp_offset_list,
600       sizeof (pic_param->cr_qp_offset_list));
601 }
602
603 static void
604 _fill_screen_content_ext_parameter (GstVaH265Dec * decoder,
605     GstH265SPS * sps, GstH265PPS * pps)
606 {
607   VAPictureParameterBufferHEVCScc *pic_param = &decoder->pic_param.scc;
608   const GstH265PPSSccExtensionParams *pps_scc = &pps->pps_scc_extension_params;
609   const GstH265SPSSccExtensionParams *sps_scc = &sps->sps_scc_extension_params;
610   guint32 num_comps;
611   guint i, n;
612
613   /* *INDENT-OFF* */
614   *pic_param = (VAPictureParameterBufferHEVCScc) {
615     .screen_content_pic_fields.bits = {
616       .pps_curr_pic_ref_enabled_flag = pps_scc->pps_curr_pic_ref_enabled_flag,
617       .palette_mode_enabled_flag = sps_scc->palette_mode_enabled_flag,
618       .motion_vector_resolution_control_idc = sps_scc->motion_vector_resolution_control_idc,
619       .intra_boundary_filtering_disabled_flag = sps_scc->intra_boundary_filtering_disabled_flag,
620       .residual_adaptive_colour_transform_enabled_flag = pps_scc->residual_adaptive_colour_transform_enabled_flag,
621       .pps_slice_act_qp_offsets_present_flag = pps_scc->pps_slice_act_qp_offsets_present_flag,
622     },
623     .palette_max_size = sps_scc->palette_max_size,
624     .delta_palette_max_predictor_size = sps_scc->delta_palette_max_predictor_size,
625     .pps_act_y_qp_offset_plus5 = pps_scc->pps_act_y_qp_offset_plus5,
626     .pps_act_cb_qp_offset_plus5 = pps_scc->pps_act_cb_qp_offset_plus5,
627     .pps_act_cr_qp_offset_plus3 = pps_scc->pps_act_cr_qp_offset_plus3,
628   };
629   /* *INDENT-ON* */
630
631   /* firstly use the pps, then sps */
632   num_comps = sps->chroma_format_idc ? 3 : 1;
633
634   if (pps_scc->pps_palette_predictor_initializers_present_flag) {
635     pic_param->predictor_palette_size =
636         pps_scc->pps_num_palette_predictor_initializer;
637     for (n = 0; n < num_comps; n++)
638       for (i = 0; i < pps_scc->pps_num_palette_predictor_initializer; i++)
639         pic_param->predictor_palette_entries[n][i] =
640             (uint16_t) pps_scc->pps_palette_predictor_initializer[n][i];
641   } else if (sps_scc->sps_palette_predictor_initializers_present_flag) {
642     pic_param->predictor_palette_size =
643         sps_scc->sps_num_palette_predictor_initializer_minus1 + 1;
644     for (n = 0; n < num_comps; n++)
645       for (i = 0;
646           i < sps_scc->sps_num_palette_predictor_initializer_minus1 + 1; i++)
647         pic_param->predictor_palette_entries[n][i] =
648             (uint16_t) sps_scc->sps_palette_predictor_initializer[n][i];
649   }
650 }
651
652 static GstFlowReturn
653 gst_va_h265_dec_start_picture (GstH265Decoder * decoder,
654     GstH265Picture * picture, GstH265Slice * slice, GstH265Dpb * dpb)
655 {
656   GstH265PPS *pps;
657   GstH265SPS *sps;
658   GstVaH265Dec *self = GST_VA_H265_DEC (decoder);
659   GstVaBaseDec *base = &self->parent;
660   GstVaDecodePicture *va_pic;
661   GstH265ScalingList *scaling_list = NULL;
662   VAIQMatrixBufferHEVC iq_matrix = { 0, };
663   VAPictureParameterBufferHEVCExtension *pic_param = &self->pic_param;
664   gsize pic_param_size;
665   guint i;
666
667   va_pic = gst_h265_picture_get_user_data (picture);
668
669   pps = slice->header.pps;
670   sps = pps->sps;
671
672   /* *INDENT-OFF* */
673   pic_param->base = (VAPictureParameterBufferHEVC) {
674     .pic_width_in_luma_samples = sps->pic_width_in_luma_samples,
675     .pic_height_in_luma_samples = sps->pic_height_in_luma_samples,
676     .sps_max_dec_pic_buffering_minus1 = sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1],
677     .bit_depth_luma_minus8 = sps->bit_depth_luma_minus8,
678     .bit_depth_chroma_minus8 = sps->bit_depth_chroma_minus8,
679     .pcm_sample_bit_depth_luma_minus1 = sps->pcm_sample_bit_depth_luma_minus1,
680     .pcm_sample_bit_depth_chroma_minus1 = sps->pcm_sample_bit_depth_chroma_minus1,
681     .log2_min_luma_coding_block_size_minus3 = sps->log2_min_luma_coding_block_size_minus3,
682     .log2_diff_max_min_luma_coding_block_size = sps->log2_diff_max_min_luma_coding_block_size,
683     .log2_min_transform_block_size_minus2 = sps->log2_min_transform_block_size_minus2,
684     .log2_diff_max_min_transform_block_size = sps->log2_diff_max_min_transform_block_size,
685     .log2_min_pcm_luma_coding_block_size_minus3 = sps->log2_min_pcm_luma_coding_block_size_minus3,
686     .log2_diff_max_min_pcm_luma_coding_block_size = sps->log2_diff_max_min_pcm_luma_coding_block_size,
687     .max_transform_hierarchy_depth_intra = sps->max_transform_hierarchy_depth_intra,
688     .max_transform_hierarchy_depth_inter = sps->max_transform_hierarchy_depth_inter,
689     .init_qp_minus26 = pps->init_qp_minus26,
690     .diff_cu_qp_delta_depth = pps->diff_cu_qp_delta_depth,
691     .pps_cb_qp_offset = pps->cb_qp_offset,
692     .pps_cr_qp_offset = pps->cr_qp_offset,
693     .log2_parallel_merge_level_minus2 = pps->log2_parallel_merge_level_minus2,
694     .num_tile_columns_minus1 = pps->num_tile_columns_minus1,
695     .num_tile_rows_minus1 = pps->num_tile_rows_minus1,
696     .log2_max_pic_order_cnt_lsb_minus4 = sps->log2_max_pic_order_cnt_lsb_minus4,
697     .num_short_term_ref_pic_sets = sps->num_short_term_ref_pic_sets,
698     .num_long_term_ref_pic_sps = sps->num_long_term_ref_pics_sps,
699     .num_ref_idx_l0_default_active_minus1 = pps->num_ref_idx_l0_default_active_minus1,
700     .num_ref_idx_l1_default_active_minus1 = pps->num_ref_idx_l1_default_active_minus1,
701     .pps_beta_offset_div2 = pps->beta_offset_div2,
702     .pps_tc_offset_div2 = pps->tc_offset_div2,
703     .num_extra_slice_header_bits = pps->num_extra_slice_header_bits,
704     .st_rps_bits = slice->header.short_term_ref_pic_set_size, /* FIXME missing emulation bits removal */
705     .pic_fields.bits = {
706       .chroma_format_idc = sps->chroma_format_idc,
707       .separate_colour_plane_flag = sps->separate_colour_plane_flag,
708       .pcm_enabled_flag = sps->pcm_enabled_flag,
709       .scaling_list_enabled_flag = sps->scaling_list_enabled_flag,
710       .transform_skip_enabled_flag = pps->transform_skip_enabled_flag,
711       .amp_enabled_flag = sps->amp_enabled_flag,
712       .strong_intra_smoothing_enabled_flag = sps->strong_intra_smoothing_enabled_flag,
713       .sign_data_hiding_enabled_flag = pps->sign_data_hiding_enabled_flag,
714       .constrained_intra_pred_flag = pps->constrained_intra_pred_flag,
715       .cu_qp_delta_enabled_flag = pps->cu_qp_delta_enabled_flag,
716       .weighted_pred_flag = pps->weighted_pred_flag,
717       .weighted_bipred_flag = pps->weighted_bipred_flag,
718       .transquant_bypass_enabled_flag = pps->transquant_bypass_enabled_flag,
719       .tiles_enabled_flag = pps->tiles_enabled_flag,
720       .entropy_coding_sync_enabled_flag = pps->entropy_coding_sync_enabled_flag,
721       .pps_loop_filter_across_slices_enabled_flag = pps->loop_filter_across_slices_enabled_flag,
722       .loop_filter_across_tiles_enabled_flag = pps->loop_filter_across_tiles_enabled_flag,
723       .pcm_loop_filter_disabled_flag = sps->pcm_loop_filter_disabled_flag,
724       /* Not set by FFMPEG either */
725       .NoPicReorderingFlag = 0,
726       .NoBiPredFlag = 0,
727     },
728     .slice_parsing_fields.bits = {
729       .lists_modification_present_flag = pps->lists_modification_present_flag,
730       .long_term_ref_pics_present_flag = sps->long_term_ref_pics_present_flag,
731       .sps_temporal_mvp_enabled_flag = sps->temporal_mvp_enabled_flag,
732       .cabac_init_present_flag = pps->cabac_init_present_flag,
733       .output_flag_present_flag = pps->output_flag_present_flag,
734       .dependent_slice_segments_enabled_flag = pps->dependent_slice_segments_enabled_flag,
735       .pps_slice_chroma_qp_offsets_present_flag = pps->slice_chroma_qp_offsets_present_flag,
736       .sample_adaptive_offset_enabled_flag = sps->sample_adaptive_offset_enabled_flag,
737       .deblocking_filter_override_enabled_flag = pps->deblocking_filter_override_enabled_flag,
738       .pps_disable_deblocking_filter_flag = pps->deblocking_filter_disabled_flag,
739       .slice_segment_header_extension_present_flag = pps->slice_segment_header_extension_present_flag,
740       .RapPicFlag = picture->RapPicFlag,
741       .IdrPicFlag = GST_H265_IS_NAL_TYPE_IDR (slice->nalu.type),
742       .IntraPicFlag = GST_H265_IS_NAL_TYPE_IRAP (slice->nalu.type),
743     },
744   };
745   /* *INDENT-ON* */
746
747   if (_is_range_extension_profile (self->parent.profile)
748       || _is_screen_content_ext_profile (self->parent.profile)) {
749     _fill_picture_range_ext_parameter (self, sps, pps);
750     if (_is_screen_content_ext_profile (self->parent.profile))
751       _fill_screen_content_ext_parameter (self, sps, pps);
752   }
753
754   for (i = 0; i <= pps->num_tile_columns_minus1; i++)
755     pic_param->base.column_width_minus1[i] = pps->column_width_minus1[i];
756
757   for (i = 0; i <= pps->num_tile_rows_minus1; i++)
758     pic_param->base.row_height_minus1[i] = pps->row_height_minus1[i];
759
760   _fill_vaapi_pic (decoder, &pic_param->base.CurrPic, picture);
761
762   /* reference frames */
763   {
764     GArray *ref_list = gst_h265_dpb_get_pictures_all (dpb);
765     guint j;
766
767     i = 0;
768     for (j = 0; j < 15 && j < ref_list->len; j++) {
769       GstH265Picture *pic = g_array_index (ref_list, GstH265Picture *, j);
770
771       if (pic->ref) {
772         _fill_vaapi_pic (decoder, &pic_param->base.ReferenceFrames[i], pic);
773         i++;
774       }
775     }
776     g_array_unref (ref_list);
777
778     /* 7.4.3.3.3, the current decoded picture is marked as "used for
779        long-term reference". Current picture is not in the DPB now. */
780     if (pps->pps_scc_extension_params.pps_curr_pic_ref_enabled_flag && i < 15) {
781       pic_param->base.ReferenceFrames[i].picture_id =
782           gst_va_decode_picture_get_surface (gst_h265_picture_get_user_data
783           (picture));
784       pic_param->base.ReferenceFrames[i].pic_order_cnt = picture->pic_order_cnt;
785       pic_param->base.ReferenceFrames[i].flags |=
786           VA_PICTURE_HEVC_LONG_TERM_REFERENCE;
787       pic_param->base.ReferenceFrames[i].flags |=
788           _find_frame_rps_type (decoder, picture);
789       i++;
790     }
791
792     for (; i < 15; i++)
793       _init_vaapi_pic (&pic_param->base.ReferenceFrames[i]);
794   }
795
796   pic_param_size = _is_range_extension_profile (self->parent.profile)
797       || _is_screen_content_ext_profile (self->parent.profile) ?
798       sizeof (*pic_param) : sizeof (pic_param->base);
799   if (!gst_va_decoder_add_param_buffer (base->decoder, va_pic,
800           VAPictureParameterBufferType, pic_param, pic_param_size))
801     return GST_FLOW_ERROR;
802
803   if (pps->scaling_list_data_present_flag ||
804       (sps->scaling_list_enabled_flag
805           && !sps->scaling_list_data_present_flag)) {
806     scaling_list = &pps->scaling_list;
807     GST_DEBUG_OBJECT (decoder, "Passing scaling list from PPS");
808   } else if (sps->scaling_list_enabled_flag &&
809       sps->scaling_list_data_present_flag) {
810     scaling_list = &sps->scaling_list;
811     GST_DEBUG_OBJECT (decoder, "Passing scaling list from SPS");
812   }
813
814   if (scaling_list) {
815     for (i = 0; i < G_N_ELEMENTS (iq_matrix.ScalingList4x4); i++)
816       gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal
817           (iq_matrix.ScalingList4x4[i], scaling_list->scaling_lists_4x4[i]);
818
819     for (i = 0; i < G_N_ELEMENTS (iq_matrix.ScalingList8x8); i++)
820       gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal
821           (iq_matrix.ScalingList8x8[i], scaling_list->scaling_lists_8x8[i]);
822
823     for (i = 0; i < G_N_ELEMENTS (iq_matrix.ScalingList16x16); i++)
824       gst_h265_quant_matrix_16x16_get_raster_from_uprightdiagonal
825           (iq_matrix.ScalingList16x16[i], scaling_list->scaling_lists_16x16[i]);
826
827     for (i = 0; i < G_N_ELEMENTS (iq_matrix.ScalingList32x32); i++)
828       gst_h265_quant_matrix_32x32_get_raster_from_uprightdiagonal
829           (iq_matrix.ScalingList32x32[i], scaling_list->scaling_lists_32x32[i]);
830
831     for (i = 0; i < 6; i++)
832       iq_matrix.ScalingListDC16x16[i] =
833           scaling_list->scaling_list_dc_coef_minus8_16x16[i] + 8;
834
835     for (i = 0; i < 2; i++)
836       iq_matrix.ScalingListDC32x32[i] =
837           scaling_list->scaling_list_dc_coef_minus8_32x32[i] + 8;
838
839     if (!gst_va_decoder_add_param_buffer (base->decoder, va_pic,
840             VAIQMatrixBufferType, &iq_matrix, sizeof (iq_matrix))) {
841       return GST_FLOW_ERROR;
842     }
843   }
844
845   return GST_FLOW_OK;
846 }
847
848 static GstFlowReturn
849 gst_va_h265_dec_new_picture (GstH265Decoder * decoder,
850     GstVideoCodecFrame * frame, GstH265Picture * picture)
851 {
852   GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
853   GstVaH265Dec *self = GST_VA_H265_DEC (decoder);
854   GstVaDecodePicture *pic;
855   GstBuffer *output_buffer;
856   GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
857
858   output_buffer = gst_video_decoder_allocate_output_buffer (vdec);
859   if (!output_buffer) {
860     self->last_ret = GST_FLOW_ERROR;
861     goto error;
862   }
863   self->last_ret = GST_FLOW_OK;
864
865   pic = gst_va_decode_picture_new (base->decoder, output_buffer);
866   gst_buffer_unref (output_buffer);
867
868   gst_h265_picture_set_user_data (picture, pic,
869       (GDestroyNotify) gst_va_decode_picture_free);
870
871   GST_LOG_OBJECT (self, "New va decode picture %p - %#x", pic,
872       gst_va_decode_picture_get_surface (pic));
873
874   return GST_FLOW_OK;
875
876 error:
877   {
878     GST_WARNING_OBJECT (self,
879         "Failed to allocated output buffer, return %s",
880         gst_flow_get_name (self->last_ret));
881     return self->last_ret;
882   }
883 }
884
885 static guint
886 _get_rtformat (GstVaH265Dec * self, guint8 bit_depth_luma,
887     guint8 bit_depth_chroma, guint8 chroma_format_idc)
888 {
889   guint8 bit_num = MAX (bit_depth_luma, bit_depth_chroma);
890
891   switch (bit_num) {
892     case 11:
893     case 12:
894       if (chroma_format_idc == 3)
895         return VA_RT_FORMAT_YUV444_12;
896       if (chroma_format_idc == 2)
897         return VA_RT_FORMAT_YUV422_12;
898       else
899         return VA_RT_FORMAT_YUV420_12;
900       break;
901     case 9:
902     case 10:
903       if (chroma_format_idc == 3)
904         return VA_RT_FORMAT_YUV444_10;
905       if (chroma_format_idc == 2)
906         return VA_RT_FORMAT_YUV422_10;
907       else
908         return VA_RT_FORMAT_YUV420_10;
909       break;
910     case 8:
911       if (chroma_format_idc == 3)
912         return VA_RT_FORMAT_YUV444;
913       if (chroma_format_idc == 2)
914         return VA_RT_FORMAT_YUV422;
915       else
916         return VA_RT_FORMAT_YUV420;
917       break;
918     default:
919       GST_ERROR_OBJECT (self, "Unsupported chroma format: %d "
920           "(with depth luma: %d, with depth chroma: %d)",
921           chroma_format_idc, bit_depth_luma, bit_depth_chroma);
922       return 0;
923   }
924 }
925
926 /* *INDENT-OFF* */
927 static const struct
928 {
929   GstH265Profile profile;
930   VAProfile va_profile;
931 } profile_map[] = {
932 #define P(idc, va) { G_PASTE (GST_H265_PROFILE_, idc), G_PASTE (VAProfileHEVC, va) }
933   P (MAIN, Main),
934   P (MAIN_10, Main10),
935   /*P (MAIN_STILL_PICTURE, ),
936   P (MONOCHROME, ),
937   P (MONOCHROME_12, ),
938   P (MONOCHROME_16, ),*/
939   P (MAIN_12, Main12),
940   P (MAIN_422_10, Main422_10),
941   P (MAIN_422_12, Main422_12),
942   P (MAIN_444, Main444),
943   P (MAIN_444_10, Main444_10),
944   P (MAIN_444_12, Main444_12),
945   /*P (MAIN_INTRA, ),
946   P (MAIN_10_INTRA, ),
947   P (MAIN_12_INTRA, ),
948   P (MAIN_422_10_INTRA, ),
949   P (MAIN_422_12_INTRA, ),
950   P (MAIN_444_INTRA, ),
951   P (MAIN_444_10_INTRA, ),
952   P (MAIN_444_12_INTRA, ),
953   P (MAIN_444_16_INTRA, ),
954   P (MAIN_444_STILL_PICTURE, ),
955   P (MAIN_444_16_STILL_PICTURE, ),
956   P (MONOCHROME_10, ),
957   P (HIGH_THROUGHPUT_444, ),
958   P (HIGH_THROUGHPUT_444_10, ),
959   P (HIGH_THROUGHPUT_444_14, ),
960   P (HIGH_THROUGHPUT_444_16_INTRA, ),*/
961   P (SCREEN_EXTENDED_MAIN, SccMain),
962   P (SCREEN_EXTENDED_MAIN_10, SccMain10),
963   P (SCREEN_EXTENDED_MAIN_444, SccMain444),
964   /*P (SCREEN_EXTENDED_MAIN_444_10, ),
965   P (SCREEN_EXTENDED_HIGH_THROUGHPUT_444, ),
966   P (SCREEN_EXTENDED_HIGH_THROUGHPUT_444_10, ),
967   P (SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14, ),
968   P (MULTIVIEW_MAIN, ),
969   P (SCALABLE_MAIN, ),
970   P (SCALABLE_MAIN_10, ),
971   P (SCALABLE_MONOCHROME, ),
972   P (SCALABLE_MONOCHROME_12, ),
973   P (SCALABLE_MONOCHROME_16, ),
974   P (SCALABLE_MAIN_444, ),
975   P (3D_MAIN, ),*/
976 #undef P
977 };
978 /* *INDENT-ON* */
979
980 static VAProfile
981 _get_profile (GstVaH265Dec * self, const GstH265SPS * sps, gint max_dpb_size)
982 {
983   GstH265Decoder *h265_decoder = GST_H265_DECODER (self);
984   GstVaBaseDec *base = GST_VA_BASE_DEC (self);
985   GstH265Profile profile = gst_h265_get_profile_from_sps ((GstH265SPS *) sps);
986   VAProfile profiles[4];
987   gint i = 0, j;
988
989   /* 1. The profile directly specified by the SPS should always be the
990      first choice. It is the exact one.
991      2. The profile in the input caps may contain the compatible profile
992      chosen by the upstream element. Upstream element such as the parse
993      may already decide the best compatible profile for us. We also need
994      to consider it as a choice. */
995
996   for (j = 0; j < G_N_ELEMENTS (profile_map); j++) {
997     if (profile_map[j].profile == profile) {
998       profiles[i++] = profile_map[j].va_profile;
999       break;
1000     }
1001   }
1002
1003   if (h265_decoder->input_state->caps
1004       && gst_caps_is_fixed (h265_decoder->input_state->caps)) {
1005     GstH265Profile compatible_profile = GST_H265_PROFILE_INVALID;
1006     GstStructure *structure;
1007     const gchar *profile_str;
1008
1009     structure = gst_caps_get_structure (h265_decoder->input_state->caps, 0);
1010
1011     profile_str = gst_structure_get_string (structure, "profile");
1012     if (profile_str)
1013       compatible_profile = gst_h265_profile_from_string (profile_str);
1014
1015     if (compatible_profile != profile) {
1016       GST_INFO_OBJECT (self, "The upstream set the compatible profile %s, "
1017           "also consider it as a candidate.", profile_str);
1018
1019       for (j = 0; j < G_N_ELEMENTS (profile_map); j++) {
1020         if (profile_map[j].profile == compatible_profile) {
1021           profiles[i++] = profile_map[j].va_profile;
1022           break;
1023         }
1024       }
1025     }
1026   }
1027
1028   for (j = 0; j < i && j < G_N_ELEMENTS (profiles); j++) {
1029     if (gst_va_decoder_has_profile (base->decoder, profiles[j]))
1030       return profiles[j];
1031   }
1032
1033   GST_ERROR_OBJECT (self, "Unsupported profile: %d", profile);
1034
1035   return VAProfileNone;
1036 }
1037
1038 static GstFlowReturn
1039 gst_va_h265_dec_new_sequence (GstH265Decoder * decoder, const GstH265SPS * sps,
1040     gint max_dpb_size)
1041 {
1042   GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
1043   GstVaH265Dec *self = GST_VA_H265_DEC (decoder);
1044   VAProfile profile;
1045   gint display_width;
1046   gint display_height;
1047   gint padding_left, padding_right, padding_top, padding_bottom;
1048   guint rt_format;
1049   gboolean negotiation_needed = FALSE;
1050
1051   if (self->dpb_size < max_dpb_size)
1052     self->dpb_size = max_dpb_size;
1053
1054   if (sps->conformance_window_flag) {
1055     display_width = sps->crop_rect_width;
1056     display_height = sps->crop_rect_height;
1057     padding_left = sps->crop_rect_x;
1058     padding_right = sps->width - sps->crop_rect_x - display_width;
1059     padding_top = sps->crop_rect_y;
1060     padding_bottom = sps->height - sps->crop_rect_y - display_height;
1061   } else {
1062     display_width = sps->width;
1063     display_height = sps->height;
1064     padding_left = padding_right = padding_top = padding_bottom = 0;
1065   }
1066
1067   profile = _get_profile (self, sps, max_dpb_size);
1068   if (profile == VAProfileNone)
1069     return GST_FLOW_NOT_NEGOTIATED;
1070
1071   rt_format = _get_rtformat (self, sps->bit_depth_luma_minus8 + 8,
1072       sps->bit_depth_chroma_minus8 + 8, sps->chroma_format_idc);
1073   if (rt_format == 0)
1074     return GST_FLOW_NOT_NEGOTIATED;
1075
1076   if (!gst_va_decoder_config_is_equal (base->decoder, profile,
1077           rt_format, sps->width, sps->height)) {
1078     base->profile = profile;
1079     base->rt_format = rt_format;
1080     self->coded_width = sps->width;
1081     self->coded_height = sps->height;
1082
1083     negotiation_needed = TRUE;
1084     GST_INFO_OBJECT (self, "Format changed to %s [%x] (%dx%d)",
1085         gst_va_profile_name (profile), rt_format, self->coded_width,
1086         self->coded_height);
1087   }
1088
1089   if (base->width != display_width || base->height != display_height) {
1090     base->width = display_width;
1091     base->height = display_height;
1092
1093     negotiation_needed = TRUE;
1094     GST_INFO_OBJECT (self, "Resolution changed to %dx%d", base->width,
1095         base->height);
1096   }
1097
1098   base->need_valign = base->width < self->coded_width
1099       || base->height < self->coded_height;
1100   if (base->need_valign) {
1101     /* *INDENT-OFF* */
1102     if (base->valign.padding_left != padding_left ||
1103         base->valign.padding_right != padding_right ||
1104         base->valign.padding_top != padding_top ||
1105         base->valign.padding_bottom != padding_bottom) {
1106       negotiation_needed = TRUE;
1107       GST_INFO_OBJECT (self, "crop rect changed to (%d,%d)-->(%d,%d)",
1108           padding_left, padding_top, padding_right, padding_bottom);
1109     }
1110     base->valign = (GstVideoAlignment) {
1111       .padding_left = padding_left,
1112       .padding_right = padding_right,
1113       .padding_top = padding_top,
1114       .padding_bottom = padding_bottom,
1115     };
1116     /* *INDENT-ON* */
1117   }
1118
1119   base->min_buffers = self->dpb_size + 4;       /* dpb size + scratch surfaces */
1120
1121   if (negotiation_needed) {
1122     base->need_negotiation = TRUE;
1123     if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) {
1124       GST_ERROR_OBJECT (self, "Failed to negotiate with downstream");
1125       return GST_FLOW_NOT_NEGOTIATED;
1126     }
1127   }
1128
1129   {
1130     /* FIXME: We don't have parser API for sps_range_extension, so
1131      * assuming high_precision_offsets_enabled_flag as zero */
1132     guint high_precision_offsets_enabled_flag = 0, bitdepthC = 0;
1133
1134     /* Calculate WpOffsetHalfRangeC: (7-34) */
1135     bitdepthC = sps->bit_depth_chroma_minus8 + 8;
1136     self->WpOffsetHalfRangeC =
1137         1 << (high_precision_offsets_enabled_flag ? (bitdepthC - 1) : 7);
1138   }
1139
1140   return GST_FLOW_OK;
1141 }
1142
1143 static GstCaps *
1144 _complete_sink_caps (GstCaps * sinkcaps)
1145 {
1146   GstCaps *caps = gst_caps_copy (sinkcaps);
1147   GValue val = G_VALUE_INIT;
1148   const gchar *streamformat[] = { "hvc1", "hev1", "byte-stream" };
1149   gint i;
1150
1151   g_value_init (&val, G_TYPE_STRING);
1152   g_value_set_string (&val, "au");
1153   gst_caps_set_value (caps, "alignment", &val);
1154   g_value_unset (&val);
1155
1156   gst_value_list_init (&val, G_N_ELEMENTS (streamformat));
1157   for (i = 0; i < G_N_ELEMENTS (streamformat); i++) {
1158     GValue v = G_VALUE_INIT;
1159
1160     g_value_init (&v, G_TYPE_STRING);
1161     g_value_set_string (&v, streamformat[i]);
1162     gst_value_list_append_value (&val, &v);
1163     g_value_unset (&v);
1164   }
1165   gst_caps_set_value (caps, "stream-format", &val);
1166   g_value_unset (&val);
1167
1168   return caps;
1169 }
1170
1171 static GstCaps *
1172 gst_va_h265_dec_getcaps (GstVideoDecoder * decoder, GstCaps * filter)
1173 {
1174   GstCaps *sinkcaps, *caps = NULL, *tmp;
1175   GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
1176
1177   if (base->decoder)
1178     caps = gst_va_decoder_get_sinkpad_caps (base->decoder);
1179
1180   if (caps) {
1181     sinkcaps = _complete_sink_caps (caps);
1182     gst_caps_unref (caps);
1183     if (filter) {
1184       tmp = gst_caps_intersect_full (filter, sinkcaps,
1185           GST_CAPS_INTERSECT_FIRST);
1186       gst_caps_unref (sinkcaps);
1187       caps = tmp;
1188     } else {
1189       caps = sinkcaps;
1190     }
1191     GST_LOG_OBJECT (base, "Returning caps %" GST_PTR_FORMAT, caps);
1192   } else if (!caps) {
1193     caps = gst_video_decoder_proxy_getcaps (decoder, NULL, filter);
1194   }
1195
1196   return caps;
1197 }
1198
1199 static gboolean
1200 gst_va_h265_dec_negotiate (GstVideoDecoder * decoder)
1201 {
1202   GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
1203   GstVaH265Dec *self = GST_VA_H265_DEC (decoder);
1204   GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
1205   GstCapsFeatures *capsfeatures = NULL;
1206   GstH265Decoder *h265dec = GST_H265_DECODER (decoder);
1207
1208   /* Ignore downstream renegotiation request. */
1209   if (!base->need_negotiation)
1210     return TRUE;
1211
1212   base->need_negotiation = FALSE;
1213
1214   if (gst_va_decoder_is_open (base->decoder)
1215       && !gst_va_decoder_close (base->decoder))
1216     return FALSE;
1217
1218   if (!gst_va_decoder_open (base->decoder, base->profile, base->rt_format))
1219     return FALSE;
1220
1221   if (!gst_va_decoder_set_frame_size (base->decoder, self->coded_width,
1222           self->coded_height))
1223     return FALSE;
1224
1225   if (base->output_state)
1226     gst_video_codec_state_unref (base->output_state);
1227
1228   gst_va_base_dec_get_preferred_format_and_caps_features (base, &format,
1229       &capsfeatures);
1230
1231   base->output_state =
1232       gst_video_decoder_set_output_state (decoder, format,
1233       base->width, base->height, h265dec->input_state);
1234
1235   base->output_state->caps = gst_video_info_to_caps (&base->output_state->info);
1236   if (capsfeatures)
1237     gst_caps_set_features_simple (base->output_state->caps, capsfeatures);
1238
1239   GST_INFO_OBJECT (self, "Negotiated caps %" GST_PTR_FORMAT,
1240       base->output_state->caps);
1241
1242   return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
1243 }
1244
1245 static void
1246 gst_va_h265_dec_dispose (GObject * object)
1247 {
1248   g_free (GST_VA_H265_DEC (object)->prev_slice.data);
1249
1250   gst_va_base_dec_close (GST_VIDEO_DECODER (object));
1251
1252   G_OBJECT_CLASS (parent_class)->dispose (object);
1253 }
1254
1255 static void
1256 gst_va_h265_dec_class_init (gpointer g_class, gpointer class_data)
1257 {
1258   GstCaps *src_doc_caps, *sink_doc_caps;
1259   GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
1260   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
1261   GstH265DecoderClass *h265decoder_class = GST_H265_DECODER_CLASS (g_class);
1262   GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (g_class);
1263   struct CData *cdata = class_data;
1264   gchar *long_name;
1265
1266   if (cdata->description) {
1267     long_name = g_strdup_printf ("VA-API H.265 Decoder in %s",
1268         cdata->description);
1269   } else {
1270     long_name = g_strdup ("VA-API H.265 Decoder");
1271   }
1272
1273   gst_element_class_set_metadata (element_class, long_name,
1274       "Codec/Decoder/Video/Hardware",
1275       "VA-API based H.265 video decoder",
1276       "Nicolas Dufresne <nicolas.dufresne@collabora.com>");
1277
1278   sink_doc_caps = gst_caps_from_string (sink_caps_str);
1279   src_doc_caps = gst_caps_from_string (src_caps_str);
1280
1281   parent_class = g_type_class_peek_parent (g_class);
1282
1283   gst_va_base_dec_class_init (GST_VA_BASE_DEC_CLASS (g_class), HEVC,
1284       cdata->render_device_path, cdata->sink_caps, cdata->src_caps,
1285       src_doc_caps, sink_doc_caps);
1286
1287   gobject_class->dispose = gst_va_h265_dec_dispose;
1288
1289   decoder_class->getcaps = GST_DEBUG_FUNCPTR (gst_va_h265_dec_getcaps);
1290   decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_va_h265_dec_negotiate);
1291
1292   h265decoder_class->new_sequence =
1293       GST_DEBUG_FUNCPTR (gst_va_h265_dec_new_sequence);
1294   h265decoder_class->decode_slice =
1295       GST_DEBUG_FUNCPTR (gst_va_h265_dec_decode_slice);
1296
1297   h265decoder_class->new_picture =
1298       GST_DEBUG_FUNCPTR (gst_va_h265_dec_new_picture);
1299   h265decoder_class->output_picture =
1300       GST_DEBUG_FUNCPTR (gst_va_h265_dec_output_picture);
1301   h265decoder_class->start_picture =
1302       GST_DEBUG_FUNCPTR (gst_va_h265_dec_start_picture);
1303   h265decoder_class->end_picture =
1304       GST_DEBUG_FUNCPTR (gst_va_h265_dec_end_picture);
1305
1306   g_free (long_name);
1307   g_free (cdata->description);
1308   g_free (cdata->render_device_path);
1309   gst_caps_unref (cdata->src_caps);
1310   gst_caps_unref (cdata->sink_caps);
1311   g_free (cdata);
1312 }
1313
1314 static void
1315 gst_va_h265_dec_init (GTypeInstance * instance, gpointer g_class)
1316 {
1317   gst_va_base_dec_init (GST_VA_BASE_DEC (instance), GST_CAT_DEFAULT);
1318   gst_h265_decoder_set_process_ref_pic_lists (GST_H265_DECODER (instance),
1319       TRUE);
1320 }
1321
1322 static gpointer
1323 _register_debug_category (gpointer data)
1324 {
1325   GST_DEBUG_CATEGORY_INIT (gst_va_h265dec_debug, "vah265dec", 0,
1326       "VA H265 decoder");
1327
1328   return NULL;
1329 }
1330
1331 gboolean
1332 gst_va_h265_dec_register (GstPlugin * plugin, GstVaDevice * device,
1333     GstCaps * sink_caps, GstCaps * src_caps, guint rank)
1334 {
1335   static GOnce debug_once = G_ONCE_INIT;
1336   GType type;
1337   GTypeInfo type_info = {
1338     .class_size = sizeof (GstVaH265DecClass),
1339     .class_init = gst_va_h265_dec_class_init,
1340     .instance_size = sizeof (GstVaH265Dec),
1341     .instance_init = gst_va_h265_dec_init,
1342   };
1343   struct CData *cdata;
1344   gboolean ret;
1345   gchar *type_name, *feature_name;
1346
1347   g_return_val_if_fail (GST_IS_PLUGIN (plugin), FALSE);
1348   g_return_val_if_fail (GST_IS_VA_DEVICE (device), FALSE);
1349   g_return_val_if_fail (GST_IS_CAPS (sink_caps), FALSE);
1350   g_return_val_if_fail (GST_IS_CAPS (src_caps), FALSE);
1351
1352   cdata = g_new (struct CData, 1);
1353   cdata->description = NULL;
1354   cdata->render_device_path = g_strdup (device->render_device_path);
1355   cdata->sink_caps = _complete_sink_caps (sink_caps);
1356   cdata->src_caps = gst_caps_ref (src_caps);
1357
1358   /* class data will be leaked if the element never gets instantiated */
1359   GST_MINI_OBJECT_FLAG_SET (cdata->sink_caps,
1360       GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);
1361   GST_MINI_OBJECT_FLAG_SET (src_caps, GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);
1362
1363   type_info.class_data = cdata;
1364
1365   type_name = g_strdup ("GstVaH265Dec");
1366   feature_name = g_strdup ("vah265dec");
1367
1368   /* The first decoder to be registered should use a constant name,
1369    * like vah265dec, for any additional decoders, we create unique
1370    * names, using inserting the render device name. */
1371   if (g_type_from_name (type_name)) {
1372     gchar *basename = g_path_get_basename (device->render_device_path);
1373     g_free (type_name);
1374     g_free (feature_name);
1375     type_name = g_strdup_printf ("GstVa%sH265Dec", basename);
1376     feature_name = g_strdup_printf ("va%sh265dec", basename);
1377     cdata->description = basename;
1378
1379     /* lower rank for non-first device */
1380     if (rank > 0)
1381       rank--;
1382   }
1383
1384   g_once (&debug_once, _register_debug_category, NULL);
1385
1386   type = g_type_register_static (GST_TYPE_H265_DECODER,
1387       type_name, &type_info, 0);
1388
1389   ret = gst_element_register (plugin, feature_name, rank, type);
1390
1391   g_free (type_name);
1392   g_free (feature_name);
1393
1394   return ret;
1395 }