xref: /aosp_15_r20/external/mesa3d/src/gallium/frontends/vdpau/decode.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /**************************************************************************
2  *
3  * Copyright 2010 Thomas Balling Sørensen.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28 #include "util/u_memory.h"
29 #include "util/u_math.h"
30 #include "util/u_debug.h"
31 #include "util/u_video.h"
32 
33 #include "util/vl_vlc.h"
34 
35 #include "vl/vl_codec.h"
36 #include "vdpau_private.h"
37 
38 #define AV1_KEY_FRAME           0
39 #define AV1_REFS_PER_FRAME      7
40 #define AV1_NUM_REF_FRAMES      8
41 #define AV1_PRIMARY_REF_NONE    AV1_REFS_PER_FRAME
42 #define AV1_SUPERRES_DENOM_MIN  9
43 #define AV1_SUPERRES_NUM        8
44 
45 /**
46  * Create a VdpDecoder.
47  */
48 VdpStatus
vlVdpDecoderCreate(VdpDevice device,VdpDecoderProfile profile,uint32_t width,uint32_t height,uint32_t max_references,VdpDecoder * decoder)49 vlVdpDecoderCreate(VdpDevice device,
50                    VdpDecoderProfile profile,
51                    uint32_t width, uint32_t height,
52                    uint32_t max_references,
53                    VdpDecoder *decoder)
54 {
55    struct pipe_video_codec templat = {};
56    struct pipe_context *pipe;
57    struct pipe_screen *screen;
58    vlVdpDevice *dev;
59    vlVdpDecoder *vldecoder;
60    VdpStatus ret;
61    bool supported;
62    uint32_t maxwidth, maxheight;
63 
64    if (!decoder)
65       return VDP_STATUS_INVALID_POINTER;
66    *decoder = 0;
67 
68    if (!(width && height))
69       return VDP_STATUS_INVALID_VALUE;
70 
71    templat.profile = ProfileToPipe(profile);
72    if (templat.profile == PIPE_VIDEO_PROFILE_UNKNOWN)
73       return VDP_STATUS_INVALID_DECODER_PROFILE;
74 
75    dev = vlGetDataHTAB(device);
76    if (!dev)
77       return VDP_STATUS_INVALID_HANDLE;
78 
79    pipe = dev->context;
80    screen = dev->vscreen->pscreen;
81 
82    mtx_lock(&dev->mutex);
83 
84    supported = vl_codec_supported(screen, templat.profile, false);
85    if (!supported) {
86       mtx_unlock(&dev->mutex);
87       return VDP_STATUS_INVALID_DECODER_PROFILE;
88    }
89 
90    maxwidth = screen->get_video_param
91    (
92       screen,
93       templat.profile,
94       PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
95       PIPE_VIDEO_CAP_MAX_WIDTH
96    );
97    maxheight = screen->get_video_param
98    (
99       screen,
100       templat.profile,
101       PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
102       PIPE_VIDEO_CAP_MAX_HEIGHT
103    );
104    if (width > maxwidth || height > maxheight) {
105       mtx_unlock(&dev->mutex);
106       return VDP_STATUS_INVALID_SIZE;
107    }
108 
109    vldecoder = CALLOC(1,sizeof(vlVdpDecoder));
110    if (!vldecoder) {
111       mtx_unlock(&dev->mutex);
112       return VDP_STATUS_RESOURCES;
113    }
114 
115    DeviceReference(&vldecoder->device, dev);
116 
117    templat.entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM;
118    templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;
119    templat.width = width;
120    templat.height = height;
121    templat.max_references = max_references;
122 
123    if (u_reduce_video_profile(templat.profile) ==
124        PIPE_VIDEO_FORMAT_MPEG4_AVC)
125       templat.level = u_get_h264_level(templat.width, templat.height,
126                             &templat.max_references);
127 
128    vldecoder->decoder = pipe->create_video_codec(pipe, &templat);
129 
130    if (!vldecoder->decoder) {
131       ret = VDP_STATUS_ERROR;
132       goto error_decoder;
133    }
134 
135    *decoder = vlAddDataHTAB(vldecoder);
136    if (*decoder == 0) {
137       ret = VDP_STATUS_ERROR;
138       goto error_handle;
139    }
140 
141    (void) mtx_init(&vldecoder->mutex, mtx_plain);
142    mtx_unlock(&dev->mutex);
143 
144    return VDP_STATUS_OK;
145 
146 error_handle:
147    vldecoder->decoder->destroy(vldecoder->decoder);
148 
149 error_decoder:
150    mtx_unlock(&dev->mutex);
151    DeviceReference(&vldecoder->device, NULL);
152    FREE(vldecoder);
153    return ret;
154 }
155 
156 /**
157  * Destroy a VdpDecoder.
158  */
159 VdpStatus
vlVdpDecoderDestroy(VdpDecoder decoder)160 vlVdpDecoderDestroy(VdpDecoder decoder)
161 {
162    vlVdpDecoder *vldecoder;
163 
164    vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
165    if (!vldecoder)
166       return VDP_STATUS_INVALID_HANDLE;
167 
168    mtx_lock(&vldecoder->mutex);
169    vldecoder->decoder->destroy(vldecoder->decoder);
170    mtx_unlock(&vldecoder->mutex);
171    mtx_destroy(&vldecoder->mutex);
172 
173    vlRemoveDataHTAB(decoder);
174    DeviceReference(&vldecoder->device, NULL);
175    FREE(vldecoder);
176 
177    return VDP_STATUS_OK;
178 }
179 
180 /**
181  * Retrieve the parameters used to create a VdpDecoder.
182  */
183 VdpStatus
vlVdpDecoderGetParameters(VdpDecoder decoder,VdpDecoderProfile * profile,uint32_t * width,uint32_t * height)184 vlVdpDecoderGetParameters(VdpDecoder decoder,
185                           VdpDecoderProfile *profile,
186                           uint32_t *width,
187                           uint32_t *height)
188 {
189    vlVdpDecoder *vldecoder;
190 
191    vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
192    if (!vldecoder)
193       return VDP_STATUS_INVALID_HANDLE;
194 
195    *profile = PipeToProfile(vldecoder->decoder->profile);
196    *width = vldecoder->decoder->width;
197    *height = vldecoder->decoder->height;
198 
199    return VDP_STATUS_OK;
200 }
201 
202 static VdpStatus
vlVdpGetReferenceFrame(VdpVideoSurface handle,struct pipe_video_buffer ** ref_frame)203 vlVdpGetReferenceFrame(VdpVideoSurface handle, struct pipe_video_buffer **ref_frame)
204 {
205    vlVdpSurface *surface;
206 
207    /* if surfaces equals VDP_STATUS_INVALID_HANDLE, they are not used */
208    if (handle ==  VDP_INVALID_HANDLE) {
209       *ref_frame = NULL;
210       return VDP_STATUS_OK;
211    }
212 
213    surface = vlGetDataHTAB(handle);
214    if (!surface)
215       return VDP_STATUS_INVALID_HANDLE;
216 
217    *ref_frame = surface->video_buffer;
218    if (!*ref_frame)
219          return VDP_STATUS_INVALID_HANDLE;
220 
221    return VDP_STATUS_OK;
222 }
223 
224 /**
225  * Decode a mpeg 1/2 video.
226  */
227 static VdpStatus
vlVdpDecoderRenderMpeg12(struct pipe_mpeg12_picture_desc * picture,const VdpPictureInfoMPEG1Or2 * picture_info)228 vlVdpDecoderRenderMpeg12(struct pipe_mpeg12_picture_desc *picture,
229                          const VdpPictureInfoMPEG1Or2 *picture_info)
230 {
231    VdpStatus r;
232 
233    VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoding MPEG12\n");
234 
235    r = vlVdpGetReferenceFrame(picture_info->forward_reference, &picture->ref[0]);
236    if (r != VDP_STATUS_OK)
237       return r;
238 
239    r = vlVdpGetReferenceFrame(picture_info->backward_reference, &picture->ref[1]);
240    if (r != VDP_STATUS_OK)
241       return r;
242 
243    picture->picture_coding_type = picture_info->picture_coding_type;
244    picture->picture_structure = picture_info->picture_structure;
245    picture->frame_pred_frame_dct = picture_info->frame_pred_frame_dct;
246    picture->q_scale_type = picture_info->q_scale_type;
247    picture->alternate_scan = picture_info->alternate_scan;
248    picture->intra_vlc_format = picture_info->intra_vlc_format;
249    picture->concealment_motion_vectors = picture_info->concealment_motion_vectors;
250    picture->intra_dc_precision = picture_info->intra_dc_precision;
251    picture->f_code[0][0] = picture_info->f_code[0][0] - 1;
252    picture->f_code[0][1] = picture_info->f_code[0][1] - 1;
253    picture->f_code[1][0] = picture_info->f_code[1][0] - 1;
254    picture->f_code[1][1] = picture_info->f_code[1][1] - 1;
255    picture->num_slices = picture_info->slice_count;
256    picture->top_field_first = picture_info->top_field_first;
257    picture->full_pel_forward_vector = picture_info->full_pel_forward_vector;
258    picture->full_pel_backward_vector = picture_info->full_pel_backward_vector;
259    picture->intra_matrix = picture_info->intra_quantizer_matrix;
260    picture->non_intra_matrix = picture_info->non_intra_quantizer_matrix;
261 
262    return VDP_STATUS_OK;
263 }
264 
265 /**
266  * Decode a mpeg 4 video.
267  */
268 static VdpStatus
vlVdpDecoderRenderMpeg4(struct pipe_mpeg4_picture_desc * picture,const VdpPictureInfoMPEG4Part2 * picture_info)269 vlVdpDecoderRenderMpeg4(struct pipe_mpeg4_picture_desc *picture,
270                         const VdpPictureInfoMPEG4Part2 *picture_info)
271 {
272    VdpStatus r;
273    unsigned i;
274 
275    VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoding MPEG4\n");
276 
277    r = vlVdpGetReferenceFrame(picture_info->forward_reference, &picture->ref[0]);
278    if (r != VDP_STATUS_OK)
279       return r;
280 
281    r = vlVdpGetReferenceFrame(picture_info->backward_reference, &picture->ref[1]);
282    if (r != VDP_STATUS_OK)
283       return r;
284 
285    for (i = 0; i < 2; ++i) {
286       picture->trd[i] = picture_info->trd[i];
287       picture->trb[i] = picture_info->trb[i];
288    }
289    picture->vop_time_increment_resolution = picture_info->vop_time_increment_resolution;
290    picture->vop_coding_type = picture_info->vop_coding_type;
291    picture->vop_fcode_forward = picture_info->vop_fcode_forward;
292    picture->vop_fcode_backward = picture_info->vop_fcode_backward;
293    picture->resync_marker_disable = picture_info->resync_marker_disable;
294    picture->interlaced = picture_info->interlaced;
295    picture->quant_type = picture_info->quant_type;
296    picture->quarter_sample = picture_info->quarter_sample;
297    picture->short_video_header = picture_info->short_video_header;
298    picture->rounding_control = picture_info->rounding_control;
299    picture->alternate_vertical_scan_flag = picture_info->alternate_vertical_scan_flag;
300    picture->top_field_first = picture_info->top_field_first;
301    picture->intra_matrix = picture_info->intra_quantizer_matrix;
302    picture->non_intra_matrix = picture_info->non_intra_quantizer_matrix;
303 
304    return VDP_STATUS_OK;
305 }
306 
307 static VdpStatus
vlVdpDecoderRenderVC1(struct pipe_vc1_picture_desc * picture,const VdpPictureInfoVC1 * picture_info)308 vlVdpDecoderRenderVC1(struct pipe_vc1_picture_desc *picture,
309                       const VdpPictureInfoVC1 *picture_info)
310 {
311    VdpStatus r;
312 
313    VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoding VC-1\n");
314 
315    r = vlVdpGetReferenceFrame(picture_info->forward_reference, &picture->ref[0]);
316    if (r != VDP_STATUS_OK)
317       return r;
318 
319    r = vlVdpGetReferenceFrame(picture_info->backward_reference, &picture->ref[1]);
320    if (r != VDP_STATUS_OK)
321       return r;
322 
323    picture->slice_count = picture_info->slice_count;
324    picture->picture_type = picture_info->picture_type;
325    picture->frame_coding_mode = picture_info->frame_coding_mode;
326    picture->postprocflag = picture_info->postprocflag;
327    picture->pulldown = picture_info->pulldown;
328    picture->interlace = picture_info->interlace;
329    picture->tfcntrflag = picture_info->tfcntrflag;
330    picture->finterpflag = picture_info->finterpflag;
331    picture->psf = picture_info->psf;
332    picture->dquant = picture_info->dquant;
333    picture->panscan_flag = picture_info->panscan_flag;
334    picture->refdist_flag = picture_info->refdist_flag;
335    picture->quantizer = picture_info->quantizer;
336    picture->extended_mv = picture_info->extended_mv;
337    picture->extended_dmv = picture_info->extended_dmv;
338    picture->overlap = picture_info->overlap;
339    picture->vstransform = picture_info->vstransform;
340    picture->loopfilter = picture_info->loopfilter;
341    picture->fastuvmc = picture_info->fastuvmc;
342    picture->range_mapy_flag = picture_info->range_mapy_flag;
343    picture->range_mapy = picture_info->range_mapy;
344    picture->range_mapuv_flag = picture_info->range_mapuv_flag;
345    picture->range_mapuv = picture_info->range_mapuv;
346    picture->multires = picture_info->multires;
347    picture->syncmarker = picture_info->syncmarker;
348    picture->rangered = picture_info->rangered;
349    picture->maxbframes = picture_info->maxbframes;
350    picture->deblockEnable = picture_info->deblockEnable;
351    picture->pquant = picture_info->pquant;
352 
353    return VDP_STATUS_OK;
354 }
355 
356 static VdpStatus
vlVdpDecoderRenderH264(struct pipe_h264_picture_desc * picture,const VdpPictureInfoH264 * picture_info,unsigned level_idc)357 vlVdpDecoderRenderH264(struct pipe_h264_picture_desc *picture,
358                        const VdpPictureInfoH264 *picture_info,
359                        unsigned level_idc)
360 {
361    unsigned i;
362 
363    VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoding H264\n");
364 
365    picture->pps->sps->mb_adaptive_frame_field_flag = picture_info->mb_adaptive_frame_field_flag;
366    picture->pps->sps->frame_mbs_only_flag = picture_info->frame_mbs_only_flag;
367    picture->pps->sps->log2_max_frame_num_minus4 = picture_info->log2_max_frame_num_minus4;
368    picture->pps->sps->pic_order_cnt_type = picture_info->pic_order_cnt_type;
369    picture->pps->sps->log2_max_pic_order_cnt_lsb_minus4 = picture_info->log2_max_pic_order_cnt_lsb_minus4;
370    picture->pps->sps->delta_pic_order_always_zero_flag = picture_info->delta_pic_order_always_zero_flag;
371    picture->pps->sps->direct_8x8_inference_flag = picture_info->direct_8x8_inference_flag;
372    picture->pps->sps->level_idc = level_idc;
373    picture->pps->sps->MinLumaBiPredSize8x8 = (level_idc >= 31); /* See section A.3.3.2 of H264 spec */;
374 
375    picture->pps->transform_8x8_mode_flag = picture_info->transform_8x8_mode_flag;
376    picture->pps->chroma_qp_index_offset = picture_info->chroma_qp_index_offset;
377    picture->pps->second_chroma_qp_index_offset = picture_info->second_chroma_qp_index_offset;
378    picture->pps->pic_init_qp_minus26 = picture_info->pic_init_qp_minus26;
379    /*picture->pps-> pic_init_qs_minus26 not passed in VdpPictureInfoH264*/
380    picture->pps->entropy_coding_mode_flag = picture_info->entropy_coding_mode_flag;
381    picture->pps->deblocking_filter_control_present_flag = picture_info->deblocking_filter_control_present_flag;
382    picture->pps->redundant_pic_cnt_present_flag = picture_info->redundant_pic_cnt_present_flag;
383    picture->pps->constrained_intra_pred_flag = picture_info->constrained_intra_pred_flag;
384    picture->pps->weighted_pred_flag = picture_info->weighted_pred_flag;
385    picture->pps->weighted_bipred_idc = picture_info->weighted_bipred_idc;
386    picture->pps->bottom_field_pic_order_in_frame_present_flag = picture_info->pic_order_present_flag;
387    memcpy(picture->pps->ScalingList4x4, picture_info->scaling_lists_4x4, 6*16);
388    memcpy(picture->pps->ScalingList8x8, picture_info->scaling_lists_8x8, 2*64);
389 
390    picture->slice_count = picture_info->slice_count;
391    picture->field_order_cnt[0] = picture_info->field_order_cnt[0];
392    picture->field_order_cnt[1] = picture_info->field_order_cnt[1];
393    picture->is_reference = picture_info->is_reference;
394    picture->frame_num = picture_info->frame_num;
395    picture->field_pic_flag = picture_info->field_pic_flag;
396    picture->bottom_field_flag = picture_info->bottom_field_flag;
397    picture->num_ref_frames = picture_info->num_ref_frames;
398 
399    picture->num_ref_idx_l0_active_minus1 = picture_info->num_ref_idx_l0_active_minus1;
400    picture->num_ref_idx_l1_active_minus1 = picture_info->num_ref_idx_l1_active_minus1;
401 
402    for (i = 0; i < 16; ++i) {
403       VdpStatus ret = vlVdpGetReferenceFrame
404       (
405          picture_info->referenceFrames[i].surface,
406          &picture->ref[i]
407       );
408       if (ret != VDP_STATUS_OK)
409          return ret;
410 
411       picture->is_long_term[i] = picture_info->referenceFrames[i].is_long_term;
412       picture->top_is_reference[i] = picture_info->referenceFrames[i].top_is_reference;
413       picture->bottom_is_reference[i] = picture_info->referenceFrames[i].bottom_is_reference;
414       picture->field_order_cnt_list[i][0] = picture_info->referenceFrames[i].field_order_cnt[0];
415       picture->field_order_cnt_list[i][1] = picture_info->referenceFrames[i].field_order_cnt[1];
416       picture->frame_num_list[i] = picture_info->referenceFrames[i].frame_idx;
417    }
418 
419    return VDP_STATUS_OK;
420 }
421 
422 static VdpStatus
vlVdpDecoderRenderH265(struct pipe_h265_picture_desc * picture,const VdpPictureInfoHEVC * picture_info)423 vlVdpDecoderRenderH265(struct pipe_h265_picture_desc *picture,
424                        const VdpPictureInfoHEVC *picture_info)
425 {
426    unsigned i;
427 
428    picture->pps->sps->chroma_format_idc = picture_info->chroma_format_idc;
429    picture->pps->sps->separate_colour_plane_flag = picture_info->separate_colour_plane_flag;
430    picture->pps->sps->pic_width_in_luma_samples = picture_info->pic_width_in_luma_samples;
431    picture->pps->sps->pic_height_in_luma_samples = picture_info->pic_height_in_luma_samples;
432    picture->pps->sps->bit_depth_luma_minus8 = picture_info->bit_depth_luma_minus8;
433    picture->pps->sps->bit_depth_chroma_minus8 = picture_info->bit_depth_chroma_minus8;
434    picture->pps->sps->log2_max_pic_order_cnt_lsb_minus4 = picture_info->log2_max_pic_order_cnt_lsb_minus4;
435    picture->pps->sps->sps_max_dec_pic_buffering_minus1 = picture_info->sps_max_dec_pic_buffering_minus1;
436    picture->pps->sps->log2_min_luma_coding_block_size_minus3 = picture_info->log2_min_luma_coding_block_size_minus3;
437    picture->pps->sps->log2_diff_max_min_luma_coding_block_size = picture_info->log2_diff_max_min_luma_coding_block_size;
438    picture->pps->sps->log2_min_transform_block_size_minus2 = picture_info->log2_min_transform_block_size_minus2;
439    picture->pps->sps->log2_diff_max_min_transform_block_size = picture_info->log2_diff_max_min_transform_block_size;
440    picture->pps->sps->max_transform_hierarchy_depth_inter = picture_info->max_transform_hierarchy_depth_inter;
441    picture->pps->sps->max_transform_hierarchy_depth_intra = picture_info->max_transform_hierarchy_depth_intra;
442    picture->pps->sps->scaling_list_enabled_flag = picture_info->scaling_list_enabled_flag;
443    memcpy(picture->pps->sps->ScalingList4x4, picture_info->ScalingList4x4, 6*16);
444    memcpy(picture->pps->sps->ScalingList8x8, picture_info->ScalingList8x8, 6*64);
445    memcpy(picture->pps->sps->ScalingList16x16, picture_info->ScalingList16x16, 6*64);
446    memcpy(picture->pps->sps->ScalingList32x32, picture_info->ScalingList32x32, 2*64);
447    memcpy(picture->pps->sps->ScalingListDCCoeff16x16, picture_info->ScalingListDCCoeff16x16, 6);
448    memcpy(picture->pps->sps->ScalingListDCCoeff32x32, picture_info->ScalingListDCCoeff32x32, 2);
449    picture->pps->sps->amp_enabled_flag = picture_info->amp_enabled_flag;
450    picture->pps->sps->sample_adaptive_offset_enabled_flag = picture_info->sample_adaptive_offset_enabled_flag;
451    picture->pps->sps->pcm_enabled_flag = picture_info->pcm_enabled_flag;
452    picture->pps->sps->pcm_sample_bit_depth_luma_minus1 = picture_info->pcm_sample_bit_depth_luma_minus1;
453    picture->pps->sps->pcm_sample_bit_depth_chroma_minus1 = picture_info->pcm_sample_bit_depth_chroma_minus1;
454    picture->pps->sps->log2_min_pcm_luma_coding_block_size_minus3 = picture_info->log2_min_pcm_luma_coding_block_size_minus3;
455    picture->pps->sps->log2_diff_max_min_pcm_luma_coding_block_size = picture_info->log2_diff_max_min_pcm_luma_coding_block_size;
456    picture->pps->sps->pcm_loop_filter_disabled_flag = picture_info->pcm_loop_filter_disabled_flag;
457    picture->pps->sps->num_short_term_ref_pic_sets = picture_info->num_short_term_ref_pic_sets;
458    picture->pps->sps->long_term_ref_pics_present_flag = picture_info->long_term_ref_pics_present_flag;
459    picture->pps->sps->num_long_term_ref_pics_sps = picture_info->num_long_term_ref_pics_sps;
460    picture->pps->sps->sps_temporal_mvp_enabled_flag = picture_info->sps_temporal_mvp_enabled_flag;
461    picture->pps->sps->strong_intra_smoothing_enabled_flag = picture_info->strong_intra_smoothing_enabled_flag;
462 
463    picture->pps->dependent_slice_segments_enabled_flag = picture_info->dependent_slice_segments_enabled_flag;
464    picture->pps->output_flag_present_flag = picture_info->output_flag_present_flag;
465    picture->pps->num_extra_slice_header_bits = picture_info->num_extra_slice_header_bits;
466    picture->pps->sign_data_hiding_enabled_flag = picture_info->sign_data_hiding_enabled_flag;
467    picture->pps->cabac_init_present_flag = picture_info->cabac_init_present_flag;
468    picture->pps->num_ref_idx_l0_default_active_minus1 = picture_info->num_ref_idx_l0_default_active_minus1;
469    picture->pps->num_ref_idx_l1_default_active_minus1 = picture_info->num_ref_idx_l1_default_active_minus1;
470    picture->pps->init_qp_minus26 = picture_info->init_qp_minus26;
471    picture->pps->constrained_intra_pred_flag = picture_info->constrained_intra_pred_flag;
472    picture->pps->transform_skip_enabled_flag = picture_info->transform_skip_enabled_flag;
473    picture->pps->cu_qp_delta_enabled_flag = picture_info->cu_qp_delta_enabled_flag;
474    picture->pps->diff_cu_qp_delta_depth = picture_info->diff_cu_qp_delta_depth;
475    picture->pps->pps_cb_qp_offset = picture_info->pps_cb_qp_offset;
476    picture->pps->pps_cr_qp_offset = picture_info->pps_cr_qp_offset;
477    picture->pps->pps_slice_chroma_qp_offsets_present_flag = picture_info->pps_slice_chroma_qp_offsets_present_flag;
478    picture->pps->weighted_pred_flag = picture_info->weighted_pred_flag;
479    picture->pps->weighted_bipred_flag = picture_info->weighted_bipred_flag;
480    picture->pps->transquant_bypass_enabled_flag = picture_info->transquant_bypass_enabled_flag;
481    picture->pps->tiles_enabled_flag = picture_info->tiles_enabled_flag;
482    picture->pps->entropy_coding_sync_enabled_flag = picture_info->entropy_coding_sync_enabled_flag;
483    picture->pps->num_tile_columns_minus1 = picture_info->num_tile_columns_minus1;
484    picture->pps->num_tile_rows_minus1 = picture_info->num_tile_rows_minus1;
485    picture->pps->uniform_spacing_flag = picture_info->uniform_spacing_flag;
486    memcpy(picture->pps->column_width_minus1, picture_info->column_width_minus1, 20 * 2);
487    memcpy(picture->pps->row_height_minus1, picture_info->row_height_minus1, 22 * 2);
488    picture->pps->loop_filter_across_tiles_enabled_flag = picture_info->loop_filter_across_tiles_enabled_flag;
489    picture->pps->pps_loop_filter_across_slices_enabled_flag = picture_info->pps_loop_filter_across_slices_enabled_flag;
490    picture->pps->deblocking_filter_control_present_flag = picture_info->deblocking_filter_control_present_flag;
491    picture->pps->deblocking_filter_override_enabled_flag = picture_info->deblocking_filter_override_enabled_flag;
492    picture->pps->pps_deblocking_filter_disabled_flag = picture_info->pps_deblocking_filter_disabled_flag;
493    picture->pps->pps_beta_offset_div2 = picture_info->pps_beta_offset_div2;
494    picture->pps->pps_tc_offset_div2 = picture_info->pps_tc_offset_div2;
495    picture->pps->lists_modification_present_flag = picture_info->lists_modification_present_flag;
496    picture->pps->log2_parallel_merge_level_minus2 = picture_info->log2_parallel_merge_level_minus2;
497    picture->pps->slice_segment_header_extension_present_flag = picture_info->slice_segment_header_extension_present_flag;
498 
499    picture->IDRPicFlag = picture_info->IDRPicFlag;
500    picture->RAPPicFlag = picture_info->RAPPicFlag;
501    picture->IntraPicFlag = picture_info->RAPPicFlag;
502    picture->CurrRpsIdx = picture_info->CurrRpsIdx;
503    picture->NumPocTotalCurr = picture_info->NumPocTotalCurr;
504    picture->NumDeltaPocsOfRefRpsIdx = picture_info->NumDeltaPocsOfRefRpsIdx;
505    picture->NumShortTermPictureSliceHeaderBits = picture_info->NumShortTermPictureSliceHeaderBits;
506    picture->NumLongTermPictureSliceHeaderBits = picture_info->NumLongTermPictureSliceHeaderBits;
507    picture->CurrPicOrderCntVal = picture_info->CurrPicOrderCntVal;
508 
509    for (i = 0; i < 16; ++i) {
510       VdpStatus ret = vlVdpGetReferenceFrame
511       (
512          picture_info->RefPics[i],
513          &picture->ref[i]
514       );
515       if (ret != VDP_STATUS_OK)
516          return ret;
517 
518       picture->PicOrderCntVal[i] = picture_info->PicOrderCntVal[i];
519       picture->IsLongTerm[i] = picture_info->IsLongTerm[i];
520    }
521 
522    picture->NumPocStCurrBefore = picture_info->NumPocStCurrBefore;
523    picture->NumPocStCurrAfter = picture_info->NumPocStCurrAfter;
524    picture->NumPocLtCurr = picture_info->NumPocLtCurr;
525    memcpy(picture->RefPicSetStCurrBefore, picture_info->RefPicSetStCurrBefore, 8);
526    memcpy(picture->RefPicSetStCurrAfter, picture_info->RefPicSetStCurrAfter, 8);
527    memcpy(picture->RefPicSetLtCurr, picture_info->RefPicSetLtCurr, 8);
528    picture->UseRefPicList = false;
529    picture->UseStRpsBits = false;
530 
531    return VDP_STATUS_OK;
532 }
533 
534 static void
copyArrayInt8FromShort(int8_t * dest,const short * src,unsigned count)535 copyArrayInt8FromShort(int8_t *dest, const short *src, unsigned count) {
536    unsigned i;
537 
538    for (i = 0; i < count; ++i) {
539       *dest = *src;
540       ++dest;
541       ++src;
542    }
543 }
544 
545 static void
copyAV1ScalingPoints(uint8_t * value,uint8_t * scaling,const unsigned char point[][2],unsigned count)546 copyAV1ScalingPoints(uint8_t *value, uint8_t *scaling, const unsigned char point[][2], unsigned count) {
547    unsigned i;
548 
549    for (i = 0; i < count; ++i) {
550       *value = (*point)[0];
551       ++value;
552       *scaling = (*point)[1];
553       ++scaling;
554       ++point;
555    }
556 }
557 
558 static uint8_t
indexOfAV1RefFrame(uint32_t frame,const unsigned int * ref_frame_map)559 indexOfAV1RefFrame(uint32_t frame, const unsigned int *ref_frame_map) {
560     uint8_t i;
561 
562     for (i = 0; i < AV1_NUM_REF_FRAMES; ++i) {
563        if (frame == *ref_frame_map) {
564           break;
565        }
566        ++ref_frame_map;
567     }
568 
569     return i;
570 }
571 
572 static void
copyAV1TileInfo(struct pipe_av1_picture_desc * picture,const VdpPictureInfoAV1 * picture_info)573 copyAV1TileInfo(struct pipe_av1_picture_desc *picture,
574                 const VdpPictureInfoAV1 *picture_info)
575 {
576    uint32_t sbCols, sbRows;
577    uint32_t startSb, i;
578    int32_t width_sb, height_sb;
579    uint32_t MiCols = ((picture_info->width + 7) >> 3) << 1;
580    uint32_t MiRows = ((picture_info->height + 7) >> 3) << 1;
581 
582    if (picture_info->use_superres) {
583       const uint32_t superres_scale_denominator = picture_info->coded_denom + AV1_SUPERRES_DENOM_MIN;
584       const uint32_t width = ((picture_info->width * 8) + (superres_scale_denominator / 2))
585          / superres_scale_denominator;
586       MiCols = (((width - 1) + 8) >> 3) << 1;
587    }
588 
589    sbCols = picture_info->use_128x128_superblock ? ((MiCols + 31) >> 5) : ((MiCols + 15) >> 4);
590    sbRows = picture_info->use_128x128_superblock ? ((MiRows + 31) >> 5) : ((MiRows + 15) >> 4);
591 
592    width_sb = sbCols;
593    height_sb = sbRows;
594 
595    startSb = 0;
596    for (i = 0; startSb < sbCols; ++i) {
597       const uint32_t tile_width = picture_info->tile_widths[i];
598       picture->picture_parameter.width_in_sbs[i] = tile_width;
599 
600       picture->picture_parameter.tile_col_start_sb[i] = startSb;
601       startSb += tile_width;
602       width_sb -= tile_width;
603    }
604    picture->picture_parameter.tile_col_start_sb[i] = startSb + width_sb;
605 
606    startSb = 0;
607    for (i = 0; startSb < sbRows; ++i) {
608       const uint32_t tile_height = picture_info->tile_heights[i];
609       picture->picture_parameter.height_in_sbs[i] = tile_height;
610 
611       picture->picture_parameter.tile_row_start_sb[i] = startSb;
612       startSb += tile_height;
613       height_sb -= tile_height;
614    }
615    picture->picture_parameter.tile_row_start_sb[i] = startSb + height_sb;
616 }
617 
618 static VdpStatus
vlVdpDecoderRenderAV1(struct pipe_av1_picture_desc * picture,VdpVideoSurface target,const VdpPictureInfoAV1 * picture_info)619 vlVdpDecoderRenderAV1(struct pipe_av1_picture_desc *picture,
620                       VdpVideoSurface target,
621                       const VdpPictureInfoAV1 *picture_info)
622 {
623    unsigned i, j;
624 
625    picture->film_grain_target = NULL;
626 
627    picture->picture_parameter.profile = picture_info->profile;
628    picture->picture_parameter.order_hint_bits_minus_1 = picture_info->order_hint_bits_minus1;
629    picture->picture_parameter.bit_depth_idx = picture_info->bit_depth_minus8 >> 1;
630 
631    picture->picture_parameter.seq_info_fields.use_128x128_superblock =
632       picture_info->use_128x128_superblock;
633    picture->picture_parameter.seq_info_fields.enable_filter_intra =
634       picture_info->enable_filter_intra;
635    picture->picture_parameter.seq_info_fields.enable_intra_edge_filter =
636       picture_info->enable_intra_edge_filter;
637    picture->picture_parameter.seq_info_fields.enable_interintra_compound =
638       picture_info->enable_interintra_compound;
639    picture->picture_parameter.seq_info_fields.enable_masked_compound =
640       picture_info->enable_masked_compound;
641 
642    picture->picture_parameter.seq_info_fields.enable_dual_filter =
643       picture_info->enable_dual_filter;
644    picture->picture_parameter.seq_info_fields.enable_order_hint =
645       picture_info->enable_order_hint;
646    picture->picture_parameter.seq_info_fields.enable_jnt_comp =
647       picture_info->enable_jnt_comp;
648    picture->picture_parameter.seq_info_fields.enable_cdef =
649       picture_info->enable_cdef;
650    picture->picture_parameter.seq_info_fields.mono_chrome =
651       picture_info->mono_chrome;
652    picture->picture_parameter.seq_info_fields.ref_frame_mvs =
653       picture_info->enable_order_hint;
654    picture->picture_parameter.seq_info_fields.film_grain_params_present =
655       picture_info->enable_fgs;
656 
657    picture->picture_parameter.current_frame_id = target;
658    picture->picture_parameter.frame_width = picture_info->width;
659    picture->picture_parameter.frame_height = picture_info->height;
660    picture->picture_parameter.max_width = picture_info->width;
661    picture->picture_parameter.max_height = picture_info->height;
662 
663    for (i = 0; i < AV1_NUM_REF_FRAMES; ++i) {
664       if (picture_info->frame_type == AV1_KEY_FRAME && picture_info->show_frame) {
665          picture->ref[i] = NULL;
666       } else {
667          VdpStatus ret = vlVdpGetReferenceFrame(picture_info->ref_frame_map[i], &picture->ref[i]);
668          if (ret != VDP_STATUS_OK) {
669             return ret;
670          }
671       }
672    }
673 
674    for (i = 0; i < AV1_REFS_PER_FRAME; ++i) {
675       const uint8_t idx = indexOfAV1RefFrame(picture_info->ref_frame[i].index,
676                                              picture_info->ref_frame_map);
677       if (idx == AV1_NUM_REF_FRAMES) {
678          return VDP_STATUS_ERROR;
679       }
680       picture->picture_parameter.ref_frame_idx[i] = idx;
681    }
682 
683    if (picture_info->primary_ref_frame == VDP_INVALID_HANDLE) {
684       picture->picture_parameter.primary_ref_frame = AV1_PRIMARY_REF_NONE;
685    } else {
686       const uint8_t *ref_index = picture->picture_parameter.ref_frame_idx;
687       const uint8_t idx = indexOfAV1RefFrame(picture_info->primary_ref_frame,
688                                              picture_info->ref_frame_map);
689       if (idx == AV1_NUM_REF_FRAMES) {
690          return VDP_STATUS_ERROR;
691       }
692 
693       for (i = 0; i < AV1_REFS_PER_FRAME; ++i) {
694          if (idx == *ref_index) {
695             break;
696          }
697          ++ref_index;
698       }
699       picture->picture_parameter.primary_ref_frame = i;
700    }
701 
702    picture->picture_parameter.refresh_frame_flags = 0x01;
703    picture->picture_parameter.order_hint = picture_info->frame_offset;
704 
705    // Segment Info
706    picture->picture_parameter.seg_info.segment_info_fields.enabled =
707       picture_info->segmentation_enabled;
708    picture->picture_parameter.seg_info.segment_info_fields.update_map =
709       picture_info->segmentation_update_map;
710    picture->picture_parameter.seg_info.segment_info_fields.update_data =
711       picture_info->segmentation_update_data;
712    picture->picture_parameter.seg_info.segment_info_fields.temporal_update =
713       picture_info->segmentation_temporal_update;
714    memcpy(picture->picture_parameter.seg_info.feature_data,
715           picture_info->segmentation_feature_data,
716           sizeof(picture->picture_parameter.seg_info.feature_data));
717    memcpy(picture->picture_parameter.seg_info.feature_mask,
718           picture_info->segmentation_feature_mask,
719           sizeof(picture->picture_parameter.seg_info.feature_mask));
720 
721    // Film Grain Info
722    if (picture_info->enable_fgs) {
723       picture->picture_parameter.film_grain_info.film_grain_info_fields.apply_grain =
724          picture_info->apply_grain;
725       picture->picture_parameter.film_grain_info.film_grain_info_fields.chroma_scaling_from_luma =
726          picture_info->chroma_scaling_from_luma;
727       picture->picture_parameter.film_grain_info.film_grain_info_fields.grain_scaling_minus_8 =
728          picture_info->scaling_shift_minus8;
729       picture->picture_parameter.film_grain_info.film_grain_info_fields.ar_coeff_lag =
730          picture_info->ar_coeff_lag;
731       picture->picture_parameter.film_grain_info.film_grain_info_fields.ar_coeff_shift_minus_6 =
732          picture_info->ar_coeff_shift_minus6;
733       picture->picture_parameter.film_grain_info.film_grain_info_fields.grain_scale_shift =
734          picture_info->grain_scale_shift;
735       picture->picture_parameter.film_grain_info.film_grain_info_fields.overlap_flag =
736          picture_info->overlap_flag;
737       picture->picture_parameter.film_grain_info.film_grain_info_fields.clip_to_restricted_range =
738          picture_info->clip_to_restricted_range;
739 
740       picture->picture_parameter.film_grain_info.grain_seed =
741          picture_info->random_seed;
742       picture->picture_parameter.film_grain_info.num_y_points =
743          picture_info->num_y_points;
744       picture->picture_parameter.film_grain_info.num_cb_points =
745          picture_info->num_cb_points;
746       picture->picture_parameter.film_grain_info.num_cr_points =
747          picture_info->num_cr_points;
748       picture->picture_parameter.film_grain_info.cb_mult =
749          picture_info->cb_mult;
750       picture->picture_parameter.film_grain_info.cb_luma_mult =
751          picture_info->cb_luma_mult;
752       picture->picture_parameter.film_grain_info.cb_offset =
753          picture_info->cb_offset;
754       picture->picture_parameter.film_grain_info.cr_mult =
755          picture_info->cr_mult;
756       picture->picture_parameter.film_grain_info.cr_luma_mult =
757          picture_info->cr_luma_mult;
758       picture->picture_parameter.film_grain_info.cr_offset =
759          picture_info->cr_offset;
760 
761       copyAV1ScalingPoints(
762          picture->picture_parameter.film_grain_info.point_y_value,
763          picture->picture_parameter.film_grain_info.point_y_scaling,
764          picture_info->scaling_points_y,
765          ARRAY_SIZE(picture->picture_parameter.film_grain_info.point_y_value));
766       copyAV1ScalingPoints(
767          picture->picture_parameter.film_grain_info.point_cb_value,
768          picture->picture_parameter.film_grain_info.point_cb_scaling,
769          picture_info->scaling_points_cb,
770          ARRAY_SIZE(picture->picture_parameter.film_grain_info.point_cb_value));
771       copyAV1ScalingPoints(
772          picture->picture_parameter.film_grain_info.point_cr_value,
773          picture->picture_parameter.film_grain_info.point_cr_scaling,
774          picture_info->scaling_points_cr,
775          ARRAY_SIZE(picture->picture_parameter.film_grain_info.point_cr_value));
776 
777       copyArrayInt8FromShort(
778          picture->picture_parameter.film_grain_info.ar_coeffs_y,
779          picture_info->ar_coeffs_y,
780          ARRAY_SIZE(picture->picture_parameter.film_grain_info.ar_coeffs_y));
781       copyArrayInt8FromShort(
782          picture->picture_parameter.film_grain_info.ar_coeffs_cb,
783          picture_info->ar_coeffs_cb,
784          ARRAY_SIZE(picture->picture_parameter.film_grain_info.ar_coeffs_cb));
785       copyArrayInt8FromShort(
786          picture->picture_parameter.film_grain_info.ar_coeffs_cr,
787          picture_info->ar_coeffs_cr,
788          ARRAY_SIZE(picture->picture_parameter.film_grain_info.ar_coeffs_cr));
789    }
790 
791    // Picture Info
792    picture->picture_parameter.pic_info_fields.frame_type =
793       picture_info->frame_type;
794    picture->picture_parameter.pic_info_fields.show_frame =
795       picture_info->show_frame;
796    picture->picture_parameter.pic_info_fields.showable_frame = 1;
797    picture->picture_parameter.pic_info_fields.error_resilient_mode = 1;
798    picture->picture_parameter.pic_info_fields.disable_cdf_update =
799       picture_info->disable_cdf_update;
800    picture->picture_parameter.pic_info_fields.allow_screen_content_tools =
801       picture_info->allow_screen_content_tools;
802    picture->picture_parameter.pic_info_fields.force_integer_mv =
803       picture_info->force_integer_mv;
804    picture->picture_parameter.pic_info_fields.allow_intrabc =
805       picture_info->allow_intrabc;
806    picture->picture_parameter.pic_info_fields.use_superres =
807       picture_info->use_superres;
808    picture->picture_parameter.pic_info_fields.allow_high_precision_mv =
809       picture_info->allow_high_precision_mv;
810    picture->picture_parameter.pic_info_fields.is_motion_mode_switchable =
811       picture_info->switchable_motion_mode;
812    picture->picture_parameter.pic_info_fields.use_ref_frame_mvs =
813       picture_info->use_ref_frame_mvs;
814    picture->picture_parameter.pic_info_fields.disable_frame_end_update_cdf =
815       picture_info->disable_frame_end_update_cdf;
816    picture->picture_parameter.pic_info_fields.uniform_tile_spacing_flag = 0;
817    picture->picture_parameter.pic_info_fields.allow_warped_motion =
818       picture_info->allow_warped_motion;
819    picture->picture_parameter.pic_info_fields.large_scale_tile = 0;
820 
821    picture->picture_parameter.superres_scale_denominator =
822       picture_info->use_superres ? picture_info->coded_denom + AV1_SUPERRES_DENOM_MIN : AV1_SUPERRES_NUM;
823 
824    // Loop Filter
825    picture->picture_parameter.interp_filter = picture_info->interp_filter;
826    memcpy(picture->picture_parameter.filter_level,
827           picture_info->loop_filter_level,
828           sizeof(picture->picture_parameter.filter_level));
829    picture->picture_parameter.filter_level_u =
830       picture_info->loop_filter_level_u;
831    picture->picture_parameter.filter_level_v =
832       picture_info->loop_filter_level_v;
833    picture->picture_parameter.loop_filter_info_fields.sharpness_level =
834       picture_info->loop_filter_sharpness;
835    picture->picture_parameter.loop_filter_info_fields.mode_ref_delta_enabled =
836       picture_info->loop_filter_delta_enabled;
837    picture->picture_parameter.loop_filter_info_fields.mode_ref_delta_update =
838       picture_info->loop_filter_delta_update;
839    memcpy(picture->picture_parameter.ref_deltas,
840           picture_info->loop_filter_ref_deltas,
841           sizeof(picture->picture_parameter.ref_deltas));
842    memcpy(picture->picture_parameter.mode_deltas,
843           picture_info->loop_filter_mode_deltas,
844           sizeof(picture->picture_parameter.mode_deltas));
845 
846    // Tile Info
847    picture->picture_parameter.tile_cols = picture_info->num_tile_cols;
848    picture->picture_parameter.tile_rows = picture_info->num_tile_rows;
849    picture->picture_parameter.context_update_tile_id =
850       picture_info->context_update_tile_id;
851    copyAV1TileInfo(picture, picture_info);
852 
853    // Quantization Parameters
854    picture->picture_parameter.base_qindex = picture_info->base_qindex;
855    picture->picture_parameter.y_dc_delta_q = picture_info->qp_y_dc_delta_q;
856    picture->picture_parameter.u_dc_delta_q = picture_info->qp_u_dc_delta_q;
857    picture->picture_parameter.u_ac_delta_q = picture_info->qp_u_ac_delta_q;
858    picture->picture_parameter.v_dc_delta_q = picture_info->qp_v_dc_delta_q;
859    picture->picture_parameter.v_ac_delta_q = picture_info->qp_v_ac_delta_q;
860 
861    // QMatrix
862    picture->picture_parameter.qmatrix_fields.using_qmatrix =
863       picture_info->using_qmatrix;
864    if (picture_info->using_qmatrix) {
865       picture->picture_parameter.qmatrix_fields.qm_y = picture_info->qm_y;
866       picture->picture_parameter.qmatrix_fields.qm_u = picture_info->qm_u;
867       picture->picture_parameter.qmatrix_fields.qm_v = picture_info->qm_v;
868    } else {
869       picture->picture_parameter.qmatrix_fields.qm_y = 0x0f;
870       picture->picture_parameter.qmatrix_fields.qm_u = 0x0f;
871       picture->picture_parameter.qmatrix_fields.qm_v = 0x0f;
872    }
873 
874    // Mode Control Fields
875    picture->picture_parameter.mode_control_fields.delta_q_present_flag =
876       picture_info->delta_q_present;
877    picture->picture_parameter.mode_control_fields.log2_delta_q_res =
878       picture_info->delta_q_res;
879    picture->picture_parameter.mode_control_fields.delta_lf_present_flag =
880       picture_info->delta_lf_present;
881    picture->picture_parameter.mode_control_fields.log2_delta_lf_res =
882       picture_info->delta_lf_res;
883    picture->picture_parameter.mode_control_fields.delta_lf_multi =
884       picture_info->delta_lf_multi;
885    picture->picture_parameter.mode_control_fields.tx_mode =
886       picture_info->tx_mode;
887    picture->picture_parameter.mode_control_fields.reference_select =
888       picture_info->reference_mode;
889    picture->picture_parameter.mode_control_fields.reduced_tx_set_used =
890       picture_info->reduced_tx_set;
891    picture->picture_parameter.mode_control_fields.skip_mode_present =
892       picture_info->skip_mode;
893 
894    // CDEF
895    picture->picture_parameter.cdef_damping_minus_3 =
896       picture_info->cdef_damping_minus_3;
897    picture->picture_parameter.cdef_bits = picture_info->cdef_bits;
898    for (i = 0; i < ARRAY_SIZE(picture->picture_parameter.cdef_y_strengths); ++i) {
899       picture->picture_parameter.cdef_y_strengths[i] =
900          ((picture_info->cdef_y_strength[i] & 0xf) << 2) +
901          (picture_info->cdef_y_strength[i] >> 4);
902       picture->picture_parameter.cdef_uv_strengths[i] =
903          ((picture_info->cdef_uv_strength[i] & 0xf) << 2) +
904          (picture_info->cdef_uv_strength[i] >> 4);
905    }
906 
907    // Loop Restoration
908    picture->picture_parameter.loop_restoration_fields.yframe_restoration_type =
909       picture_info->lr_type[0];
910    picture->picture_parameter.loop_restoration_fields.cbframe_restoration_type =
911       picture_info->lr_type[1];
912    picture->picture_parameter.loop_restoration_fields.crframe_restoration_type =
913       picture_info->lr_type[2];
914    picture->picture_parameter.loop_restoration_fields.lr_unit_shift =
915       picture_info->lr_unit_size[0] - 1;
916    picture->picture_parameter.loop_restoration_fields.lr_uv_shift =
917       picture_info->lr_unit_size[0] - picture_info->lr_unit_size[1];
918 
919    if (picture_info->lr_type[0] || picture_info->lr_type[1] || picture_info->lr_type[2]) {
920       const uint8_t unit_shift = 6 + picture->picture_parameter.loop_restoration_fields.lr_unit_shift;
921 
922       picture->picture_parameter.lr_unit_size[0] = (1 << unit_shift);
923       picture->picture_parameter.lr_unit_size[1] =
924          1 << (unit_shift - picture->picture_parameter.loop_restoration_fields.lr_uv_shift);
925       picture->picture_parameter.lr_unit_size[2] =
926          picture->picture_parameter.lr_unit_size[1];
927    } else {
928       for (i = 0; i < ARRAY_SIZE(picture->picture_parameter.lr_unit_size); ++i) {
929          picture->picture_parameter.lr_unit_size[i] = (1 << 8);
930       }
931    }
932 
933    // Global Motion
934    for (i = 0; i < AV1_REFS_PER_FRAME; ++i) {
935       picture->picture_parameter.wm[i].invalid = picture_info->global_motion[i].invalid;
936       picture->picture_parameter.wm[i].wmtype = picture_info->global_motion[i].wmtype;
937 
938       // VDPAU only has 6 wmmat[] elements, whereas Gallium provides 8.
939       for (j = 0; j < ARRAY_SIZE(picture_info->global_motion[0].wmmat); ++j) {
940          picture->picture_parameter.wm[i].wmmat[j] = picture_info->global_motion[i].wmmat[j];
941       }
942    }
943 
944    picture->picture_parameter.matrix_coefficients = 0;
945 
946    // Tile Information
947    picture->slice_parameter.slice_count =
948       picture_info->num_tile_rows * picture_info->num_tile_cols;
949    for (i = 0; i < picture->slice_parameter.slice_count; ++i) {
950       const uint32_t start_offset = picture_info->tile_info[i * 2];
951 
952       picture->slice_parameter.slice_data_offset[i] = start_offset;
953       picture->slice_parameter.slice_data_size[i] =
954          picture_info->tile_info[i * 2 + 1] - start_offset;
955    }
956 
957    return VDP_STATUS_OK;
958 }
959 
960 static void
vlVdpDecoderFixVC1Startcode(uint32_t * num_buffers,const void * buffers[],unsigned sizes[])961 vlVdpDecoderFixVC1Startcode(uint32_t *num_buffers, const void *buffers[], unsigned sizes[])
962 {
963    static const uint8_t vc1_startcode[] = { 0x00, 0x00, 0x01, 0x0D };
964    struct vl_vlc vlc = {};
965    unsigned i;
966 
967    /* search the first 64 bytes for a startcode */
968    vl_vlc_init(&vlc, *num_buffers, buffers, sizes);
969    while (vl_vlc_search_byte(&vlc, 64*8, 0x00) && vl_vlc_bits_left(&vlc) >= 32) {
970       uint32_t value = vl_vlc_peekbits(&vlc, 32);
971       if (value == 0x0000010D ||
972           value == 0x0000010C ||
973           value == 0x0000010B)
974          return;
975       vl_vlc_eatbits(&vlc, 8);
976    }
977 
978    /* none found, ok add one manually */
979    VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Manually adding VC-1 startcode\n");
980    for (i = *num_buffers; i > 0; --i) {
981       buffers[i] = buffers[i - 1];
982       sizes[i] = sizes[i - 1];
983    }
984    ++(*num_buffers);
985    buffers[0] = vc1_startcode;
986    sizes[0] = 4;
987 }
988 
989 static bool
vlVdpQueryInterlacedH264(struct pipe_h264_picture_desc * h264)990 vlVdpQueryInterlacedH264(struct pipe_h264_picture_desc *h264)
991 {
992    if (h264->pps->sps->frame_mbs_only_flag)
993       return false;
994 
995    return h264->field_pic_flag || /* PAFF */
996       h264->pps->sps->mb_adaptive_frame_field_flag; /* MBAFF */
997 }
998 
999 /**
1000  * Decode a compressed field/frame and render the result into a VdpVideoSurface.
1001  */
1002 VdpStatus
vlVdpDecoderRender(VdpDecoder decoder,VdpVideoSurface target,VdpPictureInfo const * picture_info,uint32_t bitstream_buffer_count,VdpBitstreamBuffer const * bitstream_buffers)1003 vlVdpDecoderRender(VdpDecoder decoder,
1004                    VdpVideoSurface target,
1005                    VdpPictureInfo const *picture_info,
1006                    uint32_t bitstream_buffer_count,
1007                    VdpBitstreamBuffer const *bitstream_buffers)
1008 {
1009    const void * buffers[bitstream_buffer_count + 1];
1010    unsigned sizes[bitstream_buffer_count + 1];
1011    vlVdpDecoder *vldecoder;
1012    vlVdpSurface *vlsurf;
1013    VdpStatus ret;
1014    struct pipe_screen *screen;
1015    struct pipe_video_codec *dec;
1016    bool buffer_support[2];
1017    unsigned i;
1018    struct pipe_h264_sps sps_h264 = {};
1019    struct pipe_h264_pps pps_h264 = { &sps_h264 };
1020    struct pipe_h265_sps sps_h265 = {};
1021    struct pipe_h265_pps pps_h265 = { &sps_h265 };
1022    union {
1023       struct pipe_picture_desc base;
1024       struct pipe_mpeg12_picture_desc mpeg12;
1025       struct pipe_mpeg4_picture_desc mpeg4;
1026       struct pipe_vc1_picture_desc vc1;
1027       struct pipe_h264_picture_desc h264;
1028       struct pipe_h265_picture_desc h265;
1029       struct pipe_av1_picture_desc av1;
1030    } desc;
1031    bool picture_interlaced = false;
1032 
1033    if (!(picture_info && bitstream_buffers))
1034       return VDP_STATUS_INVALID_POINTER;
1035 
1036    vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
1037    if (!vldecoder)
1038       return VDP_STATUS_INVALID_HANDLE;
1039    dec = vldecoder->decoder;
1040    screen = dec->context->screen;
1041 
1042    vlsurf = (vlVdpSurface *)vlGetDataHTAB(target);
1043    if (!vlsurf)
1044       return VDP_STATUS_INVALID_HANDLE;
1045 
1046    if (vlsurf->device != vldecoder->device)
1047       return VDP_STATUS_HANDLE_DEVICE_MISMATCH;
1048 
1049    if (vlsurf->video_buffer != NULL &&
1050        pipe_format_to_chroma_format(vlsurf->video_buffer->buffer_format) != dec->chroma_format)
1051       // TODO: Recreate decoder with correct chroma
1052       return VDP_STATUS_INVALID_CHROMA_TYPE;
1053 
1054    for (i = 0; i < bitstream_buffer_count; ++i) {
1055       buffers[i] = bitstream_buffers[i].bitstream;
1056       sizes[i] = bitstream_buffers[i].bitstream_bytes;
1057    }
1058 
1059    memset(&desc, 0, sizeof(desc));
1060    desc.base.profile = dec->profile;
1061    switch (u_reduce_video_profile(dec->profile)) {
1062    case PIPE_VIDEO_FORMAT_MPEG12:
1063       ret = vlVdpDecoderRenderMpeg12(&desc.mpeg12, (VdpPictureInfoMPEG1Or2 *)picture_info);
1064       break;
1065    case PIPE_VIDEO_FORMAT_MPEG4:
1066       ret = vlVdpDecoderRenderMpeg4(&desc.mpeg4, (VdpPictureInfoMPEG4Part2 *)picture_info);
1067       break;
1068    case PIPE_VIDEO_FORMAT_VC1:
1069       if (dec->profile == PIPE_VIDEO_PROFILE_VC1_ADVANCED)
1070          vlVdpDecoderFixVC1Startcode(&bitstream_buffer_count, buffers, sizes);
1071       ret = vlVdpDecoderRenderVC1(&desc.vc1, (VdpPictureInfoVC1 *)picture_info);
1072       break;
1073    case PIPE_VIDEO_FORMAT_MPEG4_AVC:
1074       desc.h264.pps = &pps_h264;
1075       ret = vlVdpDecoderRenderH264(&desc.h264, (VdpPictureInfoH264 *)picture_info, dec->level);
1076       picture_interlaced = vlVdpQueryInterlacedH264(&desc.h264);
1077       break;
1078    case PIPE_VIDEO_FORMAT_HEVC:
1079       desc.h265.pps = &pps_h265;
1080       ret = vlVdpDecoderRenderH265(&desc.h265, (VdpPictureInfoHEVC *)picture_info);
1081       break;
1082    case PIPE_VIDEO_FORMAT_AV1:
1083       ret = vlVdpDecoderRenderAV1(&desc.av1, target, (VdpPictureInfoAV1 *)picture_info);
1084       break;
1085    default:
1086       return VDP_STATUS_INVALID_DECODER_PROFILE;
1087    }
1088 
1089    if (ret != VDP_STATUS_OK)
1090       return ret;
1091 
1092    buffer_support[0] = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
1093                                                PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE);
1094    buffer_support[1] = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
1095                                                PIPE_VIDEO_CAP_SUPPORTS_INTERLACED);
1096 
1097    if (vlsurf->video_buffer == NULL ||
1098        !screen->is_video_format_supported(screen, vlsurf->video_buffer->buffer_format,
1099                                           dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM) ||
1100        !buffer_support[vlsurf->video_buffer->interlaced] ||
1101        (picture_interlaced && !vlsurf->video_buffer->interlaced && buffer_support[1])) {
1102 
1103       mtx_lock(&vlsurf->device->mutex);
1104 
1105       /* destroy the old one */
1106       if (vlsurf->video_buffer)
1107          vlsurf->video_buffer->destroy(vlsurf->video_buffer);
1108 
1109       /* set the buffer format to the prefered one */
1110       vlsurf->templat.buffer_format = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
1111                                                               PIPE_VIDEO_CAP_PREFERED_FORMAT);
1112 
1113       /* also set interlacing to decoders preferences */
1114       vlsurf->templat.interlaced = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
1115                                                            PIPE_VIDEO_CAP_PREFERS_INTERLACED) || picture_interlaced;
1116 
1117       /* and recreate the video buffer */
1118       vlsurf->video_buffer = dec->context->create_video_buffer(dec->context, &vlsurf->templat);
1119 
1120       /* still no luck? get me out of here... */
1121       if (!vlsurf->video_buffer) {
1122          mtx_unlock(&vlsurf->device->mutex);
1123          return VDP_STATUS_NO_IMPLEMENTATION;
1124       }
1125       vlVdpVideoSurfaceClear(vlsurf);
1126       mtx_unlock(&vlsurf->device->mutex);
1127    }
1128 
1129    mtx_lock(&vldecoder->mutex);
1130    dec->begin_frame(dec, vlsurf->video_buffer, &desc.base);
1131    dec->decode_bitstream(dec, vlsurf->video_buffer, &desc.base, bitstream_buffer_count, buffers, sizes);
1132    dec->end_frame(dec, vlsurf->video_buffer, &desc.base);
1133    mtx_unlock(&vldecoder->mutex);
1134    return ret;
1135 }
1136