1 /*
2 * Copyright (c) 2015-2017, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file media_ddi_decode_vc1.cpp
24 //! \brief libva(and its extension) decoder implementation
25 //!
26 #include "media_libva_decoder.h"
27 #include "media_libva_util.h"
28
29 #include "media_ddi_decode_vc1.h"
30 #include "mos_solo_generic.h"
31 #include "codechal_memdecomp.h"
32 #include "media_ddi_decode_const.h"
33 #include "media_ddi_factory.h"
34
35 static const int32_t FractionToScaleFactor[21] = {
36 128, 85, 170, 64, 192,
37 51, 102, 153, 204, 43,
38 215, 37, 74, 111, 148,
39 185, 222, 32, 96, 160,
40 224,
41 };
42
CalculateQuantParams(VAPictureParameterBufferVC1 * picParam,uint32_t * outAltPquantConfig,uint32_t * outAltPquantEdgeMask)43 void DdiDecodeVC1::CalculateQuantParams(
44 VAPictureParameterBufferVC1 *picParam,
45 uint32_t *outAltPquantConfig,
46 uint32_t *outAltPquantEdgeMask)
47 {
48 uint32_t dquant = picParam->pic_quantizer_fields.bits.dquant;
49 uint32_t dqFrame = picParam->pic_quantizer_fields.bits.dq_frame;
50 uint32_t dqProfile = picParam->pic_quantizer_fields.bits.dq_profile;
51 uint32_t dqDbedge = picParam->pic_quantizer_fields.bits.dq_db_edge;
52 uint32_t dqSbedge = picParam->pic_quantizer_fields.bits.dq_sb_edge;
53 uint32_t dqBilevel = picParam->pic_quantizer_fields.bits.dq_binary_level;
54
55 uint32_t altPquantConfig = 0;
56 uint32_t altPquantEdgeMask = 0;
57
58 if (dquant == 0)
59 {
60 altPquantConfig = 0;
61 altPquantEdgeMask = 0;
62 }
63 else if (dquant == 1)
64 {
65 if (dqFrame == 0)
66 {
67 altPquantConfig = 0;
68 altPquantEdgeMask = 0;
69 }
70 else if (dqFrame == 1)
71 {
72 altPquantConfig = 1;
73 altPquantEdgeMask = 0;
74 switch (dqProfile)
75 {
76 case 0: //all edge with altpquant
77 altPquantEdgeMask = 0xf;
78 break;
79
80 case 1: //double edge with altpquant
81 if (dqDbedge == 3)
82 {
83 altPquantEdgeMask = 0x9;
84 }
85 else
86 {
87 altPquantEdgeMask = (0x3 << dqDbedge);
88 }
89 break;
90
91 case 2: //single edge with altpquant
92 altPquantEdgeMask = (0x1 << dqSbedge);
93 break;
94
95 case 3: //all mbs
96 if (dqBilevel == 0)
97 {
98 altPquantConfig = 2;
99 altPquantEdgeMask = 0;
100 }
101 else
102 {
103 altPquantConfig = 3;
104 altPquantEdgeMask = 0;
105 }
106 break;
107
108 default:
109 break;
110 }
111 }
112 }
113 else
114 {
115 altPquantConfig = 1;
116 altPquantEdgeMask = 0xf;
117 }
118
119 *outAltPquantConfig = altPquantConfig;
120 *outAltPquantEdgeMask = altPquantEdgeMask;
121 }
122
IsBIField(bool isFirstField,int16_t picType)123 static inline bool IsBIField(
124 bool isFirstField,
125 int16_t picType)
126 {
127 bool isBI = false;
128
129 if (picType == vc1BBIField)
130 {
131 isBI = (!isFirstField);
132 }
133 else if (picType == vc1BIBField)
134 {
135 isBI = isFirstField;
136 }
137 else if (picType == vc1BIBIField)
138 {
139 isBI = true;
140 }
141
142 return isBI;
143 }
144
IsBField(bool isFirstField,int16_t picType)145 static inline bool IsBField(
146 bool isFirstField,
147 int16_t picType)
148 {
149 bool isBottom = false;
150
151 if (picType == vc1BBIField)
152 {
153 isBottom = isFirstField;
154 }
155 else if (picType == vc1BIBField)
156 {
157 isBottom = (!isFirstField);
158 }
159 else if (picType == vc1BBField)
160 {
161 isBottom = true;
162 }
163
164 return isBottom;
165 }
166
IsIField(bool isFirstField,int16_t picType)167 static inline bool IsIField(
168 bool isFirstField,
169 int16_t picType)
170 {
171 bool isIF = false;
172
173 if (picType == vc1IPField)
174 {
175 isIF = isFirstField;
176 }
177 else if (picType == vc1PIField)
178 {
179 isIF = !isFirstField;
180 }
181 else if (picType == vc1IIField)
182 {
183 isIF = true;
184 }
185
186 return isIF;
187 }
188
ParsePicParams(DDI_MEDIA_CONTEXT * mediaCtx,VAPictureParameterBufferVC1 * picParam)189 VAStatus DdiDecodeVC1::ParsePicParams(
190 DDI_MEDIA_CONTEXT *mediaCtx,
191 VAPictureParameterBufferVC1 *picParam)
192 {
193 PCODEC_VC1_PIC_PARAMS codecPicParam = (PCODEC_VC1_PIC_PARAMS)(m_ddiDecodeCtx->DecodeParams.m_picParams);
194
195 if ((codecPicParam == nullptr) ||
196 (picParam == nullptr))
197 {
198 DDI_ASSERTMESSAGE("nullptr pointer in Parsing VC1 Picture parameter\n");
199 return VA_STATUS_ERROR_INVALID_PARAMETER;
200 }
201 uint32_t scaleFactor = 0;
202 // See spec, table 40 && Figure 70
203 if (picParam->b_picture_fraction < 21)
204 {
205 scaleFactor = FractionToScaleFactor[picParam->b_picture_fraction];
206 }
207 else
208 {
209 // Use one value for it if the picParam->b_picture_fraction is out of range.
210 // Since in some cases, although driver gets the invalid bFraction, HW still can handle this.
211 scaleFactor = FractionToScaleFactor[0];
212 }
213
214 uint32_t fwdRefDist = picParam->reference_fields.bits.reference_distance;
215 int32_t bwdRefDist = 0;
216
217 if (picParam->inloop_decoded_picture != DDI_CODEC_INVALID_FRAME_INDEX)
218 {
219 codecPicParam->DeblockedPicIdx = GetRenderTargetID(&(m_ddiDecodeCtx->RTtbl), m_ddiDecodeCtx->RTtbl.pCurrentRT);
220 DDI_CHK_RET(RegisterRTSurfaces(&m_ddiDecodeCtx->RTtbl, DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, picParam->inloop_decoded_picture)), "RegisterRTSurfaces failed!");
221
222 codecPicParam->CurrPic.FrameIdx = (uint16_t)GetRenderTargetID(&(m_ddiDecodeCtx->RTtbl),
223 DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, picParam->inloop_decoded_picture));
224 m_deblockPicIdx = codecPicParam->DeblockedPicIdx;
225 m_currPicIdx = codecPicParam->CurrPic.FrameIdx;
226 }
227 else
228 {
229 codecPicParam->CurrPic.FrameIdx = GetRenderTargetID(&(m_ddiDecodeCtx->RTtbl), m_ddiDecodeCtx->RTtbl.pCurrentRT);
230 codecPicParam->DeblockedPicIdx = codecPicParam->CurrPic.FrameIdx;
231 m_deblockPicIdx = DDI_CODEC_INVALID_FRAME_INDEX;
232 m_currPicIdx = codecPicParam->CurrPic.FrameIdx;
233 }
234
235 if (picParam->forward_reference_picture == DDI_CODEC_INVALID_FRAME_INDEX)
236 {
237 codecPicParam->ForwardRefIdx = codecPicParam->CurrPic.FrameIdx;
238 }
239 else
240 {
241 if (UpdateRegisteredRTSurfaceFlag(&(m_ddiDecodeCtx->RTtbl), DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, picParam->forward_reference_picture)) != VA_STATUS_SUCCESS)
242 {
243 DDI_CHK_RET(RegisterRTSurfaces(&(m_ddiDecodeCtx->RTtbl), DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, picParam->forward_reference_picture)), "RegisterRTSurfaces failed!");
244 }
245 codecPicParam->ForwardRefIdx = (uint16_t)GetRenderTargetID(&(m_ddiDecodeCtx->RTtbl), DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, picParam->forward_reference_picture));
246 }
247
248 if (picParam->backward_reference_picture == DDI_CODEC_INVALID_FRAME_INDEX)
249 {
250 codecPicParam->BackwardRefIdx = codecPicParam->CurrPic.FrameIdx;
251 }
252 else
253 {
254 if (UpdateRegisteredRTSurfaceFlag(&(m_ddiDecodeCtx->RTtbl), DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, picParam->backward_reference_picture)) != VA_STATUS_SUCCESS)
255 {
256 DDI_CHK_RET(RegisterRTSurfaces(&(m_ddiDecodeCtx->RTtbl), DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, picParam->backward_reference_picture)), "RegisterRTSurfaces failed!");
257 }
258 codecPicParam->BackwardRefIdx = (uint16_t)GetRenderTargetID(&(m_ddiDecodeCtx->RTtbl), DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, picParam->backward_reference_picture));
259 }
260
261 //add protection checking to prevent ref pic index larger than DPB size
262 if (codecPicParam->ForwardRefIdx >= CODECHAL_NUM_UNCOMPRESSED_SURFACE_VC1)
263 {
264 codecPicParam->ForwardRefIdx = CODECHAL_NUM_UNCOMPRESSED_SURFACE_VC1 - 1;
265 }
266 if (codecPicParam->BackwardRefIdx >= CODECHAL_NUM_UNCOMPRESSED_SURFACE_VC1)
267 {
268 codecPicParam->BackwardRefIdx = CODECHAL_NUM_UNCOMPRESSED_SURFACE_VC1 - 1;
269 }
270
271 if (picParam->picture_fields.bits.frame_coding_mode == 0)
272 {
273 codecPicParam->CurrPic.PicFlags = PICTURE_FRAME;
274 }
275 else if (picParam->picture_fields.bits.frame_coding_mode == 1)
276 {
277 codecPicParam->CurrPic.PicFlags = PICTURE_INTERLACED_FRAME;
278 }
279 else
280 {
281 codecPicParam->CurrPic.PicFlags = (picParam->picture_fields.bits.is_first_field ^ picParam->picture_fields.bits.top_field_first) ? PICTURE_BOTTOM_FIELD : PICTURE_TOP_FIELD;
282 }
283
284 if (picParam->picture_fields.bits.frame_coding_mode < 2) //frame structure
285 {
286 codecPicParam->picture_fields.frame_coding_mode = picParam->picture_fields.bits.frame_coding_mode;
287 codecPicParam->luma_scale = (uint16_t)picParam->luma_scale;
288 codecPicParam->luma_shift = (uint16_t)picParam->luma_shift;
289 }
290 else
291 {
292 if (picParam->picture_fields.bits.top_field_first)
293 {
294 codecPicParam->picture_fields.frame_coding_mode = 2;
295 }
296 else
297 {
298 codecPicParam->picture_fields.frame_coding_mode = 3;
299 }
300 if (picParam->picture_fields.bits.picture_type >= vc1BBField) // B interlaced frames
301 {
302 fwdRefDist = (scaleFactor * picParam->reference_fields.bits.reference_distance) >> 8;
303 bwdRefDist = picParam->reference_fields.bits.reference_distance - fwdRefDist - 1;
304 if (bwdRefDist < 0)
305 {
306 bwdRefDist = 0;
307 }
308 }
309 codecPicParam->luma_scale = (uint16_t)(picParam->luma_scale2 + (picParam->luma_scale << 8));
310 codecPicParam->luma_shift = (uint16_t)(picParam->luma_shift2 + (picParam->luma_shift << 8));
311 }
312
313 codecPicParam->sequence_fields.AdvancedProfileFlag = (picParam->sequence_fields.bits.profile == 3) ? 1 : 0;
314 codecPicParam->picture_fields.picture_type = picParam->picture_fields.bits.picture_type;
315
316 if (codecPicParam->sequence_fields.AdvancedProfileFlag)
317 {
318 codecPicParam->sequence_fields.overlap = picParam->sequence_fields.bits.overlap;
319 }
320 else
321 {
322 // see 7.1.1.14 in VC spec
323 if ((picParam->b_picture_fraction == 0x7F) && (picParam->picture_fields.bits.picture_type == vc1IFrame))
324 {
325 codecPicParam->picture_fields.picture_type = vc1BIFrame;
326 }
327
328 codecPicParam->sequence_fields.overlap = picParam->sequence_fields.bits.overlap && (picParam->pic_quantizer_fields.bits.pic_quantizer_scale >= 9);
329 }
330
331 codecPicParam->coded_width = picParam->coded_width;
332 codecPicParam->coded_height = picParam->coded_height;
333 codecPicParam->sequence_fields.syncmarker = picParam->sequence_fields.bits.syncmarker;
334 codecPicParam->sequence_fields.pulldown = picParam->sequence_fields.bits.pulldown;
335 codecPicParam->sequence_fields.interlace = picParam->sequence_fields.bits.interlace;
336 codecPicParam->sequence_fields.tfcntrflag = picParam->sequence_fields.bits.tfcntrflag;
337 codecPicParam->sequence_fields.psf = picParam->sequence_fields.bits.psf;
338 codecPicParam->sequence_fields.multires = picParam->sequence_fields.bits.multires;
339 codecPicParam->sequence_fields.rangered = picParam->sequence_fields.bits.rangered;
340 codecPicParam->sequence_fields.max_b_frames = picParam->sequence_fields.bits.max_b_frames;
341 codecPicParam->entrypoint_fields.loopfilter = picParam->entrypoint_fields.bits.loopfilter;
342 codecPicParam->entrypoint_fields.broken_link = picParam->entrypoint_fields.bits.broken_link;
343 codecPicParam->entrypoint_fields.closed_entry = picParam->entrypoint_fields.bits.closed_entry;
344 codecPicParam->entrypoint_fields.panscan_flag = picParam->entrypoint_fields.bits.panscan_flag;
345 codecPicParam->picture_fields.is_first_field = picParam->picture_fields.bits.is_first_field;
346 codecPicParam->picture_fields.top_field_first = picParam->picture_fields.bits.top_field_first;
347 codecPicParam->picture_fields.intensity_compensation = picParam->picture_fields.bits.intensity_compensation;
348
349 if (picParam->mv_fields.bits.mv_mode == VAMvModeIntensityCompensation)
350 {
351 codecPicParam->mv_fields.UnifiedMvMode = (picParam->mv_fields.bits.mv_mode2 + 1) & 0x3;
352 codecPicParam->picture_fields.intensity_compensation = 1;
353 }
354 else
355 {
356 codecPicParam->mv_fields.UnifiedMvMode = (picParam->mv_fields.bits.mv_mode + 1) & 0x3;
357 }
358
359 if (picParam->mv_fields.bits.mv_mode == VAMvMode1MvHalfPelBilinear ||
360 (picParam->mv_fields.bits.mv_mode == VAMvModeIntensityCompensation && picParam->mv_fields.bits.mv_mode2 == VAMvMode1MvHalfPelBilinear))
361 {
362 codecPicParam->mv_fields.MvMode = picParam->fast_uvmc_flag ? 9 : 8;
363 }
364 else
365 {
366 codecPicParam->mv_fields.MvMode = picParam->fast_uvmc_flag ? 1 : 0;
367 }
368
369 uint32_t altPquantConfig = 0;
370 uint32_t altPquantEdgeMask = 0;
371 CalculateQuantParams(picParam, &altPquantConfig, &altPquantEdgeMask);
372
373 codecPicParam->pic_quantizer_fields.quantizer = picParam->pic_quantizer_fields.bits.quantizer;
374 codecPicParam->pic_quantizer_fields.pic_quantizer_scale = picParam->pic_quantizer_fields.bits.pic_quantizer_scale;
375 codecPicParam->pic_quantizer_fields.alt_pic_quantizer = picParam->pic_quantizer_fields.bits.alt_pic_quantizer;
376 codecPicParam->pic_quantizer_fields.pic_quantizer_type = picParam->pic_quantizer_fields.bits.pic_quantizer_type;
377 codecPicParam->pic_quantizer_fields.half_qp = picParam->pic_quantizer_fields.bits.half_qp;
378 codecPicParam->pic_quantizer_fields.AltPQuantConfig = altPquantConfig;
379 codecPicParam->pic_quantizer_fields.AltPQuantEdgeMask = altPquantEdgeMask;
380 codecPicParam->pic_quantizer_fields.dquant = picParam->pic_quantizer_fields.bits.dquant;
381 codecPicParam->mv_fields.extended_mv_flag = picParam->mv_fields.bits.extended_mv_flag;
382 codecPicParam->mv_fields.extended_dmv_flag = picParam->mv_fields.bits.extended_dmv_flag;
383 codecPicParam->mv_fields.extended_mv_range = picParam->mv_fields.bits.extended_mv_range;
384 codecPicParam->mv_fields.extended_dmv_range = picParam->mv_fields.bits.extended_dmv_range;
385 codecPicParam->mv_fields.four_mv_switch = picParam->mv_fields.bits.four_mv_switch;
386 codecPicParam->mv_fields.two_mv_block_pattern_table = picParam->mv_fields.bits.two_mv_block_pattern_table;
387 codecPicParam->mv_fields.four_mv_block_pattern_table = picParam->mv_fields.bits.four_mv_block_pattern_table;
388 codecPicParam->mv_fields.mv_table = picParam->mv_fields.bits.mv_table;
389 codecPicParam->reference_fields.reference_distance_flag = picParam->reference_fields.bits.reference_distance_flag;
390 codecPicParam->reference_fields.reference_distance = fwdRefDist; //picParam->reference_fields.bits.reference_distance;
391 codecPicParam->reference_fields.BwdReferenceDistance = bwdRefDist; //picParam->reference_fields.bits.reference_distance;
392 codecPicParam->reference_fields.num_reference_pictures = picParam->reference_fields.bits.num_reference_pictures;
393 codecPicParam->reference_fields.reference_field_pic_indicator = picParam->reference_fields.bits.reference_field_pic_indicator;
394
395 codecPicParam->raw_coding.value = 0xFE;
396 if (picParam->picture_fields.bits.frame_coding_mode < 2) //frame structure
397 {
398 if ((picParam->picture_fields.bits.picture_type == vc1IFrame) ||
399 (picParam->picture_fields.bits.picture_type == vc1BIFrame))
400 {
401 if (picParam->picture_fields.bits.frame_coding_mode == 1) //interlaced frame
402 {
403 codecPicParam->raw_coding.field_tx = !picParam->bitplane_present.flags.bp_field_tx;
404 }
405 codecPicParam->raw_coding.ac_pred = !picParam->bitplane_present.flags.bp_ac_pred;
406 codecPicParam->raw_coding.overflags = !picParam->bitplane_present.flags.bp_overflags;
407 }
408 else if (picParam->picture_fields.bits.picture_type == vc1PFrame)
409 {
410 codecPicParam->raw_coding.skip_mb = !picParam->bitplane_present.flags.bp_skip_mb;
411 if (picParam->picture_fields.bits.frame_coding_mode == 0) //progressive frame
412 {
413 codecPicParam->raw_coding.mv_type_mb = !picParam->bitplane_present.flags.bp_mv_type_mb;
414 }
415 }
416 else
417 {
418 codecPicParam->raw_coding.direct_mb = !picParam->bitplane_present.flags.bp_direct_mb;
419 codecPicParam->raw_coding.skip_mb = !picParam->bitplane_present.flags.bp_skip_mb;
420 }
421 }
422 else
423 {
424 if ((IsIField(picParam->picture_fields.bits.is_first_field, picParam->picture_fields.bits.picture_type)) ||
425 (IsBIField(picParam->picture_fields.bits.is_first_field, picParam->picture_fields.bits.picture_type)))
426 {
427 codecPicParam->raw_coding.ac_pred = !picParam->bitplane_present.flags.bp_ac_pred;
428 codecPicParam->raw_coding.overflags = !picParam->bitplane_present.flags.bp_overflags;
429 }
430 else if (IsBField(picParam->picture_fields.bits.is_first_field, picParam->picture_fields.bits.picture_type))
431 {
432 codecPicParam->raw_coding.forward_mb = !picParam->bitplane_present.flags.bp_forward_mb;
433 }
434 }
435 uint32_t rawCoding = codecPicParam->raw_coding.value & 0xFE;
436 codecPicParam->raw_coding.bitplane_present = (rawCoding == 0xFE) ? 0 : 1;
437
438 codecPicParam->transform_fields.intra_transform_dc_table = picParam->transform_fields.bits.intra_transform_dc_table;
439 codecPicParam->transform_fields.transform_ac_codingset_idx1 = picParam->transform_fields.bits.transform_ac_codingset_idx1;
440 codecPicParam->transform_fields.transform_ac_codingset_idx2 = picParam->transform_fields.bits.transform_ac_codingset_idx2;
441 codecPicParam->transform_fields.variable_sized_transform_flag = picParam->transform_fields.bits.variable_sized_transform_flag;
442 codecPicParam->transform_fields.mb_level_transform_type_flag = picParam->transform_fields.bits.mb_level_transform_type_flag;
443 codecPicParam->transform_fields.frame_level_transform_type = picParam->transform_fields.bits.frame_level_transform_type;
444
445 codecPicParam->conditional_overlap_flag = picParam->conditional_overlap_flag ? (picParam->conditional_overlap_flag + 1) : 0;
446 codecPicParam->fast_uvmc_flag = picParam->fast_uvmc_flag;
447 codecPicParam->cbp_table = picParam->cbp_table;
448 codecPicParam->mb_mode_table = picParam->mb_mode_table;
449 codecPicParam->b_picture_fraction = picParam->b_picture_fraction; //not used
450 codecPicParam->range_reduction_frame = picParam->range_reduction_frame;
451 codecPicParam->ScaleFactor = scaleFactor;
452 codecPicParam->post_processing = picParam->post_processing;
453 codecPicParam->picture_resolution_index = 0;
454 codecPicParam->rounding_control = picParam->rounding_control;
455
456 codecPicParam->UpsamplingFlag = picParam->sequence_fields.bits.multires ? (picParam->picture_resolution_index & 0x3) : 0;
457
458 //rangemap
459 if (codecPicParam->sequence_fields.AdvancedProfileFlag)
460 {
461 codecPicParam->range_mapping_fields.luma_flag = picParam->range_mapping_fields.bits.luma_flag;
462 codecPicParam->range_mapping_fields.luma = picParam->range_mapping_fields.bits.luma;
463 codecPicParam->range_mapping_fields.chroma_flag = picParam->range_mapping_fields.bits.chroma_flag;
464 codecPicParam->range_mapping_fields.chroma = picParam->range_mapping_fields.bits.chroma;
465 codecPicParam->range_mapping_fields.range_mapping_enabled = picParam->range_mapping_fields.value;
466 }
467 else
468 {
469 codecPicParam->range_mapping_fields.range_mapping_enabled = picParam->range_reduction_frame;
470 }
471
472 // Check if OLP is needed
473 // OLP output surface must be present
474 if ((m_deblockPicIdx != DDI_CODEC_INVALID_FRAME_INDEX) &&
475 ((codecPicParam->DeblockedPicIdx != codecPicParam->CurrPic.FrameIdx) ||
476 codecPicParam->UpsamplingFlag ||
477 codecPicParam->range_mapping_fields.range_mapping_enabled))
478 {
479 m_olpNeeded = 1;
480 }
481 else
482 {
483 m_olpNeeded = 0;
484 }
485
486 return VA_STATUS_SUCCESS;
487 }
488
ParseSliceParams(DDI_MEDIA_CONTEXT * mediaCtx,VASliceParameterBufferVC1 * slcParam,uint32_t numSlices)489 VAStatus DdiDecodeVC1::ParseSliceParams(
490 DDI_MEDIA_CONTEXT *mediaCtx,
491 VASliceParameterBufferVC1 *slcParam,
492 uint32_t numSlices)
493 {
494 PCODEC_VC1_SLICE_PARAMS codecSlcParam = (PCODEC_VC1_SLICE_PARAMS)(m_ddiDecodeCtx->DecodeParams.m_sliceParams);
495
496 codecSlcParam += m_ddiDecodeCtx->DecodeParams.m_numSlices;
497
498 if ((slcParam == nullptr) || (codecSlcParam == nullptr))
499 {
500 DDI_ASSERTMESSAGE("Null pointer for Parsing VC1 Slice parameter\n");
501 return VA_STATUS_ERROR_INVALID_PARAMETER;
502 }
503
504 uint32_t sliceBaseOffset = GetBsBufOffset(m_groupIndex);
505 for (uint32_t slcCount = 0; slcCount < numSlices; slcCount++)
506 {
507 codecSlcParam[slcCount].slice_data_size = slcParam[slcCount].slice_data_size << 3;
508 codecSlcParam[slcCount].slice_data_offset = slcParam[slcCount].slice_data_offset +
509 sliceBaseOffset;
510 if (slcParam[slcCount].slice_data_flag)
511 {
512 DDI_NORMALMESSAGE("The whole slice is not in the bitstream buffer for this Execute call");
513 }
514 codecSlcParam[slcCount].macroblock_offset = slcParam[slcCount].macroblock_offset;
515 codecSlcParam[slcCount].slice_vertical_position = slcParam[slcCount].slice_vertical_position;
516 }
517
518 return VA_STATUS_SUCCESS;
519 }
520
AllocBitPlaneBuffer()521 VAStatus DdiDecodeVC1::AllocBitPlaneBuffer()
522 {
523 DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_ddiDecodeCtx->BufMgr);
524
525 DDI_CHK_NULL(bufMgr, "Null bufMgr in AllocBpBuffer", VA_STATUS_ERROR_INVALID_PARAMETER);
526
527 if (bufMgr->Codec_Param.Codec_Param_VC1.VC1BitPlane[bufMgr->Codec_Param.Codec_Param_VC1.dwVC1BitPlaneIndex].bUsed)
528 {
529 // wait until decode complete
530 mos_bo_wait_rendering(bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[bufMgr->Codec_Param.Codec_Param_VC1.dwVC1BitPlaneIndex]->bo);
531 }
532
533 bufMgr->Codec_Param.Codec_Param_VC1.VC1BitPlane[bufMgr->Codec_Param.Codec_Param_VC1.dwVC1BitPlaneIndex].bUsed = true;
534
535 return VA_STATUS_SUCCESS;
536 }
537
AllocSliceParamContext(uint32_t numSlices)538 VAStatus DdiDecodeVC1::AllocSliceParamContext(
539 uint32_t numSlices)
540 {
541 uint32_t baseSize = sizeof(CODEC_VC1_SLICE_PARAMS);
542
543 if (m_sliceParamBufNum < (m_ddiDecodeCtx->DecodeParams.m_numSlices + numSlices))
544 {
545 // in order to avoid that the buffer is reallocated multi-times,
546 // extra 10 slices are added.
547 uint32_t extraSlices = numSlices + 10;
548
549 m_ddiDecodeCtx->DecodeParams.m_sliceParams = realloc(m_ddiDecodeCtx->DecodeParams.m_sliceParams,
550 baseSize * (m_sliceParamBufNum + extraSlices));
551
552 if (m_ddiDecodeCtx->DecodeParams.m_sliceParams == nullptr)
553 {
554 return VA_STATUS_ERROR_ALLOCATION_FAILED;
555 }
556
557 memset((void *)((uint8_t *)m_ddiDecodeCtx->DecodeParams.m_sliceParams + baseSize * m_sliceParamBufNum), 0, baseSize * extraSlices);
558 m_sliceParamBufNum += extraSlices;
559 }
560
561 return VA_STATUS_SUCCESS;
562 }
563
DestroyContext(VADriverContextP ctx)564 void DdiDecodeVC1::DestroyContext(
565 VADriverContextP ctx)
566 {
567 FreeResourceBuffer();
568 // explicitly call the base function to do the further clean-up
569 DdiMediaDecode::DestroyContext(ctx);
570 }
571
GetPicParamBuf(DDI_CODEC_COM_BUFFER_MGR * bufMgr)572 uint8_t* DdiDecodeVC1::GetPicParamBuf(
573 DDI_CODEC_COM_BUFFER_MGR *bufMgr)
574 {
575 return (uint8_t*)(&(bufMgr->Codec_Param.Codec_Param_VC1.PicParamVC1));
576 }
577
AllocSliceControlBuffer(DDI_MEDIA_BUFFER * buf)578 VAStatus DdiDecodeVC1::AllocSliceControlBuffer(
579 DDI_MEDIA_BUFFER *buf)
580 {
581 DDI_CODEC_COM_BUFFER_MGR *bufMgr;
582 uint32_t availSize;
583 uint32_t newSize;
584
585 bufMgr = &(m_ddiDecodeCtx->BufMgr);
586 availSize = m_sliceCtrlBufNum - bufMgr->dwNumSliceControl;
587 if(availSize < buf->uiNumElements)
588 {
589 newSize = sizeof(VASliceParameterBufferVC1) * (m_sliceCtrlBufNum - availSize + buf->uiNumElements);
590 bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1 = (VASliceParameterBufferVC1 *)realloc(bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1, newSize);
591 if(bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1 == nullptr)
592 {
593 return VA_STATUS_ERROR_ALLOCATION_FAILED;
594 }
595 MOS_ZeroMemory(bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1 + m_sliceCtrlBufNum, sizeof(VASliceParameterBufferVC1) * (buf->uiNumElements - availSize));
596 m_sliceCtrlBufNum = m_sliceCtrlBufNum - availSize + buf->uiNumElements;
597 }
598 buf->pData = (uint8_t*)bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1;
599 buf->uiOffset = sizeof(VASliceParameterBufferVC1) * bufMgr->dwNumSliceControl;
600
601 bufMgr->dwNumSliceControl += buf->uiNumElements;
602
603 return VA_STATUS_SUCCESS;
604 }
605
ContextInit(int32_t picWidth,int32_t picHeight)606 void DdiDecodeVC1::ContextInit(
607 int32_t picWidth,
608 int32_t picHeight)
609 {
610 // call the function in base class to initialize it.
611 DdiMediaDecode::ContextInit(picWidth, picHeight);
612
613 m_ddiDecodeCtx->wMode = CODECHAL_DECODE_MODE_VC1VLD;
614 m_olpNeeded = false;
615 m_currPicIdx = DDI_CODEC_INVALID_FRAME_INDEX;
616 m_deblockPicIdx = DDI_CODEC_INVALID_FRAME_INDEX;
617
618 if (m_ddiDecodeAttr->profile == VAProfileVC1Advanced)
619 {
620 int32_t alignedHeight = MOS_ALIGN_CEIL(picHeight, 32);
621 m_height = alignedHeight;
622 m_picHeightInMB = (int16_t)(DDI_CODEC_NUM_MACROBLOCKS_HEIGHT(alignedHeight));
623 }
624 }
625
BeginPicture(VADriverContextP ctx,VAContextID context,VASurfaceID renderTarget)626 VAStatus DdiDecodeVC1::BeginPicture(
627 VADriverContextP ctx,
628 VAContextID context,
629 VASurfaceID renderTarget)
630 {
631 VAStatus vaStatus = DdiMediaDecode::BeginPicture(ctx, context, renderTarget);
632
633 if (vaStatus != VA_STATUS_SUCCESS)
634 {
635 return vaStatus;
636 }
637
638 m_ddiDecodeCtx->DecodeParams.m_vc1BitplaneSize = 0;
639
640 return VA_STATUS_SUCCESS;
641 }
642
ParseBitPlane(struct _DDI_MEDIA_BUFFER * bitPlaneBuffObject,uint8_t * buf)643 void DdiDecodeVC1::ParseBitPlane(
644 struct _DDI_MEDIA_BUFFER *bitPlaneBuffObject,
645 uint8_t *buf)
646 {
647 if (bitPlaneBuffObject->pData)
648 {
649 PCODEC_VC1_PIC_PARAMS picParam = (PCODEC_VC1_PIC_PARAMS)(m_ddiDecodeCtx->DecodeParams.m_picParams);
650
651 uint8_t *destBp = (uint8_t *)bitPlaneBuffObject->pData;
652 uint8_t *srcBp = (uint8_t *)buf;
653
654 uint32_t heightInMbs = MOS_ALIGN_CEIL(picParam->coded_height, CODECHAL_MACROBLOCK_HEIGHT) / CODECHAL_MACROBLOCK_HEIGHT;
655 uint32_t widthInMbs = MOS_ALIGN_CEIL(picParam->coded_width, CODECHAL_MACROBLOCK_WIDTH) / CODECHAL_MACROBLOCK_WIDTH;
656 uint32_t bitPlanePitch = MOS_ALIGN_CEIL(widthInMbs, 2) / 2;
657
658 uint32_t srcIdx, dstIdx;
659 uint32_t srcShift;
660 uint32_t i, j;
661 uint8_t srcValue = 0;
662 for (i = 0; i < heightInMbs; i++)
663 {
664 for (j = 0; j < widthInMbs; j++)
665 {
666 srcIdx = (i * widthInMbs + j) / 2;
667 dstIdx = j / 2;
668 srcShift = ((i * widthInMbs + j) & 1) ? 0 : 4;
669 srcValue = (srcBp[srcIdx] >> srcShift) & 0xf;
670 if (j % 2)
671 destBp[dstIdx] = destBp[dstIdx] + (srcValue << 4);
672 else
673 destBp[dstIdx] = srcValue;
674 }
675 destBp += bitPlanePitch;
676 }
677 }
678 }
679
RenderPicture(VADriverContextP ctx,VAContextID context,VABufferID * buffers,int32_t numBuffers)680 VAStatus DdiDecodeVC1::RenderPicture(
681 VADriverContextP ctx,
682 VAContextID context,
683 VABufferID *buffers,
684 int32_t numBuffers)
685 {
686 DDI_FUNCTION_ENTER();
687
688 VAStatus va = VA_STATUS_SUCCESS;
689 PDDI_MEDIA_CONTEXT mediaCtx;
690
691 mediaCtx = DdiMedia_GetMediaContext(ctx);
692
693 void *data = nullptr;
694 for (int32_t i = 0; i < numBuffers; i++)
695 {
696 if (!buffers || (buffers[i] == VA_INVALID_ID))
697 {
698 return VA_STATUS_ERROR_INVALID_BUFFER;
699 }
700
701 DDI_MEDIA_BUFFER *buf = DdiMedia_GetBufferFromVABufferID(mediaCtx, buffers[i]);
702 if (nullptr == buf)
703 {
704 return VA_STATUS_ERROR_INVALID_BUFFER;
705 }
706
707 uint32_t dataSize = buf->iSize;
708 DdiMedia_MapBuffer(ctx, buffers[i], &data);
709
710 if (data == nullptr)
711 {
712 return VA_STATUS_ERROR_INVALID_BUFFER;
713 }
714
715 switch ((int32_t)buf->uiType)
716 {
717 case VABitPlaneBufferType:
718 {
719 int32_t index = m_ddiDecodeCtx->BufMgr.Codec_Param.Codec_Param_VC1.dwVC1BitPlaneIndex;
720 if (index == DDI_CODEC_INVALID_BUFFER_INDEX)
721 {
722 return VA_STATUS_ERROR_INVALID_BUFFER;
723 }
724 if (index >= DDI_CODEC_MAX_BITSTREAM_BUFFER)
725 {
726 return VA_STATUS_ERROR_INVALID_BUFFER;
727 }
728 DDI_CHK_RET(AllocBitPlaneBuffer(),"AllocBitPlaneBuffer failed!");
729 /* Before accessing it on CPU, Use the DdiMediaUtil_LockBuffer to map it into CPU */
730 DdiMediaUtil_LockBuffer(m_ddiDecodeCtx->BufMgr.Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[index], MOS_LOCKFLAG_WRITEONLY);
731 ParseBitPlane(m_ddiDecodeCtx->BufMgr.Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[index], (uint8_t *)data);
732
733 DdiMediaUtil_UnlockBuffer(m_ddiDecodeCtx->BufMgr.Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[index]);
734
735 DdiMedia_MediaBufferToMosResource(m_ddiDecodeCtx->BufMgr.Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[index], &m_ddiDecodeCtx->BufMgr.Codec_Param.Codec_Param_VC1.resBitPlaneBuffer);
736 m_ddiDecodeCtx->DecodeParams.m_vc1BitplaneSize = dataSize;
737
738 m_ddiDecodeCtx->BufMgr.Codec_Param.Codec_Param_VC1.dwVC1BitPlaneIndex++;
739 if (m_ddiDecodeCtx->BufMgr.Codec_Param.Codec_Param_VC1.dwVC1BitPlaneIndex >= DDI_CODEC_MAX_BITSTREAM_BUFFER)
740 {
741 m_ddiDecodeCtx->BufMgr.Codec_Param.Codec_Param_VC1.dwVC1BitPlaneIndex = 0;
742 }
743 break;
744 }
745
746 case VASliceDataBufferType:
747 {
748 int32_t index = GetBitstreamBufIndexFromBuffer(&m_ddiDecodeCtx->BufMgr, buf);
749 if (index == DDI_CODEC_INVALID_BUFFER_INDEX)
750 {
751 return VA_STATUS_ERROR_INVALID_BUFFER;
752 }
753
754 DdiMedia_MediaBufferToMosResource(m_ddiDecodeCtx->BufMgr.pBitStreamBuffObject[index], &m_ddiDecodeCtx->BufMgr.resBitstreamBuffer);
755 m_ddiDecodeCtx->DecodeParams.m_dataSize += dataSize;
756 break;
757 }
758 case VASliceParameterBufferType:
759 {
760 if (buf->uiNumElements == 0)
761 {
762 return VA_STATUS_ERROR_INVALID_BUFFER;
763 }
764
765 VASliceParameterBufferVC1 *slcInfo =
766 (VASliceParameterBufferVC1 *)data;
767 uint32_t numSlices = buf->uiNumElements;
768 DDI_CHK_RET(AllocSliceParamContext(numSlices),"AllocSliceParamContext failed!");
769 DDI_CHK_RET(ParseSliceParams(mediaCtx, slcInfo, numSlices),"ParseSliceParams failed!");
770 m_ddiDecodeCtx->DecodeParams.m_numSlices += numSlices;
771 m_groupIndex++;
772 break;
773 }
774 case VAPictureParameterBufferType:
775 {
776 VAPictureParameterBufferVC1 *picParam = (VAPictureParameterBufferVC1 *)data;
777 DDI_CHK_RET(ParsePicParams(mediaCtx, picParam),"ParsePicParams failed!");
778 break;
779 }
780 case VADecodeStreamoutBufferType:
781 {
782 DdiMedia_MediaBufferToMosResource(buf, &m_ddiDecodeCtx->BufMgr.resExternalStreamOutBuffer);
783 m_streamOutEnabled = true;
784 break;
785 }
786 default:
787 va = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
788 break;
789 }
790 DdiMedia_UnmapBuffer(ctx, buffers[i]);
791 }
792
793 DDI_FUNCTION_EXIT(va);
794 return va;
795 }
796
SetDecodeParams()797 VAStatus DdiDecodeVC1::SetDecodeParams()
798 {
799 if ((&m_ddiDecodeCtx->DecodeParams)->m_numSlices == 0)
800 {
801 return VA_STATUS_ERROR_INVALID_PARAMETER;
802 }
803
804 m_destSurface.dwOffset = 0;
805 MOS_FORMAT expectedFormat = Format_NV12;
806 DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_ddiDecodeCtx->BufMgr);
807 m_destSurface.Format = expectedFormat;
808
809 if (m_deblockPicIdx != DDI_CODEC_INVALID_FRAME_INDEX)
810 {
811 DdiMedia_MediaSurfaceToMosResource((&(m_ddiDecodeCtx->RTtbl))->pRT[m_currPicIdx], &(m_destSurface.OsResource));
812 }
813 else
814 {
815 DdiMedia_MediaSurfaceToMosResource((&(m_ddiDecodeCtx->RTtbl))->pCurrentRT, &(m_destSurface.OsResource));
816 }
817
818 if (m_destSurface.OsResource.Format != expectedFormat)
819 {
820 DDI_NORMALMESSAGE("Surface fomrat of decoded surface is inconsistent with Mpeg2 bitstream\n");
821 return VA_STATUS_ERROR_INVALID_PARAMETER;
822 }
823
824 (&m_ddiDecodeCtx->DecodeParams)->m_destSurface = &m_destSurface;
825
826 memset(&m_deblockSurface, 0, sizeof(MOS_SURFACE));
827 if (m_olpNeeded)
828 {
829 memset(&m_deblockSurface, 0, sizeof(MOS_SURFACE));
830 m_deblockSurface.Format = Format_NV12;
831 m_deblockSurface.dwOffset = 0;
832 DdiMedia_MediaSurfaceToMosResource((&(m_ddiDecodeCtx->RTtbl))->pRT[m_deblockPicIdx], &(m_deblockSurface.OsResource));
833 (&m_ddiDecodeCtx->DecodeParams)->m_deblockSurface = &m_deblockSurface;
834 }
835 else
836 {
837 (&m_ddiDecodeCtx->DecodeParams)->m_deblockSurface = nullptr;
838 }
839
840 (&m_ddiDecodeCtx->DecodeParams)->m_dataBuffer = &bufMgr->resBitstreamBuffer;
841 (&m_ddiDecodeCtx->DecodeParams)->m_bitStreamBufData = bufMgr->pBitstreamBuffer;
842 Mos_Solo_OverrideBufferSize((&m_ddiDecodeCtx->DecodeParams)->m_dataSize, (&m_ddiDecodeCtx->DecodeParams)->m_dataBuffer);
843
844 (&m_ddiDecodeCtx->DecodeParams)->m_bitplaneBuffer = &(m_ddiDecodeCtx->BufMgr.Codec_Param.Codec_Param_VC1.resBitPlaneBuffer);
845
846 if (m_streamOutEnabled)
847 {
848 (&m_ddiDecodeCtx->DecodeParams)->m_streamOutEnabled = true;
849 (&m_ddiDecodeCtx->DecodeParams)->m_externalStreamOutBuffer = &bufMgr->resExternalStreamOutBuffer;
850 }
851 else
852 {
853 (&m_ddiDecodeCtx->DecodeParams)->m_streamOutEnabled = false;
854 (&m_ddiDecodeCtx->DecodeParams)->m_externalStreamOutBuffer = nullptr;
855 }
856
857 m_olpNeeded = false;
858 m_currPicIdx = DDI_CODEC_INVALID_FRAME_INDEX;
859 m_deblockPicIdx = DDI_CODEC_INVALID_FRAME_INDEX;
860
861 return VA_STATUS_SUCCESS;
862 }
863
InitResourceBuffer(DDI_MEDIA_CONTEXT * mediaCtx)864 VAStatus DdiDecodeVC1::InitResourceBuffer(DDI_MEDIA_CONTEXT *mediaCtx)
865 {
866 VAStatus vaStatus = VA_STATUS_SUCCESS;
867 DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_ddiDecodeCtx->BufMgr);
868
869 bufMgr->pSliceData = nullptr;
870
871 bufMgr->ui64BitstreamOrder = 0;
872 bufMgr->dwMaxBsSize = m_width *
873 m_height * 3 / 2;
874 // minimal 10k bytes for some special case. Will refractor this later
875 if (bufMgr->dwMaxBsSize < DDI_CODEC_MIN_VALUE_OF_MAX_BS_SIZE)
876 {
877 bufMgr->dwMaxBsSize = DDI_CODEC_MIN_VALUE_OF_MAX_BS_SIZE;
878 }
879
880 int32_t i;
881 // init decode bitstream buffer object
882 for (i = 0; i < DDI_CODEC_MAX_BITSTREAM_BUFFER; i++)
883 {
884 bufMgr->pBitStreamBuffObject[i] = (DDI_MEDIA_BUFFER *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_BUFFER));
885 if (bufMgr->pBitStreamBuffObject[i] == nullptr)
886 {
887 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
888 goto finish;
889 }
890 bufMgr->pBitStreamBuffObject[i]->iSize = bufMgr->dwMaxBsSize;
891 bufMgr->pBitStreamBuffObject[i]->uiType = VASliceDataBufferType;
892 bufMgr->pBitStreamBuffObject[i]->format = Media_Format_Buffer;
893 bufMgr->pBitStreamBuffObject[i]->uiOffset = 0;
894 bufMgr->pBitStreamBuffObject[i]->bo = nullptr;
895 bufMgr->pBitStreamBase[i] = nullptr;
896 }
897
898 bufMgr->m_maxNumSliceData = m_picHeightInMB;
899 bufMgr->pSliceData = (DDI_CODEC_BITSTREAM_BUFFER_INFO *)MOS_AllocAndZeroMemory(sizeof(bufMgr->pSliceData[0]) *
900 bufMgr->m_maxNumSliceData);
901
902 if (bufMgr->pSliceData == nullptr)
903 {
904 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
905 goto finish;
906 }
907
908 for (i = 0; i < DDI_CODEC_MAX_BITSTREAM_BUFFER; i++)
909 {
910 bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i] = (DDI_MEDIA_BUFFER *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_BUFFER));
911 if (bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i] == nullptr)
912 {
913 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
914 goto finish;
915 }
916 bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i]->iSize = MOS_ALIGN_CEIL(m_width, CODECHAL_MACROBLOCK_WIDTH) * MOS_ALIGN_CEIL(m_height, CODECHAL_MACROBLOCK_HEIGHT) * 2 / (CODECHAL_MACROBLOCK_HEIGHT * CODECHAL_MACROBLOCK_WIDTH);
917 bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i]->uiType = VABitPlaneBufferType;
918 bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i]->format = Media_Format_Buffer;
919 bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i]->uiOffset = 0;
920 bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i]->pMediaCtx = mediaCtx;
921
922 vaStatus = DdiMediaUtil_CreateBuffer(bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i], mediaCtx->pDrmBufMgr);
923 if (vaStatus != VA_STATUS_SUCCESS)
924 {
925 goto finish;
926 }
927
928 bufMgr->Codec_Param.Codec_Param_VC1.VC1BitPlane[i].pBitPlaneBase = nullptr;
929 bufMgr->Codec_Param.Codec_Param_VC1.VC1BitPlane[i].bUsed = false;
930 }
931
932 bufMgr->dwNumSliceData = 0;
933 bufMgr->dwNumSliceControl = 0;
934
935 m_sliceCtrlBufNum = m_picHeightInMB;
936 bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1 = (VASliceParameterBufferVC1 *)MOS_AllocAndZeroMemory(sizeof(VASliceParameterBufferVC1) * m_sliceCtrlBufNum);
937 if (bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1 == nullptr)
938 {
939 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
940 goto finish;
941 }
942 bufMgr->Codec_Param.Codec_Param_VC1.pBitPlaneBuffer = (uint8_t *)MOS_AllocAndZeroMemory(m_picWidthInMB * m_picHeightInMB);
943 if (bufMgr->Codec_Param.Codec_Param_VC1.pBitPlaneBuffer == nullptr)
944 {
945 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
946 goto finish;
947 }
948
949 return VA_STATUS_SUCCESS;
950
951 finish:
952 FreeResourceBuffer();
953 return vaStatus;
954 }
955
FreeResourceBuffer()956 void DdiDecodeVC1::FreeResourceBuffer()
957 {
958 DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_ddiDecodeCtx->BufMgr);
959
960 int32_t i;
961 for (i = 0; i < DDI_CODEC_MAX_BITSTREAM_BUFFER; i++)
962 {
963 if (bufMgr->pBitStreamBase[i])
964 {
965 DdiMediaUtil_UnlockBuffer(bufMgr->pBitStreamBuffObject[i]);
966 bufMgr->pBitStreamBase[i] = nullptr;
967 }
968 if (bufMgr->pBitStreamBuffObject[i])
969 {
970 DdiMediaUtil_FreeBuffer(bufMgr->pBitStreamBuffObject[i]);
971 MOS_FreeMemory(bufMgr->pBitStreamBuffObject[i]);
972 bufMgr->pBitStreamBuffObject[i] = nullptr;
973 }
974 }
975
976 if (bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1)
977 {
978 MOS_FreeMemory(bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1);
979 bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1 = nullptr;
980 }
981 if (bufMgr->Codec_Param.Codec_Param_VC1.pBitPlaneBuffer)
982 {
983 MOS_FreeMemory(bufMgr->Codec_Param.Codec_Param_VC1.pBitPlaneBuffer);
984 bufMgr->Codec_Param.Codec_Param_VC1.pBitPlaneBuffer = nullptr;
985 }
986 for (i = 0; i < DDI_CODEC_MAX_BITSTREAM_BUFFER; i++)
987 {
988 if (bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i])
989 {
990 DdiMediaUtil_UnlockBuffer(bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i]);
991 DdiMediaUtil_FreeBuffer(bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i]);
992 MOS_FreeMemory(bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i]);
993 bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i] = nullptr;
994 }
995 }
996
997 // free decode bitstream buffer object
998 MOS_FreeMemory(bufMgr->pSliceData);
999 bufMgr->pSliceData = nullptr;
1000
1001 return;
1002 }
1003
CodecHalInit(DDI_MEDIA_CONTEXT * mediaCtx,void * ptr)1004 VAStatus DdiDecodeVC1::CodecHalInit(
1005 DDI_MEDIA_CONTEXT *mediaCtx,
1006 void *ptr)
1007 {
1008 VAStatus vaStatus = VA_STATUS_SUCCESS;
1009 MOS_CONTEXT *mosCtx = (MOS_CONTEXT *)ptr;
1010
1011 CODECHAL_FUNCTION codecFunction = CODECHAL_FUNCTION_DECODE;
1012 m_ddiDecodeCtx->pCpDdiInterface->SetCpParams(m_ddiDecodeAttr->uiEncryptionType, m_codechalSettings);
1013
1014 CODECHAL_STANDARD_INFO standardInfo;
1015 memset(&standardInfo, 0, sizeof(standardInfo));
1016
1017 standardInfo.CodecFunction = codecFunction;
1018 standardInfo.Mode = (CODECHAL_MODE)m_ddiDecodeCtx->wMode;
1019
1020 m_codechalSettings->codecFunction = codecFunction;
1021 m_codechalSettings->width = m_width;
1022 m_codechalSettings->height = m_height;
1023
1024 m_codechalSettings->lumaChromaDepth = CODECHAL_LUMA_CHROMA_DEPTH_8_BITS;
1025
1026 m_codechalSettings->shortFormatInUse = m_ddiDecodeCtx->bShortFormatInUse;
1027
1028 m_codechalSettings->mode = CODECHAL_DECODE_MODE_VC1VLD;
1029 m_codechalSettings->standard = CODECHAL_VC1;
1030 /* VC1 uses the Intel-specific Format */
1031 m_codechalSettings->intelEntrypointInUse = true;
1032
1033 m_ddiDecodeCtx->DecodeParams.m_picParams = MOS_AllocAndZeroMemory(sizeof(CODEC_VC1_PIC_PARAMS));
1034 if (m_ddiDecodeCtx->DecodeParams.m_picParams == nullptr)
1035 {
1036 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1037 goto CleanUpandReturn;
1038 }
1039
1040 m_sliceParamBufNum = m_picHeightInMB;
1041 m_ddiDecodeCtx->DecodeParams.m_sliceParams = MOS_AllocAndZeroMemory(m_sliceParamBufNum * sizeof(CODEC_VC1_SLICE_PARAMS));
1042 if (m_ddiDecodeCtx->DecodeParams.m_sliceParams == nullptr)
1043 {
1044 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1045 goto CleanUpandReturn;
1046 }
1047
1048 vaStatus = CreateCodecHal(mediaCtx,
1049 ptr,
1050 &standardInfo);
1051
1052 if (vaStatus != VA_STATUS_SUCCESS)
1053 {
1054 goto CleanUpandReturn;
1055 }
1056
1057 if (InitResourceBuffer(mediaCtx) != VA_STATUS_SUCCESS)
1058 {
1059 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1060 goto CleanUpandReturn;
1061 }
1062
1063 return vaStatus;
1064
1065 CleanUpandReturn:
1066 FreeResourceBuffer();
1067
1068 if (m_ddiDecodeCtx->pCodecHal)
1069 {
1070 m_ddiDecodeCtx->pCodecHal->Destroy();
1071 MOS_Delete(m_ddiDecodeCtx->pCodecHal);
1072 m_ddiDecodeCtx->pCodecHal = nullptr;
1073 }
1074
1075 MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_picParams);
1076 m_ddiDecodeCtx->DecodeParams.m_picParams = nullptr;
1077 MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_sliceParams);
1078 m_ddiDecodeCtx->DecodeParams.m_sliceParams = nullptr;
1079
1080 return vaStatus;
1081 }
1082
1083 extern template class MediaDdiFactory<DdiMediaDecode, DDI_DECODE_CONFIG_ATTR>;
1084
1085 static bool vc1Registered =
1086 MediaDdiFactory<DdiMediaDecode, DDI_DECODE_CONFIG_ATTR>::RegisterCodec<DdiDecodeVC1>(DECODE_ID_VC1);
1087