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