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