1 /*
2 * Copyright (c) 2011-2024, 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 codechal_decode_avc.cpp
24 //! \brief This modules implements Render interface layer for AVC decoding to be used on all operating systems/DDIs, across CODECHAL components.
25 //!
26
27 #include "codechal_decoder.h"
28 #include "codechal_decode_avc.h"
29 #include "codechal_decode_sfc_avc.h"
30 #include "codechal_mmc_decode_avc.h"
31 #include "codechal_secure_decode_interface.h"
32 #include "hal_oca_interface.h"
33 #if USE_CODECHAL_DEBUG_TOOL
34 #include "codechal_debug.h"
35 #endif
36
37 //Check whether interview prediction is used through POC
38 #define CodecHalAVC_IsInterviewPred(currPic, currPoc, avcRefListIdx) ( ((avcRefListIdx)!=(currPic).FrameIdx) && \
39 (!CodecHal_PictureIsTopField(currPic) && (pAvcRefList[avcRefListIdx]->iFieldOrderCnt[1] == (currPoc)[1]) || \
40 !CodecHal_PictureIsBottomField(currPic) && (pAvcRefList[avcRefListIdx]->iFieldOrderCnt[0] == (currPoc)[0])) && \
41 ((currPic).FrameIdx != 0x7f) )
42
SendSlice(PMHW_VDBOX_AVC_SLICE_STATE avcSliceState,PMOS_COMMAND_BUFFER cmdBuffer)43 MOS_STATUS CodechalDecodeAvc::SendSlice(
44 PMHW_VDBOX_AVC_SLICE_STATE avcSliceState,
45 PMOS_COMMAND_BUFFER cmdBuffer)
46 {
47
48 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
49
50 CODECHAL_DECODE_CHK_NULL_RETURN(cmdBuffer);
51 CODECHAL_DECODE_CHK_NULL_RETURN(avcSliceState);
52 CODECHAL_DECODE_CHK_NULL_RETURN(avcSliceState->pAvcPicIdx);
53 CODECHAL_DECODE_CHK_NULL_RETURN(avcSliceState->pAvcPicParams);
54 CODECHAL_DECODE_CHK_NULL_RETURN(avcSliceState->pAvcSliceParams);
55
56 PCODEC_AVC_PIC_PARAMS avcPicParams = avcSliceState->pAvcPicParams;
57 PCODEC_AVC_SLICE_PARAMS slc = avcSliceState->pAvcSliceParams;
58
59 avcSliceState->ucDisableDeblockingFilterIdc = slc->disable_deblocking_filter_idc;
60 avcSliceState->ucSliceBetaOffsetDiv2 = slc->slice_beta_offset_div2;
61 avcSliceState->ucSliceAlphaC0OffsetDiv2 = slc->slice_alpha_c0_offset_div2;
62
63 if (avcSliceState->bShortFormatInUse)
64 {
65 // send slice address except last one
66 if (!avcSliceState->bLastSlice)
67 {
68 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdAvcSliceAddrCmd(
69 cmdBuffer,
70 avcSliceState));
71 }
72 }
73 else
74 {
75 MHW_VDBOX_AVC_REF_IDX_PARAMS refIdxParams;
76 MOS_ZeroMemory(&refIdxParams, sizeof(MHW_VDBOX_AVC_REF_IDX_PARAMS));
77
78 if (!m_mfxInterface->IsAvcISlice(slc->slice_type))
79 {
80 refIdxParams.CurrPic = avcPicParams->CurrPic;
81 refIdxParams.uiList = LIST_0;
82 refIdxParams.uiNumRefForList[LIST_0] = slc->num_ref_idx_l0_active_minus1 + 1;
83
84 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(MOS_SecureMemcpy(
85 &refIdxParams.RefPicList,
86 sizeof(refIdxParams.RefPicList),
87 &slc->RefPicList,
88 sizeof(slc->RefPicList)),
89 "Failed to copy memory");
90
91 refIdxParams.pAvcPicIdx = avcSliceState->pAvcPicIdx;
92 refIdxParams.avcRefList = (void**)m_avcRefList;
93 refIdxParams.bIntelEntrypointInUse = avcSliceState->bIntelEntrypointInUse;
94 refIdxParams.bPicIdRemappingInUse = avcSliceState->bPicIdRemappingInUse;
95
96 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcRefIdx(cmdBuffer, nullptr, &refIdxParams));
97
98 MHW_VDBOX_AVC_WEIGHTOFFSET_PARAMS weightOffsetParams;
99
100 if (m_mfxInterface->IsAvcPSlice(slc->slice_type) &&
101 avcPicParams->pic_fields.weighted_pred_flag == 1)
102 {
103 weightOffsetParams.uiList = 0;
104 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(MOS_SecureMemcpy(
105 &weightOffsetParams.Weights,
106 sizeof(weightOffsetParams.Weights),
107 &slc->Weights,
108 sizeof(slc->Weights)),
109 "Failed to copy memory");
110
111 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcWeightOffset(cmdBuffer, nullptr, &weightOffsetParams));
112 }
113
114 if (m_mfxInterface->IsAvcBSlice(slc->slice_type))
115 {
116 refIdxParams.uiList = LIST_1;
117 refIdxParams.uiNumRefForList[LIST_1] = slc->num_ref_idx_l1_active_minus1 + 1;
118 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcRefIdx(cmdBuffer, nullptr, &refIdxParams));
119
120 if (avcPicParams->pic_fields.weighted_bipred_idc == 1)
121 {
122 weightOffsetParams.uiList = 0;
123 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(MOS_SecureMemcpy(
124 &weightOffsetParams.Weights,
125 sizeof(weightOffsetParams.Weights),
126 &slc->Weights,
127 sizeof(slc->Weights)),
128 "Failed to copy memory");
129
130 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcWeightOffset(cmdBuffer, nullptr, &weightOffsetParams));
131 weightOffsetParams.uiList = 1;
132 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcWeightOffset(cmdBuffer, nullptr, &weightOffsetParams));
133 }
134 }
135 }
136 else if (MEDIA_IS_WA(m_waTable, WaDummyReference) && !m_osInterface->bSimIsActive)
137 {
138 MHW_VDBOX_AVC_REF_IDX_PARAMS refIdxParams;
139 MOS_ZeroMemory(&refIdxParams, sizeof(MHW_VDBOX_AVC_REF_IDX_PARAMS));
140 refIdxParams.bDummyReference = true;
141 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcRefIdx(cmdBuffer, nullptr, &refIdxParams));
142 }
143
144 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcSlice(cmdBuffer, nullptr, avcSliceState));
145 }
146
147 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdAvcBsdObjectCmd(
148 cmdBuffer,
149 avcSliceState));
150
151 return eStatus;
152 }
153
FormatAvcMonoPicture(PMOS_SURFACE surface)154 MOS_STATUS CodechalDecodeAvc::FormatAvcMonoPicture(PMOS_SURFACE surface)
155 {
156 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
157
158 PCODEC_AVC_PIC_PARAMS picParams = (PCODEC_AVC_PIC_PARAMS)m_avcPicParams;
159 if (picParams->seq_fields.chroma_format_idc != avcChromaFormatMono)
160 {
161 return MOS_STATUS_SUCCESS;
162 }
163
164 MOS_SURFACE dstSurface;
165 MOS_ZeroMemory(&dstSurface, sizeof(MOS_SURFACE));
166 dstSurface.Format = Format_NV12;
167 if(surface != nullptr && !Mos_ResourceIsNull(&surface->OsResource))
168 {
169 dstSurface.OsResource = surface->OsResource;
170 }
171 else
172 {
173 CODECHAL_DECODE_ASSERTMESSAGE("Surface pointer is NULL!");
174 return MOS_STATUS_INVALID_PARAMETER;
175 }
176 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, &dstSurface));
177
178 uint32_t height = dstSurface.dwHeight;
179 uint32_t pitch = dstSurface.dwPitch;
180 uint32_t chromaHeight = height / 2;
181 uint32_t frameHeight = MOS_ALIGN_CEIL(height, 16);
182 uint32_t alignedFrameHeight = MOS_ALIGN_CEIL(frameHeight, MOS_YTILE_H_ALIGNMENT);
183 uint32_t alignedChromaHeight = MOS_ALIGN_CEIL(chromaHeight, MOS_YTILE_H_ALIGNMENT);
184 uint32_t frameSize = pitch * MOS_ALIGN_CEIL((frameHeight + chromaHeight), MOS_YTILE_H_ALIGNMENT);
185 uint32_t chromaBufSize = MOS_ALIGN_CEIL(pitch * alignedChromaHeight, MHW_PAGE_SIZE);
186
187 if (Mos_ResourceIsNull(&m_resMonoPictureChromaBuffer))
188 {
189 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
190 &m_resMonoPictureChromaBuffer,
191 chromaBufSize,
192 "MonoPictureChromaBuffer",
193 true,
194 CODECHAL_DECODE_AVC_MONOPIC_CHROMA_DEFAULT),
195 "Failed to allocate MonoPicture Chroma Buffer.");
196 }
197
198 MOS_COMMAND_BUFFER cmdBuffer;
199 CodechalHucStreamoutParams hucStreamOutParams;
200 if (!m_hwInterface->m_noHuC)
201 {
202 m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContextForWa);
203 m_osInterface->pfnResetOsStates(m_osInterface);
204
205 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
206
207 CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(&cmdBuffer, false));
208
209 // use huc stream out to do clear to clear copy
210
211 MOS_ZeroMemory(&hucStreamOutParams, sizeof(hucStreamOutParams));
212 hucStreamOutParams.dataBuffer = &m_resMonoPictureChromaBuffer;
213 hucStreamOutParams.streamOutObjectBuffer = &surface->OsResource;
214 }
215
216 uint32_t uvblockHeight = CODECHAL_MACROBLOCK_HEIGHT;
217 uint32_t uvrowSize = pitch * uvblockHeight * 2;
218
219 uint32_t dstOffset = 0, x = 0, uvsize = 0;
220 if (frameHeight % MOS_YTILE_H_ALIGNMENT)
221 {
222 dstOffset = LinearToYTiledAddress(x, frameHeight, pitch);
223
224 if (m_hwInterface->m_noHuC)
225 {
226 CodechalDataCopyParams dataCopyParams;
227 MOS_ZeroMemory(&dataCopyParams, sizeof(CodechalDataCopyParams));
228 dataCopyParams.srcResource = &m_resMonoPictureChromaBuffer;
229 dataCopyParams.srcSize = uvrowSize;
230 dataCopyParams.srcOffset = 0;
231 dataCopyParams.dstResource = &surface->OsResource;
232 dataCopyParams.dstSize = frameSize;
233 dataCopyParams.dstOffset = dstOffset;
234
235 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->CopyDataSourceWithDrv(&dataCopyParams));
236 }
237 else
238 {
239 CODECHAL_DECODE_CHK_STATUS_RETURN(HucCopy(
240 &cmdBuffer, // pCmdBuffer
241 &m_resMonoPictureChromaBuffer, // presSrc
242 &surface->OsResource, // presDst
243 uvrowSize, // u32CopyLength
244 0, // u32CopyInputOffset
245 dstOffset)); // u32CopyOutputOffset
246 }
247 }
248
249 dstOffset = dstSurface.UPlaneOffset.iSurfaceOffset;
250 uvsize = frameSize - pitch * alignedFrameHeight;
251
252 if (m_hwInterface->m_noHuC)
253 {
254 CodechalDataCopyParams dataCopyParams;
255 MOS_ZeroMemory(&dataCopyParams, sizeof(CodechalDataCopyParams));
256 dataCopyParams.srcResource = &m_resMonoPictureChromaBuffer;
257 dataCopyParams.srcSize = uvsize;
258 dataCopyParams.srcOffset = 0;
259 dataCopyParams.dstResource = &surface->OsResource;
260 dataCopyParams.dstSize = frameSize;
261 dataCopyParams.dstOffset = dstOffset;
262
263 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->CopyDataSourceWithDrv(&dataCopyParams));
264 }
265 else
266 {
267 CODECHAL_DECODE_CHK_STATUS_RETURN(HucCopy(
268 &cmdBuffer, // pCmdBuffer
269 &m_resMonoPictureChromaBuffer, // presSrc
270 &surface->OsResource, // presDst
271 uvsize, // u32CopyLength
272 0, // u32CopyInputOffset
273 dstOffset)); // u32CopyOutputOffset
274
275 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
276 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
277 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(&cmdBuffer, &flushDwParams));
278
279 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
280
281 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
282
283 MOS_SYNC_PARAMS syncParams;
284
285 syncParams = g_cInitSyncParams;
286 syncParams.GpuContext = m_videoContext;
287 syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
288
289 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
290
291 syncParams = g_cInitSyncParams;
292 syncParams.GpuContext = m_videoContextForWa;
293 syncParams.presSyncResource = &m_resSyncObjectVideoContextInUse;
294
295 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
296
297 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_videoContextUsesNullHw));
298
299 m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContext);
300 }
301
302 return eStatus;
303 }
304
AllocateInvalidRefBuffer()305 MOS_STATUS CodechalDecodeAvc::AllocateInvalidRefBuffer()
306 {
307 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
308
309 //AlloctateResource
310 if (Mos_ResourceIsNull(&m_resInvalidRefBuffer))
311 {
312 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(m_osInterface, &m_destSurface));
313
314 MOS_MEMCOMP_STATE mmcMode = MOS_MEMCOMP_DISABLED;
315 #ifdef _MMC_SUPPORTED
316 if(m_mmc != nullptr && m_mmc->IsMmcEnabled())
317 {
318 CODECHAL_DECODE_CHK_STATUS_RETURN(
319 m_osInterface->pfnGetMemoryCompressionMode(
320 m_osInterface,
321 &m_destSurface.OsResource,
322 &mmcMode));
323 }
324 #endif
325
326 MOS_SURFACE surface;
327 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateSurface(
328 &surface,
329 m_destSurface.dwPitch,
330 m_destSurface.dwHeight,
331 "InvalidRefBuffer",
332 Format_NV12,
333 mmcMode != MOS_MEMCOMP_DISABLED ? true : false),
334 "Failed to allocate invalid reference buffer.");
335 m_resInvalidRefBuffer = surface.OsResource;
336
337 // set all the pixels to 1<<(BitDepth-1) according to the AVC spec
338 CodechalResLock ResourceLock(m_osInterface, &m_resInvalidRefBuffer);
339 auto data = (uint8_t*)ResourceLock.Lock(CodechalResLock::writeOnly);
340 CODECHAL_DECODE_CHK_NULL_RETURN(data);
341
342 uint32_t size = m_destSurface.dwPitch * m_destSurface.dwHeight * 3 / 2;
343 MOS_FillMemory(data, size, CODECHAL_DECODE_AVC_INVALID_REFPIC_VALUE); //INVALID_REFPIC_VALUE = 1<<(8-1): Intel Graphic only support 8bit AVC output now.
344 }
345
346 return eStatus;
347 }
348
SetAndAllocateDmvBufferIndex(PCODEC_AVC_DMV_LIST avcMVBufList,bool usedForRef,uint8_t frameIdx,uint32_t avcDmvBufferSize,uint8_t * dmvIdx,MOS_RESOURCE * avcDmvBuffers)349 MOS_STATUS CodechalDecodeAvc::SetAndAllocateDmvBufferIndex(
350 PCODEC_AVC_DMV_LIST avcMVBufList,
351 bool usedForRef,
352 uint8_t frameIdx,
353 uint32_t avcDmvBufferSize,
354 uint8_t *dmvIdx,
355 MOS_RESOURCE *avcDmvBuffers)
356 {
357 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
358
359 CODECHAL_DECODE_CHK_NULL_RETURN(avcMVBufList);
360 CODECHAL_DECODE_CHK_NULL_RETURN(dmvIdx);
361 CODECHAL_DECODE_CHK_NULL_RETURN(avcDmvBuffers);
362
363 uint8_t index = 0;
364 if (usedForRef)
365 {
366 uint8_t i;
367 for (i = 0; i < CODEC_AVC_NUM_REF_DMV_BUFFERS; i++)
368 {
369 if (!avcMVBufList[i].bInUse)
370 {
371 index = i;
372 avcMVBufList[i].bInUse = true;
373 avcMVBufList[i].ucFrameId = frameIdx;
374 break;
375 }
376 }
377 if (i == CODEC_AVC_NUM_REF_DMV_BUFFERS)
378 {
379 // Should never happen, something must be wrong
380 CODECHAL_DECODE_ASSERTMESSAGE("No DMV Buffer found.");
381 eStatus = MOS_STATUS_INVALID_PARAMETER;
382 return eStatus;
383 }
384 }
385 else
386 {
387 index = CODEC_AVC_NUM_REF_DMV_BUFFERS;
388 }
389
390 if (Mos_ResourceIsNull(&avcDmvBuffers[index]))
391 {
392 // Allocate DMV buffer if it has not been allocated already.
393 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
394 &avcDmvBuffers[index],
395 avcDmvBufferSize,
396 "MvBuffer",
397 true),
398 "Failed to allocate MV Buffer.");
399 }
400
401 *dmvIdx = index;
402 return eStatus;
403 }
404
405
SetAndAllocateDmvBufferIndexMismatched(uint8_t frameIdx,uint32_t avcDmvBufferSize,uint8_t * dmvIdx,MOS_RESOURCE * avcDmvBuffers)406 MOS_STATUS CodechalDecodeAvc::SetAndAllocateDmvBufferIndexMismatched(
407 uint8_t frameIdx,
408 uint32_t avcDmvBufferSize,
409 uint8_t *dmvIdx,
410 MOS_RESOURCE *avcDmvBuffers)
411 {
412 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
413
414 CODECHAL_DECODE_CHK_NULL_RETURN(dmvIdx);
415 CODECHAL_DECODE_CHK_NULL_RETURN(avcDmvBuffers);
416
417 uint8_t index = frameIdx;
418
419 if (Mos_ResourceIsNull(&avcDmvBuffers[index]))
420 {
421 // Allocate DMV buffer if it has not been allocated already.
422 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
423 &avcDmvBuffers[index],
424 avcDmvBufferSize,
425 "MvBuffer",
426 true),
427 "Failed to allocate MV Buffer.");
428 }
429
430 *dmvIdx = index;
431 return eStatus;
432 }
433
InitMvcDummyDmvBuffer(uint32_t * mvcWaDummyDmvBuf,uint32_t size,PMOS_RESOURCE mvcDummyDmvBuffer)434 MOS_STATUS CodechalDecodeAvc::InitMvcDummyDmvBuffer(
435 uint32_t *mvcWaDummyDmvBuf,
436 uint32_t size,
437 PMOS_RESOURCE mvcDummyDmvBuffer)
438 {
439 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
440
441 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
442 mvcDummyDmvBuffer,
443 size,
444 "MvBuffer"),
445 "Failed to allocate WA Mvc Dummy DMV Buffer.");
446
447 uint8_t *dummyDmvBuffer = nullptr, *mbDmvBuffer = nullptr;
448 CODECHAL_DECODE_CHK_NULL_RETURN(dummyDmvBuffer = (uint8_t*)MOS_AllocAndZeroMemory(size));
449 mbDmvBuffer = dummyDmvBuffer;
450
451 uint32_t i, numMBs = size / 64;
452 for (i = 0; i<numMBs; i++)
453 {
454 eStatus = (MOS_STATUS)MOS_SecureMemcpy(mbDmvBuffer, 64, mvcWaDummyDmvBuf, 64);
455 if (eStatus != MOS_STATUS_SUCCESS)
456 {
457 MOS_SafeFreeMemory(dummyDmvBuffer);
458 CODECHAL_DECODE_CHK_STATUS_RETURN(eStatus);
459 }
460 mbDmvBuffer += 64;
461 }
462
463 CodechalResLock ResourceLock(m_osInterface, mvcDummyDmvBuffer);
464 auto data = (uint8_t*)ResourceLock.Lock(CodechalResLock::writeOnly);
465
466 if (data == nullptr)
467 {
468 MOS_FreeMemory(dummyDmvBuffer);
469 CODECHAL_DECODE_CHK_NULL_RETURN(nullptr);
470 }
471
472 eStatus = (MOS_STATUS)MOS_SecureMemcpy(data, size, (void*)dummyDmvBuffer, size);
473 if (eStatus != MOS_STATUS_SUCCESS)
474 {
475 MOS_SafeFreeMemory(dummyDmvBuffer);
476 CODECHAL_DECODE_CHK_STATUS_RETURN(eStatus);
477 }
478
479 MOS_FreeMemAndSetNull(dummyDmvBuffer);
480 return eStatus;
481 }
482
SetPictureStructs()483 MOS_STATUS CodechalDecodeAvc::SetPictureStructs()
484 {
485 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
486
487 CODECHAL_DECODE_FUNCTION_ENTER;
488
489 PCODEC_AVC_PIC_PARAMS picParams = m_avcPicParams;
490 CODEC_PICTURE prevPic = m_currPic;
491 CODEC_PICTURE currPic = picParams->CurrPic;
492
493 uint8_t i, ii;
494 if (picParams->pic_fields.field_pic_flag)
495 {
496 // Note: The AVC criteria of second field following first field is not compatible with MVC.
497 // For MVC compatibility, a buffer of 16 frame indexes are used to store
498 // the consecutive first fiels of different views in the same Acess Unit.
499 ii = CODECHAL_DECODE_AVC_MAX_NUM_MVC_VIEWS;
500 // Find if the current field is a second field (no matching first field)
501 for (i = 0; i < CODECHAL_DECODE_AVC_MAX_NUM_MVC_VIEWS; i++)
502 {
503 if (m_firstFieldIdxList[i] == currPic.FrameIdx)
504 {
505 break;
506 }
507 // At the same time, find the first empty entrance to store the frame index.
508 // Used when the current field is a first field.
509 ii = (m_firstFieldIdxList[i] == CODECHAL_DECODE_AVC_INVALID_FRAME_IDX && ii == CODECHAL_DECODE_AVC_MAX_NUM_MVC_VIEWS) ? i : ii;
510 }
511
512 if ((prevPic.PicFlags != currPic.PicFlags) || (prevPic.FrameIdx != currPic.FrameIdx) || (currPic.PicFlags == PICTURE_INVALID))
513 {
514 if (i < CODECHAL_DECODE_AVC_MAX_NUM_MVC_VIEWS)
515 {
516 m_isSecondField = true;
517 m_firstFieldIdxList[i] = CODECHAL_DECODE_AVC_INVALID_FRAME_IDX;
518 while (i > 0) // Clear all smaller indexes in case there are missing fields.
519 {
520 m_firstFieldIdxList[--i] = CODECHAL_DECODE_AVC_INVALID_FRAME_IDX;
521 }
522 }
523 else
524 {
525 m_isSecondField = false;
526 if (ii == CODECHAL_DECODE_AVC_MAX_NUM_MVC_VIEWS)
527 {
528 ii = 0;
529 }
530 else
531 {
532 m_firstFieldIdxList[ii++] = currPic.FrameIdx;
533 }
534 // Clear all larger indexes in case there are missing fields.
535 while (ii < CODECHAL_DECODE_AVC_MAX_NUM_MVC_VIEWS)
536 {
537 m_firstFieldIdxList[ii++] = CODECHAL_DECODE_AVC_INVALID_FRAME_IDX;
538 }
539 }
540 }
541
542 m_height =
543 MOS_ALIGN_CEIL(m_height, MOS_YTILE_H_ALIGNMENT);
544 }
545 else
546 {
547 for (i = 0; i < CODECHAL_DECODE_AVC_MAX_NUM_MVC_VIEWS; i++)
548 {
549 m_firstFieldIdxList[i] = CODECHAL_DECODE_AVC_INVALID_FRAME_IDX;
550 }
551 m_isSecondField = false;
552 }
553
554 m_statusReportFeedbackNumber = picParams->StatusReportFeedbackNumber;
555 m_currPic = currPic;
556 m_avcRefList[currPic.FrameIdx]->RefPic = m_currPic;
557 m_avcRefList[currPic.FrameIdx]->resRefPic = m_destSurface.OsResource;
558
559 // Override reference list with ref surface passed from DDI
560 uint8_t surfCount = 0;
561 uint8_t surfIndex = 0;
562 if (m_osInterface->pfnIsMismatchOrderProgrammingSupported())
563 {
564 while (surfIndex < CODEC_AVC_NUM_UNCOMPRESSED_SURFACE)
565 {
566 if (!Mos_ResourceIsNull(&m_refFrameSurface[surfIndex].OsResource))
567 {
568 m_avcRefList[surfIndex]->resRefPic = m_refFrameSurface[surfIndex].OsResource;
569 }
570 surfIndex++;
571 }
572 }
573 else
574 {
575 while (surfCount < m_refSurfaceNum && surfIndex < CODEC_AVC_NUM_UNCOMPRESSED_SURFACE)
576 {
577 if (!Mos_ResourceIsNull(&m_refFrameSurface[surfIndex].OsResource))
578 {
579 m_avcRefList[surfIndex]->resRefPic = m_refFrameSurface[surfIndex].OsResource;
580 surfCount++;
581 }
582 surfIndex++;
583 }
584 }
585
586 uint8_t index, duplicatedIdx;
587 for (i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
588 {
589 if (!CodecHal_PictureIsInvalid(picParams->RefFrameList[i]))
590 {
591 index = picParams->RefFrameList[i].FrameIdx;
592 m_avcRefList[index]->sFrameNumber = picParams->FrameNumList[i];
593 }
594 }
595
596 PCODEC_AVC_DMV_LIST avcMVBufList = &m_avcDmvList[0];
597 uint8_t dmvidx;
598 if (!CodecHal_PictureIsInvalid(prevPic))
599 {
600 for (i = 0; i < CODEC_AVC_NUM_REF_DMV_BUFFERS; i++)
601 {
602 avcMVBufList[i].bInUse = false;
603 }
604 for (i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
605 {
606 if (!CodecHal_PictureIsInvalid(picParams->RefFrameList[i]))
607 {
608 index = picParams->RefFrameList[i].FrameIdx;
609 avcMVBufList[m_avcRefList[index]->ucDMVIdx[0]].bInUse = true;
610 avcMVBufList[m_avcRefList[index]->ucDMVIdx[1]].bInUse = true;
611 }
612 }
613 }
614 else if (m_avcRefList[currPic.FrameIdx]->bUsedAsRef && !m_isSecondField)
615 {
616 dmvidx = m_avcRefList[currPic.FrameIdx]->ucFrameId;
617 if (m_avcFrameStoreId[dmvidx].reUse)
618 {
619 m_avcFrameStoreId[dmvidx].reUse = false;
620 }
621 else
622 {
623 m_avcFrameStoreId[dmvidx].inUse = false;
624 }
625
626 dmvidx = m_avcRefList[currPic.FrameIdx]->ucDMVIdx[0];
627 if (m_avcDmvList[dmvidx].bReUse)
628 {
629 m_avcDmvList[dmvidx].bReUse = false;
630 }
631 else
632 {
633 m_avcDmvList[dmvidx].bInUse = false;
634 }
635 dmvidx = m_avcRefList[currPic.FrameIdx]->ucDMVIdx[1];
636 if (m_avcDmvList[dmvidx].bReUse)
637 {
638 m_avcDmvList[dmvidx].bReUse = false;
639 }
640 else
641 {
642 m_avcDmvList[dmvidx].bInUse = false;
643 }
644 }
645
646 if (picParams->pic_fields.reference_pic_flag)
647 {
648 if (!m_isSecondField)
649 {
650 m_avcRefList[currPic.FrameIdx]->bUsedAsRef = true;
651 }
652 }
653 else
654 {
655 m_avcRefList[currPic.FrameIdx]->bUsedAsRef = false;
656 }
657
658 if (!m_isSecondField)
659 {
660 if (m_osInterface->pfnIsMismatchOrderProgrammingSupported())
661 {
662 for (i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
663 {
664 auto frameIdx = picParams->RefFrameList[i].FrameIdx;
665 if (frameIdx != CODECHAL_NUM_UNCOMPRESSED_SURFACE_HEVC)
666 {
667 CODECHAL_DECODE_CHK_STATUS_RETURN(SetAndAllocateDmvBufferIndexMismatched(
668 frameIdx,
669 m_avcDmvBufferSize,
670 &m_avcMvBufferIndex,
671 m_resAvcDmvBuffers));
672 dmvidx = m_avcMvBufferIndex;
673 m_avcRefList[frameIdx]->ucDMVIdx[0] = dmvidx;
674 m_avcRefList[frameIdx]->ucDMVIdx[1] = dmvidx;
675 }
676 }
677 CODECHAL_DECODE_CHK_STATUS_RETURN(SetAndAllocateDmvBufferIndexMismatched(
678 currPic.FrameIdx,
679 m_avcDmvBufferSize,
680 &m_avcMvBufferIndex,
681 m_resAvcDmvBuffers));
682 dmvidx = m_avcMvBufferIndex;
683
684 //first and second field will use the same DMV buffer in field mode
685 m_avcRefList[currPic.FrameIdx]->ucDMVIdx[0] = dmvidx;
686 m_avcRefList[currPic.FrameIdx]->ucDMVIdx[1] = dmvidx;
687 }
688 else
689 {
690 CODECHAL_DECODE_CHK_STATUS_RETURN(SetAndAllocateDmvBufferIndex(
691 &m_avcDmvList[0],
692 (bool)picParams->pic_fields.reference_pic_flag,
693 currPic.FrameIdx,
694 m_avcDmvBufferSize,
695 &m_avcMvBufferIndex,
696 m_resAvcDmvBuffers));
697
698 dmvidx = m_avcMvBufferIndex;
699
700 //first and second field will use the same DMV buffer in field mode
701 m_avcRefList[currPic.FrameIdx]->ucDMVIdx[0] = dmvidx;
702 m_avcRefList[currPic.FrameIdx]->ucDMVIdx[1] = dmvidx;
703 }
704 }
705 else
706 {
707 dmvidx = m_avcRefList[currPic.FrameIdx]->ucDMVIdx[1];
708 m_avcMvBufferIndex = dmvidx;
709 }
710
711 m_avcDmvList[dmvidx].ucFrameId = currPic.FrameIdx;
712
713 for (i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
714 {
715 m_avcFrameStoreId[i].inUse = false;
716 }
717
718 PCODEC_PIC_ID picIdx = &m_avcPicIdx[0];
719 bool invalidRef = false;
720 for (i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
721 {
722 picIdx[i].bValid = false;
723 index = picParams->RefFrameList[i].FrameIdx;
724
725 if (!CodecHal_PictureIsInvalid(picParams->RefFrameList[i]))
726 {
727 if (Mos_ResourceIsNull(&(m_avcRefList[index]->resRefPic)))
728 {
729 // when I picture has invalid reference pictures, reallocate resource for the referecnce pictures.
730 if (picParams->pic_fields.IntraPicFlag)
731 {
732 eStatus = AllocateInvalidRefBuffer();
733 if (eStatus != MOS_STATUS_SUCCESS)
734 {
735 invalidRef = true;
736 CODECHAL_DECODE_ASSERTMESSAGE("Can not allocate Invalid Ref Buffer.");
737 continue;
738 }
739
740 m_avcRefList[index]->RefPic = picParams->RefFrameList[i];
741 m_avcRefList[index]->resRefPic = m_resInvalidRefBuffer;
742 m_avcRefList[index]->bUsedAsRef = true;
743 m_avcRefList[index]->ucDMVIdx[0] = m_avcRefList[currPic.FrameIdx]->ucDMVIdx[0];
744 m_avcRefList[index]->ucDMVIdx[1] = m_avcRefList[currPic.FrameIdx]->ucDMVIdx[1];
745 }
746 else
747 {
748 invalidRef = false;
749 CODECHAL_DECODE_ASSERTMESSAGE("Found Invalid Ref.");
750 continue;
751 }
752 }
753
754 duplicatedIdx = 0;
755 for (ii = 0; ii < i; ii++)
756 {
757 if (picIdx[ii].bValid && index == picParams->RefFrameList[ii].FrameIdx)
758 {
759 duplicatedIdx = 1;
760 break;
761 }
762 }
763 if (duplicatedIdx)
764 {
765 continue;
766 }
767
768 m_avcRefList[index]->RefPic.PicFlags =
769 CodecHal_CombinePictureFlags(m_avcRefList[index]->RefPic, picParams->RefFrameList[i]);
770 m_avcRefList[index]->iFieldOrderCnt[0] = picParams->FieldOrderCntList[i][0];
771 m_avcRefList[index]->iFieldOrderCnt[1] = picParams->FieldOrderCntList[i][1];
772
773 picIdx[i].bValid = true;
774 picIdx[i].ucPicIdx = index;
775
776 if (!CodecHal_PictureIsInvalid(prevPic) && !m_osInterface->pfnIsMismatchOrderProgrammingSupported())
777 {
778 for (ii = 0; ii < m_avcRefList[prevPic.FrameIdx]->ucNumRef; ii++)
779 {
780 if (index == m_avcRefList[prevPic.FrameIdx]->RefList[ii].FrameIdx)
781 {
782 if (m_avcRefList[index]->ucFrameId == 0x7f)
783 {
784 // Should never happen, something must be wrong
785 CODECHAL_DECODE_ASSERTMESSAGE("Invaid Ref Frame Id Found");
786 m_avcRefList[index]->ucFrameId = 0;
787 }
788 m_avcFrameStoreId[m_avcRefList[index]->ucFrameId].inUse = true;
789 break;
790 }
791 }
792 if (ii == m_avcRefList[prevPic.FrameIdx]->ucNumRef)
793 {
794 m_avcRefList[index]->ucFrameId = 0x7f;
795 }
796 }
797 else
798 {
799 m_avcDmvList[m_avcRefList[index]->ucDMVIdx[0]].ucFrameId =
800 m_avcDmvList[m_avcRefList[index]->ucDMVIdx[1]].ucFrameId =
801 m_avcRefList[index]->ucFrameId;
802 }
803 picIdx[i].ucDMVOffset[0] = m_avcRefList[index]->ucDMVIdx[0];
804 picIdx[i].ucDMVOffset[1] = m_avcRefList[index]->ucDMVIdx[1];
805 }
806 }
807
808 // Save the current RefList and corresponding reference frame flags
809 ii = 0;
810 uint16_t nonExistingFrameFlags = 0;
811 uint32_t usedForReferenceFlags = 0;
812 for (i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
813 {
814 if (picIdx[i].bValid)
815 {
816 m_avcRefList[currPic.FrameIdx]->RefList[ii] = picParams->RefFrameList[i];
817 nonExistingFrameFlags |= ((picParams->NonExistingFrameFlags >> i) & 1) << ii;
818 usedForReferenceFlags |= ((picParams->UsedForReferenceFlags >> (i * 2)) & 3) << (ii * 2);
819 ii++;
820 }
821 }
822 m_avcRefList[currPic.FrameIdx]->ucNumRef = ii;
823 m_avcRefList[currPic.FrameIdx]->usNonExistingFrameFlags = nonExistingFrameFlags;
824 m_avcRefList[currPic.FrameIdx]->uiUsedForReferenceFlags = usedForReferenceFlags;
825
826 if (m_osInterface->pfnIsMismatchOrderProgrammingSupported())
827 {
828 for (uint32_t ii = 0; ii < CODEC_AVC_NUM_UNCOMPRESSED_SURFACE; ii++)
829 {
830 m_avcRefList[ii]->ucFrameId = 0x7f;
831 }
832 }
833
834 SetFrameStoreIds(currPic.FrameIdx);
835
836 // Store CurrFieldOrderCnt
837 if (CodecHal_PictureIsBottomField(currPic))
838 {
839 m_avcRefList[currPic.FrameIdx]->iFieldOrderCnt[1] = picParams->CurrFieldOrderCnt[1];
840 }
841 else
842 {
843 m_avcRefList[currPic.FrameIdx]->iFieldOrderCnt[0] = picParams->CurrFieldOrderCnt[0];
844 if (CodecHal_PictureIsFrame(currPic))
845 {
846 m_avcRefList[currPic.FrameIdx]->iFieldOrderCnt[1] = picParams->CurrFieldOrderCnt[1];
847 }
848 }
849
850 //MVC related inter-view reference
851 m_avcRefList[currPic.FrameIdx]->bUsedAsInterViewRef = false;
852 if (m_mvcExtPicParams)
853 {
854 if (m_mvcExtPicParams->inter_view_flag)
855 {
856 m_avcRefList[currPic.FrameIdx]->bUsedAsInterViewRef = true;
857 }
858 }
859
860 if (invalidRef)
861 {
862 // There was an invalid reference, do not process the picture.
863 return MOS_STATUS_UNKNOWN;
864 }
865 else
866 {
867 return MOS_STATUS_SUCCESS;
868 }
869 }
870
AllocateResourcesVariableSizes()871 MOS_STATUS CodechalDecodeAvc::AllocateResourcesVariableSizes()
872 {
873 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
874
875 CODECHAL_DECODE_FUNCTION_ENTER;
876
877 PCODEC_AVC_PIC_PARAMS picParam = m_avcPicParams;
878 uint32_t numMacroblocks, numSliceRecords;
879 uint16_t picWidthInMB, picHeightInMB;
880 bool invalidSliceNum = false;
881 picWidthInMB = MOS_MAX(m_picWidthInMbLastMaxAlloced, (picParam->pic_width_in_mbs_minus1 + 1));
882 picHeightInMB = MOS_MAX(m_picHeightInMbLastMaxAlloced, (picParam->pic_height_in_mbs_minus1 + 1));
883 numMacroblocks = picWidthInMB * picHeightInMB;
884
885 numSliceRecords = numMacroblocks;
886 if (m_numSlices > numMacroblocks)
887 {
888 invalidSliceNum = true;
889 numSliceRecords = m_numSlices;
890 }
891
892 if ((numSliceRecords > (uint32_t)m_picWidthInMbLastMaxAlloced * m_picHeightInMbLastMaxAlloced) ||
893 (m_vldSliceRecord == nullptr))
894 {
895 if (m_vldSliceRecord != nullptr)
896 {
897 MOS_FreeMemory(m_vldSliceRecord);
898 }
899 m_vldSliceRecord =
900 (PCODECHAL_VLD_SLICE_RECORD)MOS_AllocAndZeroMemory(numSliceRecords * sizeof(CODECHAL_VLD_SLICE_RECORD));
901 if (m_vldSliceRecord == nullptr)
902 {
903 CODECHAL_DECODE_ASSERTMESSAGE("Failed to allocate memory.");
904 eStatus = MOS_STATUS_NO_SPACE;
905 return eStatus;
906 }
907 }
908
909 if (invalidSliceNum == true)
910 {
911 for (uint32_t i = 0; i < numSliceRecords; i++)
912 {
913 m_vldSliceRecord[i].dwSkip = true;
914 }
915 }
916
917 if ((picWidthInMB > m_picWidthInMbLastMaxAlloced) ||
918 Mos_ResourceIsNull(&m_resMfdDeblockingFilterRowStoreScratchBuffer))
919 {
920 if (!Mos_ResourceIsNull(&m_resMfdDeblockingFilterRowStoreScratchBuffer))
921 {
922 m_osInterface->pfnFreeResource(
923 m_osInterface,
924 &m_resMfdDeblockingFilterRowStoreScratchBuffer);
925 }
926
927 // Deblocking Filter Row Store Scratch buffer
928 //(Num MacroBlock Width) * (Num Cachlines) * (Cachline size)
929 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
930 &m_resMfdDeblockingFilterRowStoreScratchBuffer,
931 picWidthInMB * 4 * CODECHAL_CACHELINE_SIZE,
932 "DeblockingScratchBuffer"),
933 "Failed to allocate Deblocking Filter Row Store Scratch Buffer.");
934 }
935
936 if (m_mfxInterface->IsBsdMpcRowstoreCacheEnabled() == false)
937 {
938 uint16_t tempBsdMpcRowStoreScratchBufferPicWidthInMB;
939 tempBsdMpcRowStoreScratchBufferPicWidthInMB = MOS_MAX(m_bsdMpcRowStoreScratchBufferPicWidthInMb, (picParam->pic_width_in_mbs_minus1 + 1));
940
941 if ((tempBsdMpcRowStoreScratchBufferPicWidthInMB > m_bsdMpcRowStoreScratchBufferPicWidthInMb) ||
942 Mos_ResourceIsNull(&m_resBsdMpcRowStoreScratchBuffer))
943 {
944 if (!Mos_ResourceIsNull(&m_resBsdMpcRowStoreScratchBuffer))
945 {
946 m_osInterface->pfnFreeResource(
947 m_osInterface,
948 &m_resBsdMpcRowStoreScratchBuffer);
949 }
950 // BSD/MPC Row Store Scratch buffer
951 // (FrameWidth in MB) * (2) * (CacheLine size per MB)
952 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
953 &m_resBsdMpcRowStoreScratchBuffer,
954 tempBsdMpcRowStoreScratchBufferPicWidthInMB * 2 * CODECHAL_CACHELINE_SIZE,
955 "MpcScratchBuffer"),
956 "Failed to allocate BSD/MPC Row Store Scratch Buffer.");
957 }
958
959 //record the width and height used for allocation internal resources.
960 m_bsdMpcRowStoreScratchBufferPicWidthInMb = tempBsdMpcRowStoreScratchBufferPicWidthInMB;
961 }
962
963 if (m_mfxInterface->IsIntraRowstoreCacheEnabled() == false)
964 {
965 uint16_t tempMfdIntraRowStoreScratchBufferPicWidthInMB;
966 tempMfdIntraRowStoreScratchBufferPicWidthInMB = MOS_MAX(m_mfdIntraRowStoreScratchBufferPicWidthInMb, (picParam->pic_width_in_mbs_minus1 + 1));
967
968 if ((tempMfdIntraRowStoreScratchBufferPicWidthInMB > m_mfdIntraRowStoreScratchBufferPicWidthInMb) ||
969 Mos_ResourceIsNull(&m_resMfdIntraRowStoreScratchBuffer))
970 {
971 if (!Mos_ResourceIsNull(&m_resMfdIntraRowStoreScratchBuffer))
972 {
973 m_osInterface->pfnFreeResource(
974 m_osInterface,
975 &m_resMfdIntraRowStoreScratchBuffer);
976 }
977 // Intra Row Store Scratch buffer
978 // (FrameWidth in MB) * (CacheLine size per MB)
979 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
980 &m_resMfdIntraRowStoreScratchBuffer,
981 tempMfdIntraRowStoreScratchBufferPicWidthInMB * CODECHAL_CACHELINE_SIZE,
982 "IntraScratchBuffer"),
983 "Failed to allocate AVC BSD Intra Row Store Scratch Buffer.");
984 }
985
986 //record the width and height used for allocation internal resources.
987 m_mfdIntraRowStoreScratchBufferPicWidthInMb = tempMfdIntraRowStoreScratchBufferPicWidthInMB;
988 }
989
990 if (m_mfxInterface->IsMprRowstoreCacheEnabled() == false)
991 {
992 uint16_t tempMprRowStoreScratchBufferPicWidthInMB;
993 tempMprRowStoreScratchBufferPicWidthInMB = MOS_MAX(m_mprRowStoreScratchBufferPicWidthInMb, (picParam->pic_width_in_mbs_minus1 + 1));
994
995 if ((tempMprRowStoreScratchBufferPicWidthInMB > m_mprRowStoreScratchBufferPicWidthInMb) ||
996 Mos_ResourceIsNull(&m_resMprRowStoreScratchBuffer))
997 {
998 if (!Mos_ResourceIsNull(&m_resMprRowStoreScratchBuffer))
999 {
1000 m_osInterface->pfnFreeResource(
1001 m_osInterface,
1002 &m_resMprRowStoreScratchBuffer);
1003 }
1004 // MPR Row Store Scratch buffer
1005 // (FrameWidth in MB) * (CacheLine size per MB) * 2
1006 // IVB+ platforms need to have double MPR size for MBAFF
1007 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
1008 &m_resMprRowStoreScratchBuffer,
1009 tempMprRowStoreScratchBufferPicWidthInMB * CODECHAL_CACHELINE_SIZE * 2,
1010 "MprScratchBuffer"),
1011 "Failed to allocate AVC BSD MPR Row Store Scratch Buffer.");
1012 }
1013
1014 //record the width and height used for allocation internal resources.
1015 m_mprRowStoreScratchBufferPicWidthInMb = tempMprRowStoreScratchBufferPicWidthInMB;
1016 }
1017
1018 uint32_t ctr;
1019 if ((picWidthInMB > m_picWidthInMbLastMaxAlloced) ||
1020 (picHeightInMB > m_picHeightInMbLastMaxAlloced) ||
1021 (m_avcDmvBufferSize == 0))
1022 {
1023 uint32_t maxMvBuf = m_osInterface->pfnIsMismatchOrderProgrammingSupported() ?
1024 CODEC_AVC_NUM_UNCOMPRESSED_SURFACE :
1025 CODEC_AVC_NUM_DMV_BUFFERS;
1026 for (ctr = 0; ctr < maxMvBuf; ctr++)
1027 {
1028 if (!Mos_ResourceIsNull(&m_resAvcDmvBuffers[ctr]))
1029 {
1030 m_osInterface->pfnFreeResource(
1031 m_osInterface,
1032 &m_resAvcDmvBuffers[ctr]);
1033 }
1034 }
1035
1036 // AVC MV buffer, 64 bytes per MB
1037 m_avcDmvBufferSize =
1038 64 * picWidthInMB * (uint32_t)(MOS_ALIGN_CEIL(picHeightInMB, 2));
1039
1040 for (ctr = 0; ctr < 4; ctr++)
1041 {
1042 // Allocate first 3 ref DMV buffers and then grow as needed, always
1043 // allocate the last DMV buffer which is used for non referenced pictures.
1044 if (ctr == 3)
1045 {
1046 ctr = CODEC_AVC_NUM_DMV_BUFFERS - 1;
1047 }
1048
1049 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
1050 &m_resAvcDmvBuffers[ctr],
1051 m_avcDmvBufferSize,
1052 "MvBuffer",
1053 true),
1054 "Failed to allocate Linux WA AVC BSD MV Buffer.");
1055 }
1056 }
1057
1058 if (m_secureDecoder)
1059 {
1060 CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->AllocateResource(this));
1061 }
1062
1063 //record the width and height used for allocation internal resources.
1064 m_picWidthInMbLastMaxAlloced = picWidthInMB;
1065 m_picHeightInMbLastMaxAlloced = picHeightInMB;
1066
1067 return eStatus;
1068 }
1069
AllocateResourcesFixedSizes()1070 MOS_STATUS CodechalDecodeAvc::AllocateResourcesFixedSizes()
1071 {
1072 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1073
1074 CODECHAL_DECODE_FUNCTION_ENTER;
1075
1076 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateSyncResource(
1077 m_osInterface,
1078 &m_resSyncObjectWaContextInUse));
1079
1080 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateSyncResource(
1081 m_osInterface,
1082 &m_resSyncObjectVideoContextInUse));
1083
1084 MOS_LOCK_PARAMS lockFlagsWriteOnly;
1085 MOS_ZeroMemory(&lockFlagsWriteOnly, sizeof(MOS_LOCK_PARAMS));
1086 lockFlagsWriteOnly.WriteOnly = 1;
1087
1088 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalAllocateDataList(
1089 m_avcRefList,
1090 CODEC_AVC_NUM_UNCOMPRESSED_SURFACE));
1091
1092 m_currPic.PicFlags = PICTURE_INVALID;
1093 m_currPic.FrameIdx = CODEC_AVC_NUM_UNCOMPRESSED_SURFACE;
1094
1095 return eStatus;
1096 }
1097
InitMmcState()1098 MOS_STATUS CodechalDecodeAvc::InitMmcState()
1099 {
1100 #ifdef _MMC_SUPPORTED
1101 m_mmc = MOS_New(CodechalMmcDecodeAvc, m_hwInterface, this);
1102 CODECHAL_DECODE_CHK_NULL_RETURN(m_mmc);
1103 #endif
1104 return MOS_STATUS_SUCCESS;
1105 }
1106
InitSfcState()1107 MOS_STATUS CodechalDecodeAvc::InitSfcState()
1108 {
1109 #ifdef _DECODE_PROCESSING_SUPPORTED
1110 m_sfcState = MOS_New(CodechalAvcSfcState);
1111 CODECHAL_DECODE_CHK_NULL_RETURN(m_sfcState);
1112 CODECHAL_DECODE_CHK_STATUS_RETURN(m_sfcState->InitializeSfcState(
1113 this,
1114 m_hwInterface,
1115 m_osInterface));
1116 #endif
1117 return MOS_STATUS_SUCCESS;
1118 }
1119
AllocateStandard(CodechalSetting * settings)1120 MOS_STATUS CodechalDecodeAvc::AllocateStandard(
1121 CodechalSetting *settings)
1122 {
1123 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1124
1125 CODECHAL_DECODE_FUNCTION_ENTER;
1126
1127 CODECHAL_DECODE_CHK_NULL_RETURN(settings);
1128
1129 CODECHAL_DECODE_CHK_STATUS_RETURN(InitMmcState());
1130
1131 if (settings->downsamplingHinted)
1132 {
1133 bool isComputeContextEnabled = false;
1134 MOS_GPUCTX_CREATOPTIONS createOption;
1135
1136 #if (_DEBUG || _RELEASE_INTERNAL)
1137 MOS_USER_FEATURE_VALUE_DATA userFeatureData;
1138 MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
1139 MOS_UserFeature_ReadValue_ID(
1140 nullptr,
1141 __MEDIA_USER_FEATURE_VALUE_DECODE_ENABLE_COMPUTE_CONTEXT_ID,
1142 &userFeatureData,
1143 m_osInterface->pOsContext);
1144 isComputeContextEnabled = (userFeatureData.u32Data) ? true : false;
1145 #endif
1146
1147 if (!MEDIA_IS_SKU(m_skuTable, FtrCCSNode))
1148 {
1149 isComputeContextEnabled = false;
1150 }
1151
1152 if (isComputeContextEnabled)
1153 {
1154 // Create Render Context for field scaling
1155 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateGpuContext(
1156 m_osInterface,
1157 MOS_GPU_CONTEXT_COMPUTE,
1158 MOS_GPU_NODE_COMPUTE,
1159 &createOption));
1160 m_renderContext = MOS_GPU_CONTEXT_COMPUTE;
1161 }
1162 else
1163 {
1164 // Create Render Context for field scaling
1165 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateGpuContext(
1166 m_osInterface,
1167 MOS_GPU_CONTEXT_RENDER,
1168 MOS_GPU_NODE_3D,
1169 &createOption));
1170 m_renderContext = MOS_GPU_CONTEXT_RENDER;
1171 }
1172 }
1173
1174 m_intelEntrypointInUse = (settings->intelEntrypointInUse) ? true : false;
1175 m_width = settings->width;
1176 m_height = settings->height;
1177 m_picWidthInMb = (uint16_t)CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_width);
1178 m_picHeightInMb = (uint16_t)CODECHAL_GET_WIDTH_IN_MACROBLOCKS(m_height);
1179 m_shortFormatInUse = (settings->shortFormatInUse) ? true : false;
1180
1181 CODECHAL_DECODE_CHK_STATUS_RETURN(InitSfcState());
1182
1183 for (uint8_t i = 0; i < CODECHAL_DECODE_AVC_MAX_NUM_MVC_VIEWS; i++)
1184 {
1185 m_firstFieldIdxList[i] = CODECHAL_DECODE_AVC_INVALID_FRAME_IDX;
1186 }
1187
1188 // Picture Level Commands
1189 m_hwInterface->GetMfxStateCommandsDataSize(
1190 CODECHAL_DECODE_MODE_AVCVLD,
1191 &m_commandBufferSizeNeeded,
1192 &m_commandPatchListSizeNeeded,
1193 m_shortFormatInUse);
1194
1195 // Slice Level Commands (cannot be placed in 2nd level batch)
1196 m_hwInterface->GetMfxPrimitiveCommandsDataSize(
1197 CODECHAL_DECODE_MODE_AVCVLD,
1198 &m_standardDecodeSizeNeeded,
1199 &m_standardDecodePatchListSizeNeeded,
1200 m_shortFormatInUse);
1201
1202 CODECHAL_DECODE_CHK_STATUS_RETURN(AllocateResourcesFixedSizes());
1203
1204 return eStatus;
1205 }
1206
~CodechalDecodeAvc()1207 CodechalDecodeAvc::~CodechalDecodeAvc()
1208 {
1209 CODECHAL_DECODE_FUNCTION_ENTER;
1210
1211 CodecHalFreeDataList(m_avcRefList, CODEC_AVC_NUM_UNCOMPRESSED_SURFACE);
1212
1213 m_osInterface->pfnDestroySyncResource(
1214 m_osInterface,
1215 &m_resSyncObjectWaContextInUse);
1216
1217 m_osInterface->pfnDestroySyncResource(
1218 m_osInterface,
1219 &m_resSyncObjectVideoContextInUse);
1220
1221 MOS_FreeMemory(m_vldSliceRecord);
1222
1223 m_osInterface->pfnFreeResource(
1224 m_osInterface,
1225 &m_resMfdDeblockingFilterRowStoreScratchBuffer);
1226
1227 m_osInterface->pfnFreeResource(
1228 m_osInterface,
1229 &m_resBsdMpcRowStoreScratchBuffer);
1230
1231 m_osInterface->pfnFreeResource(
1232 m_osInterface,
1233 &m_resMfdIntraRowStoreScratchBuffer);
1234
1235 m_osInterface->pfnFreeResource(
1236 m_osInterface,
1237 &m_resMprRowStoreScratchBuffer);
1238
1239 if (!Mos_ResourceIsNull(&m_resMonoPictureChromaBuffer))
1240 {
1241 m_osInterface->pfnFreeResource(
1242 m_osInterface,
1243 &m_resMonoPictureChromaBuffer);
1244 }
1245
1246 uint32_t maxMvBuf = m_osInterface->pfnIsMismatchOrderProgrammingSupported() ?
1247 CODEC_AVC_NUM_UNCOMPRESSED_SURFACE :
1248 CODEC_AVC_NUM_DMV_BUFFERS;
1249 for (uint32_t ctr = 0; ctr < maxMvBuf; ctr++)
1250 {
1251 m_osInterface->pfnFreeResource(
1252 m_osInterface,
1253 &m_resAvcDmvBuffers[ctr]);
1254 }
1255
1256 if (!Mos_ResourceIsNull(&m_resInvalidRefBuffer))
1257 {
1258 m_osInterface->pfnFreeResource(
1259 m_osInterface,
1260 &m_resInvalidRefBuffer);
1261 }
1262
1263 #ifdef _DECODE_PROCESSING_SUPPORTED
1264 if (m_sfcState)
1265 {
1266 MOS_Delete(m_sfcState);
1267 m_sfcState = nullptr;
1268 }
1269 #endif
1270
1271 return;
1272 }
1273
SetFrameStates()1274 MOS_STATUS CodechalDecodeAvc::SetFrameStates()
1275 {
1276 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1277
1278 CODECHAL_DECODE_FUNCTION_ENTER;
1279
1280 CODECHAL_DECODE_CHK_NULL_RETURN(m_decodeParams.m_destSurface);
1281
1282 m_dataSize = m_decodeParams.m_dataSize;
1283 m_dataOffset = m_decodeParams.m_dataOffset;
1284 m_numSlices = m_decodeParams.m_numSlices;
1285 m_avcPicParams = (PCODEC_AVC_PIC_PARAMS)m_decodeParams.m_picParams;
1286 m_mvcExtPicParams = (PCODEC_MVC_EXT_PIC_PARAMS)m_decodeParams.m_extPicParams;
1287 m_avcSliceParams = (PCODEC_AVC_SLICE_PARAMS)m_decodeParams.m_sliceParams;
1288 m_avcIqMatrixParams = (PCODEC_AVC_IQ_MATRIX_PARAMS)m_decodeParams.m_iqMatrixBuffer;
1289 m_destSurface = *(m_decodeParams.m_destSurface);
1290 m_refFrameSurface = m_decodeParams.m_refFrameSurface;
1291 m_refSurfaceNum = m_decodeParams.m_refSurfaceNum;
1292 CODECHAL_DECODE_CHK_NULL_RETURN(m_decodeParams.m_dataBuffer);
1293 m_resDataBuffer = *(m_decodeParams.m_dataBuffer);
1294 m_picIdRemappingInUse = (m_decodeParams.m_picIdRemappingInUse) ? true : false;
1295
1296 m_cencBuf = m_decodeParams.m_cencBuf;
1297 m_fullFrameData = m_decodeParams.m_bFullFrameData;
1298
1299 CODECHAL_DECODE_CHK_NULL_RETURN(m_avcPicParams);
1300 CODECHAL_DECODE_CHK_NULL_RETURN(m_avcIqMatrixParams);
1301
1302 m_width = (m_avcPicParams->pic_width_in_mbs_minus1 + 1) * CODECHAL_MACROBLOCK_WIDTH;
1303 m_height = (m_avcPicParams->pic_height_in_mbs_minus1 + 1) * CODECHAL_MACROBLOCK_HEIGHT;
1304 m_deblockingEnabled = false;
1305
1306 if (m_shortFormatInUse)
1307 {
1308 // When HW parses the slice_header, disable_deblocking_filter_idc is not yet known,
1309 // so always enable ILDB in this case.
1310 m_deblockingEnabled = true;
1311 }
1312 else
1313 {
1314 for (uint32_t i = 0; i < m_numSlices; i++)
1315 {
1316 if (m_avcSliceParams[i].disable_deblocking_filter_idc != 1)
1317 {
1318 m_deblockingEnabled = true;
1319 break;
1320 }
1321 }
1322 }
1323
1324 if (m_mfxInterface->IsRowStoreCachingSupported())
1325 {
1326 MHW_VDBOX_ROWSTORE_PARAMS rowstoreParams;
1327 MOS_ZeroMemory(&rowstoreParams, sizeof(rowstoreParams));
1328 rowstoreParams.Mode = CODECHAL_DECODE_MODE_AVCVLD;
1329 rowstoreParams.bMbaff = m_avcPicParams->seq_fields.mb_adaptive_frame_field_flag;
1330 rowstoreParams.bIsFrame = m_avcPicParams->seq_fields.frame_mbs_only_flag;
1331 rowstoreParams.dwPicWidth = m_width;
1332 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->SetRowstoreCachingOffsets(&rowstoreParams));
1333 }
1334
1335 CODECHAL_DECODE_CHK_STATUS_RETURN(AllocateResourcesVariableSizes());
1336
1337 CODECHAL_DECODE_CHK_STATUS_RETURN(SetPictureStructs());
1338
1339 CODECHAL_DECODE_CHK_STATUS_RETURN(FormatAvcMonoPicture(m_decodeParams.m_destSurface));
1340
1341 if (m_avcPicParams->pic_fields.IntraPicFlag)
1342 {
1343 m_perfType = I_TYPE;
1344 }
1345 else
1346 {
1347 // Not possible to determine whether P or B is used for short format.
1348 // For long format iterating through all of the slices to determine P vs
1349 // B, so in order to avoid this, declare all other pictures MIXED_TYPE.
1350 m_perfType = MIXED_TYPE;
1351 }
1352 #ifdef _DECODE_PROCESSING_SUPPORTED
1353 auto decProcessingParams = (DecodeProcessingParams *)m_decodeParams.m_procParams;
1354 if (decProcessingParams != nullptr)
1355 {
1356 if (!decProcessingParams->m_isReferenceOnlyPattern && m_downsamplingHinted)
1357 {
1358 CODECHAL_DECODE_CHK_NULL_RETURN(m_fieldScalingInterface);
1359 }
1360
1361 CODECHAL_DECODE_CHK_STATUS_RETURN(m_sfcState->CheckAndInitialize(
1362 decProcessingParams,
1363 m_avcPicParams,
1364 m_width,
1365 m_height,
1366 m_deblockingEnabled));
1367
1368 if (!((!CodecHal_PictureIsFrame(m_avcPicParams->CurrPic) ||
1369 m_avcPicParams->seq_fields.mb_adaptive_frame_field_flag) &&
1370 (m_downsamplingHinted && m_fieldScalingInterface->IsFieldScalingSupported(decProcessingParams))) &&
1371 m_sfcState->m_sfcPipeOut == false &&
1372 !decProcessingParams->m_isReferenceOnlyPattern)
1373 {
1374 m_vdSfcSupported = false;
1375 }
1376 else
1377 {
1378 m_vdSfcSupported = true;
1379 }
1380 }
1381 #endif
1382 m_crrPic = m_avcPicParams->CurrPic;
1383
1384 if(m_fullFieldsFrame == (PICTURE_BOTTOM_FIELD | PICTURE_TOP_FIELD))
1385 {
1386 m_fullFieldsFrame = 0;
1387 }
1388
1389 m_secondField = false;
1390
1391 if(CodecHal_PictureIsField(m_avcPicParams->CurrPic))
1392 {
1393 if(CodecHal_PictureIsTopField(m_avcPicParams->CurrPic))
1394 {
1395 m_fullFieldsFrame |= PICTURE_TOP_FIELD;
1396 }
1397 if (CodecHal_PictureIsBottomField(m_avcPicParams->CurrPic))
1398 {
1399 m_fullFieldsFrame |= PICTURE_BOTTOM_FIELD;
1400 }
1401 }
1402 else
1403 {
1404 m_fullFieldsFrame = 0;
1405 }
1406
1407 if(m_fullFieldsFrame == (PICTURE_BOTTOM_FIELD | PICTURE_TOP_FIELD))
1408 {
1409 m_secondField = true;
1410 }
1411
1412 if (m_pCodechalOcaDumper)
1413 {
1414 m_pCodechalOcaDumper->SetAvcDecodeParam(
1415 m_avcPicParams,
1416 m_avcSliceParams,
1417 m_numSlices);
1418 }
1419
1420 CODECHAL_DEBUG_TOOL(
1421 m_debugInterface->m_currPic = m_crrPic;
1422 m_debugInterface->m_secondField = m_secondField;
1423 m_debugInterface->m_frameType = m_perfType;
1424
1425 if (m_avcPicParams) {
1426 CODECHAL_DECODE_CHK_STATUS_RETURN(DumpPicParams(
1427 m_avcPicParams));
1428 }
1429
1430 if (m_avcIqMatrixParams) {
1431 CODECHAL_DECODE_CHK_STATUS_RETURN(DumpIQParams(
1432 m_avcIqMatrixParams));
1433 }
1434
1435 if (m_mvcExtPicParams) {
1436 CODECHAL_DECODE_CHK_STATUS_RETURN(DumpMvcExtPicParams(
1437 m_mvcExtPicParams));
1438 }
1439
1440 if (m_avcSliceParams) {
1441 CODECHAL_DECODE_CHK_STATUS_RETURN(DumpSliceParams(
1442 m_avcSliceParams,
1443 m_numSlices));
1444 })
1445
1446 return eStatus;
1447 }
1448
InitPicMhwParams(PIC_MHW_PARAMS * picMhwParams)1449 MOS_STATUS CodechalDecodeAvc::InitPicMhwParams(
1450 PIC_MHW_PARAMS *picMhwParams)
1451 {
1452 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1453
1454 CODECHAL_DECODE_FUNCTION_ENTER;
1455 PMOS_RESOURCE firstValidFrame = nullptr;
1456
1457 if (MEDIA_IS_WA(m_waTable, WaDummyReference) && !Mos_ResourceIsNull(&m_dummyReference.OsResource))
1458 {
1459 firstValidFrame = &m_dummyReference.OsResource;
1460 }
1461 else
1462 {
1463 firstValidFrame = &m_destSurface.OsResource;
1464 }
1465
1466 CODECHAL_DECODE_CHK_NULL_RETURN(picMhwParams);
1467
1468 picMhwParams->PipeModeSelectParams = {};
1469 picMhwParams->PipeBufAddrParams = {};
1470 picMhwParams->ImgParams = {};
1471 MOS_ZeroMemory(&picMhwParams->SurfaceParams,
1472 sizeof(picMhwParams->SurfaceParams));
1473 MOS_ZeroMemory(&picMhwParams->IndObjBaseAddrParams,
1474 sizeof(picMhwParams->IndObjBaseAddrParams));
1475 MOS_ZeroMemory(&picMhwParams->BspBufBaseAddrParams,
1476 sizeof(picMhwParams->BspBufBaseAddrParams));
1477 MOS_ZeroMemory(&picMhwParams->QmParams,
1478 sizeof(picMhwParams->QmParams));
1479 MOS_ZeroMemory(&picMhwParams->PicIdParams,
1480 sizeof(picMhwParams->PicIdParams));
1481 MOS_ZeroMemory(&picMhwParams->AvcDirectmodeParams,
1482 sizeof(picMhwParams->AvcDirectmodeParams));
1483
1484 picMhwParams->PipeModeSelectParams.Mode = CODECHAL_DECODE_MODE_AVCVLD;
1485 //enable decodestreamout if either app or codechal dump need it
1486 picMhwParams->PipeModeSelectParams.bStreamOutEnabled =
1487 m_decodeParams.m_streamOutEnabled || m_streamOutEnabled;
1488 picMhwParams->PipeModeSelectParams.bPostDeblockOutEnable = m_deblockingEnabled;
1489 picMhwParams->PipeModeSelectParams.bPreDeblockOutEnable = !m_deblockingEnabled;
1490 picMhwParams->PipeModeSelectParams.bShortFormatInUse = m_shortFormatInUse;
1491
1492 picMhwParams->SurfaceParams.Mode = CODECHAL_DECODE_MODE_AVCVLD;
1493 picMhwParams->SurfaceParams.psSurface = &m_destSurface;
1494
1495 picMhwParams->PipeBufAddrParams.Mode = CODECHAL_DECODE_MODE_AVCVLD;
1496 if (m_deblockingEnabled)
1497 {
1498 picMhwParams->PipeBufAddrParams.psPostDeblockSurface = &m_destSurface;
1499 }
1500 else
1501 {
1502 picMhwParams->PipeBufAddrParams.psPreDeblockSurface = &m_destSurface;
1503 }
1504
1505 #ifdef _MMC_SUPPORTED
1506 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetPipeBufAddr(&picMhwParams->PipeBufAddrParams));
1507 #endif
1508
1509 picMhwParams->PipeBufAddrParams.presMfdIntraRowStoreScratchBuffer =
1510 &m_resMfdIntraRowStoreScratchBuffer;
1511 picMhwParams->PipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer =
1512 &m_resMfdDeblockingFilterRowStoreScratchBuffer;
1513
1514 //Do not support export decode streamout to app buffer and codechal_dump simultenously
1515 //which can lead to extra memory copy
1516 //decode streamout to application
1517 if (m_decodeParams.m_streamOutEnabled)
1518 {
1519 picMhwParams->PipeBufAddrParams.presStreamOutBuffer = m_decodeParams.m_externalStreamOutBuffer;
1520 }
1521 //decode streamout to codechal_dump
1522 else if (m_streamOutEnabled)
1523 {
1524 picMhwParams->PipeBufAddrParams.presStreamOutBuffer =
1525 &(m_streamOutBuffer[m_streamOutCurrBufIdx]);
1526
1527 CODECHAL_DEBUG_TOOL(
1528 // mark the buffer as in-use
1529 m_streamOutCurrStatusIdx[m_streamOutCurrBufIdx] = 0;
1530 )
1531 }
1532
1533 MOS_SURFACE dstSurface;
1534 uint8_t firstValidFrameId = CODEC_AVC_MAX_NUM_REF_FRAME;
1535 uint8_t activeFrameCnt = 0;
1536 uint8_t picIdx, frameId, i;
1537 MOS_ZeroMemory(m_presReferences, (sizeof(PMOS_RESOURCE) * CODEC_AVC_MAX_NUM_REF_FRAME));
1538 for (i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
1539 {
1540 if (m_avcPicIdx[i].bValid)
1541 {
1542 activeFrameCnt++;
1543 picIdx = m_avcPicIdx[i].ucPicIdx;
1544 frameId =
1545 (m_picIdRemappingInUse) ? i : m_avcRefList[picIdx]->ucFrameId;
1546
1547 m_presReferences[frameId] =
1548 &(m_avcRefList[picIdx]->resRefPic);
1549
1550 CODECHAL_DEBUG_TOOL(
1551 MOS_ZeroMemory(&dstSurface, sizeof(MOS_SURFACE));
1552 dstSurface.Format = Format_NV12;
1553 dstSurface.OsResource = *(m_presReferences[frameId]);
1554 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
1555 m_osInterface,
1556 &dstSurface));
1557
1558 m_debugInterface->m_refIndex = frameId;
1559 std::string refSurfName = "RefSurf[" + std::to_string(static_cast<uint32_t>(m_debugInterface->m_refIndex)) + "]";
1560 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
1561 &dstSurface,
1562 CodechalDbgAttr::attrDecodeReferenceSurfaces,
1563 refSurfName.data()));)
1564
1565 if (frameId < firstValidFrameId)
1566 {
1567 firstValidFrameId = frameId;
1568 firstValidFrame = m_presReferences[frameId];
1569 }
1570 }
1571 }
1572
1573 for (i = 0; i < CODEC_AVC_MAX_NUM_REF_FRAME; i++)
1574 {
1575 // error concealment for the unset reference addresses
1576 if (!m_presReferences[i])
1577 {
1578 m_presReferences[i] = firstValidFrame;
1579 }
1580 }
1581
1582 #ifdef _MMC_SUPPORTED
1583 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->CheckReferenceList(&picMhwParams->PipeBufAddrParams));
1584
1585 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SetRefrenceSync(m_disableDecodeSyncLock, m_disableLockForTranscode));
1586 #endif
1587
1588 CODECHAL_DECODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(picMhwParams->PipeBufAddrParams.presReferences, sizeof(PMOS_RESOURCE) * CODEC_AVC_MAX_NUM_REF_FRAME, m_presReferences, sizeof(PMOS_RESOURCE) * CODEC_AVC_MAX_NUM_REF_FRAME));
1589
1590 picMhwParams->IndObjBaseAddrParams.Mode = CODECHAL_DECODE_MODE_AVCVLD;
1591 picMhwParams->IndObjBaseAddrParams.presDataBuffer = &m_resDataBuffer;
1592 picMhwParams->IndObjBaseAddrParams.dwDataSize = m_dataSize;
1593 picMhwParams->IndObjBaseAddrParams.dwDataOffset = m_dataOffset;
1594
1595 if (m_secureDecoder)
1596 {
1597 CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->SetBitstreamBuffer(&picMhwParams->IndObjBaseAddrParams));
1598 }
1599
1600 picMhwParams->BspBufBaseAddrParams.presBsdMpcRowStoreScratchBuffer = &m_resBsdMpcRowStoreScratchBuffer;
1601 picMhwParams->BspBufBaseAddrParams.presMprRowStoreScratchBuffer = &m_resMprRowStoreScratchBuffer;
1602
1603 picMhwParams->QmParams.Standard = CODECHAL_AVC;
1604 picMhwParams->QmParams.pAvcIqMatrix = (PMHW_VDBOX_AVC_QM_PARAMS)m_avcIqMatrixParams;
1605
1606 picMhwParams->PicIdParams.bPicIdRemappingInUse = m_picIdRemappingInUse;
1607 picMhwParams->PicIdParams.pAvcPicIdx = &(m_avcPicIdx[0]);
1608
1609 picMhwParams->ImgParams.pAvcPicParams = m_avcPicParams;
1610 picMhwParams->ImgParams.pMvcExtPicParams = m_mvcExtPicParams;
1611 picMhwParams->ImgParams.ucActiveFrameCnt = activeFrameCnt;
1612
1613 picMhwParams->AvcDirectmodeParams.CurrPic = m_currPic;
1614 picMhwParams->AvcDirectmodeParams.uiUsedForReferenceFlags = m_avcPicParams->UsedForReferenceFlags;
1615 picMhwParams->AvcDirectmodeParams.presAvcDmvBuffers = &(m_resAvcDmvBuffers[0]);
1616 picMhwParams->AvcDirectmodeParams.ucAvcDmvIdx = m_avcMvBufferIndex;
1617 picMhwParams->AvcDirectmodeParams.pAvcDmvList = &(m_avcDmvList[0]);
1618 picMhwParams->AvcDirectmodeParams.pAvcPicIdx = &(m_avcPicIdx[0]);
1619 picMhwParams->AvcDirectmodeParams.avcRefList = (void**)m_avcRefList;
1620 picMhwParams->AvcDirectmodeParams.bPicIdRemappingInUse = m_picIdRemappingInUse;
1621 picMhwParams->AvcDirectmodeParams.presMvcDummyDmvBuffer = &(m_resMvcDummyDmvBuffer[(m_avcPicParams->seq_fields.direct_8x8_inference_flag) ? 1 : 0]);
1622
1623 CODECHAL_DEBUG_TOOL(
1624
1625 CODEC_REF_LIST * *refList;
1626 MHW_MI_CHK_NULL(refList = (CODEC_REF_LIST **)picMhwParams->AvcDirectmodeParams.avcRefList);
1627
1628 for (auto i = 0; i < CODEC_MAX_NUM_REF_FRAME; i++)
1629 {
1630 if (picMhwParams->AvcDirectmodeParams.pAvcPicIdx[i].bValid)
1631 {
1632 uint8_t idx = picMhwParams->AvcDirectmodeParams.pAvcPicIdx[i].ucPicIdx;
1633 uint8_t picID = picMhwParams->AvcDirectmodeParams.bPicIdRemappingInUse ? i : refList[idx]->ucFrameId;
1634 uint8_t mvIdx = refList[idx]->ucDMVIdx[0];
1635
1636 // dump Reference mvdata
1637 std::string mvBufDumpName = "_DEC_Ref_MV_" + std::to_string(i);
1638 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
1639 &picMhwParams->AvcDirectmodeParams.presAvcDmvBuffers[mvIdx],
1640 CodechalDbgAttr::attrMvData,
1641 mvBufDumpName.c_str(),
1642 m_avcDmvBufferSize));
1643 }
1644 }
1645
1646 // dump Current mvdata
1647 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
1648 &picMhwParams->AvcDirectmodeParams.presAvcDmvBuffers[picMhwParams->AvcDirectmodeParams.ucAvcDmvIdx],
1649 CodechalDbgAttr::attrMvData,
1650 "DEC_Cur_MV_",
1651 m_avcDmvBufferSize));
1652 );
1653
1654 return eStatus;
1655 }
1656
AddPictureCmds(PMOS_COMMAND_BUFFER cmdBuf,PIC_MHW_PARAMS * picMhwParams)1657 MOS_STATUS CodechalDecodeAvc::AddPictureCmds(
1658 PMOS_COMMAND_BUFFER cmdBuf,
1659 PIC_MHW_PARAMS *picMhwParams)
1660 {
1661 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1662
1663 CODECHAL_DECODE_FUNCTION_ENTER;
1664
1665 CODECHAL_DECODE_CHK_NULL_RETURN(cmdBuf);
1666 CODECHAL_DECODE_CHK_NULL_RETURN(picMhwParams);
1667
1668 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeModeSelectCmd(cmdBuf, &picMhwParams->PipeModeSelectParams));
1669
1670 #ifdef _DECODE_PROCESSING_SUPPORTED
1671 CODECHAL_DECODE_CHK_STATUS_RETURN(m_sfcState->AddSfcCommands(cmdBuf));
1672 #endif
1673
1674 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxSurfaceCmd(cmdBuf, &picMhwParams->SurfaceParams));
1675
1676 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxPipeBufAddrCmd(cmdBuf, &picMhwParams->PipeBufAddrParams));
1677
1678 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxIndObjBaseAddrCmd(cmdBuf, &picMhwParams->IndObjBaseAddrParams));
1679
1680 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxBspBufBaseAddrCmd(cmdBuf, &picMhwParams->BspBufBaseAddrParams));
1681
1682 if (m_shortFormatInUse)
1683 {
1684 MHW_VDBOX_AVC_DPB_PARAMS dpbParams;
1685 MOS_ZeroMemory(&dpbParams, sizeof(dpbParams));
1686 dpbParams.pAvcPicParams = m_avcPicParams;
1687 dpbParams.pMvcExtPicParams = m_mvcExtPicParams;
1688 dpbParams.ppAvcRefList = &(m_avcRefList[0]);
1689 dpbParams.pAvcPicIdx = &(m_avcPicIdx[0]);
1690 dpbParams.bPicIdRemappingInUse = m_picIdRemappingInUse;
1691
1692 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdAvcDpbCmd(cmdBuf, &dpbParams));
1693 }
1694
1695 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfdAvcPicidCmd(cmdBuf, &picMhwParams->PicIdParams));
1696
1697 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcImgCmd(cmdBuf, nullptr, &picMhwParams->ImgParams));
1698
1699 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxQmCmd(cmdBuf, &picMhwParams->QmParams));
1700
1701 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->AddMfxAvcDirectmodeCmd(cmdBuf, &picMhwParams->AvcDirectmodeParams));
1702
1703 return eStatus;
1704 }
1705
DecodeStateLevel()1706 MOS_STATUS CodechalDecodeAvc::DecodeStateLevel()
1707 {
1708 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1709
1710 CODECHAL_DECODE_FUNCTION_ENTER;
1711
1712 if (m_secureDecoder)
1713 {
1714 CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->Execute(this));
1715 }
1716
1717 MOS_COMMAND_BUFFER cmdBuffer;
1718 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
1719
1720 CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(
1721 &cmdBuffer, true));
1722
1723 PIC_MHW_PARAMS picMhwParams;
1724 CODECHAL_DECODE_CHK_STATUS_RETURN(InitPicMhwParams(&picMhwParams));
1725
1726 auto mmioRegisters = m_hwInterface->GetMfxInterface()->GetMmioRegisters(m_vdboxIndex);
1727 HalOcaInterface::On1stLevelBBStart(cmdBuffer, *m_osInterface->pOsContext, m_osInterface->CurrentGpuContextHandle, *m_miInterface, *mmioRegisters);
1728
1729 if (m_cencBuf && m_cencBuf->checkStatusRequired)
1730 {
1731 CODECHAL_DECODE_COND_ASSERTMESSAGE((m_vdboxIndex > m_hwInterface->GetMfxInterface()->GetMaxVdboxIndex()), "ERROR - vdbox index exceed the maximum");
1732
1733 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->GetCpInterface()->CheckStatusReportNum(
1734 mmioRegisters,
1735 m_cencBuf->bufIdx,
1736 m_cencBuf->resStatus,
1737 &cmdBuffer));
1738 }
1739
1740 if (m_statusQueryReportingEnabled)
1741 {
1742 CODECHAL_DECODE_CHK_STATUS_RETURN(StartStatusReport(&cmdBuffer));
1743 }
1744
1745 CODECHAL_DECODE_CHK_STATUS_RETURN(AddPictureCmds(&cmdBuffer, &picMhwParams));
1746
1747 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1748
1749 return eStatus;
1750 }
1751
ParseSlice(PMOS_COMMAND_BUFFER cmdBuf)1752 MOS_STATUS CodechalDecodeAvc::ParseSlice(
1753 PMOS_COMMAND_BUFFER cmdBuf)
1754 {
1755 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1756 CODECHAL_DECODE_FUNCTION_ENTER;
1757
1758 PCODEC_AVC_SLICE_PARAMS slc = m_avcSliceParams;
1759 uint16_t frameInMbs = (m_avcPicParams->pic_height_in_mbs_minus1 + 1) * (m_avcPicParams->pic_width_in_mbs_minus1 + 1);
1760
1761 CODECHAL_DECODE_CHK_NULL_RETURN(m_vldSliceRecord);
1762 CODECHAL_DECODE_CHK_NULL_RETURN(slc);
1763
1764 // Setup static slice state parameters
1765 MHW_VDBOX_AVC_SLICE_STATE avcSliceState;
1766 MOS_ZeroMemory(&avcSliceState, sizeof(avcSliceState));
1767 avcSliceState.bIntelEntrypointInUse = m_intelEntrypointInUse;
1768 avcSliceState.bPicIdRemappingInUse = m_picIdRemappingInUse;
1769 avcSliceState.bShortFormatInUse = m_shortFormatInUse;
1770 avcSliceState.presDataBuffer = &m_resDataBuffer;
1771 avcSliceState.pAvcPicParams = m_avcPicParams;
1772 avcSliceState.pMvcExtPicParams = m_mvcExtPicParams;
1773 avcSliceState.pAvcPicIdx = &(m_avcPicIdx[0]);
1774 avcSliceState.bPhantomSlice = false;
1775 avcSliceState.dwTotalBytesConsumed = 0;
1776
1777 uint32_t length = 0, slcCount = 0;
1778 uint32_t offset = 0;
1779 uint32_t lastValidSlice = 0;
1780 bool firstValidSlice = true;
1781 bool invalidSlicePresent = false;
1782 for (slcCount = 0; slcCount < m_numSlices; slcCount++)
1783 {
1784
1785 if (invalidSlicePresent == true)
1786 {
1787 break;
1788 }
1789
1790 if (m_vldSliceRecord[slcCount].dwSkip)
1791 {
1792 continue;
1793 }
1794
1795 length = slc->slice_data_size;
1796
1797 if (slcCount < m_numSlices - 1)
1798 {
1799 // Skip remaining slices if the number of MBs already reaches the total before the last slice or slice overlap occurs.
1800 if ((!m_shortFormatInUse) &&
1801 ((slc->first_mb_in_slice + slc->NumMbsForSlice >= frameInMbs) ||
1802 ((slc + 1)->first_mb_in_slice <= slc->first_mb_in_slice)))
1803 {
1804 uint32_t count = slcCount + 1;
1805
1806 slc->first_mb_in_next_slice = 0;
1807 invalidSlicePresent = true;
1808
1809 while (count < m_numSlices)
1810 {
1811 m_vldSliceRecord[count++].dwSkip = true;
1812 }
1813 }
1814 else
1815 {
1816 slc->first_mb_in_next_slice = (slc + 1)->first_mb_in_slice;
1817 }
1818 }
1819 else
1820 {
1821 slc->first_mb_in_next_slice = 0;
1822 }
1823
1824 // error handling for garbage data
1825 if (((uint64_t)(slc->slice_data_offset) + length) > m_dataSize)
1826 {
1827 slc++;
1828 m_vldSliceRecord[slcCount].dwSkip = true;
1829 continue;
1830 }
1831
1832 if (!m_shortFormatInUse)
1833 {
1834 offset = (slc->slice_data_bit_offset >> 3) + m_osInterface->dwNumNalUnitBytesIncluded;
1835
1836 if (offset > length)
1837 {
1838 slc++;
1839 m_vldSliceRecord[slcCount].dwSkip = true;
1840 continue;
1841 }
1842
1843 // For first slice, first_mb_in_slice must be 0, otherwise it is corrupted
1844 // Skip slice when first_mb_in_slice is corrupted.
1845 if ((0 == slcCount && slc->first_mb_in_slice) ||
1846 (slc->first_mb_in_slice >= frameInMbs) ||
1847 (m_avcPicParams->seq_fields.mb_adaptive_frame_field_flag &&
1848 !m_avcPicParams->pic_fields.field_pic_flag &&
1849 (slc->first_mb_in_slice >= frameInMbs / 2)))
1850 {
1851 slc++;
1852 m_vldSliceRecord[slcCount].dwSkip = true;
1853 continue;
1854 }
1855
1856 if (firstValidSlice && slc->first_mb_in_slice)
1857 {
1858
1859 uint16_t usStartMbNum, usNextStartMbNum;
1860
1861 // ensure that slc->first_mb_in_next_slice is always non-zero for this phantom slice
1862
1863 usNextStartMbNum = slc->first_mb_in_next_slice;
1864 usStartMbNum = slc->first_mb_in_slice;
1865 slc->first_mb_in_slice = 0;
1866 slc->first_mb_in_next_slice = usStartMbNum;
1867
1868 avcSliceState.pAvcSliceParams = slc;
1869 avcSliceState.dwOffset = 0;
1870 avcSliceState.dwLength = slc->slice_data_offset;
1871 avcSliceState.dwNextOffset = slc->slice_data_offset;
1872 avcSliceState.dwNextLength = slc->slice_data_size;
1873
1874 CODECHAL_DECODE_CHK_STATUS_RETURN(SendSlice(&avcSliceState, cmdBuf));
1875
1876 slc->first_mb_in_slice = usStartMbNum;
1877 slc->first_mb_in_next_slice = usNextStartMbNum;
1878 }
1879 }
1880
1881 firstValidSlice = false;
1882 lastValidSlice = slcCount;
1883 length -= offset;
1884 m_vldSliceRecord[slcCount].dwLength = length;
1885 m_vldSliceRecord[slcCount].dwOffset = offset;
1886 slc++;
1887 }
1888 slc = m_avcSliceParams;
1889
1890 uint32_t skippedSlc = 0;
1891 for (slcCount = 0; slcCount < m_numSlices; slcCount++)
1892 {
1893 if (m_vldSliceRecord[slcCount].dwSkip)
1894 {
1895 //For DECE clear bytes calculation: Total bytes in the bit-stream consumed so far
1896 avcSliceState.dwTotalBytesConsumed = slc->slice_data_offset + slc->slice_data_size;
1897
1898 slc++;
1899 skippedSlc++;
1900 continue;
1901 }
1902
1903 if (slcCount < lastValidSlice)
1904 {
1905 offset = (slc + 1)->slice_data_offset;
1906 length = (slc + 1)->slice_data_size;
1907 }
1908 avcSliceState.pAvcSliceParams = slc;
1909 avcSliceState.dwOffset = m_vldSliceRecord[slcCount].dwOffset;
1910 avcSliceState.dwLength = m_vldSliceRecord[slcCount].dwLength;
1911 avcSliceState.dwNextOffset = offset;
1912 avcSliceState.dwNextLength = length;
1913 avcSliceState.dwSliceIndex = slcCount;
1914 avcSliceState.bLastSlice = (slcCount == lastValidSlice);
1915 avcSliceState.bFullFrameData = m_fullFrameData;
1916
1917 CODECHAL_DECODE_CHK_STATUS_RETURN(SendSlice(&avcSliceState, cmdBuf));
1918
1919 //For DECE clear bytes calculation: Total bytes in the bit-stream consumed so far
1920 avcSliceState.dwTotalBytesConsumed = slc->slice_data_offset + slc->slice_data_size;
1921
1922 slc++;
1923 }
1924
1925 MOS_ZeroMemory(m_vldSliceRecord, (m_numSlices * sizeof(CODECHAL_VLD_SLICE_RECORD)));
1926
1927 return eStatus;
1928 }
1929
DecodePrimitiveLevel()1930 MOS_STATUS CodechalDecodeAvc::DecodePrimitiveLevel()
1931 {
1932 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1933 CODECHAL_DECODE_FUNCTION_ENTER;
1934
1935 CODECHAL_DECODE_CHK_NULL_RETURN(m_osInterface);
1936 CODECHAL_DECODE_CHK_NULL_RETURN(m_avcPicParams);
1937
1938 MOS_COMMAND_BUFFER cmdBuffer;
1939 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
1940
1941 if (m_cencBuf)
1942 {
1943 CODECHAL_DECODE_CHK_STATUS_RETURN(SetCencBatchBuffer(&cmdBuffer));
1944 }
1945 else
1946 {
1947 CODECHAL_DECODE_CHK_STATUS_RETURN(ParseSlice(&cmdBuffer));
1948 }
1949
1950 // Check if destination surface needs to be synchronized
1951 MOS_SYNC_PARAMS syncParams;
1952 syncParams = g_cInitSyncParams;
1953 syncParams.GpuContext = m_videoContext;
1954 syncParams.presSyncResource = &m_destSurface.OsResource;
1955 syncParams.bReadOnly = false;
1956 syncParams.bDisableDecodeSyncLock = m_disableDecodeSyncLock;
1957 syncParams.bDisableLockForTranscode = m_disableLockForTranscode;
1958
1959 if (!CodecHal_PictureIsField(m_avcPicParams->CurrPic) ||
1960 !m_isSecondField)
1961 {
1962 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnPerformOverlaySync(m_osInterface, &syncParams));
1963 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams));
1964
1965 // Update the resource tag (s/w tag) for On-Demand Sync
1966 m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams);
1967 }
1968
1969 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
1970 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
1971
1972 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
1973 &cmdBuffer,
1974 &flushDwParams));
1975
1976 // Update the tag in GPU Sync eStatus buffer (H/W Tag) to match the current S/W tag
1977 if (m_osInterface->bTagResourceSync &&
1978 (!CodecHal_PictureIsField(m_avcPicParams->CurrPic) || m_isSecondField))
1979 {
1980 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->WriteSyncTagToResource(&cmdBuffer, &syncParams));
1981 }
1982
1983 if (m_statusQueryReportingEnabled)
1984 {
1985 CodechalDecodeStatusReport decodeStatusReport;
1986
1987 decodeStatusReport.m_statusReportNumber = m_statusReportFeedbackNumber;
1988 decodeStatusReport.m_currDecodedPic = m_avcPicParams->CurrPic;
1989 decodeStatusReport.m_currDeblockedPic = m_avcPicParams->CurrPic;
1990 decodeStatusReport.m_codecStatus = CODECHAL_STATUS_UNAVAILABLE;
1991 decodeStatusReport.m_currDecodedPicRes = m_avcRefList[m_avcPicParams->CurrPic.FrameIdx]->resRefPic;
1992
1993 CODECHAL_DEBUG_TOOL(
1994 if (m_streamOutEnabled) {
1995 // add current streamout buffer to the report and move onto the next one
1996 decodeStatusReport.m_streamOutBuf = &(m_streamOutBuffer[m_streamOutCurrBufIdx]);
1997 decodeStatusReport.m_streamoutIdx = m_streamOutCurrBufIdx;
1998 if (++m_streamOutCurrBufIdx >= CODECHAL_DECODE_NUM_STREAM_OUT_BUFFERS)
1999 {
2000 m_streamOutCurrBufIdx = 0;
2001 }
2002 // check next buffer in the list is free.
2003 if (m_streamOutCurrStatusIdx[m_streamOutCurrBufIdx] != CODECHAL_DECODE_STATUS_NUM)
2004 {
2005 // We've run out of buffers. Temporarily lock the next one down to force a wait. Then mark it as free.
2006 CodechalResLock ResourceLock(m_osInterface, &(m_streamOutBuffer[m_streamOutCurrBufIdx]));
2007 ResourceLock.Lock(CodechalResLock::readOnly);
2008
2009 m_streamOutCurrStatusIdx[m_streamOutCurrBufIdx] = CODECHAL_DECODE_STATUS_NUM;
2010 }
2011 }
2012
2013 decodeStatusReport.m_secondField = m_secondField;
2014 decodeStatusReport.m_frameType = m_perfType;)
2015
2016 CODECHAL_DECODE_CHK_STATUS_RETURN(EndStatusReport(decodeStatusReport, &cmdBuffer));
2017 }
2018
2019 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(&cmdBuffer, nullptr));
2020
2021 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
2022
2023 bool syncCompleteFrame = (m_avcPicParams->seq_fields.chroma_format_idc == avcChromaFormatMono && !m_hwInterface->m_noHuC);
2024 if (syncCompleteFrame)
2025 {
2026 syncParams = g_cInitSyncParams;
2027 syncParams.GpuContext = m_videoContextForWa;
2028 syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
2029
2030 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineSignal(m_osInterface, &syncParams));
2031
2032 syncParams = g_cInitSyncParams;
2033 syncParams.GpuContext = m_videoContext;
2034 syncParams.presSyncResource = &m_resSyncObjectWaContextInUse;
2035
2036 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnEngineWait(m_osInterface, &syncParams));
2037 }
2038
2039 CODECHAL_DEBUG_TOOL(
2040 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpCmdBuffer(
2041 &cmdBuffer,
2042 CODECHAL_NUM_MEDIA_STATES,
2043 "_DEC"));
2044
2045 //CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgReplaceAllCommands(
2046 // m_debugInterface,
2047 // &cmdBuffer));
2048 )
2049
2050 HalOcaInterface::DumpCodechalParam(cmdBuffer, (MOS_CONTEXT_HANDLE)m_osInterface->pOsContext, m_pCodechalOcaDumper, CODECHAL_AVC);
2051 HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface);
2052
2053 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(m_osInterface, &cmdBuffer, m_videoContextUsesNullHw));
2054
2055 CODECHAL_DEBUG_TOOL(
2056 m_mmc->UpdateUserFeatureKey(&m_destSurface);)
2057
2058 #ifdef _DECODE_PROCESSING_SUPPORTED
2059 auto decProcessingParams = (DecodeProcessingParams *)m_decodeParams.m_procParams;
2060 if (decProcessingParams != nullptr && !m_sfcState->m_sfcPipeOut && (m_isSecondField || m_avcPicParams->seq_fields.mb_adaptive_frame_field_flag))
2061 {
2062 CODECHAL_DECODE_CHK_STATUS_RETURN(m_fieldScalingInterface->DoFieldScaling(
2063 decProcessingParams,
2064 m_renderContext,
2065 m_disableDecodeSyncLock,
2066 m_disableLockForTranscode));
2067 }
2068 else
2069 #endif
2070 {
2071 if (m_statusQueryReportingEnabled)
2072 {
2073 CODECHAL_DECODE_CHK_STATUS_RETURN(ResetStatusReport(m_videoContextUsesNullHw));
2074 }
2075 }
2076
2077 // Needs to be re-set for Linux buffer re-use scenarios
2078 m_avcRefList[m_avcPicParams->CurrPic.FrameIdx]->resRefPic =
2079 m_destSurface.OsResource;
2080
2081 // Send the signal to indicate decode completion, in case On-Demand Sync is not present
2082 if (!CodecHal_PictureIsField(m_avcPicParams->CurrPic) || m_isSecondField)
2083 {
2084 syncParams = g_cInitSyncParams;
2085 syncParams.GpuContext = m_videoContext;
2086 syncParams.presSyncResource = &m_destSurface.OsResource;
2087
2088 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
2089 #ifdef _DECODE_PROCESSING_SUPPORTED
2090 if (decProcessingParams && !m_sfcState->m_sfcPipeOut)
2091 {
2092 syncParams = g_cInitSyncParams;
2093 syncParams.GpuContext = m_renderContext;
2094 syncParams.presSyncResource = &decProcessingParams->m_outputSurface->OsResource;
2095
2096 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceSignal(m_osInterface, &syncParams));
2097 }
2098 #endif
2099 }
2100 #ifdef _DECODE_PROCESSING_SUPPORTED
2101 CODECHAL_DEBUG_TOOL(
2102 // Dump out downsampling result
2103 if (decProcessingParams && decProcessingParams->m_outputSurface)
2104 {
2105 MOS_SURFACE dstSurface;
2106 MOS_ZeroMemory(&dstSurface, sizeof(dstSurface));
2107 dstSurface.Format = Format_NV12;
2108 dstSurface.OsResource = decProcessingParams->m_outputSurface->OsResource;
2109
2110 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
2111 m_osInterface,
2112 &dstSurface));
2113
2114 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
2115 &dstSurface,
2116 CodechalDbgAttr::attrSfcOutputSurface,
2117 "SfcDstSurf"));
2118 }
2119 )
2120 #endif
2121 return eStatus;
2122 }
2123
CalcDownsamplingParams(void * picParams,uint32_t * refSurfWidth,uint32_t * refSurfHeight,MOS_FORMAT * format,uint8_t * frameIdx)2124 MOS_STATUS CodechalDecodeAvc::CalcDownsamplingParams(
2125 void *picParams,
2126 uint32_t *refSurfWidth,
2127 uint32_t *refSurfHeight,
2128 MOS_FORMAT *format,
2129 uint8_t *frameIdx)
2130 {
2131 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
2132
2133 CODECHAL_DECODE_CHK_NULL_RETURN(picParams);
2134 CODECHAL_DECODE_CHK_NULL_RETURN(refSurfWidth);
2135 CODECHAL_DECODE_CHK_NULL_RETURN(refSurfHeight);
2136 CODECHAL_DECODE_CHK_NULL_RETURN(format);
2137 CODECHAL_DECODE_CHK_NULL_RETURN(frameIdx);
2138
2139 PCODEC_AVC_PIC_PARAMS avcPicParams = (PCODEC_AVC_PIC_PARAMS)picParams;
2140
2141 *refSurfWidth = 0;
2142 *refSurfHeight = 0;
2143 *format = Format_NV12;
2144 *frameIdx = avcPicParams->CurrPic.FrameIdx;
2145
2146 *refSurfWidth = (avcPicParams->pic_width_in_mbs_minus1 + 1) * CODECHAL_MACROBLOCK_WIDTH;
2147 *refSurfHeight = (avcPicParams->pic_height_in_mbs_minus1 + 1) * CODECHAL_MACROBLOCK_HEIGHT;
2148
2149
2150 return eStatus;
2151 }
2152
CodechalDecodeAvc(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)2153 CodechalDecodeAvc::CodechalDecodeAvc(
2154 CodechalHwInterface *hwInterface,
2155 CodechalDebugInterface* debugInterface,
2156 PCODECHAL_STANDARD_INFO standardInfo) :
2157 CodechalDecode(hwInterface, debugInterface, standardInfo)
2158 {
2159 m_mmc = nullptr;
2160 m_hwInterface = hwInterface;
2161 // Parameters passed by application
2162 m_picWidthInMb = 0;
2163 m_picHeightInMb = 0;
2164 m_picWidthInMbLastMaxAlloced = 0;
2165 m_picHeightInMbLastMaxAlloced = 0;
2166 m_intelEntrypointInUse = false;
2167 m_shortFormatInUse = false;
2168 m_picIdRemappingInUse = false;
2169 m_dataSize = 0;
2170 m_dataOffset = 0;
2171 m_numSlices = 0;
2172 m_refSurfaceNum = 0;
2173 m_avcPicParams = nullptr;
2174 m_mvcExtPicParams = nullptr;
2175 m_avcSliceParams = nullptr;
2176 m_avcIqMatrixParams = nullptr;
2177
2178 MOS_ZeroMemory(m_presReferences, (sizeof(PMOS_RESOURCE) * CODEC_AVC_MAX_NUM_REF_FRAME));
2179 MOS_ZeroMemory(&m_resDataBuffer, sizeof(MOS_RESOURCE));
2180 MOS_ZeroMemory(&m_resMonoPictureChromaBuffer, sizeof(MOS_RESOURCE));
2181 MOS_ZeroMemory(&m_resMfdIntraRowStoreScratchBuffer, sizeof(MOS_RESOURCE));
2182 MOS_ZeroMemory(&m_resMfdDeblockingFilterRowStoreScratchBuffer, sizeof(MOS_RESOURCE));
2183 MOS_ZeroMemory(&m_resBsdMpcRowStoreScratchBuffer, sizeof(MOS_RESOURCE));
2184 MOS_ZeroMemory(&m_resMprRowStoreScratchBuffer, sizeof(MOS_RESOURCE));
2185 MOS_ZeroMemory(&m_resAvcDmvBuffers, (sizeof(MOS_RESOURCE) * CODEC_AVC_NUM_UNCOMPRESSED_SURFACE));
2186 MOS_ZeroMemory(&m_resInvalidRefBuffer, sizeof(MOS_RESOURCE));
2187 MOS_ZeroMemory(&m_resMvcDummyDmvBuffer, (sizeof(MOS_RESOURCE) * 2));
2188 MOS_ZeroMemory(&m_destSurface, sizeof(MOS_SURFACE));
2189 MOS_ZeroMemory(&m_resSyncObjectWaContextInUse, sizeof(MOS_RESOURCE));
2190 MOS_ZeroMemory(&m_resSyncObjectVideoContextInUse, sizeof(MOS_RESOURCE));
2191 m_refFrameSurface = nullptr;
2192
2193 m_vldSliceRecord = nullptr;
2194
2195 m_bsdMpcRowStoreScratchBufferPicWidthInMb = 0;
2196 m_mfdIntraRowStoreScratchBufferPicWidthInMb = 0;
2197 m_mprRowStoreScratchBufferPicWidthInMb = 0;
2198
2199 MOS_ZeroMemory(m_firstFieldIdxList, (sizeof(uint8_t) * CODECHAL_DECODE_AVC_MAX_NUM_MVC_VIEWS));
2200
2201 m_isSecondField = false;
2202 m_deblockingEnabled = false;
2203
2204 // Decode process usage
2205 MOS_ZeroMemory(&m_currPic, sizeof(CODEC_PICTURE));
2206
2207 MOS_ZeroMemory(&m_avcFrameStoreId, (sizeof(CODEC_AVC_FRAME_STORE_ID) * CODEC_AVC_MAX_NUM_REF_FRAME));
2208
2209 m_avcMvBufferIndex = 0;
2210 MOS_ZeroMemory(&m_avcDmvList, (sizeof(CODEC_AVC_DMV_LIST) * CODEC_AVC_NUM_DMV_BUFFERS));
2211
2212 MOS_ZeroMemory(&m_avcPicIdx, (sizeof(CODEC_PIC_ID) * CODEC_AVC_MAX_NUM_REF_FRAME));
2213 MOS_ZeroMemory(m_avcRefList, (sizeof(PCODEC_REF_LIST) * CODEC_AVC_NUM_UNCOMPRESSED_SURFACE));
2214
2215 m_avcDmvBufferSize = 0;
2216
2217 //Currently, crc calculation is only supported in AVC decoder
2218 m_reportFrameCrc = true;
2219
2220 m_fullFrameData = false;
2221
2222 };
2223
2224 #if USE_CODECHAL_DEBUG_TOOL
DumpMvcExtPicParams(PCODEC_MVC_EXT_PIC_PARAMS mvcExtPicParams)2225 MOS_STATUS CodechalDecodeAvc::DumpMvcExtPicParams(
2226 PCODEC_MVC_EXT_PIC_PARAMS mvcExtPicParams)
2227 {
2228 CODECHAL_DEBUG_FUNCTION_ENTER;
2229
2230 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrMvcExtPicParams))
2231 {
2232 return MOS_STATUS_SUCCESS;
2233 }
2234 CODECHAL_DEBUG_CHK_NULL(mvcExtPicParams);
2235
2236 std::ostringstream oss;
2237 oss.setf(std::ios::showbase | std::ios::uppercase);
2238
2239 oss << "CurrViewID: " << std::hex << +mvcExtPicParams->CurrViewID << std::endl;
2240 oss << "anchor_pic_flag: " << +mvcExtPicParams->anchor_pic_flag << std::endl;
2241 oss << "inter_view_flag: " << +mvcExtPicParams->inter_view_flag << std::endl;
2242 oss << "NumInterViewRefsL0: " << +mvcExtPicParams->NumInterViewRefsL0 << std::endl;
2243 oss << "NumInterViewRefsL1: " << +mvcExtPicParams->NumInterViewRefsL1 << std::endl;
2244 oss << "bPicFlags: " << +mvcExtPicParams->bPicFlags << std::endl;
2245 oss << "SwitchToAVC: " << +mvcExtPicParams->SwitchToAVC << std::endl;
2246 oss << "Reserved7Bits: " << +mvcExtPicParams->Reserved7Bits << std::endl;
2247 oss << "Reserved8Bits: " << +mvcExtPicParams->Reserved8Bits << std::endl;
2248
2249 //Dump ViewIDList[16]
2250 for (uint8_t i = 0; i < 16; ++i)
2251 {
2252 oss << "ViewIDList[" << +i << "]: "
2253 << +mvcExtPicParams->ViewIDList[i] << std::endl;
2254 }
2255
2256 //Dump InterViewRefList[2][16]
2257 for (uint8_t i = 0; i < 16; ++i)
2258 {
2259 oss << "InterViewRefList[0][" << +i << "]: "
2260 << +mvcExtPicParams->InterViewRefList[0][i] << std::endl;
2261 oss << "InterViewRefList[1][" << +i << "]: "
2262 << +mvcExtPicParams->InterViewRefList[1][i] << std::endl;
2263 }
2264
2265 const char *fileName = m_debugInterface->CreateFileName(
2266 "_DEC",
2267 CodechalDbgBufferType::bufMvcPicParams,
2268 CodechalDbgExtType::txt);
2269
2270 std::ofstream ofs(fileName, std::ios::out);
2271 ofs << oss.str();
2272 ofs.close();
2273
2274 return MOS_STATUS_SUCCESS;
2275 }
2276
DumpPicParams(PCODEC_AVC_PIC_PARAMS picParams)2277 MOS_STATUS CodechalDecodeAvc::DumpPicParams(
2278 PCODEC_AVC_PIC_PARAMS picParams)
2279 {
2280 CODECHAL_DEBUG_FUNCTION_ENTER;
2281
2282 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrPicParams))
2283 {
2284 return MOS_STATUS_SUCCESS;
2285 }
2286
2287 CODECHAL_DEBUG_CHK_NULL(picParams);
2288
2289 std::ostringstream oss;
2290 oss.setf(std::ios::showbase | std::ios::uppercase);
2291
2292 oss << "CurrPic FrameIdx: " << std::dec << +picParams->CurrPic.FrameIdx << std::endl;
2293 oss << "CurrPic PicFlags: " << std::hex << +picParams->CurrPic.PicFlags << std::endl;
2294
2295 //Dump RefFrameList[15]
2296 for (uint8_t i = 0; i < 15; ++i)
2297 {
2298 oss << "RefFrameList[" << std::dec << +i << "] FrameIdx:" << +picParams->RefFrameList[i].FrameIdx << std::endl;
2299 oss << "RefFrameList[" << +i << "] PicFlags:" << std::hex << +picParams->RefFrameList[i].PicFlags << std::endl;
2300 }
2301
2302 oss << "pic_width_in_mbs_minus1: " << std::dec << +picParams->pic_width_in_mbs_minus1 << std::endl;
2303 oss << "pic_height_in_mbs_minus1: " << +picParams->pic_height_in_mbs_minus1 << std::endl;
2304 oss << "bit_depth_luma_minus8: " << +picParams->bit_depth_luma_minus8 << std::endl;
2305 oss << "bit_depth_chroma_minus8: " << +picParams->bit_depth_chroma_minus8 << std::endl;
2306 oss << "num_ref_frames: " << +picParams->num_ref_frames << std::endl;
2307 oss << "CurrFieldOrderCnt: " << +picParams->CurrFieldOrderCnt[0] << std::endl;
2308 oss << "CurrFieldOrderCnt: " << +picParams->CurrFieldOrderCnt[1] << std::endl;
2309
2310 //Dump FieldOrderCntList (16x2)
2311 for (uint8_t i = 0; i < 2; ++i)
2312 {
2313 oss << "FieldOrderCntList[" << +i << "]:";
2314 for (uint8_t j = 0; j < 16; j++)
2315 oss << +picParams->FieldOrderCntList[j][i] << " ";
2316 oss << std::endl;
2317 }
2318
2319 //Dump seq_fields
2320 oss << "seq_fields value: " << +picParams->seq_fields.value << std::endl;
2321 oss << "chroma_format_idc: " << +picParams->seq_fields.chroma_format_idc << std::endl;
2322 oss << "residual_colour_transform_flag: " << std::hex << +picParams->seq_fields.residual_colour_transform_flag << std::endl;
2323 oss << "frame_mbs_only_flag: " << std::hex << +picParams->seq_fields.frame_mbs_only_flag << std::endl;
2324 oss << "mb_adaptive_frame_field_flag: " << std::hex << +picParams->seq_fields.mb_adaptive_frame_field_flag << std::endl;
2325 oss << "direct_8x8_inference_flag: " << std::hex << +picParams->seq_fields.direct_8x8_inference_flag << std::endl;
2326 oss << "log2_max_frame_num_minus4: " << std::dec << +picParams->seq_fields.log2_max_frame_num_minus4 << std::endl;
2327 oss << "pic_order_cnt_type: " << +picParams->seq_fields.pic_order_cnt_type << std::endl;
2328 oss << "log2_max_pic_order_cnt_lsb_minus4: " << +picParams->seq_fields.log2_max_pic_order_cnt_lsb_minus4 << std::endl;
2329 oss << "delta_pic_order_always_zero_flag: " << std::hex << +picParams->seq_fields.delta_pic_order_always_zero_flag << std::endl;
2330 oss << "num_slice_groups_minus1:" << std::dec << +picParams->num_slice_groups_minus1 << std::endl;
2331 oss << "slice_group_map_type:" << std::dec << +picParams->slice_group_map_type << std::endl;
2332 oss << "slice_group_change_rate_minus1:" << std::dec << +picParams->slice_group_change_rate_minus1 << std::endl;
2333 oss << "pic_init_qp_minus26:" << std::dec << +picParams->pic_init_qp_minus26 << std::endl;
2334 oss << "chroma_qp_index_offset:" << std::dec << +picParams->chroma_qp_index_offset << std::endl;
2335 oss << "second_chroma_qp_index_offset:" << std::dec << +picParams->second_chroma_qp_index_offset << std::endl;
2336
2337 //Dump pic_fields
2338 oss << "pic_fields value: " << std::dec << +picParams->pic_fields.value << std::endl;
2339 oss << "entropy_coding_mode_flag: " << std::hex << +picParams->pic_fields.entropy_coding_mode_flag << std::endl;
2340 oss << "weighted_pred_flag: " << std::hex << +picParams->pic_fields.weighted_pred_flag << std::endl;
2341 oss << "weighted_bipred_idc: " << std::dec << +picParams->pic_fields.weighted_bipred_idc << std::endl;
2342 oss << "transform_8x8_mode_flag: " << std::hex << +picParams->pic_fields.transform_8x8_mode_flag << std::endl;
2343 oss << "field_pic_flag: " << std::hex << +picParams->pic_fields.field_pic_flag << std::endl;
2344 oss << "constrained_intra_pred_flag: " << std::hex << +picParams->pic_fields.constrained_intra_pred_flag << std::endl;
2345 oss << "pic_order_present_flag: " << std::hex << +picParams->pic_fields.pic_order_present_flag << std::endl;
2346 oss << "deblocking_filter_control_present_flag: " << std::hex << +picParams->pic_fields.deblocking_filter_control_present_flag << std::endl;
2347 oss << "redundant_pic_cnt_present_flag: " << std::hex << +picParams->pic_fields.redundant_pic_cnt_present_flag << std::endl;
2348 oss << "reference_pic_flag: " << std::hex << +picParams->pic_fields.reference_pic_flag << std::endl;
2349 oss << "IntraPicFlag: " << std::hex << +picParams->pic_fields.IntraPicFlag << std::endl;
2350
2351 //Dump Short format specific
2352 oss << "num_ref_idx_l0_active_minus1: " << std::dec << +picParams->num_ref_idx_l0_active_minus1 << std::endl;
2353 oss << "num_ref_idx_l1_active_minus1: " << std::dec << +picParams->num_ref_idx_l1_active_minus1 << std::endl;
2354 oss << "NonExistingFrameFlags: " << std::hex << +picParams->NonExistingFrameFlags << std::endl;
2355 oss << "UsedForReferenceFlags: " << std::hex << +picParams->UsedForReferenceFlags << std::endl;
2356 oss << "frame_num: " << std::dec << +picParams->frame_num << std::endl;
2357 oss << "StatusReportFeedbackNumber: " << std::dec << +picParams->StatusReportFeedbackNumber << std::endl;
2358
2359 //Dump FrameNumList[16]
2360 oss << "scaling_list_present_flag_buffer:";
2361 for (uint8_t i = 0; i < 16; i++)
2362 oss << std::hex << picParams->FrameNumList[i];
2363 oss << std::endl;
2364
2365 const char *fileName = m_debugInterface->CreateFileName(
2366 "_DEC",
2367 CodechalDbgBufferType::bufPicParams,
2368 CodechalDbgExtType::txt);
2369
2370 std::ofstream ofs(fileName, std::ios::out);
2371 ofs << oss.str();
2372 ofs.close();
2373 return MOS_STATUS_SUCCESS;
2374 }
2375
DumpSliceParams(PCODEC_AVC_SLICE_PARAMS sliceParams,uint32_t numSlices)2376 MOS_STATUS CodechalDecodeAvc::DumpSliceParams(
2377 PCODEC_AVC_SLICE_PARAMS sliceParams,
2378 uint32_t numSlices)
2379 {
2380 CODECHAL_DEBUG_FUNCTION_ENTER;
2381
2382 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSlcParams))
2383 {
2384 return MOS_STATUS_SUCCESS;
2385 }
2386
2387 CODECHAL_DEBUG_CHK_NULL(sliceParams);
2388
2389 PCODEC_AVC_SLICE_PARAMS sliceControl = nullptr;
2390
2391 std::ostringstream oss;
2392 oss.setf(std::ios::showbase | std::ios::uppercase);
2393
2394 for (uint16_t j = 0; j < numSlices; j++)
2395 {
2396 sliceControl = &sliceParams[j];
2397
2398 oss << "Data for Slice number = " << std::dec << +j << std::endl;
2399 oss << "slice_data_size: " << std::dec << +sliceControl->slice_data_size << std::endl;
2400 oss << "slice_data_offset: " << std::dec << +sliceControl->slice_data_offset << std::endl;
2401 //Dump Long format specific
2402 oss << "slice_data_bit_offset: " << std::dec << +sliceControl->slice_data_bit_offset << std::endl;
2403 oss << "first_mb_in_slice: " << std::dec << +sliceControl->first_mb_in_slice << std::endl;
2404 oss << "NumMbsForSlice: " << std::dec << +sliceControl->NumMbsForSlice << std::endl;
2405 oss << "slice_type: " << std::dec << +sliceControl->slice_type << std::endl;
2406 oss << "direct_spatial_mv_pred_flag: " << std::hex << +sliceControl->direct_spatial_mv_pred_flag << std::endl;
2407 oss << "num_ref_idx_l0_active_minus1: " << std::dec << +sliceControl->num_ref_idx_l0_active_minus1 << std::endl;
2408 oss << "num_ref_idx_l1_active_minus1: " << std::dec << +sliceControl->num_ref_idx_l1_active_minus1 << std::endl;
2409 oss << "cabac_init_idc: " << std::dec << +sliceControl->cabac_init_idc << std::endl;
2410 oss << "slice_qp_delta: " << std::dec << +sliceControl->slice_qp_delta << std::endl;
2411 oss << "disable_deblocking_filter_idc: " << std::dec << +sliceControl->disable_deblocking_filter_idc << std::endl;
2412 oss << "slice_alpha_c0_offset_div2: " << std::dec << +sliceControl->slice_alpha_c0_offset_div2 << std::endl;
2413 oss << "slice_beta_offset_div2: " << std::dec << +sliceControl->slice_beta_offset_div2 << std::endl;
2414
2415 //Dump RefPicList[2][32]
2416 for (uint8_t i = 0; i < 32; ++i)
2417 {
2418 oss << "RefPicList[0][" << std::dec << +i << "] FrameIdx: " << std::dec << +sliceControl->RefPicList[0][i].FrameIdx << std::endl;
2419 oss << "RefPicList[0][" << std::dec << +i << "] PicFlags: " << std::hex << +sliceControl->RefPicList[0][i].PicFlags << std::endl;
2420 oss << "RefPicList[1][" << std::dec << +i << "] FrameIdx: " << std::dec << +sliceControl->RefPicList[1][i].FrameIdx << std::endl;
2421 oss << "RefPicList[1][" << std::dec << +i << "] PicFlags: " << std::hex << +sliceControl->RefPicList[1][i].PicFlags << std::endl;
2422 }
2423
2424 oss << "luma_log2_weight_denom: " << std::dec << +sliceControl->luma_log2_weight_denom << std::endl;
2425 oss << "chroma_log2_weight_denom: " << std::dec << +sliceControl->chroma_log2_weight_denom << std::endl;
2426 oss << "slice_id: " << std::dec << +sliceControl->slice_id << std::endl;
2427
2428 //Dump Weights[2][32][3][2]
2429 for (uint8_t i = 0; i < 32; ++i)
2430 {
2431 oss << "Weights[0][" << std::dec << +i << "][0][0]: " << std::hex << +sliceControl->Weights[0][i][0][0] << std::endl;
2432 oss << "Weights[0][" << std::dec << +i << "][0][1]: " << std::hex << +sliceControl->Weights[0][i][0][1] << std::endl;
2433 oss << "Weights[0][" << std::dec << +i << "][1][0]: " << std::hex << +sliceControl->Weights[0][i][1][0] << std::endl;
2434 oss << "Weights[0][" << std::dec << +i << "][1][1]: " << std::hex << +sliceControl->Weights[0][i][1][1] << std::endl;
2435 oss << "Weights[1][" << std::dec << +i << "][0][0]: " << std::hex << +sliceControl->Weights[1][i][0][0] << std::endl;
2436 oss << "Weights[1][" << std::dec << +i << "][0][1]: " << std::hex << +sliceControl->Weights[1][i][0][1] << std::endl;
2437 oss << "Weights[1][" << std::dec << +i << "][1][0]: " << std::hex << +sliceControl->Weights[1][i][1][0] << std::endl;
2438 oss << "Weights[1][" << std::dec << +i << "][1][1]: " << std::hex << +sliceControl->Weights[1][i][1][1] << std::endl;
2439 oss << "Weights[0][" << std::dec << +i << "][2][0]: " << std::hex << +sliceControl->Weights[0][i][2][0] << std::endl;
2440 oss << "Weights[0][" << std::dec << +i << "][2][1]: " << std::hex << +sliceControl->Weights[0][i][2][1] << std::endl;
2441 oss << "Weights[1][" << std::dec << +i << "][2][0]: " << std::hex << +sliceControl->Weights[1][i][2][0] << std::endl;
2442 oss << "Weights[1][" << std::dec << +i << "][2][1]: " << std::hex << +sliceControl->Weights[1][i][2][1] << std::endl;
2443 }
2444
2445 const char *fileName = m_debugInterface->CreateFileName(
2446 "_DEC",
2447 CodechalDbgBufferType::bufSlcParams,
2448 CodechalDbgExtType::txt);
2449
2450 std::ofstream ofs;
2451 if (j == 0)
2452 {
2453 ofs.open(fileName, std::ios::out);
2454 }
2455 else
2456 {
2457 ofs.open(fileName, std::ios::app);
2458 }
2459 ofs << oss.str();
2460 ofs.close();
2461 }
2462
2463 return MOS_STATUS_SUCCESS;
2464 }
2465
DumpIQParams(PCODEC_AVC_IQ_MATRIX_PARAMS matrixData)2466 MOS_STATUS CodechalDecodeAvc::DumpIQParams(
2467 PCODEC_AVC_IQ_MATRIX_PARAMS matrixData)
2468 {
2469 CODECHAL_DEBUG_FUNCTION_ENTER;
2470
2471 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrIqParams))
2472 {
2473 return MOS_STATUS_SUCCESS;
2474 }
2475
2476 CODECHAL_DEBUG_CHK_NULL(matrixData);
2477
2478 std::ostringstream oss;
2479 oss.setf(std::ios::showbase | std::ios::uppercase);
2480
2481 uint32_t idx, idx2;
2482 // 4x4 block
2483 for (idx2 = 0; idx2 < 6; idx2++)
2484 {
2485 oss << "Qmatrix_H264_ScalingLists4x4[" << std::dec << +idx2 << "]:" << std::endl;
2486 for (idx = 0; idx < 12; idx += 4)
2487 {
2488 oss << "ScalingList4x4[" << std::dec << +idx / 4 << "]:";
2489 oss << std::hex << +matrixData->ScalingList4x4[idx2][idx] << " ";
2490 oss << std::hex << +matrixData->ScalingList4x4[idx2][idx + 1] << " ";
2491 oss << std::hex << +matrixData->ScalingList4x4[idx2][idx + 2] << " ";
2492 oss << std::hex << +matrixData->ScalingList4x4[idx2][idx + 3] << " ";
2493 oss << std::endl;
2494 }
2495 oss << std::endl;
2496 }
2497 // 8x8 block
2498 for (idx2 = 0; idx2 < 2; idx2++)
2499 {
2500 oss << "Qmatrix_H264_ScalingLists8x8[" << std::dec << +idx2 << "]:" << std::endl;
2501 for (idx = 0; idx < 56; idx += 8)
2502 {
2503 oss << "ScalingList8x8[" << std::dec << +idx / 8 << "]:";
2504 oss << std::hex << +matrixData->ScalingList8x8[idx2][idx] << " " ;
2505 oss << std::hex << +matrixData->ScalingList8x8[idx2][idx + 1] << " " ;
2506 oss << std::hex << +matrixData->ScalingList8x8[idx2][idx + 2] << " " ;
2507 oss << std::hex << +matrixData->ScalingList8x8[idx2][idx + 3] << " " ;
2508 oss << std::hex << +matrixData->ScalingList8x8[idx2][idx + 4] << " " ;
2509 oss << std::hex << +matrixData->ScalingList8x8[idx2][idx + 5] << " " ;
2510 oss << std::hex << +matrixData->ScalingList8x8[idx2][idx + 6] << " " ;
2511 oss << std::hex << +matrixData->ScalingList8x8[idx2][idx + 7] << " " ;
2512 oss << std::endl;
2513 }
2514 oss << std::endl;
2515 }
2516
2517 const char *fileName = m_debugInterface->CreateFileName(
2518 "_DEC",
2519 CodechalDbgBufferType::bufIqParams,
2520 CodechalDbgExtType::txt);
2521
2522 std::ofstream ofs(fileName, std::ios::out);
2523 ofs << oss.str();
2524 ofs.close();
2525
2526 return MOS_STATUS_SUCCESS;
2527 }
2528 #endif
2529
SetFrameStoreIds(uint8_t frameIdx)2530 MOS_STATUS CodechalDecodeAvc::SetFrameStoreIds(uint8_t frameIdx)
2531 {
2532 CODECHAL_DECODE_CHK_NULL_RETURN(m_avcFrameStoreId);
2533
2534 uint8_t invalidFrame = 0x7f;
2535
2536 for (uint8_t i = 0; i < m_avcRefList[frameIdx]->ucNumRef; i++)
2537 {
2538 uint8_t index;
2539 index = m_avcRefList[frameIdx]->RefList[i].FrameIdx;
2540 if (m_avcRefList[index]->ucFrameId == invalidFrame)
2541 {
2542 uint8_t j;
2543 for (j = 0; j < CODEC_AVC_MAX_NUM_REF_FRAME; j++)
2544 {
2545 if (!m_avcFrameStoreId[j].inUse)
2546 {
2547 m_avcRefList[index]->ucFrameId = j;
2548 m_avcFrameStoreId[j].inUse = true;
2549 break;
2550 }
2551 }
2552 if (j == CODEC_AVC_MAX_NUM_REF_FRAME)
2553 {
2554 // should never happen, something must be wrong
2555 CODECHAL_PUBLIC_ASSERT(false);
2556 m_avcRefList[index]->ucFrameId = 0;
2557 m_avcFrameStoreId[0].inUse = true;
2558 }
2559 }
2560 }
2561 return MOS_STATUS_SUCCESS;
2562 }
2563