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.cpp
24 //! \brief Defines the interface for hevc vdenc encode pipeline
25 //!
26 #include "encode_hevc_vdenc_pipeline.h"
27 #include "codec_def_encode.h"
28 #include "encode_utils.h"
29 #include "encode_tile.h"
30 #include "encode_hevc_brc.h"
31 #include "encode_vdenc_lpla_analysis.h"
32
33 namespace encode {
34
HevcVdencPipeline(CodechalHwInterfaceNext * hwInterface,CodechalDebugInterface * debugInterface)35 HevcVdencPipeline::HevcVdencPipeline(
36 CodechalHwInterfaceNext * hwInterface,
37 CodechalDebugInterface *debugInterface)
38 : HevcPipeline(hwInterface, debugInterface)
39 {
40 }
41
Initialize(void * settings)42 MOS_STATUS HevcVdencPipeline::Initialize(void *settings)
43 {
44 ENCODE_FUNC_CALL();
45 ENCODE_CHK_STATUS_RETURN(HevcPipeline::Initialize(settings));
46 return MOS_STATUS_SUCCESS;
47 }
48
Uninitialize()49 MOS_STATUS HevcVdencPipeline::Uninitialize()
50 {
51 ENCODE_FUNC_CALL();
52 return HevcPipeline::Uninitialize();
53 }
54
UserFeatureReport()55 MOS_STATUS HevcVdencPipeline::UserFeatureReport()
56 {
57 ENCODE_FUNC_CALL();
58 ENCODE_CHK_STATUS_RETURN(HevcPipeline::UserFeatureReport());
59
60 #if (_DEBUG || _RELEASE_INTERNAL)
61 ReportUserSettingForDebug(
62 m_userSettingPtr,
63 "VDENC In Use",
64 1,
65 MediaUserSetting::Group::Sequence);
66 #endif
67
68 return MOS_STATUS_SUCCESS;
69 }
70
Prepare(void * params)71 MOS_STATUS HevcVdencPipeline::Prepare(void *params)
72 {
73 EncoderParams *encodeParams = (EncoderParams *)params;
74
75 ENCODE_CHK_NULL_RETURN(encodeParams);
76
77 if (encodeParams->ExecCodecFunction != CODECHAL_FUNCTION_ENC_VDENC_PAK)
78 {
79 return MOS_STATUS_INVALID_PARAMETER;
80 }
81
82 ENCODE_CHK_STATUS_RETURN(HevcPipeline::Prepare(params));
83
84 return MOS_STATUS_SUCCESS;
85 }
86
HuCCheckAndInit()87 MOS_STATUS HevcVdencPipeline::HuCCheckAndInit()
88 {
89 ENCODE_FUNC_CALL();
90
91 bool immediateSubmit = !m_singleTaskPhaseSupported;
92 ENCODE_CHK_STATUS_RETURN(ActivatePacket(HucBrcInit, immediateSubmit, 0, 0));
93
94 return MOS_STATUS_SUCCESS;
95 }
96
ActivateVdencVideoPackets()97 MOS_STATUS HevcVdencPipeline::ActivateVdencVideoPackets()
98 {
99 ENCODE_FUNC_CALL();
100
101 auto brcFeature = dynamic_cast<HEVCEncodeBRC*>(m_featureManager->GetFeature(HevcFeatureIDs::hevcBrcFeature));
102 ENCODE_CHK_NULL_RETURN(brcFeature);
103 bool immediateSubmit = !m_singleTaskPhaseSupported;
104
105 if (brcFeature->IsBRCInitRequired())
106 {
107 ENCODE_CHK_STATUS_RETURN(HuCCheckAndInit());
108 }
109
110 bool tileEnabled = false;
111 RUN_FEATURE_INTERFACE_RETURN(HevcEncodeTile, HevcFeatureIDs::encodeTile, IsEnabled, tileEnabled);
112
113 for (uint8_t curPass = 0; curPass < GetPassNum(); curPass++)
114 {
115 auto laAnalysisFeature = dynamic_cast<VdencLplaAnalysis *>(m_featureManager->GetFeature(HevcFeatureIDs::vdencLplaAnalysisFeature));
116 if (laAnalysisFeature && !laAnalysisFeature->IsLastPicInStream())
117 {
118 if (brcFeature->IsBRCUpdateRequired())
119 {
120 ENCODE_CHK_STATUS_RETURN(ActivatePacket(HucBrcUpdate, immediateSubmit, curPass, 0));
121 }
122
123 for (uint8_t curPipe = 0; curPipe < GetPipeNum(); curPipe++)
124 {
125 ENCODE_CHK_STATUS_RETURN(ActivatePacket(hevcVdencPacket, immediateSubmit, curPass, curPipe, GetPipeNum()));
126 }
127 }
128
129 if (laAnalysisFeature && laAnalysisFeature->IsLaAnalysisRequired())
130 {
131 if (!laAnalysisFeature->IsLastPicInStream())
132 {
133 if (laAnalysisFeature->IsLaInitRequired())
134 {
135 ENCODE_CHK_STATUS_RETURN(ActivatePacket(HucLaInit, immediateSubmit, 0, 0));
136 }
137 ENCODE_CHK_STATUS_RETURN(ActivatePacket(HucLaUpdate, immediateSubmit, curPass, 0));
138 }
139 else
140 {
141 // Flush the last frames
142 ENCODE_CHK_STATUS_RETURN(ActivatePacket(HucLaUpdate, immediateSubmit, curPass, 0));
143 }
144 }
145
146 if (tileEnabled)
147 {
148 ENCODE_CHK_STATUS_RETURN(ActivatePacket(hevcPakIntegrate, immediateSubmit, curPass, 0));
149 }
150 }
151
152 // Last element in m_activePacketList must be immediately submitted
153 m_activePacketList.back().immediateSubmit = true;
154
155 auto basicFeature = dynamic_cast<HevcBasicFeature *>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
156 ENCODE_CHK_NULL_RETURN(basicFeature);
157 if (basicFeature->m_422State && basicFeature->m_422State->GetFeature422Flag())
158 {
159 m_activePacketList.front().frameTrackingRequested = false;
160 ENCODE_CHK_STATUS_RETURN(ActivatePacket(hevcVdencPacket422, true, 0, 0));
161 }
162
163 SetFrameTrackingForMultiTaskPhase();
164
165 return MOS_STATUS_SUCCESS;
166 }
167
ActivateVdencTileReplayVideoPackets()168 MOS_STATUS HevcVdencPipeline::ActivateVdencTileReplayVideoPackets()
169 {
170 ENCODE_FUNC_CALL();
171
172 auto brcFeature = dynamic_cast<HEVCEncodeBRC*>(m_featureManager->GetFeature(HevcFeatureIDs::hevcBrcFeature));
173 ENCODE_CHK_NULL_RETURN(brcFeature);
174 bool immediateSubmit = !m_singleTaskPhaseSupported;
175
176 // BRC init
177 if (brcFeature->IsBRCInitRequired())
178 {
179 ENCODE_CHK_STATUS_RETURN(ActivatePacket(HucBrcInit, immediateSubmit, 0, 0));
180 }
181 // BRC frame level HuC update
182 if (brcFeature->IsBRCUpdateRequired())
183 {
184 ENCODE_CHK_STATUS_RETURN(ActivatePacket(HucBrcUpdate, immediateSubmit, 0, 0));
185 }
186
187 uint16_t numTileRows = 1;
188 uint16_t numTileColumns = 1;
189 RUN_FEATURE_INTERFACE_RETURN(HevcEncodeTile, HevcFeatureIDs::encodeTile, GetTileRowColumns, numTileRows, numTileColumns);
190
191 uint8_t numPassForTileReplay = brcFeature->IsBRCUpdateRequired() ? 2 : 1;
192
193 for (uint8_t curPipe = 0; curPipe < GetPipeNum(); curPipe++)
194 {
195 ENCODE_CHK_STATUS_RETURN(ActivatePacket(hevcVdencPicPacket, immediateSubmit, 0, curPipe, GetPipeNum()));
196 }
197
198 // Tile Row Level Update
199 for (uint8_t curRow = 0; curRow < numTileRows; curRow++)
200 {
201 for (uint8_t curPass = 0; curPass < numPassForTileReplay; curPass++)
202 {
203 for (uint8_t curPipe = 0; curPipe < GetPipeNum(); curPipe++)
204 {
205 // if 2nd pass, BRC tile row level HuC update
206 if (brcFeature->IsBRCUpdateRequired())
207 {
208 ENCODE_CHK_STATUS_RETURN(ActivatePacket(HucBrcTileRowUpdate, immediateSubmit, 0, 0));
209 }
210 // BRC tile row level ENC+PAK
211 ENCODE_CHK_STATUS_RETURN(ActivatePacket(hevcVdencTileRowPacket, immediateSubmit, 0, curPipe, GetPipeNum(), curPass, curRow));
212 }
213 }
214 }
215
216 // Frame Level Pak Integration
217 ENCODE_CHK_STATUS_RETURN(ActivatePacket(hevcPakIntegrate, immediateSubmit, 0, 0));
218
219 SetFrameTrackingForMultiTaskPhase();
220
221 // Last element in m_activePacketList must be immediately submitted
222 m_activePacketList.back().immediateSubmit = true;
223
224 return MOS_STATUS_SUCCESS;
225 }
226
CreateFeatureManager()227 MOS_STATUS HevcVdencPipeline::CreateFeatureManager()
228 {
229 ENCODE_FUNC_CALL();
230 m_featureManager = MOS_New(EncodeHevcVdencFeatureManager, m_allocator, m_hwInterface, m_trackedBuf, m_recycleBuf);
231 ENCODE_CHK_NULL_RETURN(m_featureManager);
232 return MOS_STATUS_SUCCESS;
233 }
234
SwitchContext(uint8_t outputChromaFormat,uint16_t numTileRows,uint16_t numTileColumns,bool enableTileReplay)235 MOS_STATUS HevcVdencPipeline::SwitchContext(uint8_t outputChromaFormat, uint16_t numTileRows, uint16_t numTileColumns, bool enableTileReplay)
236 {
237 ENCODE_FUNC_CALL();
238
239 if (!m_scalPars)
240 {
241 m_scalPars = std::make_shared<EncodeScalabilityPars>();
242 }
243
244 *m_scalPars = {};
245 m_scalPars->enableVDEnc = true;
246 m_scalPars->enableVE = MOS_VE_SUPPORTED(m_osInterface);
247 m_scalPars->numVdbox = m_numVdbox;
248
249 m_scalPars->forceMultiPipe = true;
250 m_scalPars->outputChromaFormat = outputChromaFormat;
251
252 m_scalPars->numTileRows = numTileRows;
253 m_scalPars->numTileColumns = numTileColumns;
254
255 m_scalPars->IsPak = true;
256
257 m_scalPars->enableTileReplay = enableTileReplay;
258
259 m_mediaContext->SwitchContext(VdboxEncodeFunc, &*m_scalPars, &m_scalability);
260 ENCODE_CHK_NULL_RETURN(m_scalability);
261
262 m_scalability->SetPassNumber(m_featureManager->GetNumPass());
263
264 return MOS_STATUS_SUCCESS;
265 }
266
267 }
268