1848b8605Smrg/**************************************************************************
2848b8605Smrg *
3848b8605Smrg * Copyright 2010 Thomas Balling Sørensen.
4848b8605Smrg * All Rights Reserved.
5848b8605Smrg *
6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
7848b8605Smrg * copy of this software and associated documentation files (the
8848b8605Smrg * "Software"), to deal in the Software without restriction, including
9848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish,
10848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to
11848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to
12848b8605Smrg * the following conditions:
13848b8605Smrg *
14848b8605Smrg * The above copyright notice and this permission notice (including the
15848b8605Smrg * next paragraph) shall be included in all copies or substantial portions
16848b8605Smrg * of the Software.
17848b8605Smrg *
18848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20848b8605Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21848b8605Smrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22848b8605Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23848b8605Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24848b8605Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25848b8605Smrg *
26848b8605Smrg **************************************************************************/
27848b8605Smrg
28848b8605Smrg#include "util/u_memory.h"
29848b8605Smrg#include "util/u_math.h"
30848b8605Smrg#include "util/u_debug.h"
31848b8605Smrg#include "util/u_video.h"
32848b8605Smrg
33848b8605Smrg#include "vl/vl_vlc.h"
34848b8605Smrg
35848b8605Smrg#include "vdpau_private.h"
36848b8605Smrg
37848b8605Smrg/**
38848b8605Smrg * Create a VdpDecoder.
39848b8605Smrg */
40848b8605SmrgVdpStatus
41848b8605SmrgvlVdpDecoderCreate(VdpDevice device,
42848b8605Smrg                   VdpDecoderProfile profile,
43848b8605Smrg                   uint32_t width, uint32_t height,
44848b8605Smrg                   uint32_t max_references,
45848b8605Smrg                   VdpDecoder *decoder)
46848b8605Smrg{
47848b8605Smrg   struct pipe_video_codec templat = {};
48848b8605Smrg   struct pipe_context *pipe;
49848b8605Smrg   struct pipe_screen *screen;
50848b8605Smrg   vlVdpDevice *dev;
51848b8605Smrg   vlVdpDecoder *vldecoder;
52848b8605Smrg   VdpStatus ret;
53848b8605Smrg   bool supported;
54848b8605Smrg   uint32_t maxwidth, maxheight;
55848b8605Smrg
56848b8605Smrg   if (!decoder)
57848b8605Smrg      return VDP_STATUS_INVALID_POINTER;
58848b8605Smrg   *decoder = 0;
59848b8605Smrg
60848b8605Smrg   if (!(width && height))
61848b8605Smrg      return VDP_STATUS_INVALID_VALUE;
62848b8605Smrg
63848b8605Smrg   templat.profile = ProfileToPipe(profile);
64848b8605Smrg   if (templat.profile == PIPE_VIDEO_PROFILE_UNKNOWN)
65848b8605Smrg      return VDP_STATUS_INVALID_DECODER_PROFILE;
66848b8605Smrg
67848b8605Smrg   dev = vlGetDataHTAB(device);
68848b8605Smrg   if (!dev)
69848b8605Smrg      return VDP_STATUS_INVALID_HANDLE;
70848b8605Smrg
71848b8605Smrg   pipe = dev->context;
72848b8605Smrg   screen = dev->vscreen->pscreen;
73848b8605Smrg
74b8e80941Smrg   mtx_lock(&dev->mutex);
75848b8605Smrg
76848b8605Smrg   supported = screen->get_video_param
77848b8605Smrg   (
78848b8605Smrg      screen,
79848b8605Smrg      templat.profile,
80848b8605Smrg      PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
81848b8605Smrg      PIPE_VIDEO_CAP_SUPPORTED
82848b8605Smrg   );
83848b8605Smrg   if (!supported) {
84b8e80941Smrg      mtx_unlock(&dev->mutex);
85848b8605Smrg      return VDP_STATUS_INVALID_DECODER_PROFILE;
86848b8605Smrg   }
87848b8605Smrg
88848b8605Smrg   maxwidth = screen->get_video_param
89848b8605Smrg   (
90848b8605Smrg      screen,
91848b8605Smrg      templat.profile,
92848b8605Smrg      PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
93848b8605Smrg      PIPE_VIDEO_CAP_MAX_WIDTH
94848b8605Smrg   );
95848b8605Smrg   maxheight = screen->get_video_param
96848b8605Smrg   (
97848b8605Smrg      screen,
98848b8605Smrg      templat.profile,
99848b8605Smrg      PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
100848b8605Smrg      PIPE_VIDEO_CAP_MAX_HEIGHT
101848b8605Smrg   );
102848b8605Smrg   if (width > maxwidth || height > maxheight) {
103b8e80941Smrg      mtx_unlock(&dev->mutex);
104848b8605Smrg      return VDP_STATUS_INVALID_SIZE;
105848b8605Smrg   }
106848b8605Smrg
107848b8605Smrg   vldecoder = CALLOC(1,sizeof(vlVdpDecoder));
108848b8605Smrg   if (!vldecoder) {
109b8e80941Smrg      mtx_unlock(&dev->mutex);
110848b8605Smrg      return VDP_STATUS_RESOURCES;
111848b8605Smrg   }
112848b8605Smrg
113848b8605Smrg   DeviceReference(&vldecoder->device, dev);
114848b8605Smrg
115848b8605Smrg   templat.entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM;
116848b8605Smrg   templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;
117848b8605Smrg   templat.width = width;
118848b8605Smrg   templat.height = height;
119848b8605Smrg   templat.max_references = max_references;
120848b8605Smrg
121b8e80941Smrg   if (u_reduce_video_profile(templat.profile) ==
122b8e80941Smrg       PIPE_VIDEO_FORMAT_MPEG4_AVC)
123b8e80941Smrg      templat.level = u_get_h264_level(templat.width, templat.height,
124b8e80941Smrg                            &templat.max_references);
125b8e80941Smrg
126848b8605Smrg   vldecoder->decoder = pipe->create_video_codec(pipe, &templat);
127848b8605Smrg
128848b8605Smrg   if (!vldecoder->decoder) {
129848b8605Smrg      ret = VDP_STATUS_ERROR;
130848b8605Smrg      goto error_decoder;
131848b8605Smrg   }
132848b8605Smrg
133848b8605Smrg   *decoder = vlAddDataHTAB(vldecoder);
134848b8605Smrg   if (*decoder == 0) {
135848b8605Smrg      ret = VDP_STATUS_ERROR;
136848b8605Smrg      goto error_handle;
137848b8605Smrg   }
138848b8605Smrg
139b8e80941Smrg   (void) mtx_init(&vldecoder->mutex, mtx_plain);
140b8e80941Smrg   mtx_unlock(&dev->mutex);
141848b8605Smrg
142848b8605Smrg   return VDP_STATUS_OK;
143848b8605Smrg
144848b8605Smrgerror_handle:
145848b8605Smrg   vldecoder->decoder->destroy(vldecoder->decoder);
146848b8605Smrg
147848b8605Smrgerror_decoder:
148b8e80941Smrg   mtx_unlock(&dev->mutex);
149848b8605Smrg   DeviceReference(&vldecoder->device, NULL);
150848b8605Smrg   FREE(vldecoder);
151848b8605Smrg   return ret;
152848b8605Smrg}
153848b8605Smrg
154848b8605Smrg/**
155848b8605Smrg * Destroy a VdpDecoder.
156848b8605Smrg */
157848b8605SmrgVdpStatus
158848b8605SmrgvlVdpDecoderDestroy(VdpDecoder decoder)
159848b8605Smrg{
160848b8605Smrg   vlVdpDecoder *vldecoder;
161848b8605Smrg
162848b8605Smrg   vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
163848b8605Smrg   if (!vldecoder)
164848b8605Smrg      return VDP_STATUS_INVALID_HANDLE;
165848b8605Smrg
166b8e80941Smrg   mtx_lock(&vldecoder->mutex);
167848b8605Smrg   vldecoder->decoder->destroy(vldecoder->decoder);
168b8e80941Smrg   mtx_unlock(&vldecoder->mutex);
169b8e80941Smrg   mtx_destroy(&vldecoder->mutex);
170848b8605Smrg
171848b8605Smrg   vlRemoveDataHTAB(decoder);
172848b8605Smrg   DeviceReference(&vldecoder->device, NULL);
173848b8605Smrg   FREE(vldecoder);
174848b8605Smrg
175848b8605Smrg   return VDP_STATUS_OK;
176848b8605Smrg}
177848b8605Smrg
178848b8605Smrg/**
179848b8605Smrg * Retrieve the parameters used to create a VdpDecoder.
180848b8605Smrg */
181848b8605SmrgVdpStatus
182848b8605SmrgvlVdpDecoderGetParameters(VdpDecoder decoder,
183848b8605Smrg                          VdpDecoderProfile *profile,
184848b8605Smrg                          uint32_t *width,
185848b8605Smrg                          uint32_t *height)
186848b8605Smrg{
187848b8605Smrg   vlVdpDecoder *vldecoder;
188848b8605Smrg
189848b8605Smrg   vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
190848b8605Smrg   if (!vldecoder)
191848b8605Smrg      return VDP_STATUS_INVALID_HANDLE;
192848b8605Smrg
193848b8605Smrg   *profile = PipeToProfile(vldecoder->decoder->profile);
194848b8605Smrg   *width = vldecoder->decoder->width;
195848b8605Smrg   *height = vldecoder->decoder->height;
196848b8605Smrg
197848b8605Smrg   return VDP_STATUS_OK;
198848b8605Smrg}
199848b8605Smrg
200848b8605Smrgstatic VdpStatus
201848b8605SmrgvlVdpGetReferenceFrame(VdpVideoSurface handle, struct pipe_video_buffer **ref_frame)
202848b8605Smrg{
203848b8605Smrg   vlVdpSurface *surface;
204848b8605Smrg
205848b8605Smrg   /* if surfaces equals VDP_STATUS_INVALID_HANDLE, they are not used */
206848b8605Smrg   if (handle ==  VDP_INVALID_HANDLE) {
207848b8605Smrg      *ref_frame = NULL;
208848b8605Smrg      return VDP_STATUS_OK;
209848b8605Smrg   }
210848b8605Smrg
211848b8605Smrg   surface = vlGetDataHTAB(handle);
212848b8605Smrg   if (!surface)
213848b8605Smrg      return VDP_STATUS_INVALID_HANDLE;
214848b8605Smrg
215848b8605Smrg   *ref_frame = surface->video_buffer;
216848b8605Smrg   if (!*ref_frame)
217848b8605Smrg         return VDP_STATUS_INVALID_HANDLE;
218848b8605Smrg
219848b8605Smrg   return VDP_STATUS_OK;
220848b8605Smrg}
221848b8605Smrg
222848b8605Smrg/**
223848b8605Smrg * Decode a mpeg 1/2 video.
224848b8605Smrg */
225848b8605Smrgstatic VdpStatus
226848b8605SmrgvlVdpDecoderRenderMpeg12(struct pipe_mpeg12_picture_desc *picture,
227848b8605Smrg                         VdpPictureInfoMPEG1Or2 *picture_info)
228848b8605Smrg{
229848b8605Smrg   VdpStatus r;
230848b8605Smrg
231848b8605Smrg   VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoding MPEG12\n");
232848b8605Smrg
233848b8605Smrg   r = vlVdpGetReferenceFrame(picture_info->forward_reference, &picture->ref[0]);
234848b8605Smrg   if (r != VDP_STATUS_OK)
235848b8605Smrg      return r;
236848b8605Smrg
237848b8605Smrg   r = vlVdpGetReferenceFrame(picture_info->backward_reference, &picture->ref[1]);
238848b8605Smrg   if (r != VDP_STATUS_OK)
239848b8605Smrg      return r;
240848b8605Smrg
241848b8605Smrg   picture->picture_coding_type = picture_info->picture_coding_type;
242848b8605Smrg   picture->picture_structure = picture_info->picture_structure;
243848b8605Smrg   picture->frame_pred_frame_dct = picture_info->frame_pred_frame_dct;
244848b8605Smrg   picture->q_scale_type = picture_info->q_scale_type;
245848b8605Smrg   picture->alternate_scan = picture_info->alternate_scan;
246848b8605Smrg   picture->intra_vlc_format = picture_info->intra_vlc_format;
247848b8605Smrg   picture->concealment_motion_vectors = picture_info->concealment_motion_vectors;
248848b8605Smrg   picture->intra_dc_precision = picture_info->intra_dc_precision;
249848b8605Smrg   picture->f_code[0][0] = picture_info->f_code[0][0] - 1;
250848b8605Smrg   picture->f_code[0][1] = picture_info->f_code[0][1] - 1;
251848b8605Smrg   picture->f_code[1][0] = picture_info->f_code[1][0] - 1;
252848b8605Smrg   picture->f_code[1][1] = picture_info->f_code[1][1] - 1;
253848b8605Smrg   picture->num_slices = picture_info->slice_count;
254848b8605Smrg   picture->top_field_first = picture_info->top_field_first;
255848b8605Smrg   picture->full_pel_forward_vector = picture_info->full_pel_forward_vector;
256848b8605Smrg   picture->full_pel_backward_vector = picture_info->full_pel_backward_vector;
257848b8605Smrg   picture->intra_matrix = picture_info->intra_quantizer_matrix;
258848b8605Smrg   picture->non_intra_matrix = picture_info->non_intra_quantizer_matrix;
259848b8605Smrg
260848b8605Smrg   return VDP_STATUS_OK;
261848b8605Smrg}
262848b8605Smrg
263848b8605Smrg/**
264848b8605Smrg * Decode a mpeg 4 video.
265848b8605Smrg */
266848b8605Smrgstatic VdpStatus
267848b8605SmrgvlVdpDecoderRenderMpeg4(struct pipe_mpeg4_picture_desc *picture,
268848b8605Smrg                        VdpPictureInfoMPEG4Part2 *picture_info)
269848b8605Smrg{
270848b8605Smrg   VdpStatus r;
271848b8605Smrg   unsigned i;
272848b8605Smrg
273848b8605Smrg   VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoding MPEG4\n");
274848b8605Smrg
275848b8605Smrg   r = vlVdpGetReferenceFrame(picture_info->forward_reference, &picture->ref[0]);
276848b8605Smrg   if (r != VDP_STATUS_OK)
277848b8605Smrg      return r;
278848b8605Smrg
279848b8605Smrg   r = vlVdpGetReferenceFrame(picture_info->backward_reference, &picture->ref[1]);
280848b8605Smrg   if (r != VDP_STATUS_OK)
281848b8605Smrg      return r;
282848b8605Smrg
283848b8605Smrg   for (i = 0; i < 2; ++i) {
284848b8605Smrg      picture->trd[i] = picture_info->trd[i];
285848b8605Smrg      picture->trb[i] = picture_info->trb[i];
286848b8605Smrg   }
287848b8605Smrg   picture->vop_time_increment_resolution = picture_info->vop_time_increment_resolution;
288848b8605Smrg   picture->vop_coding_type = picture_info->vop_coding_type;
289848b8605Smrg   picture->vop_fcode_forward = picture_info->vop_fcode_forward;
290848b8605Smrg   picture->vop_fcode_backward = picture_info->vop_fcode_backward;
291848b8605Smrg   picture->resync_marker_disable = picture_info->resync_marker_disable;
292848b8605Smrg   picture->interlaced = picture_info->interlaced;
293848b8605Smrg   picture->quant_type = picture_info->quant_type;
294848b8605Smrg   picture->quarter_sample = picture_info->quarter_sample;
295848b8605Smrg   picture->short_video_header = picture_info->short_video_header;
296848b8605Smrg   picture->rounding_control = picture_info->rounding_control;
297848b8605Smrg   picture->alternate_vertical_scan_flag = picture_info->alternate_vertical_scan_flag;
298848b8605Smrg   picture->top_field_first = picture_info->top_field_first;
299848b8605Smrg   picture->intra_matrix = picture_info->intra_quantizer_matrix;
300848b8605Smrg   picture->non_intra_matrix = picture_info->non_intra_quantizer_matrix;
301848b8605Smrg
302848b8605Smrg   return VDP_STATUS_OK;
303848b8605Smrg}
304848b8605Smrg
305848b8605Smrgstatic VdpStatus
306848b8605SmrgvlVdpDecoderRenderVC1(struct pipe_vc1_picture_desc *picture,
307848b8605Smrg                      VdpPictureInfoVC1 *picture_info)
308848b8605Smrg{
309848b8605Smrg   VdpStatus r;
310848b8605Smrg
311848b8605Smrg   VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoding VC-1\n");
312848b8605Smrg
313848b8605Smrg   r = vlVdpGetReferenceFrame(picture_info->forward_reference, &picture->ref[0]);
314848b8605Smrg   if (r != VDP_STATUS_OK)
315848b8605Smrg      return r;
316848b8605Smrg
317848b8605Smrg   r = vlVdpGetReferenceFrame(picture_info->backward_reference, &picture->ref[1]);
318848b8605Smrg   if (r != VDP_STATUS_OK)
319848b8605Smrg      return r;
320848b8605Smrg
321848b8605Smrg   picture->slice_count = picture_info->slice_count;
322848b8605Smrg   picture->picture_type = picture_info->picture_type;
323848b8605Smrg   picture->frame_coding_mode = picture_info->frame_coding_mode;
324848b8605Smrg   picture->postprocflag = picture_info->postprocflag;
325848b8605Smrg   picture->pulldown = picture_info->pulldown;
326848b8605Smrg   picture->interlace = picture_info->interlace;
327848b8605Smrg   picture->tfcntrflag = picture_info->tfcntrflag;
328848b8605Smrg   picture->finterpflag = picture_info->finterpflag;
329848b8605Smrg   picture->psf = picture_info->psf;
330848b8605Smrg   picture->dquant = picture_info->dquant;
331848b8605Smrg   picture->panscan_flag = picture_info->panscan_flag;
332848b8605Smrg   picture->refdist_flag = picture_info->refdist_flag;
333848b8605Smrg   picture->quantizer = picture_info->quantizer;
334848b8605Smrg   picture->extended_mv = picture_info->extended_mv;
335848b8605Smrg   picture->extended_dmv = picture_info->extended_dmv;
336848b8605Smrg   picture->overlap = picture_info->overlap;
337848b8605Smrg   picture->vstransform = picture_info->vstransform;
338848b8605Smrg   picture->loopfilter = picture_info->loopfilter;
339848b8605Smrg   picture->fastuvmc = picture_info->fastuvmc;
340848b8605Smrg   picture->range_mapy_flag = picture_info->range_mapy_flag;
341848b8605Smrg   picture->range_mapy = picture_info->range_mapy;
342848b8605Smrg   picture->range_mapuv_flag = picture_info->range_mapuv_flag;
343848b8605Smrg   picture->range_mapuv = picture_info->range_mapuv;
344848b8605Smrg   picture->multires = picture_info->multires;
345848b8605Smrg   picture->syncmarker = picture_info->syncmarker;
346848b8605Smrg   picture->rangered = picture_info->rangered;
347848b8605Smrg   picture->maxbframes = picture_info->maxbframes;
348848b8605Smrg   picture->deblockEnable = picture_info->deblockEnable;
349848b8605Smrg   picture->pquant = picture_info->pquant;
350848b8605Smrg
351848b8605Smrg   return VDP_STATUS_OK;
352848b8605Smrg}
353848b8605Smrg
354848b8605Smrgstatic VdpStatus
355848b8605SmrgvlVdpDecoderRenderH264(struct pipe_h264_picture_desc *picture,
356848b8605Smrg                       VdpPictureInfoH264 *picture_info)
357848b8605Smrg{
358848b8605Smrg   unsigned i;
359848b8605Smrg
360848b8605Smrg   VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Decoding H264\n");
361848b8605Smrg
362848b8605Smrg   picture->pps->sps->mb_adaptive_frame_field_flag = picture_info->mb_adaptive_frame_field_flag;
363848b8605Smrg   picture->pps->sps->frame_mbs_only_flag = picture_info->frame_mbs_only_flag;
364848b8605Smrg   picture->pps->sps->log2_max_frame_num_minus4 = picture_info->log2_max_frame_num_minus4;
365848b8605Smrg   picture->pps->sps->pic_order_cnt_type = picture_info->pic_order_cnt_type;
366848b8605Smrg   picture->pps->sps->log2_max_pic_order_cnt_lsb_minus4 = picture_info->log2_max_pic_order_cnt_lsb_minus4;
367848b8605Smrg   picture->pps->sps->delta_pic_order_always_zero_flag = picture_info->delta_pic_order_always_zero_flag;
368848b8605Smrg   picture->pps->sps->direct_8x8_inference_flag = picture_info->direct_8x8_inference_flag;
369848b8605Smrg
370848b8605Smrg   picture->pps->transform_8x8_mode_flag = picture_info->transform_8x8_mode_flag;
371848b8605Smrg   picture->pps->chroma_qp_index_offset = picture_info->chroma_qp_index_offset;
372848b8605Smrg   picture->pps->second_chroma_qp_index_offset = picture_info->second_chroma_qp_index_offset;
373848b8605Smrg   picture->pps->pic_init_qp_minus26 = picture_info->pic_init_qp_minus26;
374848b8605Smrg   picture->pps->entropy_coding_mode_flag = picture_info->entropy_coding_mode_flag;
375848b8605Smrg   picture->pps->deblocking_filter_control_present_flag = picture_info->deblocking_filter_control_present_flag;
376848b8605Smrg   picture->pps->redundant_pic_cnt_present_flag = picture_info->redundant_pic_cnt_present_flag;
377848b8605Smrg   picture->pps->constrained_intra_pred_flag = picture_info->constrained_intra_pred_flag;
378848b8605Smrg   picture->pps->weighted_pred_flag = picture_info->weighted_pred_flag;
379848b8605Smrg   picture->pps->weighted_bipred_idc = picture_info->weighted_bipred_idc;
380848b8605Smrg   picture->pps->bottom_field_pic_order_in_frame_present_flag = picture_info->pic_order_present_flag;
381848b8605Smrg   memcpy(picture->pps->ScalingList4x4, picture_info->scaling_lists_4x4, 6*16);
382848b8605Smrg   memcpy(picture->pps->ScalingList8x8, picture_info->scaling_lists_8x8, 2*64);
383848b8605Smrg
384848b8605Smrg   picture->slice_count = picture_info->slice_count;
385848b8605Smrg   picture->field_order_cnt[0] = picture_info->field_order_cnt[0];
386848b8605Smrg   picture->field_order_cnt[1] = picture_info->field_order_cnt[1];
387848b8605Smrg   picture->is_reference = picture_info->is_reference;
388848b8605Smrg   picture->frame_num = picture_info->frame_num;
389848b8605Smrg   picture->field_pic_flag = picture_info->field_pic_flag;
390848b8605Smrg   picture->bottom_field_flag = picture_info->bottom_field_flag;
391848b8605Smrg   picture->num_ref_frames = picture_info->num_ref_frames;
392848b8605Smrg
393848b8605Smrg   picture->num_ref_idx_l0_active_minus1 = picture_info->num_ref_idx_l0_active_minus1;
394848b8605Smrg   picture->num_ref_idx_l1_active_minus1 = picture_info->num_ref_idx_l1_active_minus1;
395848b8605Smrg
396848b8605Smrg   for (i = 0; i < 16; ++i) {
397848b8605Smrg      VdpStatus ret = vlVdpGetReferenceFrame
398848b8605Smrg      (
399848b8605Smrg         picture_info->referenceFrames[i].surface,
400848b8605Smrg         &picture->ref[i]
401848b8605Smrg      );
402848b8605Smrg      if (ret != VDP_STATUS_OK)
403848b8605Smrg         return ret;
404848b8605Smrg
405848b8605Smrg      picture->is_long_term[i] = picture_info->referenceFrames[i].is_long_term;
406848b8605Smrg      picture->top_is_reference[i] = picture_info->referenceFrames[i].top_is_reference;
407848b8605Smrg      picture->bottom_is_reference[i] = picture_info->referenceFrames[i].bottom_is_reference;
408848b8605Smrg      picture->field_order_cnt_list[i][0] = picture_info->referenceFrames[i].field_order_cnt[0];
409848b8605Smrg      picture->field_order_cnt_list[i][1] = picture_info->referenceFrames[i].field_order_cnt[1];
410848b8605Smrg      picture->frame_num_list[i] = picture_info->referenceFrames[i].frame_idx;
411848b8605Smrg   }
412848b8605Smrg
413848b8605Smrg   return VDP_STATUS_OK;
414848b8605Smrg}
415848b8605Smrg
416b8e80941Smrgstatic VdpStatus
417b8e80941SmrgvlVdpDecoderRenderH265(struct pipe_h265_picture_desc *picture,
418b8e80941Smrg                       VdpPictureInfoHEVC *picture_info)
419b8e80941Smrg{
420b8e80941Smrg   unsigned i;
421b8e80941Smrg
422b8e80941Smrg   picture->pps->sps->chroma_format_idc = picture_info->chroma_format_idc;
423b8e80941Smrg   picture->pps->sps->separate_colour_plane_flag = picture_info->separate_colour_plane_flag;
424b8e80941Smrg   picture->pps->sps->pic_width_in_luma_samples = picture_info->pic_width_in_luma_samples;
425b8e80941Smrg   picture->pps->sps->pic_height_in_luma_samples = picture_info->pic_height_in_luma_samples;
426b8e80941Smrg   picture->pps->sps->bit_depth_luma_minus8 = picture_info->bit_depth_luma_minus8;
427b8e80941Smrg   picture->pps->sps->bit_depth_chroma_minus8 = picture_info->bit_depth_chroma_minus8;
428b8e80941Smrg   picture->pps->sps->log2_max_pic_order_cnt_lsb_minus4 = picture_info->log2_max_pic_order_cnt_lsb_minus4;
429b8e80941Smrg   picture->pps->sps->sps_max_dec_pic_buffering_minus1 = picture_info->sps_max_dec_pic_buffering_minus1;
430b8e80941Smrg   picture->pps->sps->log2_min_luma_coding_block_size_minus3 = picture_info->log2_min_luma_coding_block_size_minus3;
431b8e80941Smrg   picture->pps->sps->log2_diff_max_min_luma_coding_block_size = picture_info->log2_diff_max_min_luma_coding_block_size;
432b8e80941Smrg   picture->pps->sps->log2_min_transform_block_size_minus2 = picture_info->log2_min_transform_block_size_minus2;
433b8e80941Smrg   picture->pps->sps->log2_diff_max_min_transform_block_size = picture_info->log2_diff_max_min_transform_block_size;
434b8e80941Smrg   picture->pps->sps->max_transform_hierarchy_depth_inter = picture_info->max_transform_hierarchy_depth_inter;
435b8e80941Smrg   picture->pps->sps->max_transform_hierarchy_depth_intra = picture_info->max_transform_hierarchy_depth_intra;
436b8e80941Smrg   picture->pps->sps->scaling_list_enabled_flag = picture_info->scaling_list_enabled_flag;
437b8e80941Smrg   memcpy(picture->pps->sps->ScalingList4x4, picture_info->ScalingList4x4, 6*16);
438b8e80941Smrg   memcpy(picture->pps->sps->ScalingList8x8, picture_info->ScalingList8x8, 6*64);
439b8e80941Smrg   memcpy(picture->pps->sps->ScalingList16x16, picture_info->ScalingList16x16, 6*64);
440b8e80941Smrg   memcpy(picture->pps->sps->ScalingList32x32, picture_info->ScalingList32x32, 2*64);
441b8e80941Smrg   memcpy(picture->pps->sps->ScalingListDCCoeff16x16, picture_info->ScalingListDCCoeff16x16, 6);
442b8e80941Smrg   memcpy(picture->pps->sps->ScalingListDCCoeff32x32, picture_info->ScalingListDCCoeff32x32, 2);
443b8e80941Smrg   picture->pps->sps->amp_enabled_flag = picture_info->amp_enabled_flag;
444b8e80941Smrg   picture->pps->sps->sample_adaptive_offset_enabled_flag = picture_info->sample_adaptive_offset_enabled_flag;
445b8e80941Smrg   picture->pps->sps->pcm_enabled_flag = picture_info->pcm_enabled_flag;
446b8e80941Smrg   picture->pps->sps->pcm_sample_bit_depth_luma_minus1 = picture_info->pcm_sample_bit_depth_luma_minus1;
447b8e80941Smrg   picture->pps->sps->pcm_sample_bit_depth_chroma_minus1 = picture_info->pcm_sample_bit_depth_chroma_minus1;
448b8e80941Smrg   picture->pps->sps->log2_min_pcm_luma_coding_block_size_minus3 = picture_info->log2_min_pcm_luma_coding_block_size_minus3;
449b8e80941Smrg   picture->pps->sps->log2_diff_max_min_pcm_luma_coding_block_size = picture_info->log2_diff_max_min_pcm_luma_coding_block_size;
450b8e80941Smrg   picture->pps->sps->pcm_loop_filter_disabled_flag = picture_info->pcm_loop_filter_disabled_flag;
451b8e80941Smrg   picture->pps->sps->num_short_term_ref_pic_sets = picture_info->num_short_term_ref_pic_sets;
452b8e80941Smrg   picture->pps->sps->long_term_ref_pics_present_flag = picture_info->long_term_ref_pics_present_flag;
453b8e80941Smrg   picture->pps->sps->num_long_term_ref_pics_sps = picture_info->num_long_term_ref_pics_sps;
454b8e80941Smrg   picture->pps->sps->sps_temporal_mvp_enabled_flag = picture_info->sps_temporal_mvp_enabled_flag;
455b8e80941Smrg   picture->pps->sps->strong_intra_smoothing_enabled_flag = picture_info->strong_intra_smoothing_enabled_flag;
456b8e80941Smrg
457b8e80941Smrg   picture->pps->dependent_slice_segments_enabled_flag = picture_info->dependent_slice_segments_enabled_flag;
458b8e80941Smrg   picture->pps->output_flag_present_flag = picture_info->output_flag_present_flag;
459b8e80941Smrg   picture->pps->num_extra_slice_header_bits = picture_info->num_extra_slice_header_bits;
460b8e80941Smrg   picture->pps->sign_data_hiding_enabled_flag = picture_info->sign_data_hiding_enabled_flag;
461b8e80941Smrg   picture->pps->cabac_init_present_flag = picture_info->cabac_init_present_flag;
462b8e80941Smrg   picture->pps->num_ref_idx_l0_default_active_minus1 = picture_info->num_ref_idx_l0_default_active_minus1;
463b8e80941Smrg   picture->pps->num_ref_idx_l1_default_active_minus1 = picture_info->num_ref_idx_l1_default_active_minus1;
464b8e80941Smrg   picture->pps->init_qp_minus26 = picture_info->init_qp_minus26;
465b8e80941Smrg   picture->pps->constrained_intra_pred_flag = picture_info->constrained_intra_pred_flag;
466b8e80941Smrg   picture->pps->transform_skip_enabled_flag = picture_info->transform_skip_enabled_flag;
467b8e80941Smrg   picture->pps->cu_qp_delta_enabled_flag = picture_info->cu_qp_delta_enabled_flag;
468b8e80941Smrg   picture->pps->diff_cu_qp_delta_depth = picture_info->diff_cu_qp_delta_depth;
469b8e80941Smrg   picture->pps->pps_cb_qp_offset = picture_info->pps_cb_qp_offset;
470b8e80941Smrg   picture->pps->pps_cr_qp_offset = picture_info->pps_cr_qp_offset;
471b8e80941Smrg   picture->pps->pps_slice_chroma_qp_offsets_present_flag = picture_info->pps_slice_chroma_qp_offsets_present_flag;
472b8e80941Smrg   picture->pps->weighted_pred_flag = picture_info->weighted_pred_flag;
473b8e80941Smrg   picture->pps->weighted_bipred_flag = picture_info->weighted_bipred_flag;
474b8e80941Smrg   picture->pps->transquant_bypass_enabled_flag = picture_info->transquant_bypass_enabled_flag;
475b8e80941Smrg   picture->pps->tiles_enabled_flag = picture_info->tiles_enabled_flag;
476b8e80941Smrg   picture->pps->entropy_coding_sync_enabled_flag = picture_info->entropy_coding_sync_enabled_flag;
477b8e80941Smrg   picture->pps->num_tile_columns_minus1 = picture_info->num_tile_columns_minus1;
478b8e80941Smrg   picture->pps->num_tile_rows_minus1 = picture_info->num_tile_rows_minus1;
479b8e80941Smrg   picture->pps->uniform_spacing_flag = picture_info->uniform_spacing_flag;
480b8e80941Smrg   memcpy(picture->pps->column_width_minus1, picture_info->column_width_minus1, 20 * 2);
481b8e80941Smrg   memcpy(picture->pps->row_height_minus1, picture_info->row_height_minus1, 22 * 2);
482b8e80941Smrg   picture->pps->loop_filter_across_tiles_enabled_flag = picture_info->loop_filter_across_tiles_enabled_flag;
483b8e80941Smrg   picture->pps->pps_loop_filter_across_slices_enabled_flag = picture_info->pps_loop_filter_across_slices_enabled_flag;
484b8e80941Smrg   picture->pps->deblocking_filter_control_present_flag = picture_info->deblocking_filter_control_present_flag;
485b8e80941Smrg   picture->pps->deblocking_filter_override_enabled_flag = picture_info->deblocking_filter_override_enabled_flag;
486b8e80941Smrg   picture->pps->pps_deblocking_filter_disabled_flag = picture_info->pps_deblocking_filter_disabled_flag;
487b8e80941Smrg   picture->pps->pps_beta_offset_div2 = picture_info->pps_beta_offset_div2;
488b8e80941Smrg   picture->pps->pps_tc_offset_div2 = picture_info->pps_tc_offset_div2;
489b8e80941Smrg   picture->pps->lists_modification_present_flag = picture_info->lists_modification_present_flag;
490b8e80941Smrg   picture->pps->log2_parallel_merge_level_minus2 = picture_info->log2_parallel_merge_level_minus2;
491b8e80941Smrg   picture->pps->slice_segment_header_extension_present_flag = picture_info->slice_segment_header_extension_present_flag;
492b8e80941Smrg
493b8e80941Smrg   picture->IDRPicFlag = picture_info->IDRPicFlag;
494b8e80941Smrg   picture->RAPPicFlag = picture_info->RAPPicFlag;
495b8e80941Smrg   picture->CurrRpsIdx = picture_info->CurrRpsIdx;
496b8e80941Smrg   picture->NumPocTotalCurr = picture_info->NumPocTotalCurr;
497b8e80941Smrg   picture->NumDeltaPocsOfRefRpsIdx = picture_info->NumDeltaPocsOfRefRpsIdx;
498b8e80941Smrg   picture->NumShortTermPictureSliceHeaderBits = picture_info->NumShortTermPictureSliceHeaderBits;
499b8e80941Smrg   picture->NumLongTermPictureSliceHeaderBits = picture_info->NumLongTermPictureSliceHeaderBits;
500b8e80941Smrg   picture->CurrPicOrderCntVal = picture_info->CurrPicOrderCntVal;
501b8e80941Smrg
502b8e80941Smrg   for (i = 0; i < 16; ++i) {
503b8e80941Smrg      VdpStatus ret = vlVdpGetReferenceFrame
504b8e80941Smrg      (
505b8e80941Smrg         picture_info->RefPics[i],
506b8e80941Smrg         &picture->ref[i]
507b8e80941Smrg      );
508b8e80941Smrg      if (ret != VDP_STATUS_OK)
509b8e80941Smrg         return ret;
510b8e80941Smrg
511b8e80941Smrg      picture->PicOrderCntVal[i] = picture_info->PicOrderCntVal[i];
512b8e80941Smrg      picture->IsLongTerm[i] = picture_info->IsLongTerm[i];
513b8e80941Smrg   }
514b8e80941Smrg
515b8e80941Smrg   picture->NumPocStCurrBefore = picture_info->NumPocStCurrBefore;
516b8e80941Smrg   picture->NumPocStCurrAfter = picture_info->NumPocStCurrAfter;
517b8e80941Smrg   picture->NumPocLtCurr = picture_info->NumPocLtCurr;
518b8e80941Smrg   memcpy(picture->RefPicSetStCurrBefore, picture_info->RefPicSetStCurrBefore, 8);
519b8e80941Smrg   memcpy(picture->RefPicSetStCurrAfter, picture_info->RefPicSetStCurrAfter, 8);
520b8e80941Smrg   memcpy(picture->RefPicSetLtCurr, picture_info->RefPicSetLtCurr, 8);
521b8e80941Smrg   picture->UseRefPicList = false;
522b8e80941Smrg
523b8e80941Smrg   return VDP_STATUS_OK;
524b8e80941Smrg}
525b8e80941Smrg
526848b8605Smrgstatic void
527848b8605SmrgvlVdpDecoderFixVC1Startcode(uint32_t *num_buffers, const void *buffers[], unsigned sizes[])
528848b8605Smrg{
529848b8605Smrg   static const uint8_t vc1_startcode[] = { 0x00, 0x00, 0x01, 0x0D };
530b8e80941Smrg   struct vl_vlc vlc = {};
531848b8605Smrg   unsigned i;
532848b8605Smrg
533848b8605Smrg   /* search the first 64 bytes for a startcode */
534848b8605Smrg   vl_vlc_init(&vlc, *num_buffers, buffers, sizes);
535848b8605Smrg   while (vl_vlc_search_byte(&vlc, 64*8, 0x00) && vl_vlc_bits_left(&vlc) >= 32) {
536848b8605Smrg      uint32_t value = vl_vlc_peekbits(&vlc, 32);
537848b8605Smrg      if (value == 0x0000010D ||
538848b8605Smrg          value == 0x0000010C ||
539848b8605Smrg          value == 0x0000010B)
540848b8605Smrg         return;
541848b8605Smrg      vl_vlc_eatbits(&vlc, 8);
542848b8605Smrg   }
543848b8605Smrg
544848b8605Smrg   /* none found, ok add one manually */
545848b8605Smrg   VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Manually adding VC-1 startcode\n");
546848b8605Smrg   for (i = *num_buffers; i > 0; --i) {
547848b8605Smrg      buffers[i] = buffers[i - 1];
548848b8605Smrg      sizes[i] = sizes[i - 1];
549848b8605Smrg   }
550848b8605Smrg   ++(*num_buffers);
551848b8605Smrg   buffers[0] = vc1_startcode;
552848b8605Smrg   sizes[0] = 4;
553848b8605Smrg}
554848b8605Smrg
555848b8605Smrg/**
556848b8605Smrg * Decode a compressed field/frame and render the result into a VdpVideoSurface.
557848b8605Smrg */
558848b8605SmrgVdpStatus
559848b8605SmrgvlVdpDecoderRender(VdpDecoder decoder,
560848b8605Smrg                   VdpVideoSurface target,
561848b8605Smrg                   VdpPictureInfo const *picture_info,
562848b8605Smrg                   uint32_t bitstream_buffer_count,
563848b8605Smrg                   VdpBitstreamBuffer const *bitstream_buffers)
564848b8605Smrg{
565848b8605Smrg   const void * buffers[bitstream_buffer_count + 1];
566848b8605Smrg   unsigned sizes[bitstream_buffer_count + 1];
567848b8605Smrg   vlVdpDecoder *vldecoder;
568848b8605Smrg   vlVdpSurface *vlsurf;
569848b8605Smrg   VdpStatus ret;
570848b8605Smrg   struct pipe_screen *screen;
571848b8605Smrg   struct pipe_video_codec *dec;
572848b8605Smrg   bool buffer_support[2];
573848b8605Smrg   unsigned i;
574b8e80941Smrg   struct pipe_h264_sps sps_h264 = {};
575b8e80941Smrg   struct pipe_h264_pps pps_h264 = { &sps_h264 };
576b8e80941Smrg   struct pipe_h265_sps sps_h265 = {};
577b8e80941Smrg   struct pipe_h265_pps pps_h265 = { &sps_h265 };
578848b8605Smrg   union {
579848b8605Smrg      struct pipe_picture_desc base;
580848b8605Smrg      struct pipe_mpeg12_picture_desc mpeg12;
581848b8605Smrg      struct pipe_mpeg4_picture_desc mpeg4;
582848b8605Smrg      struct pipe_vc1_picture_desc vc1;
583848b8605Smrg      struct pipe_h264_picture_desc h264;
584b8e80941Smrg      struct pipe_h265_picture_desc h265;
585848b8605Smrg   } desc;
586848b8605Smrg
587848b8605Smrg   if (!(picture_info && bitstream_buffers))
588848b8605Smrg      return VDP_STATUS_INVALID_POINTER;
589848b8605Smrg
590848b8605Smrg   vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
591848b8605Smrg   if (!vldecoder)
592848b8605Smrg      return VDP_STATUS_INVALID_HANDLE;
593848b8605Smrg   dec = vldecoder->decoder;
594848b8605Smrg   screen = dec->context->screen;
595848b8605Smrg
596848b8605Smrg   vlsurf = (vlVdpSurface *)vlGetDataHTAB(target);
597848b8605Smrg   if (!vlsurf)
598848b8605Smrg      return VDP_STATUS_INVALID_HANDLE;
599848b8605Smrg
600848b8605Smrg   if (vlsurf->device != vldecoder->device)
601848b8605Smrg      return VDP_STATUS_HANDLE_DEVICE_MISMATCH;
602848b8605Smrg
603848b8605Smrg   if (vlsurf->video_buffer != NULL && vlsurf->video_buffer->chroma_format != dec->chroma_format)
604848b8605Smrg      // TODO: Recreate decoder with correct chroma
605848b8605Smrg      return VDP_STATUS_INVALID_CHROMA_TYPE;
606848b8605Smrg
607848b8605Smrg   buffer_support[0] = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
608848b8605Smrg                                               PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE);
609848b8605Smrg   buffer_support[1] = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
610848b8605Smrg                                               PIPE_VIDEO_CAP_SUPPORTS_INTERLACED);
611848b8605Smrg
612848b8605Smrg   if (vlsurf->video_buffer == NULL ||
613848b8605Smrg       !screen->is_video_format_supported(screen, vlsurf->video_buffer->buffer_format,
614848b8605Smrg                                          dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM) ||
615848b8605Smrg       !buffer_support[vlsurf->video_buffer->interlaced]) {
616848b8605Smrg
617b8e80941Smrg      mtx_lock(&vlsurf->device->mutex);
618848b8605Smrg
619848b8605Smrg      /* destroy the old one */
620848b8605Smrg      if (vlsurf->video_buffer)
621848b8605Smrg         vlsurf->video_buffer->destroy(vlsurf->video_buffer);
622848b8605Smrg
623848b8605Smrg      /* set the buffer format to the prefered one */
624848b8605Smrg      vlsurf->templat.buffer_format = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
625848b8605Smrg                                                              PIPE_VIDEO_CAP_PREFERED_FORMAT);
626848b8605Smrg
627848b8605Smrg      /* also set interlacing to decoders preferences */
628848b8605Smrg      vlsurf->templat.interlaced = screen->get_video_param(screen, dec->profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
629848b8605Smrg                                                           PIPE_VIDEO_CAP_PREFERS_INTERLACED);
630848b8605Smrg
631848b8605Smrg      /* and recreate the video buffer */
632848b8605Smrg      vlsurf->video_buffer = dec->context->create_video_buffer(dec->context, &vlsurf->templat);
633848b8605Smrg
634848b8605Smrg      /* still no luck? get me out of here... */
635848b8605Smrg      if (!vlsurf->video_buffer) {
636b8e80941Smrg         mtx_unlock(&vlsurf->device->mutex);
637848b8605Smrg         return VDP_STATUS_NO_IMPLEMENTATION;
638848b8605Smrg      }
639848b8605Smrg      vlVdpVideoSurfaceClear(vlsurf);
640b8e80941Smrg      mtx_unlock(&vlsurf->device->mutex);
641848b8605Smrg   }
642848b8605Smrg
643848b8605Smrg   for (i = 0; i < bitstream_buffer_count; ++i) {
644848b8605Smrg      buffers[i] = bitstream_buffers[i].bitstream;
645848b8605Smrg      sizes[i] = bitstream_buffers[i].bitstream_bytes;
646848b8605Smrg   }
647848b8605Smrg
648848b8605Smrg   memset(&desc, 0, sizeof(desc));
649848b8605Smrg   desc.base.profile = dec->profile;
650848b8605Smrg   switch (u_reduce_video_profile(dec->profile)) {
651848b8605Smrg   case PIPE_VIDEO_FORMAT_MPEG12:
652848b8605Smrg      ret = vlVdpDecoderRenderMpeg12(&desc.mpeg12, (VdpPictureInfoMPEG1Or2 *)picture_info);
653848b8605Smrg      break;
654848b8605Smrg   case PIPE_VIDEO_FORMAT_MPEG4:
655848b8605Smrg      ret = vlVdpDecoderRenderMpeg4(&desc.mpeg4, (VdpPictureInfoMPEG4Part2 *)picture_info);
656848b8605Smrg      break;
657848b8605Smrg   case PIPE_VIDEO_FORMAT_VC1:
658848b8605Smrg      if (dec->profile == PIPE_VIDEO_PROFILE_VC1_ADVANCED)
659848b8605Smrg         vlVdpDecoderFixVC1Startcode(&bitstream_buffer_count, buffers, sizes);
660848b8605Smrg      ret = vlVdpDecoderRenderVC1(&desc.vc1, (VdpPictureInfoVC1 *)picture_info);
661848b8605Smrg      break;
662848b8605Smrg   case PIPE_VIDEO_FORMAT_MPEG4_AVC:
663b8e80941Smrg      desc.h264.pps = &pps_h264;
664848b8605Smrg      ret = vlVdpDecoderRenderH264(&desc.h264, (VdpPictureInfoH264 *)picture_info);
665848b8605Smrg      break;
666b8e80941Smrg   case PIPE_VIDEO_FORMAT_HEVC:
667b8e80941Smrg      desc.h265.pps = &pps_h265;
668b8e80941Smrg      ret = vlVdpDecoderRenderH265(&desc.h265, (VdpPictureInfoHEVC *)picture_info);
669b8e80941Smrg      break;
670848b8605Smrg   default:
671848b8605Smrg      return VDP_STATUS_INVALID_DECODER_PROFILE;
672848b8605Smrg   }
673848b8605Smrg
674848b8605Smrg   if (ret != VDP_STATUS_OK)
675848b8605Smrg      return ret;
676848b8605Smrg
677b8e80941Smrg   mtx_lock(&vldecoder->mutex);
678848b8605Smrg   dec->begin_frame(dec, vlsurf->video_buffer, &desc.base);
679848b8605Smrg   dec->decode_bitstream(dec, vlsurf->video_buffer, &desc.base, bitstream_buffer_count, buffers, sizes);
680848b8605Smrg   dec->end_frame(dec, vlsurf->video_buffer, &desc.base);
681b8e80941Smrg   mtx_unlock(&vldecoder->mutex);
682848b8605Smrg   return ret;
683848b8605Smrg}
684