• 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 /**
39  * Create a VdpDecoder.
40  */
41 VdpStatus
vlVdpDecoderCreate(VdpDevice device,VdpDecoderProfile profile,uint32_t width,uint32_t height,uint32_t max_references,VdpDecoder * decoder)42 vlVdpDecoderCreate(VdpDevice device,
43                    VdpDecoderProfile profile,
44                    uint32_t width, uint32_t height,
45                    uint32_t max_references,
46                    VdpDecoder *decoder)
47 {
48    struct pipe_video_codec templat = {};
49    struct pipe_context *pipe;
50    struct pipe_screen *screen;
51    vlVdpDevice *dev;
52    vlVdpDecoder *vldecoder;
53    VdpStatus ret;
54    bool supported;
55    uint32_t maxwidth, maxheight;
56 
57    if (!decoder)
58       return VDP_STATUS_INVALID_POINTER;
59    *decoder = 0;
60 
61    if (!(width && height))
62       return VDP_STATUS_INVALID_VALUE;
63 
64    templat.profile = ProfileToPipe(profile);
65    if (templat.profile == PIPE_VIDEO_PROFILE_UNKNOWN)
66       return VDP_STATUS_INVALID_DECODER_PROFILE;
67 
68    dev = vlGetDataHTAB(device);
69    if (!dev)
70       return VDP_STATUS_INVALID_HANDLE;
71 
72    pipe = dev->context;
73    screen = dev->vscreen->pscreen;
74 
75    mtx_lock(&dev->mutex);
76 
77    supported = vl_codec_supported(screen, templat.profile, false);
78    if (!supported) {
79       mtx_unlock(&dev->mutex);
80       return VDP_STATUS_INVALID_DECODER_PROFILE;
81    }
82 
83    maxwidth = screen->get_video_param
84    (
85       screen,
86       templat.profile,
87       PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
88       PIPE_VIDEO_CAP_MAX_WIDTH
89    );
90    maxheight = screen->get_video_param
91    (
92       screen,
93       templat.profile,
94       PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
95       PIPE_VIDEO_CAP_MAX_HEIGHT
96    );
97    if (width > maxwidth || height > maxheight) {
98       mtx_unlock(&dev->mutex);
99       return VDP_STATUS_INVALID_SIZE;
100    }
101 
102    vldecoder = CALLOC(1,sizeof(vlVdpDecoder));
103    if (!vldecoder) {
104       mtx_unlock(&dev->mutex);
105       return VDP_STATUS_RESOURCES;
106    }
107 
108    DeviceReference(&vldecoder->device, dev);
109 
110    templat.entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM;
111    templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;
112    templat.width = width;
113    templat.height = height;
114    templat.max_references = max_references;
115 
116    if (u_reduce_video_profile(templat.profile) ==
117        PIPE_VIDEO_FORMAT_MPEG4_AVC)
118       templat.level = u_get_h264_level(templat.width, templat.height,
119                             &templat.max_references);
120 
121    vldecoder->decoder = pipe->create_video_codec(pipe, &templat);
122 
123    if (!vldecoder->decoder) {
124       ret = VDP_STATUS_ERROR;
125       goto error_decoder;
126    }
127 
128    *decoder = vlAddDataHTAB(vldecoder);
129    if (*decoder == 0) {
130       ret = VDP_STATUS_ERROR;
131       goto error_handle;
132    }
133 
134    (void) mtx_init(&vldecoder->mutex, mtx_plain);
135    mtx_unlock(&dev->mutex);
136 
137    return VDP_STATUS_OK;
138 
139 error_handle:
140    vldecoder->decoder->destroy(vldecoder->decoder);
141 
142 error_decoder:
143    mtx_unlock(&dev->mutex);
144    DeviceReference(&vldecoder->device, NULL);
145    FREE(vldecoder);
146    return ret;
147 }
148 
149 /**
150  * Destroy a VdpDecoder.
151  */
152 VdpStatus
vlVdpDecoderDestroy(VdpDecoder decoder)153 vlVdpDecoderDestroy(VdpDecoder decoder)
154 {
155    vlVdpDecoder *vldecoder;
156 
157    vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
158    if (!vldecoder)
159       return VDP_STATUS_INVALID_HANDLE;
160 
161    mtx_lock(&vldecoder->mutex);
162    vldecoder->decoder->destroy(vldecoder->decoder);
163    mtx_unlock(&vldecoder->mutex);
164    mtx_destroy(&vldecoder->mutex);
165 
166    vlRemoveDataHTAB(decoder);
167    DeviceReference(&vldecoder->device, NULL);
168    FREE(vldecoder);
169 
170    return VDP_STATUS_OK;
171 }
172 
173 /**
174  * Retrieve the parameters used to create a VdpDecoder.
175  */
176 VdpStatus
vlVdpDecoderGetParameters(VdpDecoder decoder,VdpDecoderProfile * profile,uint32_t * width,uint32_t * height)177 vlVdpDecoderGetParameters(VdpDecoder decoder,
178                           VdpDecoderProfile *profile,
179                           uint32_t *width,
180                           uint32_t *height)
181 {
182    vlVdpDecoder *vldecoder;
183 
184    vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
185    if (!vldecoder)
186       return VDP_STATUS_INVALID_HANDLE;
187 
188    *profile = PipeToProfile(vldecoder->decoder->profile);
189    *width = vldecoder->decoder->width;
190    *height = vldecoder->decoder->height;
191 
192    return VDP_STATUS_OK;
193 }
194 
195 static VdpStatus
vlVdpGetReferenceFrame(VdpVideoSurface handle,struct pipe_video_buffer ** ref_frame)196 vlVdpGetReferenceFrame(VdpVideoSurface handle, struct pipe_video_buffer **ref_frame)
197 {
198    vlVdpSurface *surface;
199 
200    /* if surfaces equals VDP_STATUS_INVALID_HANDLE, they are not used */
201    if (handle ==  VDP_INVALID_HANDLE) {
202       *ref_frame = NULL;
203       return VDP_STATUS_OK;
204    }
205 
206    surface = vlGetDataHTAB(handle);
207    if (!surface)
208       return VDP_STATUS_INVALID_HANDLE;
209 
210    *ref_frame = surface->video_buffer;
211    if (!*ref_frame)
212          return VDP_STATUS_INVALID_HANDLE;
213 
214    return VDP_STATUS_OK;
215 }
216 
217 /**
218  * Decode a mpeg 1/2 video.
219  */
220 static VdpStatus
vlVdpDecoderRenderMpeg12(struct pipe_mpeg12_picture_desc * picture,VdpPictureInfoMPEG1Or2 * picture_info)221 vlVdpDecoderRenderMpeg12(struct pipe_mpeg12_picture_desc *picture,
222                          VdpPictureInfoMPEG1Or2 *picture_info)
223 {
224    VdpStatus r;
225 
226    VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoding MPEG12\n");
227 
228    r = vlVdpGetReferenceFrame(picture_info->forward_reference, &picture->ref[0]);
229    if (r != VDP_STATUS_OK)
230       return r;
231 
232    r = vlVdpGetReferenceFrame(picture_info->backward_reference, &picture->ref[1]);
233    if (r != VDP_STATUS_OK)
234       return r;
235 
236    picture->picture_coding_type = picture_info->picture_coding_type;
237    picture->picture_structure = picture_info->picture_structure;
238    picture->frame_pred_frame_dct = picture_info->frame_pred_frame_dct;
239    picture->q_scale_type = picture_info->q_scale_type;
240    picture->alternate_scan = picture_info->alternate_scan;
241    picture->intra_vlc_format = picture_info->intra_vlc_format;
242    picture->concealment_motion_vectors = picture_info->concealment_motion_vectors;
243    picture->intra_dc_precision = picture_info->intra_dc_precision;
244    picture->f_code[0][0] = picture_info->f_code[0][0] - 1;
245    picture->f_code[0][1] = picture_info->f_code[0][1] - 1;
246    picture->f_code[1][0] = picture_info->f_code[1][0] - 1;
247    picture->f_code[1][1] = picture_info->f_code[1][1] - 1;
248    picture->num_slices = picture_info->slice_count;
249    picture->top_field_first = picture_info->top_field_first;
250    picture->full_pel_forward_vector = picture_info->full_pel_forward_vector;
251    picture->full_pel_backward_vector = picture_info->full_pel_backward_vector;
252    picture->intra_matrix = picture_info->intra_quantizer_matrix;
253    picture->non_intra_matrix = picture_info->non_intra_quantizer_matrix;
254 
255    return VDP_STATUS_OK;
256 }
257 
258 /**
259  * Decode a mpeg 4 video.
260  */
261 static VdpStatus
vlVdpDecoderRenderMpeg4(struct pipe_mpeg4_picture_desc * picture,VdpPictureInfoMPEG4Part2 * picture_info)262 vlVdpDecoderRenderMpeg4(struct pipe_mpeg4_picture_desc *picture,
263                         VdpPictureInfoMPEG4Part2 *picture_info)
264 {
265    VdpStatus r;
266    unsigned i;
267 
268    VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoding MPEG4\n");
269 
270    r = vlVdpGetReferenceFrame(picture_info->forward_reference, &picture->ref[0]);
271    if (r != VDP_STATUS_OK)
272       return r;
273 
274    r = vlVdpGetReferenceFrame(picture_info->backward_reference, &picture->ref[1]);
275    if (r != VDP_STATUS_OK)
276       return r;
277 
278    for (i = 0; i < 2; ++i) {
279       picture->trd[i] = picture_info->trd[i];
280       picture->trb[i] = picture_info->trb[i];
281    }
282    picture->vop_time_increment_resolution = picture_info->vop_time_increment_resolution;
283    picture->vop_coding_type = picture_info->vop_coding_type;
284    picture->vop_fcode_forward = picture_info->vop_fcode_forward;
285    picture->vop_fcode_backward = picture_info->vop_fcode_backward;
286    picture->resync_marker_disable = picture_info->resync_marker_disable;
287    picture->interlaced = picture_info->interlaced;
288    picture->quant_type = picture_info->quant_type;
289    picture->quarter_sample = picture_info->quarter_sample;
290    picture->short_video_header = picture_info->short_video_header;
291    picture->rounding_control = picture_info->rounding_control;
292    picture->alternate_vertical_scan_flag = picture_info->alternate_vertical_scan_flag;
293    picture->top_field_first = picture_info->top_field_first;
294    picture->intra_matrix = picture_info->intra_quantizer_matrix;
295    picture->non_intra_matrix = picture_info->non_intra_quantizer_matrix;
296 
297    return VDP_STATUS_OK;
298 }
299 
300 static VdpStatus
vlVdpDecoderRenderVC1(struct pipe_vc1_picture_desc * picture,VdpPictureInfoVC1 * picture_info)301 vlVdpDecoderRenderVC1(struct pipe_vc1_picture_desc *picture,
302                       VdpPictureInfoVC1 *picture_info)
303 {
304    VdpStatus r;
305 
306    VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoding VC-1\n");
307 
308    r = vlVdpGetReferenceFrame(picture_info->forward_reference, &picture->ref[0]);
309    if (r != VDP_STATUS_OK)
310       return r;
311 
312    r = vlVdpGetReferenceFrame(picture_info->backward_reference, &picture->ref[1]);
313    if (r != VDP_STATUS_OK)
314       return r;
315 
316    picture->slice_count = picture_info->slice_count;
317    picture->picture_type = picture_info->picture_type;
318    picture->frame_coding_mode = picture_info->frame_coding_mode;
319    picture->postprocflag = picture_info->postprocflag;
320    picture->pulldown = picture_info->pulldown;
321    picture->interlace = picture_info->interlace;
322    picture->tfcntrflag = picture_info->tfcntrflag;
323    picture->finterpflag = picture_info->finterpflag;
324    picture->psf = picture_info->psf;
325    picture->dquant = picture_info->dquant;
326    picture->panscan_flag = picture_info->panscan_flag;
327    picture->refdist_flag = picture_info->refdist_flag;
328    picture->quantizer = picture_info->quantizer;
329    picture->extended_mv = picture_info->extended_mv;
330    picture->extended_dmv = picture_info->extended_dmv;
331    picture->overlap = picture_info->overlap;
332    picture->vstransform = picture_info->vstransform;
333    picture->loopfilter = picture_info->loopfilter;
334    picture->fastuvmc = picture_info->fastuvmc;
335    picture->range_mapy_flag = picture_info->range_mapy_flag;
336    picture->range_mapy = picture_info->range_mapy;
337    picture->range_mapuv_flag = picture_info->range_mapuv_flag;
338    picture->range_mapuv = picture_info->range_mapuv;
339    picture->multires = picture_info->multires;
340    picture->syncmarker = picture_info->syncmarker;
341    picture->rangered = picture_info->rangered;
342    picture->maxbframes = picture_info->maxbframes;
343    picture->deblockEnable = picture_info->deblockEnable;
344    picture->pquant = picture_info->pquant;
345 
346    return VDP_STATUS_OK;
347 }
348 
349 static VdpStatus
vlVdpDecoderRenderH264(struct pipe_h264_picture_desc * picture,VdpPictureInfoH264 * picture_info,unsigned level_idc)350 vlVdpDecoderRenderH264(struct pipe_h264_picture_desc *picture,
351                        VdpPictureInfoH264 *picture_info, unsigned level_idc)
352 {
353    unsigned i;
354 
355    VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoding H264\n");
356 
357    picture->pps->sps->mb_adaptive_frame_field_flag = picture_info->mb_adaptive_frame_field_flag;
358    picture->pps->sps->frame_mbs_only_flag = picture_info->frame_mbs_only_flag;
359    picture->pps->sps->log2_max_frame_num_minus4 = picture_info->log2_max_frame_num_minus4;
360    picture->pps->sps->pic_order_cnt_type = picture_info->pic_order_cnt_type;
361    picture->pps->sps->log2_max_pic_order_cnt_lsb_minus4 = picture_info->log2_max_pic_order_cnt_lsb_minus4;
362    picture->pps->sps->delta_pic_order_always_zero_flag = picture_info->delta_pic_order_always_zero_flag;
363    picture->pps->sps->direct_8x8_inference_flag = picture_info->direct_8x8_inference_flag;
364    picture->pps->sps->level_idc = level_idc;
365    picture->pps->sps->MinLumaBiPredSize8x8 = (level_idc >= 31); /* See section A.3.3.2 of H264 spec */;
366 
367    picture->pps->transform_8x8_mode_flag = picture_info->transform_8x8_mode_flag;
368    picture->pps->chroma_qp_index_offset = picture_info->chroma_qp_index_offset;
369    picture->pps->second_chroma_qp_index_offset = picture_info->second_chroma_qp_index_offset;
370    picture->pps->pic_init_qp_minus26 = picture_info->pic_init_qp_minus26;
371    /*picture->pps-> pic_init_qs_minus26 not passed in VdpPictureInfoH264*/
372    picture->pps->entropy_coding_mode_flag = picture_info->entropy_coding_mode_flag;
373    picture->pps->deblocking_filter_control_present_flag = picture_info->deblocking_filter_control_present_flag;
374    picture->pps->redundant_pic_cnt_present_flag = picture_info->redundant_pic_cnt_present_flag;
375    picture->pps->constrained_intra_pred_flag = picture_info->constrained_intra_pred_flag;
376    picture->pps->weighted_pred_flag = picture_info->weighted_pred_flag;
377    picture->pps->weighted_bipred_idc = picture_info->weighted_bipred_idc;
378    picture->pps->bottom_field_pic_order_in_frame_present_flag = picture_info->pic_order_present_flag;
379    memcpy(picture->pps->ScalingList4x4, picture_info->scaling_lists_4x4, 6*16);
380    memcpy(picture->pps->ScalingList8x8, picture_info->scaling_lists_8x8, 2*64);
381 
382    picture->slice_count = picture_info->slice_count;
383    picture->field_order_cnt[0] = picture_info->field_order_cnt[0];
384    picture->field_order_cnt[1] = picture_info->field_order_cnt[1];
385    picture->is_reference = picture_info->is_reference;
386    picture->frame_num = picture_info->frame_num;
387    picture->field_pic_flag = picture_info->field_pic_flag;
388    picture->bottom_field_flag = picture_info->bottom_field_flag;
389    picture->num_ref_frames = picture_info->num_ref_frames;
390 
391    picture->num_ref_idx_l0_active_minus1 = picture_info->num_ref_idx_l0_active_minus1;
392    picture->num_ref_idx_l1_active_minus1 = picture_info->num_ref_idx_l1_active_minus1;
393 
394    for (i = 0; i < 16; ++i) {
395       VdpStatus ret = vlVdpGetReferenceFrame
396       (
397          picture_info->referenceFrames[i].surface,
398          &picture->ref[i]
399       );
400       if (ret != VDP_STATUS_OK)
401          return ret;
402 
403       picture->is_long_term[i] = picture_info->referenceFrames[i].is_long_term;
404       picture->top_is_reference[i] = picture_info->referenceFrames[i].top_is_reference;
405       picture->bottom_is_reference[i] = picture_info->referenceFrames[i].bottom_is_reference;
406       picture->field_order_cnt_list[i][0] = picture_info->referenceFrames[i].field_order_cnt[0];
407       picture->field_order_cnt_list[i][1] = picture_info->referenceFrames[i].field_order_cnt[1];
408       picture->frame_num_list[i] = picture_info->referenceFrames[i].frame_idx;
409    }
410 
411    return VDP_STATUS_OK;
412 }
413 
414 static VdpStatus
vlVdpDecoderRenderH265(struct pipe_h265_picture_desc * picture,VdpPictureInfoHEVC * picture_info)415 vlVdpDecoderRenderH265(struct pipe_h265_picture_desc *picture,
416                        VdpPictureInfoHEVC *picture_info)
417 {
418    unsigned i;
419 
420    picture->pps->sps->chroma_format_idc = picture_info->chroma_format_idc;
421    picture->pps->sps->separate_colour_plane_flag = picture_info->separate_colour_plane_flag;
422    picture->pps->sps->pic_width_in_luma_samples = picture_info->pic_width_in_luma_samples;
423    picture->pps->sps->pic_height_in_luma_samples = picture_info->pic_height_in_luma_samples;
424    picture->pps->sps->bit_depth_luma_minus8 = picture_info->bit_depth_luma_minus8;
425    picture->pps->sps->bit_depth_chroma_minus8 = picture_info->bit_depth_chroma_minus8;
426    picture->pps->sps->log2_max_pic_order_cnt_lsb_minus4 = picture_info->log2_max_pic_order_cnt_lsb_minus4;
427    picture->pps->sps->sps_max_dec_pic_buffering_minus1 = picture_info->sps_max_dec_pic_buffering_minus1;
428    picture->pps->sps->log2_min_luma_coding_block_size_minus3 = picture_info->log2_min_luma_coding_block_size_minus3;
429    picture->pps->sps->log2_diff_max_min_luma_coding_block_size = picture_info->log2_diff_max_min_luma_coding_block_size;
430    picture->pps->sps->log2_min_transform_block_size_minus2 = picture_info->log2_min_transform_block_size_minus2;
431    picture->pps->sps->log2_diff_max_min_transform_block_size = picture_info->log2_diff_max_min_transform_block_size;
432    picture->pps->sps->max_transform_hierarchy_depth_inter = picture_info->max_transform_hierarchy_depth_inter;
433    picture->pps->sps->max_transform_hierarchy_depth_intra = picture_info->max_transform_hierarchy_depth_intra;
434    picture->pps->sps->scaling_list_enabled_flag = picture_info->scaling_list_enabled_flag;
435    memcpy(picture->pps->sps->ScalingList4x4, picture_info->ScalingList4x4, 6*16);
436    memcpy(picture->pps->sps->ScalingList8x8, picture_info->ScalingList8x8, 6*64);
437    memcpy(picture->pps->sps->ScalingList16x16, picture_info->ScalingList16x16, 6*64);
438    memcpy(picture->pps->sps->ScalingList32x32, picture_info->ScalingList32x32, 2*64);
439    memcpy(picture->pps->sps->ScalingListDCCoeff16x16, picture_info->ScalingListDCCoeff16x16, 6);
440    memcpy(picture->pps->sps->ScalingListDCCoeff32x32, picture_info->ScalingListDCCoeff32x32, 2);
441    picture->pps->sps->amp_enabled_flag = picture_info->amp_enabled_flag;
442    picture->pps->sps->sample_adaptive_offset_enabled_flag = picture_info->sample_adaptive_offset_enabled_flag;
443    picture->pps->sps->pcm_enabled_flag = picture_info->pcm_enabled_flag;
444    picture->pps->sps->pcm_sample_bit_depth_luma_minus1 = picture_info->pcm_sample_bit_depth_luma_minus1;
445    picture->pps->sps->pcm_sample_bit_depth_chroma_minus1 = picture_info->pcm_sample_bit_depth_chroma_minus1;
446    picture->pps->sps->log2_min_pcm_luma_coding_block_size_minus3 = picture_info->log2_min_pcm_luma_coding_block_size_minus3;
447    picture->pps->sps->log2_diff_max_min_pcm_luma_coding_block_size = picture_info->log2_diff_max_min_pcm_luma_coding_block_size;
448    picture->pps->sps->pcm_loop_filter_disabled_flag = picture_info->pcm_loop_filter_disabled_flag;
449    picture->pps->sps->num_short_term_ref_pic_sets = picture_info->num_short_term_ref_pic_sets;
450    picture->pps->sps->long_term_ref_pics_present_flag = picture_info->long_term_ref_pics_present_flag;
451    picture->pps->sps->num_long_term_ref_pics_sps = picture_info->num_long_term_ref_pics_sps;
452    picture->pps->sps->sps_temporal_mvp_enabled_flag = picture_info->sps_temporal_mvp_enabled_flag;
453    picture->pps->sps->strong_intra_smoothing_enabled_flag = picture_info->strong_intra_smoothing_enabled_flag;
454 
455    picture->pps->dependent_slice_segments_enabled_flag = picture_info->dependent_slice_segments_enabled_flag;
456    picture->pps->output_flag_present_flag = picture_info->output_flag_present_flag;
457    picture->pps->num_extra_slice_header_bits = picture_info->num_extra_slice_header_bits;
458    picture->pps->sign_data_hiding_enabled_flag = picture_info->sign_data_hiding_enabled_flag;
459    picture->pps->cabac_init_present_flag = picture_info->cabac_init_present_flag;
460    picture->pps->num_ref_idx_l0_default_active_minus1 = picture_info->num_ref_idx_l0_default_active_minus1;
461    picture->pps->num_ref_idx_l1_default_active_minus1 = picture_info->num_ref_idx_l1_default_active_minus1;
462    picture->pps->init_qp_minus26 = picture_info->init_qp_minus26;
463    picture->pps->constrained_intra_pred_flag = picture_info->constrained_intra_pred_flag;
464    picture->pps->transform_skip_enabled_flag = picture_info->transform_skip_enabled_flag;
465    picture->pps->cu_qp_delta_enabled_flag = picture_info->cu_qp_delta_enabled_flag;
466    picture->pps->diff_cu_qp_delta_depth = picture_info->diff_cu_qp_delta_depth;
467    picture->pps->pps_cb_qp_offset = picture_info->pps_cb_qp_offset;
468    picture->pps->pps_cr_qp_offset = picture_info->pps_cr_qp_offset;
469    picture->pps->pps_slice_chroma_qp_offsets_present_flag = picture_info->pps_slice_chroma_qp_offsets_present_flag;
470    picture->pps->weighted_pred_flag = picture_info->weighted_pred_flag;
471    picture->pps->weighted_bipred_flag = picture_info->weighted_bipred_flag;
472    picture->pps->transquant_bypass_enabled_flag = picture_info->transquant_bypass_enabled_flag;
473    picture->pps->tiles_enabled_flag = picture_info->tiles_enabled_flag;
474    picture->pps->entropy_coding_sync_enabled_flag = picture_info->entropy_coding_sync_enabled_flag;
475    picture->pps->num_tile_columns_minus1 = picture_info->num_tile_columns_minus1;
476    picture->pps->num_tile_rows_minus1 = picture_info->num_tile_rows_minus1;
477    picture->pps->uniform_spacing_flag = picture_info->uniform_spacing_flag;
478    memcpy(picture->pps->column_width_minus1, picture_info->column_width_minus1, 20 * 2);
479    memcpy(picture->pps->row_height_minus1, picture_info->row_height_minus1, 22 * 2);
480    picture->pps->loop_filter_across_tiles_enabled_flag = picture_info->loop_filter_across_tiles_enabled_flag;
481    picture->pps->pps_loop_filter_across_slices_enabled_flag = picture_info->pps_loop_filter_across_slices_enabled_flag;
482    picture->pps->deblocking_filter_control_present_flag = picture_info->deblocking_filter_control_present_flag;
483    picture->pps->deblocking_filter_override_enabled_flag = picture_info->deblocking_filter_override_enabled_flag;
484    picture->pps->pps_deblocking_filter_disabled_flag = picture_info->pps_deblocking_filter_disabled_flag;
485    picture->pps->pps_beta_offset_div2 = picture_info->pps_beta_offset_div2;
486    picture->pps->pps_tc_offset_div2 = picture_info->pps_tc_offset_div2;
487    picture->pps->lists_modification_present_flag = picture_info->lists_modification_present_flag;
488    picture->pps->log2_parallel_merge_level_minus2 = picture_info->log2_parallel_merge_level_minus2;
489    picture->pps->slice_segment_header_extension_present_flag = picture_info->slice_segment_header_extension_present_flag;
490 
491    picture->IDRPicFlag = picture_info->IDRPicFlag;
492    picture->RAPPicFlag = picture_info->RAPPicFlag;
493    picture->CurrRpsIdx = picture_info->CurrRpsIdx;
494    picture->NumPocTotalCurr = picture_info->NumPocTotalCurr;
495    picture->NumDeltaPocsOfRefRpsIdx = picture_info->NumDeltaPocsOfRefRpsIdx;
496    picture->NumShortTermPictureSliceHeaderBits = picture_info->NumShortTermPictureSliceHeaderBits;
497    picture->NumLongTermPictureSliceHeaderBits = picture_info->NumLongTermPictureSliceHeaderBits;
498    picture->CurrPicOrderCntVal = picture_info->CurrPicOrderCntVal;
499 
500    for (i = 0; i < 16; ++i) {
501       VdpStatus ret = vlVdpGetReferenceFrame
502       (
503          picture_info->RefPics[i],
504          &picture->ref[i]
505       );
506       if (ret != VDP_STATUS_OK)
507          return ret;
508 
509       picture->PicOrderCntVal[i] = picture_info->PicOrderCntVal[i];
510       picture->IsLongTerm[i] = picture_info->IsLongTerm[i];
511    }
512 
513    picture->NumPocStCurrBefore = picture_info->NumPocStCurrBefore;
514    picture->NumPocStCurrAfter = picture_info->NumPocStCurrAfter;
515    picture->NumPocLtCurr = picture_info->NumPocLtCurr;
516    memcpy(picture->RefPicSetStCurrBefore, picture_info->RefPicSetStCurrBefore, 8);
517    memcpy(picture->RefPicSetStCurrAfter, picture_info->RefPicSetStCurrAfter, 8);
518    memcpy(picture->RefPicSetLtCurr, picture_info->RefPicSetLtCurr, 8);
519    picture->UseRefPicList = false;
520    picture->UseStRpsBits = false;
521 
522    return VDP_STATUS_OK;
523 }
524 
525 static void
vlVdpDecoderFixVC1Startcode(uint32_t * num_buffers,const void * buffers[],unsigned sizes[])526 vlVdpDecoderFixVC1Startcode(uint32_t *num_buffers, const void *buffers[], unsigned sizes[])
527 {
528    static const uint8_t vc1_startcode[] = { 0x00, 0x00, 0x01, 0x0D };
529    struct vl_vlc vlc = {};
530    unsigned i;
531 
532    /* search the first 64 bytes for a startcode */
533    vl_vlc_init(&vlc, *num_buffers, buffers, sizes);
534    while (vl_vlc_search_byte(&vlc, 64*8, 0x00) && vl_vlc_bits_left(&vlc) >= 32) {
535       uint32_t value = vl_vlc_peekbits(&vlc, 32);
536       if (value == 0x0000010D ||
537           value == 0x0000010C ||
538           value == 0x0000010B)
539          return;
540       vl_vlc_eatbits(&vlc, 8);
541    }
542 
543    /* none found, ok add one manually */
544    VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Manually adding VC-1 startcode\n");
545    for (i = *num_buffers; i > 0; --i) {
546       buffers[i] = buffers[i - 1];
547       sizes[i] = sizes[i - 1];
548    }
549    ++(*num_buffers);
550    buffers[0] = vc1_startcode;
551    sizes[0] = 4;
552 }
553 
554 /**
555  * Decode a compressed field/frame and render the result into a VdpVideoSurface.
556  */
557 VdpStatus
vlVdpDecoderRender(VdpDecoder decoder,VdpVideoSurface target,VdpPictureInfo const * picture_info,uint32_t bitstream_buffer_count,VdpBitstreamBuffer const * bitstream_buffers)558 vlVdpDecoderRender(VdpDecoder decoder,
559                    VdpVideoSurface target,
560                    VdpPictureInfo const *picture_info,
561                    uint32_t bitstream_buffer_count,
562                    VdpBitstreamBuffer const *bitstream_buffers)
563 {
564    const void * buffers[bitstream_buffer_count + 1];
565    unsigned sizes[bitstream_buffer_count + 1];
566    vlVdpDecoder *vldecoder;
567    vlVdpSurface *vlsurf;
568    VdpStatus ret;
569    struct pipe_screen *screen;
570    struct pipe_video_codec *dec;
571    bool buffer_support[2];
572    unsigned i;
573    struct pipe_h264_sps sps_h264 = {};
574    struct pipe_h264_pps pps_h264 = { &sps_h264 };
575    struct pipe_h265_sps sps_h265 = {};
576    struct pipe_h265_pps pps_h265 = { &sps_h265 };
577    union {
578       struct pipe_picture_desc base;
579       struct pipe_mpeg12_picture_desc mpeg12;
580       struct pipe_mpeg4_picture_desc mpeg4;
581       struct pipe_vc1_picture_desc vc1;
582       struct pipe_h264_picture_desc h264;
583       struct pipe_h265_picture_desc h265;
584    } desc;
585 
586    if (!(picture_info && bitstream_buffers))
587       return VDP_STATUS_INVALID_POINTER;
588 
589    vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
590    if (!vldecoder)
591       return VDP_STATUS_INVALID_HANDLE;
592    dec = vldecoder->decoder;
593    screen = dec->context->screen;
594 
595    vlsurf = (vlVdpSurface *)vlGetDataHTAB(target);
596    if (!vlsurf)
597       return VDP_STATUS_INVALID_HANDLE;
598 
599    if (vlsurf->device != vldecoder->device)
600       return VDP_STATUS_HANDLE_DEVICE_MISMATCH;
601 
602    if (vlsurf->video_buffer != NULL &&
603        pipe_format_to_chroma_format(vlsurf->video_buffer->buffer_format) != dec->chroma_format)
604       // TODO: Recreate decoder with correct chroma
605       return VDP_STATUS_INVALID_CHROMA_TYPE;
606 
607    buffer_support[0] = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
608                                                PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE);
609    buffer_support[1] = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
610                                                PIPE_VIDEO_CAP_SUPPORTS_INTERLACED);
611 
612    if (vlsurf->video_buffer == NULL ||
613        !screen->is_video_format_supported(screen, vlsurf->video_buffer->buffer_format,
614                                           dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM) ||
615        !buffer_support[vlsurf->video_buffer->interlaced]) {
616 
617       mtx_lock(&vlsurf->device->mutex);
618 
619       /* destroy the old one */
620       if (vlsurf->video_buffer)
621          vlsurf->video_buffer->destroy(vlsurf->video_buffer);
622 
623       /* set the buffer format to the prefered one */
624       vlsurf->templat.buffer_format = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
625                                                               PIPE_VIDEO_CAP_PREFERED_FORMAT);
626 
627       /* also set interlacing to decoders preferences */
628       vlsurf->templat.interlaced = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
629                                                            PIPE_VIDEO_CAP_PREFERS_INTERLACED);
630 
631       /* and recreate the video buffer */
632       vlsurf->video_buffer = dec->context->create_video_buffer(dec->context, &vlsurf->templat);
633 
634       /* still no luck? get me out of here... */
635       if (!vlsurf->video_buffer) {
636          mtx_unlock(&vlsurf->device->mutex);
637          return VDP_STATUS_NO_IMPLEMENTATION;
638       }
639       vlVdpVideoSurfaceClear(vlsurf);
640       mtx_unlock(&vlsurf->device->mutex);
641    }
642 
643    for (i = 0; i < bitstream_buffer_count; ++i) {
644       buffers[i] = bitstream_buffers[i].bitstream;
645       sizes[i] = bitstream_buffers[i].bitstream_bytes;
646    }
647 
648    memset(&desc, 0, sizeof(desc));
649    desc.base.profile = dec->profile;
650    switch (u_reduce_video_profile(dec->profile)) {
651    case PIPE_VIDEO_FORMAT_MPEG12:
652       ret = vlVdpDecoderRenderMpeg12(&desc.mpeg12, (VdpPictureInfoMPEG1Or2 *)picture_info);
653       break;
654    case PIPE_VIDEO_FORMAT_MPEG4:
655       ret = vlVdpDecoderRenderMpeg4(&desc.mpeg4, (VdpPictureInfoMPEG4Part2 *)picture_info);
656       break;
657    case PIPE_VIDEO_FORMAT_VC1:
658       if (dec->profile == PIPE_VIDEO_PROFILE_VC1_ADVANCED)
659          vlVdpDecoderFixVC1Startcode(&bitstream_buffer_count, buffers, sizes);
660       ret = vlVdpDecoderRenderVC1(&desc.vc1, (VdpPictureInfoVC1 *)picture_info);
661       break;
662    case PIPE_VIDEO_FORMAT_MPEG4_AVC:
663       desc.h264.pps = &pps_h264;
664       ret = vlVdpDecoderRenderH264(&desc.h264, (VdpPictureInfoH264 *)picture_info, dec->level);
665       break;
666    case PIPE_VIDEO_FORMAT_HEVC:
667       desc.h265.pps = &pps_h265;
668       ret = vlVdpDecoderRenderH265(&desc.h265, (VdpPictureInfoHEVC *)picture_info);
669       break;
670    default:
671       return VDP_STATUS_INVALID_DECODER_PROFILE;
672    }
673 
674    if (ret != VDP_STATUS_OK)
675       return ret;
676 
677    mtx_lock(&vldecoder->mutex);
678    dec->begin_frame(dec, vlsurf->video_buffer, &desc.base);
679    dec->decode_bitstream(dec, vlsurf->video_buffer, &desc.base, bitstream_buffer_count, buffers, sizes);
680    dec->end_frame(dec, vlsurf->video_buffer, &desc.base);
681    mtx_unlock(&vldecoder->mutex);
682    return ret;
683 }
684