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