1 /*
2 * Copyright (c) 2020, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22
23 //!
24 //! \file decode_hevc_mem_compression.cpp
25 //! \brief Defines the common interface for Hevc decode mmc
26 //! \details The mmc is to handle mmc operations,
27 //! including compression and decompressin of Hevc decode
28 //!
29
30 #include "mos_defs.h"
31 #include "decode_hevc_mem_compression.h"
32
33 namespace decode
34 {
35
HevcDecodeMemComp(CodechalHwInterface * hwInterface)36 HevcDecodeMemComp::HevcDecodeMemComp(CodechalHwInterface *hwInterface)
37 {
38 m_osInterface = hwInterface->GetOsInterface();
39 }
40
SetRefSurfaceMask(HevcBasicFeature & hevcBasicFeature,const MHW_VDBOX_PIPE_BUF_ADDR_PARAMS & pipeBufAddrParams,MHW_VDBOX_SURFACE_PARAMS & refSurfaceParams)41 MOS_STATUS HevcDecodeMemComp::SetRefSurfaceMask(
42 HevcBasicFeature &hevcBasicFeature,
43 const MHW_VDBOX_PIPE_BUF_ADDR_PARAMS &pipeBufAddrParams,
44 MHW_VDBOX_SURFACE_PARAMS &refSurfaceParams)
45 {
46 if (hevcBasicFeature.m_isSCCIBCMode)
47 {
48 HevcReferenceFrames &refFrames = hevcBasicFeature.m_refFrames;
49 DECODE_ASSERT(hevcBasicFeature.m_hevcPicParams != nullptr);
50 const std::vector<uint8_t> &activeRefList = refFrames.GetActiveReferenceList(*hevcBasicFeature.m_hevcPicParams);
51
52 uint8_t IBCRefIdx = refFrames.m_IBCRefIdx;
53 DECODE_CHK_COND(activeRefList.size() <= IBCRefIdx, "Invalid IBC reference index.");
54 uint8_t IBCFrameIdx = activeRefList[IBCRefIdx];
55
56 uint8_t skipMask = 0;
57 for (uint8_t i = 0; i < CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC; i++)
58 {
59 if (pipeBufAddrParams.presReferences[i] == refFrames.GetReferenceByFrameIndex(IBCFrameIdx))
60 {
61 skipMask |= (1 << i);
62 }
63 }
64 refSurfaceParams.mmcSkipMask = skipMask;
65 DECODE_NORMALMESSAGE("IBC ref index %d, MMC skip mask %d,", IBCRefIdx, skipMask);
66 }
67
68 if (hevcBasicFeature.m_useDummyReference)
69 {
70 uint8_t skipMask = 0;
71 for (uint8_t i = 0; i < CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC; i++)
72 {
73 if (hevcBasicFeature.m_dummyReferenceSlot[i])
74 {
75 skipMask |= (1 << i);
76 }
77 }
78 refSurfaceParams.mmcSkipMask |= skipMask;
79 }
80
81 return MOS_STATUS_SUCCESS;
82 }
83
CheckReferenceList(HevcBasicFeature & hevcBasicFeature,MHW_VDBOX_PIPE_BUF_ADDR_PARAMS & pipeBufAddrParams)84 MOS_STATUS HevcDecodeMemComp::CheckReferenceList(
85 HevcBasicFeature &hevcBasicFeature, MHW_VDBOX_PIPE_BUF_ADDR_PARAMS &pipeBufAddrParams)
86 {
87 DECODE_FUNC_CALL();
88 DECODE_CHK_NULL(m_osInterface);
89
90 // Disable MMC if self-reference is dectected (mainly for error concealment)
91 if (!hevcBasicFeature.m_refFrames.m_curIsIntra)
92 {
93 if (pipeBufAddrParams.PostDeblockSurfMmcState != MOS_MEMCOMP_DISABLED ||
94 pipeBufAddrParams.PreDeblockSurfMmcState != MOS_MEMCOMP_DISABLED)
95 {
96 DECODE_ASSERT(hevcBasicFeature.m_hevcPicParams);
97 CODEC_HEVC_PIC_PARAMS &hevcPicParams = *(hevcBasicFeature.m_hevcPicParams);
98
99 for (uint8_t i = 0; i < CODEC_MAX_NUM_REF_FRAME_HEVC; i++)
100 {
101 if (hevcPicParams.CurrPic.FrameIdx == hevcPicParams.RefFrameList[i].FrameIdx)
102 {
103 DECODE_NORMALMESSAGE("Self-reference is detected for P/B frames!");
104 pipeBufAddrParams.PostDeblockSurfMmcState = MOS_MEMCOMP_DISABLED;
105 pipeBufAddrParams.PreDeblockSurfMmcState = MOS_MEMCOMP_DISABLED;
106
107 // Decompress current frame to avoid green corruptions in this error handling case
108 MOS_MEMCOMP_STATE mmcMode = MOS_MEMCOMP_DISABLED;
109 MOS_SURFACE &destSurface = hevcBasicFeature.m_destSurface;
110 DECODE_CHK_STATUS(m_osInterface->pfnGetMemoryCompressionMode(
111 m_osInterface, &destSurface.OsResource, &mmcMode));
112 if (mmcMode != MOS_MEMCOMP_DISABLED)
113 {
114 DECODE_CHK_STATUS(m_osInterface->pfnDecompResource(m_osInterface, &destSurface.OsResource));
115 }
116
117 break;
118 }
119 }
120 }
121 }
122
123 // Do surface decompression to make sure the MMC states are consistent in the reference list
124 bool sameMmcStatus = true;
125 MOS_MEMCOMP_STATE mmcModePrev = MOS_MEMCOMP_DISABLED;
126 for (uint8_t i = 0; i < CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC; i++)
127 {
128 if (pipeBufAddrParams.presReferences[i] != nullptr)
129 {
130 MOS_MEMCOMP_STATE mmcMode = MOS_MEMCOMP_DISABLED;
131 DECODE_CHK_STATUS(m_osInterface->pfnGetMemoryCompressionMode(
132 m_osInterface, pipeBufAddrParams.presReferences[i], &mmcMode));
133
134 if (i == 0)
135 {
136 mmcModePrev = mmcMode;
137 }
138 else if (mmcModePrev != mmcMode)
139 {
140 sameMmcStatus = false;
141 break;
142 }
143 }
144 }
145
146 if(!sameMmcStatus)
147 {
148 for (uint8_t i = 0; i < CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC; i++)
149 {
150 if (pipeBufAddrParams.presReferences[i] != nullptr)
151 {
152 MOS_MEMCOMP_STATE mmcMode = MOS_MEMCOMP_DISABLED;
153 DECODE_CHK_STATUS(m_osInterface->pfnGetMemoryCompressionMode(
154 m_osInterface, pipeBufAddrParams.presReferences[i], &mmcMode));
155 if(mmcMode != MOS_MEMCOMP_DISABLED)
156 {
157 m_osInterface->pfnDecompResource(m_osInterface, pipeBufAddrParams.presReferences[i]);
158 }
159 }
160 }
161 }
162
163 return MOS_STATUS_SUCCESS;
164 }
165
166 }
167