1 /*
2 * Copyright (c) 2022-2023, 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 ddi_decode_vp9_specific.cpp
24 //! \brief Implements class for DDI media VP9 decode
25 //!
26
27 #include "media_libva_util_next.h"
28 #include "media_libva_interface_next.h"
29 #include "ddi_decode_vp9_specific.h"
30 #include "ddi_decode_trace_specific.h"
31
32 namespace decode
33 {
34
ParseSliceParams(DDI_MEDIA_CONTEXT * mediaCtx,VASliceParameterBufferVP9 * slcParam)35 VAStatus DdiDecodeVp9::ParseSliceParams(
36 DDI_MEDIA_CONTEXT *mediaCtx,
37 VASliceParameterBufferVP9 *slcParam)
38 {
39 DDI_CODEC_FUNC_ENTER;
40
41 PCODEC_VP9_PIC_PARAMS picParam = (PCODEC_VP9_PIC_PARAMS)(m_decodeCtx->DecodeParams.m_picParams);
42 PCODEC_VP9_SEGMENT_PARAMS segParams = (PCODEC_VP9_SEGMENT_PARAMS)(m_decodeCtx->DecodeParams.m_iqMatrixBuffer);
43
44 if ((slcParam == nullptr) ||
45 (picParam == nullptr) ||
46 (segParams == nullptr))
47 {
48 DDI_CODEC_ASSERTMESSAGE("Invalid Parameter for Parsing VP9 Slice parameter\n");
49 return VA_STATUS_ERROR_INVALID_PARAMETER;
50 }
51
52 picParam->BSBytesInBuffer = slcParam->slice_data_size;
53
54 int32_t i = 0, j = 0, k = 0;
55 for (i = 0; i < 8; i++)
56 {
57 segParams->SegData[i].SegmentFlags.fields.SegmentReferenceEnabled = slcParam->seg_param[i].segment_flags.fields.segment_reference_enabled;
58 segParams->SegData[i].SegmentFlags.fields.SegmentReference = slcParam->seg_param[i].segment_flags.fields.segment_reference;
59 segParams->SegData[i].SegmentFlags.fields.SegmentReferenceSkipped = slcParam->seg_param[i].segment_flags.fields.segment_reference_skipped;
60
61 for (j = 0; j < 4; j++)
62 {
63 for (k = 0; k < 2; k++)
64 {
65 segParams->SegData[i].FilterLevel[j][k] = slcParam->seg_param[i].filter_level[j][k];
66 }
67 }
68
69 segParams->SegData[i].LumaACQuantScale = slcParam->seg_param[i].luma_ac_quant_scale;
70 segParams->SegData[i].LumaDCQuantScale = slcParam->seg_param[i].luma_dc_quant_scale;
71 segParams->SegData[i].ChromaACQuantScale = slcParam->seg_param[i].chroma_ac_quant_scale;
72 segParams->SegData[i].ChromaDCQuantScale = slcParam->seg_param[i].chroma_dc_quant_scale;
73 }
74
75 return VA_STATUS_SUCCESS;
76 }
77
ParsePicParams(DDI_MEDIA_CONTEXT * mediaCtx,VADecPictureParameterBufferVP9 * picParam)78 VAStatus DdiDecodeVp9::ParsePicParams(
79 DDI_MEDIA_CONTEXT *mediaCtx,
80 VADecPictureParameterBufferVP9 *picParam)
81 {
82 DDI_CODEC_FUNC_ENTER;
83
84 PCODEC_VP9_PIC_PARAMS picVp9Params = (PCODEC_VP9_PIC_PARAMS)(m_decodeCtx->DecodeParams.m_picParams);
85
86 if ((picParam == nullptr) || (picVp9Params == nullptr))
87 {
88 DDI_CODEC_ASSERTMESSAGE("Invalid Parameter for Parsing VP9 Picture parameter\n");
89 return VA_STATUS_ERROR_INVALID_PARAMETER;
90 }
91
92 picVp9Params->FrameHeightMinus1 = picParam->frame_height - 1;
93 picVp9Params->FrameWidthMinus1 = picParam->frame_width - 1;
94
95 picVp9Params->PicFlags.fields.frame_type = picParam->pic_fields.bits.frame_type;
96 picVp9Params->PicFlags.fields.show_frame = picParam->pic_fields.bits.show_frame;
97 picVp9Params->PicFlags.fields.error_resilient_mode = picParam->pic_fields.bits.error_resilient_mode;
98 picVp9Params->PicFlags.fields.intra_only = picParam->pic_fields.bits.intra_only;
99 picVp9Params->PicFlags.fields.LastRefIdx = picParam->pic_fields.bits.last_ref_frame;
100 picVp9Params->PicFlags.fields.LastRefSignBias = picParam->pic_fields.bits.last_ref_frame_sign_bias;
101 picVp9Params->PicFlags.fields.GoldenRefIdx = picParam->pic_fields.bits.golden_ref_frame;
102 picVp9Params->PicFlags.fields.GoldenRefSignBias = picParam->pic_fields.bits.golden_ref_frame_sign_bias;
103 picVp9Params->PicFlags.fields.AltRefIdx = picParam->pic_fields.bits.alt_ref_frame;
104 picVp9Params->PicFlags.fields.AltRefSignBias = picParam->pic_fields.bits.alt_ref_frame_sign_bias;
105 picVp9Params->PicFlags.fields.allow_high_precision_mv = picParam->pic_fields.bits.allow_high_precision_mv;
106 picVp9Params->PicFlags.fields.mcomp_filter_type = picParam->pic_fields.bits.mcomp_filter_type;
107 picVp9Params->PicFlags.fields.frame_parallel_decoding_mode = picParam->pic_fields.bits.frame_parallel_decoding_mode;
108 picVp9Params->PicFlags.fields.segmentation_enabled = picParam->pic_fields.bits.segmentation_enabled;
109 picVp9Params->PicFlags.fields.segmentation_temporal_update = picParam->pic_fields.bits.segmentation_temporal_update;
110 picVp9Params->PicFlags.fields.segmentation_update_map = picParam->pic_fields.bits.segmentation_update_map;
111 picVp9Params->PicFlags.fields.reset_frame_context = picParam->pic_fields.bits.reset_frame_context;
112 picVp9Params->PicFlags.fields.refresh_frame_context = picParam->pic_fields.bits.refresh_frame_context;
113 picVp9Params->PicFlags.fields.frame_context_idx = picParam->pic_fields.bits.frame_context_idx;
114 picVp9Params->PicFlags.fields.LosslessFlag = picParam->pic_fields.bits.lossless_flag;
115
116 int32_t frameIdx;
117 frameIdx = GetRenderTargetID(&m_decodeCtx->RTtbl, m_decodeCtx->RTtbl.pCurrentRT);
118 if (frameIdx == (int32_t)DDI_CODEC_INVALID_FRAME_INDEX)
119 {
120 return VA_STATUS_ERROR_INVALID_PARAMETER;
121 }
122 picVp9Params->CurrPic.FrameIdx = frameIdx;
123
124 int32_t i;
125 for (i = 0; i < 8; i++)
126 {
127 if (picParam->reference_frames[i] < mediaCtx->uiNumSurfaces)
128 {
129 PDDI_MEDIA_SURFACE refSurface = MediaLibvaCommonNext::GetSurfaceFromVASurfaceID(mediaCtx, picParam->reference_frames[i]);
130 frameIdx = GetRenderTargetID(&m_decodeCtx->RTtbl, refSurface);
131 picVp9Params->RefFrameList[i].FrameIdx = ((uint32_t)frameIdx >= CODECHAL_NUM_UNCOMPRESSED_SURFACE_VP9) ? (CODECHAL_NUM_UNCOMPRESSED_SURFACE_VP9 - 1) : frameIdx;
132 }
133 else
134 {
135 PDDI_MEDIA_SURFACE refSurface = MediaLibvaCommonNext::GetSurfaceFromVASurfaceID(mediaCtx, picParam->reference_frames[i]);
136 if (refSurface != nullptr)
137 {
138 frameIdx = GetRenderTargetID(&m_decodeCtx->RTtbl, refSurface);
139 if (frameIdx != DDI_CODEC_INVALID_FRAME_INDEX)
140 {
141 picVp9Params->RefFrameList[i].FrameIdx = ((uint32_t)frameIdx >= CODECHAL_NUM_UNCOMPRESSED_SURFACE_VP9) ? (CODECHAL_NUM_UNCOMPRESSED_SURFACE_VP9 - 1) : frameIdx;
142 }
143 else
144 {
145 picVp9Params->RefFrameList[i].FrameIdx = CODECHAL_NUM_UNCOMPRESSED_SURFACE_VP9 - 1;
146 }
147 }
148 else
149 {
150 picVp9Params->RefFrameList[i].FrameIdx = CODECHAL_NUM_UNCOMPRESSED_SURFACE_VP9 - 1;
151 }
152 }
153 }
154
155 picVp9Params->filter_level = picParam->filter_level;
156 picVp9Params->sharpness_level = picParam->sharpness_level;
157 picVp9Params->log2_tile_rows = picParam->log2_tile_rows;
158 picVp9Params->log2_tile_columns = picParam->log2_tile_columns;
159 picVp9Params->UncompressedHeaderLengthInBytes = picParam->frame_header_length_in_bytes;
160 picVp9Params->FirstPartitionSize = picParam->first_partition_size;
161 picVp9Params->profile = picParam->profile;
162
163 /* Only 8bit depth is supported on picParam->profile=0.
164 * If picParam->profile=2,3, it is possible to support the 10/12 bit-depth.
165 * otherwise the bit_depth is 8.
166 */
167 if (((picParam->profile == CODEC_PROFILE_VP9_PROFILE2) ||
168 (picParam->profile == CODEC_PROFILE_VP9_PROFILE3)) &&
169 (picParam->bit_depth >= 8))
170 {
171 picVp9Params->BitDepthMinus8 = picParam->bit_depth - 8;
172 }
173 else
174 {
175 picVp9Params->BitDepthMinus8 = 0;
176 }
177
178 picVp9Params->subsampling_x = picParam->pic_fields.bits.subsampling_x;
179 picVp9Params->subsampling_y = picParam->pic_fields.bits.subsampling_y;
180
181 MOS_SecureMemcpy(picVp9Params->SegTreeProbs, 7, picParam->mb_segment_tree_probs, 7);
182 MOS_SecureMemcpy(picVp9Params->SegPredProbs, 3, picParam->segment_pred_probs, 3);
183
184 #if MOS_EVENT_TRACE_DUMP_SUPPORTED
185 // Picture Info
186 uint32_t subSamplingSum = picVp9Params->subsampling_x + picVp9Params->subsampling_y;
187 DECODE_EVENTDATA_INFO_PICTUREVA eventData = {0};
188 eventData.CodecFormat = m_decodeCtx->wMode;
189 eventData.FrameType = picVp9Params->PicFlags.fields.frame_type == 0 ? I_TYPE : MIXED_TYPE;
190 eventData.PicStruct = FRAME_PICTURE;
191 eventData.Width = picVp9Params->FrameWidthMinus1 + 1;
192 eventData.Height = picVp9Params->FrameHeightMinus1 + 1;
193 eventData.Bitdepth = picVp9Params->BitDepthMinus8 + 8;
194 eventData.ChromaFormat = (subSamplingSum == 2) ? 1 : (subSamplingSum == 1 ? 2 : 3); // 1-4:2:0; 2-4:2:2; 3-4:4:4
195 eventData.EnabledSegment = picVp9Params->PicFlags.fields.segmentation_enabled;
196 MOS_TraceEvent(EVENT_DECODE_INFO_PICTUREVA, EVENT_TYPE_INFO, &eventData, sizeof(eventData), NULL, 0);
197 #endif
198
199 return VA_STATUS_SUCCESS;
200 }
201
SetDecodeParams()202 VAStatus DdiDecodeVp9::SetDecodeParams()
203 {
204 DDI_CODEC_FUNC_ENTER;
205
206 DDI_CODEC_CHK_RET(DdiDecodeBase::SetDecodeParams(),"SetDecodeParams failed!");
207 #ifdef _DECODE_PROCESSING_SUPPORTED
208 // Bridge the SFC input with vdbox output
209 if (m_decProcessingType == VA_DEC_PROCESSING)
210 {
211 auto procParams = (DecodeProcessingParams *)m_decodeCtx->DecodeParams.m_procParams;
212 procParams->m_inputSurface = (&m_decodeCtx->DecodeParams)->m_destSurface;
213 // codechal_decode_sfc.c expects Input Width/Height information.
214 procParams->m_inputSurface->dwWidth = procParams->m_inputSurface->OsResource.iWidth;
215 procParams->m_inputSurface->dwHeight = procParams->m_inputSurface->OsResource.iHeight;
216 procParams->m_inputSurface->dwPitch = procParams->m_inputSurface->OsResource.iPitch;
217 procParams->m_inputSurface->Format = procParams->m_inputSurface->OsResource.Format;
218
219 if (m_requireInputRegion)
220 {
221 procParams->m_inputSurfaceRegion.m_x = 0;
222 procParams->m_inputSurfaceRegion.m_y = 0;
223 procParams->m_inputSurfaceRegion.m_width = procParams->m_inputSurface->dwWidth;
224 procParams->m_inputSurfaceRegion.m_height = procParams->m_inputSurface->dwHeight;
225 }
226 }
227 #endif
228 return VA_STATUS_SUCCESS;
229 }
230
RenderPicture(VADriverContextP ctx,VAContextID context,VABufferID * buffers,int32_t numBuffers)231 VAStatus DdiDecodeVp9::RenderPicture(
232 VADriverContextP ctx,
233 VAContextID context,
234 VABufferID *buffers,
235 int32_t numBuffers)
236 {
237 DDI_CODEC_FUNC_ENTER;
238
239 VAStatus va = VA_STATUS_SUCCESS;
240 PDDI_MEDIA_CONTEXT mediaCtx = GetMediaContext(ctx);
241
242 void *data = nullptr;
243 for (int32_t i = 0; i < numBuffers; i++)
244 {
245 if (!buffers || (buffers[i] == VA_INVALID_ID))
246 {
247 return VA_STATUS_ERROR_INVALID_BUFFER;
248 }
249 DDI_MEDIA_BUFFER *buf = MediaLibvaCommonNext::GetBufferFromVABufferID(mediaCtx, buffers[i]);
250 if (nullptr == buf)
251 {
252 return VA_STATUS_ERROR_INVALID_BUFFER;
253 }
254
255 uint32_t dataSize = buf->iSize;
256 MediaLibvaInterfaceNext::MapBuffer(ctx, buffers[i], &data);
257
258 if (data == nullptr)
259 {
260 return VA_STATUS_ERROR_INVALID_BUFFER;
261 }
262
263 switch ((int32_t)buf->uiType)
264 {
265 case VASliceDataBufferType:
266 {
267 if (slcFlag)
268 {
269 // VP9 only supports only one slice_data. If it is passed, another slice_data
270 // buffer will be ignored.
271 DDI_CODEC_NORMALMESSAGE("Slice data is already rendered\n");
272 break;
273 }
274 int32_t index = GetBitstreamBufIndexFromBuffer(&m_decodeCtx->BufMgr, buf);
275 if (index == DDI_CODEC_INVALID_BUFFER_INDEX)
276 {
277 return VA_STATUS_ERROR_INVALID_BUFFER;
278 }
279
280 MediaLibvaCommonNext::MediaBufferToMosResource(m_decodeCtx->BufMgr.pBitStreamBuffObject[index], &m_decodeCtx->BufMgr.resBitstreamBuffer);
281 m_decodeCtx->DecodeParams.m_dataSize += dataSize;
282 slcFlag = true;
283
284 break;
285 }
286 case VASliceParameterBufferType:
287 {
288 if (m_decodeCtx->DecodeParams.m_numSlices)
289 {
290 // VP9 only supports only one slice. If it is passed, another slice_param
291 // buffer will be ignored.
292 DDI_CODEC_NORMALMESSAGE("SliceParamBufferVP9 is already rendered\n");
293 break;
294 }
295 if (buf->uiNumElements == 0)
296 {
297 return VA_STATUS_ERROR_INVALID_BUFFER;
298 }
299
300 VASliceParameterBufferVP9 *slcInfoVP9 = (VASliceParameterBufferVP9 *)data;
301 DDI_CODEC_CHK_RET(ParseSliceParams(mediaCtx, slcInfoVP9),"ParseSliceParams failed!");
302 m_decodeCtx->DecodeParams.m_numSlices++;
303 m_groupIndex++;
304 break;
305 }
306 case VAPictureParameterBufferType:
307 {
308 VADecPictureParameterBufferVP9 *picParam;
309
310 picParam = (VADecPictureParameterBufferVP9 *)data;
311 DDI_CODEC_CHK_RET(ParsePicParams(mediaCtx, picParam),"ParsePicParams failed!");
312 break;
313 }
314
315 case VAProcPipelineParameterBufferType:
316 {
317 DDI_CODEC_CHK_RET(ParseProcessingBuffer(mediaCtx, data),"ParseProcessingBuffer failed!");
318 break;
319 }
320 case VADecodeStreamoutBufferType:
321 {
322 MediaLibvaCommonNext::MediaBufferToMosResource(buf, &m_decodeCtx->BufMgr.resExternalStreamOutBuffer);
323 m_streamOutEnabled = true;
324 break;
325 }
326
327 default:
328 va = m_decodeCtx->pCpDdiInterfaceNext->RenderCencPicture(ctx, context, buf, data);
329 break;
330 }
331 MediaLibvaInterfaceNext::UnmapBuffer(ctx, buffers[i]);
332 }
333
334 return va;
335 }
336
InitResourceBuffer()337 VAStatus DdiDecodeVp9::InitResourceBuffer()
338 {
339 DDI_CODEC_FUNC_ENTER;
340
341 VAStatus vaStatus = VA_STATUS_SUCCESS;
342 DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_decodeCtx->BufMgr);
343
344 bufMgr->pSliceData = nullptr;
345
346 bufMgr->ui64BitstreamOrder = 0;
347 bufMgr->dwMaxBsSize = m_width * m_height * 3 / 2;
348 // minimal 10k bytes for some special case. Will refractor this later
349 if (bufMgr->dwMaxBsSize < DDI_CODEC_MIN_VALUE_OF_MAX_BS_SIZE)
350 {
351 bufMgr->dwMaxBsSize = DDI_CODEC_MIN_VALUE_OF_MAX_BS_SIZE;
352 }
353
354 int32_t i;
355 // init decode bitstream buffer object
356 for (i = 0; i < DDI_CODEC_MAX_BITSTREAM_BUFFER; i++)
357 {
358 bufMgr->pBitStreamBuffObject[i] = (DDI_MEDIA_BUFFER *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_BUFFER));
359 if (bufMgr->pBitStreamBuffObject[i] == nullptr)
360 {
361 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
362 FreeResourceBuffer();
363 return vaStatus;
364 }
365 bufMgr->pBitStreamBuffObject[i]->iSize = bufMgr->dwMaxBsSize;
366 bufMgr->pBitStreamBuffObject[i]->uiType = VASliceDataBufferType;
367 bufMgr->pBitStreamBuffObject[i]->format = Media_Format_Buffer;
368 bufMgr->pBitStreamBuffObject[i]->uiOffset = 0;
369 bufMgr->pBitStreamBuffObject[i]->bo = nullptr;
370 bufMgr->pBitStreamBase[i] = nullptr;
371 }
372
373 // VP9 can support only one SliceDataBuffer. In such case only one is enough.
374 // 2 is allocated for the safety.
375 bufMgr->m_maxNumSliceData = 2;
376 bufMgr->pSliceData = (DDI_CODEC_BITSTREAM_BUFFER_INFO *)MOS_AllocAndZeroMemory(sizeof(bufMgr->pSliceData[0]) * 2);
377
378 if (bufMgr->pSliceData == nullptr)
379 {
380 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
381 FreeResourceBuffer();
382 return vaStatus;
383 }
384
385 bufMgr->dwNumSliceData = 0;
386 bufMgr->dwNumSliceControl = 0;
387
388 bufMgr->Codec_Param.Codec_Param_VP9.pVASliceParaBufVP9 = (VASliceParameterBufferVP9 *)MOS_AllocAndZeroMemory(sizeof(VASliceParameterBufferVP9));
389 if (bufMgr->Codec_Param.Codec_Param_VP9.pVASliceParaBufVP9 == nullptr)
390 {
391 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
392 FreeResourceBuffer();
393 return vaStatus;
394 }
395
396 return VA_STATUS_SUCCESS;
397 }
398
FreeResourceBuffer()399 void DdiDecodeVp9::FreeResourceBuffer()
400 {
401 DDI_CODEC_FUNC_ENTER;
402
403 DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_decodeCtx->BufMgr);
404
405 int32_t i = 0;
406 for (i = 0; i < DDI_CODEC_MAX_BITSTREAM_BUFFER; i++)
407 {
408 if (bufMgr->pBitStreamBase[i])
409 {
410 MediaLibvaUtilNext::UnlockBuffer(bufMgr->pBitStreamBuffObject[i]);
411 bufMgr->pBitStreamBase[i] = nullptr;
412 }
413 if (bufMgr->pBitStreamBuffObject[i])
414 {
415 MediaLibvaUtilNext::FreeBuffer(bufMgr->pBitStreamBuffObject[i]);
416 MOS_FreeMemory(bufMgr->pBitStreamBuffObject[i]);
417 bufMgr->pBitStreamBuffObject[i] = nullptr;
418 }
419 }
420
421 if (bufMgr->Codec_Param.Codec_Param_VP9.pVASliceParaBufVP9)
422 {
423 MOS_FreeMemory(bufMgr->Codec_Param.Codec_Param_VP9.pVASliceParaBufVP9);
424 bufMgr->Codec_Param.Codec_Param_VP9.pVASliceParaBufVP9 = nullptr;
425 }
426
427 // free decode bitstream buffer object
428 MOS_FreeMemory(bufMgr->pSliceData);
429 bufMgr->pSliceData = nullptr;
430
431 return;
432 }
433
GetPicParamBuf(DDI_CODEC_COM_BUFFER_MGR * bufMgr)434 uint8_t* DdiDecodeVp9::GetPicParamBuf(
435 DDI_CODEC_COM_BUFFER_MGR *bufMgr)
436 {
437 DDI_CODEC_FUNC_ENTER;
438
439 return (uint8_t*)(&(bufMgr->Codec_Param.Codec_Param_VP9.PicParamVP9));
440 }
441
AllocSliceControlBuffer(DDI_MEDIA_BUFFER * buf)442 VAStatus DdiDecodeVp9::AllocSliceControlBuffer(
443 DDI_MEDIA_BUFFER *buf)
444 {
445 DDI_CODEC_FUNC_ENTER;
446
447 DDI_CODEC_COM_BUFFER_MGR *bufMgr = nullptr;
448
449 bufMgr = &(m_decodeCtx->BufMgr);
450 if (bufMgr->Codec_Param.Codec_Param_VP9.pVASliceParaBufVP9 == nullptr)
451 {
452 return VA_STATUS_ERROR_ALLOCATION_FAILED;
453 }
454 buf->pData = (uint8_t*)bufMgr->Codec_Param.Codec_Param_VP9.pVASliceParaBufVP9;
455 buf->uiOffset = bufMgr->dwNumSliceControl * sizeof(VASliceParameterBufferVP9);
456
457 bufMgr->dwNumSliceControl += buf->uiNumElements;
458
459 return VA_STATUS_SUCCESS;
460 }
461
CodecHalInit(DDI_MEDIA_CONTEXT * mediaCtx,void * ptr)462 VAStatus DdiDecodeVp9::CodecHalInit(
463 DDI_MEDIA_CONTEXT *mediaCtx,
464 void *ptr)
465 {
466 DDI_CODEC_FUNC_ENTER;
467
468 VAStatus vaStatus = VA_STATUS_SUCCESS;
469 MOS_CONTEXT *mosCtx = (MOS_CONTEXT *)ptr;
470
471 CODECHAL_FUNCTION codecFunction = CODECHAL_FUNCTION_DECODE;
472 m_decodeCtx->pCpDdiInterfaceNext->SetCpParams(m_ddiDecodeAttr->componentData.data.encryptType, m_codechalSettings);
473
474 CODECHAL_STANDARD_INFO standardInfo;
475 memset(&standardInfo, 0, sizeof(standardInfo));
476
477 standardInfo.CodecFunction = codecFunction;
478 standardInfo.Mode = (CODECHAL_MODE)m_decodeCtx->wMode;
479
480 m_codechalSettings->codecFunction = codecFunction;
481 m_codechalSettings->width = m_width;
482 m_codechalSettings->height = m_height;
483 m_codechalSettings->intelEntrypointInUse = false;
484
485 m_codechalSettings->lumaChromaDepth = CODECHAL_LUMA_CHROMA_DEPTH_8_BITS;
486 if ((m_ddiDecodeAttr->profile == VAProfileVP9Profile2) ||
487 (m_ddiDecodeAttr->profile == VAProfileVP9Profile3))
488 {
489 m_codechalSettings->lumaChromaDepth |= CODECHAL_LUMA_CHROMA_DEPTH_10_BITS;
490 }
491
492 m_codechalSettings->shortFormatInUse = m_decodeCtx->bShortFormatInUse;
493
494 m_codechalSettings->mode = CODECHAL_DECODE_MODE_VP9VLD;
495 m_codechalSettings->standard = CODECHAL_VP9;
496 m_codechalSettings->chromaFormat = HCP_CHROMA_FORMAT_YUV420;
497
498 if (m_ddiDecodeAttr->profile == VAProfileVP9Profile1 ||
499 m_ddiDecodeAttr->profile == VAProfileVP9Profile3)
500 {
501 m_codechalSettings->chromaFormat = HCP_CHROMA_FORMAT_YUV444;
502 }
503
504 m_decodeCtx->DecodeParams.m_iqMatrixBuffer = MOS_AllocAndZeroMemory(sizeof(CODEC_VP9_SEGMENT_PARAMS));
505 if (m_decodeCtx->DecodeParams.m_iqMatrixBuffer == nullptr)
506 {
507 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
508 FreeResource();
509 return vaStatus;
510 }
511 m_decodeCtx->DecodeParams.m_picParams = MOS_AllocAndZeroMemory(sizeof(CODEC_VP9_PIC_PARAMS));
512 if (m_decodeCtx->DecodeParams.m_picParams == nullptr)
513 {
514 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
515 FreeResource();
516 return vaStatus;
517 }
518 #ifdef _DECODE_PROCESSING_SUPPORTED
519 if (m_decProcessingType == VA_DEC_PROCESSING)
520 {
521 DecodeProcessingParams *procParams = nullptr;
522
523 m_codechalSettings->downsamplingHinted = true;
524
525 procParams = (DecodeProcessingParams *)MOS_AllocAndZeroMemory(sizeof(DecodeProcessingParams));
526 if (procParams == nullptr)
527 {
528 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
529 FreeResource();
530 return vaStatus;
531 }
532
533 m_decodeCtx->DecodeParams.m_procParams = procParams;
534 procParams->m_outputSurface = (PMOS_SURFACE)MOS_AllocAndZeroMemory(sizeof(MOS_SURFACE));
535 if (procParams->m_outputSurface == nullptr)
536 {
537 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
538 FreeResource();
539 return vaStatus;
540 }
541 }
542 #endif
543 vaStatus = CreateCodecHal(mediaCtx,
544 ptr,
545 &standardInfo);
546
547 if (vaStatus != VA_STATUS_SUCCESS)
548 {
549 FreeResource();
550 return vaStatus;
551 }
552
553 if (InitResourceBuffer() != VA_STATUS_SUCCESS)
554 {
555 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
556 FreeResource();
557 return vaStatus;
558 }
559
560 return vaStatus;
561 }
562
FreeResource()563 void DdiDecodeVp9::FreeResource()
564 {
565 DDI_CODEC_FUNC_ENTER;
566
567 FreeResourceBuffer();
568
569 if (m_decodeCtx->pCodecHal)
570 {
571 m_decodeCtx->pCodecHal->Destroy();
572 MOS_Delete(m_decodeCtx->pCodecHal);
573 m_decodeCtx->pCodecHal = nullptr;
574 }
575
576 MOS_FreeMemory(m_decodeCtx->DecodeParams.m_iqMatrixBuffer);
577 m_decodeCtx->DecodeParams.m_iqMatrixBuffer = nullptr;
578 MOS_FreeMemory(m_decodeCtx->DecodeParams.m_picParams);
579 m_decodeCtx->DecodeParams.m_picParams = nullptr;
580 MOS_FreeMemory(m_decodeCtx->DecodeParams.m_sliceParams);
581 m_decodeCtx->DecodeParams.m_sliceParams = nullptr;
582 #ifdef _DECODE_PROCESSING_SUPPORTED
583 if (m_decodeCtx->DecodeParams.m_procParams)
584 {
585 auto procParams =
586 (DecodeProcessingParams *)m_decodeCtx->DecodeParams.m_procParams;
587 MOS_FreeMemory(procParams->m_outputSurface);
588
589 MOS_FreeMemory(m_decodeCtx->DecodeParams.m_procParams);
590 m_decodeCtx->DecodeParams.m_procParams = nullptr;
591 }
592 #endif
593
594 return;
595 }
596
InitDecodeParams(VADriverContextP ctx,VAContextID context)597 VAStatus DdiDecodeVp9::InitDecodeParams(
598 VADriverContextP ctx,
599 VAContextID context)
600 {
601 DDI_CODEC_FUNC_ENTER;
602
603 slcFlag = false;
604 /* skip the mediaCtx check as it is checked in caller */
605 PDDI_MEDIA_CONTEXT mediaCtx = GetMediaContext(ctx);
606 DDI_CODEC_CHK_RET(DecodeCombineBitstream(mediaCtx),"DecodeCombineBitstream failed!");
607 DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_decodeCtx->BufMgr);
608 bufMgr->dwNumSliceData = 0;
609 bufMgr->dwNumSliceControl = 0;
610
611 DDI_CODEC_RENDER_TARGET_TABLE *rtTbl = &(m_decodeCtx->RTtbl);
612
613 if ((rtTbl == nullptr) || (rtTbl->pCurrentRT == nullptr))
614 {
615 return VA_STATUS_ERROR_INVALID_PARAMETER;
616 }
617 return VA_STATUS_SUCCESS;
618 }
619
GetFormat()620 MOS_FORMAT DdiDecodeVp9::GetFormat()
621 {
622 DDI_CODEC_FUNC_ENTER;
623
624 slcFlag = false;
625 MOS_FORMAT Format = Format_NV12;
626 DDI_CODEC_RENDER_TARGET_TABLE *rtTbl = &(m_decodeCtx->RTtbl);
627 CodechalDecodeParams *decodeParams = &m_decodeCtx->DecodeParams;
628
629 CODEC_VP9_PIC_PARAMS *picParams = (CODEC_VP9_PIC_PARAMS *)decodeParams->m_picParams;
630 if ((picParams->profile == CODEC_PROFILE_VP9_PROFILE1) &&
631 (picParams->BitDepthMinus8 == 0))
632 {
633 Format = Format_AYUV;
634 }
635 if (((picParams->profile == CODEC_PROFILE_VP9_PROFILE2) ||
636 (picParams->profile == CODEC_PROFILE_VP9_PROFILE3)) &&
637 (picParams->BitDepthMinus8 > 0))
638 {
639 Format = Format_P010;
640 if ((picParams->BitDepthMinus8 > 2) || (rtTbl->pCurrentRT->format == Media_Format_P016 || rtTbl->pCurrentRT->format == Media_Format_P012))
641 {
642 Format = Format_P016;
643 }
644 if ((picParams->subsampling_x == 1) && (picParams->subsampling_y == 0))
645 {
646 Format = Format_Y210;
647 }
648 else if ((picParams->subsampling_x == 0) && (picParams->subsampling_y == 0))
649 {
650 if (picParams->BitDepthMinus8 == 2)
651 {
652 Format = Format_Y410;
653
654 // 10bit decode in 12bit
655 #if VA_CHECK_VERSION(1, 9, 0)
656 if (rtTbl->pCurrentRT->format == Media_Format_Y416 || rtTbl->pCurrentRT->format == Media_Format_Y412)
657 #else
658 if (rtTbl->pCurrentRT->format == Media_Format_Y416)
659 #endif
660 {
661 Format = Format_Y416;
662 }
663 }
664 else if (picParams->BitDepthMinus8 > 2)
665 {
666 Format = Format_Y416;
667 }
668 }
669 }
670 return Format;
671 }
672
DestroyContext(VADriverContextP ctx)673 void DdiDecodeVp9::DestroyContext(
674 VADriverContextP ctx)
675 {
676 DDI_CODEC_FUNC_ENTER;
677
678 FreeResourceBuffer();
679 // explicitly call the base function to do the further clean-up
680 DdiDecodeBase::DestroyContext(ctx);
681
682 return;
683 }
684
ContextInit(int32_t picWidth,int32_t picHeight)685 void DdiDecodeVp9::ContextInit(
686 int32_t picWidth,
687 int32_t picHeight)
688 {
689 DDI_CODEC_FUNC_ENTER;
690
691 // call the function in base class to initialize it.
692 DdiDecodeBase::ContextInit(picWidth, picHeight);
693
694 m_decodeCtx->wMode = CODECHAL_DECODE_MODE_VP9VLD;
695
696 return;
697 }
698
699 } // namespace decode
700