1 /*
2 * Copyright (c) 2018-2021, 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_hevc_vdenc_pipeline_xe_xpm_base.cpp
24 //! \brief    Defines the interface for hevc vdenc encode pipeline
25 //!
26 #include "encode_hevc_vdenc_pipeline_xe_xpm_base.h"
27 #include "encode_utils.h"
28 #include "encode_status_report_defs.h"
29 #include "encode_scalability_defs.h"
30 #include "encode_mem_compression_g12.h"
31 #include "encode_vdenc_lpla_analysis.h"
32 
33 namespace encode {
34 
HevcVdencPipelineXe_Xpm_Base(CodechalHwInterfaceNext * hwInterface,CodechalDebugInterface * debugInterface)35 HevcVdencPipelineXe_Xpm_Base::HevcVdencPipelineXe_Xpm_Base(
36     CodechalHwInterfaceNext     *hwInterface,
37     CodechalDebugInterface  *debugInterface)
38     : HevcVdencPipeline(hwInterface, debugInterface)
39 {
40 
41 }
42 
Init(void * settings)43 MOS_STATUS HevcVdencPipelineXe_Xpm_Base::Init(void *settings)
44 {
45     ENCODE_FUNC_CALL();
46 
47     return MOS_STATUS_SUCCESS;
48 }
49 
GetSystemVdboxNumber()50 MOS_STATUS HevcVdencPipelineXe_Xpm_Base::GetSystemVdboxNumber()
51 {
52     MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
53 
54     ENCODE_FUNC_CALL();
55 
56     ENCODE_CHK_STATUS_RETURN(EncodePipeline::GetSystemVdboxNumber());
57 
58     MediaUserSetting::Value outValue;
59     MOS_STATUS statusKey = MOS_STATUS_SUCCESS;
60     statusKey            = ReadUserSetting(
61         m_userSettingPtr,
62         outValue,
63         "Disable Media Encode Scalability",
64         MediaUserSetting::Group::Sequence);
65     bool disableScalability = m_hwInterface->IsDisableScalability();
66     if (statusKey == MOS_STATUS_SUCCESS)
67     {
68         disableScalability = outValue.Get<bool>();
69     }
70 
71     if (disableScalability)
72     {
73         m_numVdbox = 1;
74     }
75 
76     return eStatus;
77 }
78 
Prepare(void * params)79 MOS_STATUS HevcVdencPipelineXe_Xpm_Base::Prepare(void *params)
80 {
81     ENCODE_FUNC_CALL();
82     ENCODE_CHK_NULL_RETURN(params);
83     EncoderParams *encodeParams = (EncoderParams *)params;
84 
85     PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS hevcSeqParams = static_cast<PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS>(encodeParams->pSeqParams);
86     ENCODE_CHK_NULL_RETURN(hevcSeqParams);
87 
88     ENCODE_CHK_STATUS_RETURN(HevcVdencPipeline::Prepare(params));
89 
90     PCODEC_HEVC_ENCODE_PICTURE_PARAMS picParams = static_cast<PCODEC_HEVC_ENCODE_PICTURE_PARAMS>(encodeParams->pPicParams);
91     ENCODE_CHK_NULL_RETURN(picParams);
92 
93     auto feature = dynamic_cast<HevcBasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
94     ENCODE_CHK_NULL_RETURN(feature);
95 
96     EncodeScalabilityPars scalPars;
97     MOS_ZeroMemory(&scalPars, sizeof(EncodeScalabilityPars));
98     scalPars.enableVDEnc = true;
99     scalPars.enableVE = MOS_VE_SUPPORTED(m_osInterface);
100     scalPars.numVdbox = m_numVdbox;
101 
102     scalPars.forceMultiPipe = true;
103     scalPars.outputChromaFormat = feature->m_outputChromaFormat;
104 
105     RUN_FEATURE_INTERFACE_RETURN(HevcEncodeTile, FeatureIDs::encodeTile, GetTileRowColumns,
106         scalPars.numTileRows, scalPars.numTileColumns);
107 
108     scalPars.IsPak = true;
109 
110     RUN_FEATURE_INTERFACE_RETURN(HevcEncodeTile, FeatureIDs::encodeTile, IsTileReplayEnabled, scalPars.enableTileReplay);
111 
112     m_mediaContext->SwitchContext(VdboxEncodeFunc, &scalPars, &m_scalability);
113     ENCODE_CHK_NULL_RETURN(m_scalability);
114 
115     // Only multi-pipe contain tile report data
116     RUN_FEATURE_INTERFACE_RETURN(HevcEncodeTile, FeatureIDs::encodeTile, SetTileReportDataVaild,
117         (GetPipeNum() > 1));
118 
119     m_scalability->SetPassNumber(m_featureManager->GetNumPass());
120 
121     EncoderStatusParameters inputParameters = {};
122     MOS_ZeroMemory(&inputParameters, sizeof(EncoderStatusParameters));
123 
124 
125     inputParameters.statusReportFeedbackNumber = picParams->StatusReportFeedbackNumber;
126     inputParameters.codecFunction              = encodeParams->ExecCodecFunction;
127     inputParameters.currRefList                = feature->m_ref.GetCurrRefList();
128     inputParameters.picWidthInMb               = feature->m_picWidthInMb;
129     inputParameters.frameFieldHeightInMb       = feature->m_frameFieldHeightInMb;
130     inputParameters.currOriginalPic            = feature->m_currOriginalPic;
131     inputParameters.pictureCodingType          = feature->m_pictureCodingType;
132     inputParameters.numUsedVdbox               = m_numVdbox;
133     inputParameters.hwWalker                   = false;
134     inputParameters.maxNumSlicesAllowed        = 0;
135     inputParameters.numberTilesInFrame         = (picParams->num_tile_columns_minus1 + 1)*(picParams->num_tile_rows_minus1 + 1);
136 
137     m_statusReport->Init(&inputParameters);
138 
139     return MOS_STATUS_SUCCESS;
140 }
141 
Execute()142 MOS_STATUS HevcVdencPipelineXe_Xpm_Base::Execute()
143 {
144     ENCODE_FUNC_CALL();
145 
146     PERF_UTILITY_AUTO(__FUNCTION__, PERF_ENCODE, PERF_LEVEL_HAL);
147 
148     bool isTileReplayEnabled = false;
149     RUN_FEATURE_INTERFACE_RETURN(HevcEncodeTile, FeatureIDs::encodeTile, IsTileReplayEnabled, isTileReplayEnabled);
150     if (isTileReplayEnabled)
151     {
152         ENCODE_CHK_STATUS_RETURN(ActivateVdencTileReplayVideoPackets());
153     }
154     else
155     {
156         ENCODE_CHK_STATUS_RETURN(ActivateVdencVideoPackets());
157     }
158 
159     ENCODE_CHK_STATUS_RETURN(ExecuteActivePackets());
160 
161     ENCODE_CHK_STATUS_RETURN(ResetParams());
162 
163     return MOS_STATUS_SUCCESS;
164 }
165 
GetStatusReport(void * status,uint16_t numStatus)166 MOS_STATUS HevcVdencPipelineXe_Xpm_Base::GetStatusReport(void *status, uint16_t numStatus)
167 {
168     ENCODE_FUNC_CALL();
169     m_statusReport->GetReport(numStatus, status);
170 
171     return MOS_STATUS_SUCCESS;
172 }
173 
Destroy()174 MOS_STATUS HevcVdencPipelineXe_Xpm_Base::Destroy()
175 {
176     ENCODE_FUNC_CALL();
177 
178     ENCODE_CHK_STATUS_RETURN(Uninitialize());
179 
180     return MOS_STATUS_SUCCESS;
181 }
182 
Initialize(void * settings)183 MOS_STATUS HevcVdencPipelineXe_Xpm_Base::Initialize(void *settings)
184 {
185     ENCODE_FUNC_CALL();
186     ENCODE_CHK_STATUS_RETURN(InitMmcState());
187     CodechalSetting* codecSettings = (CodechalSetting*)settings;
188     codecSettings ->isMmcEnabled = m_mmcState ? m_mmcState->IsMmcEnabled() : false;
189     ENCODE_CHK_STATUS_RETURN(HevcVdencPipeline::Initialize(settings));
190 
191     CODECHAL_DEBUG_TOOL(
192         if (m_debugInterface != nullptr) {
193             MOS_Delete(m_debugInterface);
194         }
195         m_debugInterface = MOS_New(CodechalDebugInterface);
196         ENCODE_CHK_NULL_RETURN(m_debugInterface);
197         ENCODE_CHK_NULL_RETURN(m_mediaCopyWrapper);
198         ENCODE_CHK_STATUS_RETURN(
199             m_debugInterface->Initialize(m_hwInterface, m_codecFunction, m_mediaCopyWrapper));
200 
201         if (m_statusReportDebugInterface != nullptr) {
202             MOS_Delete(m_statusReportDebugInterface);
203         }
204         m_statusReportDebugInterface = MOS_New(CodechalDebugInterface);
205         ENCODE_CHK_NULL_RETURN(m_statusReportDebugInterface);
206         ENCODE_CHK_STATUS_RETURN(
207             m_statusReportDebugInterface->Initialize(m_hwInterface, m_codecFunction, m_mediaCopyWrapper)););
208     ENCODE_CHK_STATUS_RETURN(GetSystemVdboxNumber());
209 
210     return MOS_STATUS_SUCCESS;
211 }
212 
Uninitialize()213 MOS_STATUS HevcVdencPipelineXe_Xpm_Base::Uninitialize()
214 {
215     ENCODE_FUNC_CALL();
216 
217     if (m_mmcState != nullptr)
218     {
219         MOS_Delete(m_mmcState);
220     }
221 
222     ENCODE_CHK_STATUS_RETURN(HevcVdencPipeline::Uninitialize());
223 
224     return MOS_STATUS_SUCCESS;
225 }
226 
ResetParams()227 MOS_STATUS HevcVdencPipelineXe_Xpm_Base::ResetParams()
228 {
229     ENCODE_FUNC_CALL();
230 
231     m_currRecycledBufIdx =
232         (m_currRecycledBufIdx + 1) % CODECHAL_ENCODE_RECYCLED_BUFFER_NUM;
233 
234     if (m_currRecycledBufIdx == 0)
235     {
236         MOS_ZeroMemory(m_recycledBufStatusNum, sizeof(m_recycledBufStatusNum));
237     }
238 
239     auto feature = dynamic_cast<EncodeBasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
240     ENCODE_CHK_NULL_RETURN(feature);
241 
242     // Only update user features for first frame.
243     if (feature->m_frameNum == 0)
244     {
245         ENCODE_CHK_STATUS_RETURN(UserFeatureReport());
246     }
247 
248     feature->m_frameNum++;
249 
250     RUN_FEATURE_INTERFACE_RETURN(VdencLplaAnalysis, HevcFeatureIDs::vdencLplaAnalysisFeature, UpdateLaDataIdx);
251 
252     ENCODE_CHK_STATUS_RETURN(m_statusReport->Reset());
253 
254     return MOS_STATUS_SUCCESS;
255 }
256 
UserFeatureReport()257 MOS_STATUS HevcVdencPipelineXe_Xpm_Base::UserFeatureReport()
258 {
259     ENCODE_FUNC_CALL();
260 
261     ENCODE_CHK_STATUS_RETURN(HevcVdencPipeline::UserFeatureReport());
262 
263 #if (_DEBUG || _RELEASE_INTERNAL)
264     ReportUserSettingForDebug(
265         m_userSettingPtr,
266         "Enable Encode VE CtxBasedScheduling",
267         MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface),
268         MediaUserSetting::Group::Sequence);
269 #endif
270 
271     return MOS_STATUS_SUCCESS;
272 }
273 
InitMmcState()274 MOS_STATUS HevcVdencPipelineXe_Xpm_Base::InitMmcState()
275 {
276 #ifdef _MMC_SUPPORTED
277     ENCODE_CHK_NULL_RETURN(m_hwInterface);
278     m_mmcState = MOS_New(EncodeMemCompG12, m_hwInterface);
279     ENCODE_CHK_NULL_RETURN(m_mmcState);
280 #endif
281     return MOS_STATUS_SUCCESS;
282 }
283 
CreateFeatureManager()284 MOS_STATUS HevcVdencPipelineXe_Xpm_Base::CreateFeatureManager()
285 {
286     ENCODE_FUNC_CALL();
287     m_featureManager = MOS_New(EncodeHevcVdencFeatureManagerXe_Xpm_Base, m_allocator, m_hwInterface, m_trackedBuf, m_recycleBuf);
288     ENCODE_CHK_NULL_RETURN(m_featureManager);
289     return MOS_STATUS_SUCCESS;
290 }
291 
Reformat()292 MOS_STATUS HevcVdencPipelineXe_Xpm_Base::Reformat()
293 {
294     ENCODE_FUNC_CALL();
295     return MOS_STATUS_SUCCESS;
296 }
297 
PrepareReformat()298 MOS_STATUS HevcVdencPipelineXe_Xpm_Base::PrepareReformat()
299 {
300     ENCODE_FUNC_CALL();
301     return MOS_STATUS_SUCCESS;
302 }
303 
304 }
305