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 //! \file encode_avc_vdenc_roi_interface.cpp
24 //! \brief implementation of basic ROI features of AVC VDENC
25
26 #include "encode_avc_vdenc_roi_interface.h"
27
28 #include "mos_defs.h"
29 #include "media_avc_feature_defs.h"
30 #include "encode_avc_vdenc_feature_manager.h"
31
32 namespace encode
33 {
34
AvcVdencRoiInterface(MediaFeatureManager * featureManager,EncodeAllocator * allocator,CodechalHwInterfaceNext * hwInterface,void * constSettings,SupportedModes & supportedModes)35 AvcVdencRoiInterface::AvcVdencRoiInterface(
36 MediaFeatureManager *featureManager,
37 EncodeAllocator *allocator,
38 CodechalHwInterfaceNext *hwInterface,
39 void *constSettings,
40 SupportedModes &supportedModes) :
41 MediaFeature(constSettings),
42 m_allocator(allocator),
43 m_hwInterface(hwInterface),
44 m_supportedModes(supportedModes)
45 {
46 m_featureManager = featureManager;
47 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_featureManager);
48
49 m_basicFeature = dynamic_cast<AvcBasicFeature*>(m_featureManager->GetFeature(AvcFeatureIDs::basicFeature));
50 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_basicFeature);
51
52 m_brcFeature = dynamic_cast<AvcEncodeBRC*>(m_featureManager->GetFeature(AvcFeatureIDs::avcBrcFeature));
53 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_brcFeature);
54
55 m_vdencStreamInFeature = dynamic_cast<AvcVdencStreamInFeature*>(m_featureManager->GetFeature(AvcFeatureIDs::avcVdencStreamInFeature));
56 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_vdencStreamInFeature);
57 }
58
Init(void * setting)59 MOS_STATUS AvcVdencRoiInterface::Init(void *setting)
60 {
61 ENCODE_FUNC_CALL();
62 ENCODE_CHK_NULL_RETURN(setting);
63
64 return MOS_STATUS_SUCCESS;
65 }
66
Update(void * params)67 MOS_STATUS AvcVdencRoiInterface::Update(void *params)
68 {
69 ENCODE_FUNC_CALL();
70 ENCODE_CHK_NULL_RETURN(params);
71 m_picParam = m_basicFeature->m_picParam;
72
73 if (m_basicFeature->m_mbQpDataEnabled)
74 {
75 ENCODE_CHK_STATUS_RETURN(IsModesSupported(m_supportedModes.MBQP_ForceQP | m_supportedModes.MBQP_DeltaQP, "MBQP"));
76 if (m_picParam->NumROI || m_picParam->NumDirtyROI)
77 {
78 ENCODE_ASSERTMESSAGE("MBQP feature is not compatible with ROI/DirtyROI\n");
79 return MOS_STATUS_INVALID_PARAMETER;
80 }
81 ENCODE_CHK_STATUS_RETURN(SetupMBQP());
82 }
83 else if (m_basicFeature->m_brcAdaptiveRegionBoostEnabled)
84 {
85 ENCODE_CHK_STATUS_RETURN(IsModesSupported(m_supportedModes.ArbROI, "ArbROI"));
86 if (m_picParam->NumROI || m_picParam->NumDirtyROI)
87 {
88 ENCODE_ASSERTMESSAGE("ROI/DirtyROI is not supported with ArbROI\n");
89 return MOS_STATUS_INVALID_PARAMETER;
90 }
91 ENCODE_CHK_STATUS_RETURN(SetupArbROI());
92 }
93 else if (m_picParam->NumROI)
94 {
95 ENCODE_CHK_STATUS_RETURN(IsModesSupported(m_supportedModes.ROI_Native | m_supportedModes.ROI_NonNative, "ROI"));
96
97 m_picParam->bNativeROI = ProcessRoiDeltaQp();
98 ENCODE_CHK_STATUS_RETURN(SetupROI());
99 }
100 else if (m_picParam->NumDirtyROI)
101 {
102 ENCODE_CHK_STATUS_RETURN(IsModesSupported(m_supportedModes.DirtyROI, "DirtyROI"));
103 ENCODE_CHK_STATUS_RETURN(SetupDirtyROI());
104 }
105
106 if (m_picParam->ForceSkip.Enable && (m_basicFeature->m_pictureCodingType != I_TYPE))
107 {
108 m_picParam->ForceSkip.Enable = 1;
109 ENCODE_CHK_STATUS_RETURN(SetupForceSkip());
110 }
111 else
112 m_picParam->ForceSkip.Enable = 0;
113
114 return MOS_STATUS_SUCCESS;
115 }
116
ProcessRoiDeltaQp()117 bool AvcVdencRoiInterface::ProcessRoiDeltaQp()
118 {
119 ENCODE_FUNC_CALL();
120
121 // Intialize ROIDistinctDeltaQp to be min expected delta qp, setting to -128
122 // Check if forceQp is needed or not
123 // forceQp is enabled if there are greater than 3 distinct delta qps or if the deltaqp is beyond range (-8, 7)
124 for (auto k = 0; k < m_maxNumRoi; k++)
125 {
126 m_picParam->ROIDistinctDeltaQp[k] = -128;
127 }
128
129 int32_t numQp = 0;
130 for (int32_t i = 0; i < m_picParam->NumROI; i++)
131 {
132 bool dqpNew = true;
133
134 //Get distinct delta Qps among all ROI regions, index 0 having the lowest delta qp
135 int32_t k = numQp - 1;
136 for (; k >= 0; k--)
137 {
138 if (m_picParam->ROI[i].PriorityLevelOrDQp == m_picParam->ROIDistinctDeltaQp[k] ||
139 m_picParam->ROI[i].PriorityLevelOrDQp == 0)
140 {
141 dqpNew = false;
142 break;
143 }
144 else if (m_picParam->ROI[i].PriorityLevelOrDQp < m_picParam->ROIDistinctDeltaQp[k])
145 {
146 continue;
147 }
148 else
149 {
150 break;
151 }
152 }
153
154 if (dqpNew)
155 {
156 for (int32_t j = numQp - 1; (j >= k + 1 && j >= 0); j--)
157 {
158 m_picParam->ROIDistinctDeltaQp[j + 1] = m_picParam->ROIDistinctDeltaQp[j];
159 }
160 m_picParam->ROIDistinctDeltaQp[k + 1] = m_picParam->ROI[i].PriorityLevelOrDQp;
161 numQp++;
162 }
163 }
164
165 //Set the ROI DeltaQp to zero for remaining array elements
166 for (auto k = numQp; k < m_maxNumRoi; k++)
167 {
168 m_picParam->ROIDistinctDeltaQp[k] = 0;
169 }
170
171 m_picParam->NumROIDistinctDeltaQp = (int8_t)numQp;
172
173 int32_t lastROIIdx = MOS_CLAMP_MIN_MAX(numQp - 1, 0, m_maxNumRoi - 1);
174
175 #if _MEDIA_RESERVED
176 return (!(numQp > m_maxNumNativeRoi || m_picParam->ROIDistinctDeltaQp[0] < -8 || m_picParam->ROIDistinctDeltaQp[lastROIIdx] > 7));
177 #else
178 bool bIsNativeROI = (!(numQp > m_maxNumNativeRoi || m_picParam->ROIDistinctDeltaQp[0] < -8 || m_picParam->ROIDistinctDeltaQp[lastROIIdx] > 7));
179 bool bIsNativeROIAllowed = !m_brcFeature->IsVdencBrcEnabled() || m_brcFeature->IsMbBrcEnabled(); // BRC native ROI require MBBRC on
180
181 // return whether is native ROI or not
182 return bIsNativeROI && bIsNativeROIAllowed;
183 #endif // _MEDIA_RESERVED
184 }
185
SetupROI()186 MOS_STATUS AvcVdencRoiInterface::SetupROI()
187 {
188 ENCODE_FUNC_CALL();
189 ENCODE_ASSERTMESSAGE("ROI feature is not supported");
190 return MOS_STATUS_INVALID_PARAMETER;
191 }
192
SetupDirtyROI()193 MOS_STATUS AvcVdencRoiInterface::SetupDirtyROI()
194 {
195 ENCODE_FUNC_CALL();
196 ENCODE_ASSERTMESSAGE("DirtyROI feature is not supported");
197 return MOS_STATUS_INVALID_PARAMETER;
198 }
199
SetupMBQP()200 MOS_STATUS AvcVdencRoiInterface::SetupMBQP()
201 {
202 ENCODE_FUNC_CALL();
203 ENCODE_ASSERTMESSAGE("MBQP feature is not supported");
204 return MOS_STATUS_INVALID_PARAMETER;
205 }
206
SetupForceSkip()207 MOS_STATUS AvcVdencRoiInterface::SetupForceSkip()
208 {
209 ENCODE_FUNC_CALL();
210 ENCODE_ASSERTMESSAGE("ForceSkip feature is not supported");
211 return MOS_STATUS_INVALID_PARAMETER;
212 }
213
SetupArbROI()214 MOS_STATUS AvcVdencRoiInterface::SetupArbROI()
215 {
216 ENCODE_FUNC_CALL();
217 ENCODE_ASSERTMESSAGE("ARB feature is not supported");
218 return MOS_STATUS_INVALID_PARAMETER;
219 }
220
IsModesSupported(uint32_t modes,std::string featureName)221 MOS_STATUS AvcVdencRoiInterface::IsModesSupported(uint32_t modes, std::string featureName)
222 {
223 if (modes == 0)
224 {
225 ENCODE_ASSERTMESSAGE("%s feature is not supported", featureName.c_str());
226 return MOS_STATUS_INVALID_PARAMETER;
227 }
228 return MOS_STATUS_SUCCESS;
229 }
230
GetDeltaQPIndex(uint32_t maxNumRoi,int32_t dqp,int32_t & dqpIdx)231 MOS_STATUS AvcVdencRoiInterface::GetDeltaQPIndex(uint32_t maxNumRoi, int32_t dqp, int32_t& dqpIdx)
232 {
233 ENCODE_FUNC_CALL();
234
235 dqpIdx = -1;
236 for (uint32_t j = 0; j < maxNumRoi; j++)
237 {
238 if (m_picParam->ROIDistinctDeltaQp[j] == dqp)
239 {
240 dqpIdx = j;
241 break;
242 }
243 }
244 if (dqpIdx == -1)
245 {
246 return MOS_STATUS_INVALID_PARAMETER;
247 }
248
249 return MOS_STATUS_SUCCESS;
250 }
251 }
252