1 /*
2 * Copyright (c) 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_jpeg_pipeline.cpp
24 //! \brief    Defines the interface for jpeg encode pipeline
25 //!
26 
27 #include "encode_jpeg_pipeline.h"
28 #include "encode_jpeg_basic_feature.h"
29 #include "encode_scalability_defs.h"
30 #include "encode_status_report_defs.h"
31 #include "encode_jpeg_packet.h"
32 #include "encode_jpeg_feature_manager.h"
33 
34 namespace encode {
35 
JpegPipeline(CodechalHwInterfaceNext * hwInterface,CodechalDebugInterface * debugInterface)36 JpegPipeline::JpegPipeline(
37     CodechalHwInterfaceNext *   hwInterface,
38     CodechalDebugInterface *debugInterface)
39     : EncodePipeline(hwInterface, debugInterface)
40 {
41 }
42 
Initialize(void * settings)43 MOS_STATUS JpegPipeline::Initialize(void *settings)
44 {
45     ENCODE_FUNC_CALL();
46 
47     CodechalSetting *codecSettings = (CodechalSetting *)settings;
48     ENCODE_CHK_NULL_RETURN(m_hwInterface);
49     ENCODE_CHK_STATUS_RETURN(m_hwInterface->Initialize(codecSettings));
50     ENCODE_CHK_STATUS_RETURN(InitMmcState());
51 
52     ENCODE_CHK_STATUS_RETURN(EncodePipeline::Initialize(settings));
53 
54     CODECHAL_DEBUG_TOOL(
55         if (m_debugInterface != nullptr) {
56             MOS_Delete(m_debugInterface);
57         }
58         m_debugInterface = MOS_New(CodechalDebugInterface);
59         ENCODE_CHK_NULL_RETURN(m_debugInterface);
60         ENCODE_CHK_NULL_RETURN(m_mediaCopyWrapper);
61         ENCODE_CHK_STATUS_RETURN(
62             m_debugInterface->Initialize(m_hwInterface, m_codecFunction, m_mediaCopyWrapper));
63 
64         if (m_statusReportDebugInterface != nullptr) {
65             MOS_Delete(m_statusReportDebugInterface);
66         }
67         m_statusReportDebugInterface = MOS_New(CodechalDebugInterface);
68         ENCODE_CHK_NULL_RETURN(m_statusReportDebugInterface);
69         ENCODE_CHK_STATUS_RETURN(
70             m_statusReportDebugInterface->Initialize(m_hwInterface, m_codecFunction, m_mediaCopyWrapper));
71     );
72 
73     ENCODE_CHK_STATUS_RETURN(GetSystemVdboxNumber());
74 
75     return MOS_STATUS_SUCCESS;
76 }
77 
Uninitialize()78 MOS_STATUS JpegPipeline::Uninitialize()
79 {
80     ENCODE_FUNC_CALL();
81     if (m_mmcState != nullptr)
82     {
83         MOS_Delete(m_mmcState);
84     }
85 
86     ENCODE_CHK_STATUS_RETURN(EncodePipeline::Uninitialize());
87     return MOS_STATUS_SUCCESS;
88 }
89 
UserFeatureReport()90 MOS_STATUS JpegPipeline::UserFeatureReport()
91 {
92     ENCODE_FUNC_CALL();
93 
94     ENCODE_CHK_STATUS_RETURN(EncodePipeline::UserFeatureReport());
95 
96     ReportUserSetting(
97         m_userSettingPtr,
98         "JPEG Encode Mode",
99         m_codecFunction,
100         MediaUserSetting::Group::Sequence);
101 
102 #if (_DEBUG || _RELEASE_INTERNAL)
103     ReportUserSettingForDebug(
104         m_userSettingPtr,
105         "Enable Encode VE CtxBasedScheduling",
106         MOS_VE_CTXBASEDSCHEDULING_SUPPORTED(m_osInterface),
107         MediaUserSetting::Group::Sequence);
108 #endif
109 
110     return MOS_STATUS_SUCCESS;
111 }
112 
Prepare(void * params)113 MOS_STATUS JpegPipeline::Prepare(void *params)
114 {
115     ENCODE_FUNC_CALL();
116 
117     EncoderParams *encodeParams = (EncoderParams *)params;
118     ENCODE_CHK_NULL_RETURN(encodeParams);
119 
120     //TODO: should check with m_codecFunction
121     if (encodeParams->ExecCodecFunction != CODECHAL_FUNCTION_ENC_VDENC_PAK &&
122         encodeParams->ExecCodecFunction != CODECHAL_FUNCTION_PAK)
123     {
124         return MOS_STATUS_INVALID_PARAMETER;
125     }
126 
127     ENCODE_CHK_STATUS_RETURN(EncodePipeline::Prepare(params));
128 
129     CodecEncodeJpegPictureParams *picParams = static_cast<CodecEncodeJpegPictureParams*>(encodeParams->pPicParams);
130     ENCODE_CHK_NULL_RETURN(picParams);
131 
132     auto basicFeature = dynamic_cast<JpegBasicFeature *>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
133     ENCODE_CHK_NULL_RETURN(basicFeature);
134 
135     basicFeature->m_bitstreamUpperBound = encodeParams->dwBitstreamSize;
136 
137     EncodeScalabilityPars scalPars;
138     MOS_ZeroMemory(&scalPars, sizeof(EncodeScalabilityPars));
139     scalPars.enableVE           = MOS_VE_SUPPORTED(m_osInterface);
140     scalPars.numVdbox           = m_numVdbox;
141     scalPars.forceMultiPipe     = false;
142     scalPars.outputChromaFormat = basicFeature->m_outputChromaFormat;
143     scalPars.numTileRows        = 1;
144     scalPars.numTileColumns     = 1;
145     scalPars.IsPak              = true;
146 
147     ENCODE_CHK_STATUS_RETURN(m_mediaContext->SwitchContext(VdboxEncodeFunc, &scalPars, &m_scalability));
148 
149     EncoderStatusParameters inputParameters = {};
150     MOS_ZeroMemory(&inputParameters, sizeof(EncoderStatusParameters));
151 
152     inputParameters.statusReportFeedbackNumber = picParams->m_statusReportFeedbackNumber;
153     inputParameters.codecFunction              = encodeParams->ExecCodecFunction;
154     inputParameters.currRefList                = basicFeature->m_ref->GetCurrRefList();
155     inputParameters.picWidthInMb               = basicFeature->m_picWidthInMb;
156     inputParameters.frameFieldHeightInMb       = basicFeature->m_frameFieldHeightInMb;
157     inputParameters.currOriginalPic            = basicFeature->m_currOriginalPic;
158     inputParameters.pictureCodingType          = basicFeature->m_pictureCodingType;
159     inputParameters.numUsedVdbox               = m_numVdbox;
160     inputParameters.hwWalker                   = false;
161     inputParameters.maxNumSlicesAllowed        = 1;
162     inputParameters.numberTilesInFrame         = 0;
163 
164     ENCODE_CHK_STATUS_RETURN(m_statusReport->Init(&inputParameters));
165 
166     return MOS_STATUS_SUCCESS;
167 }
168 
Execute()169 MOS_STATUS JpegPipeline::Execute()
170 {
171     ENCODE_FUNC_CALL();
172 
173     ENCODE_CHK_STATUS_RETURN(ActivateVideoPackets());
174     ENCODE_CHK_STATUS_RETURN(ExecuteActivePackets());
175     ENCODE_CHK_STATUS_RETURN(ResetParams());
176 
177     return MOS_STATUS_SUCCESS;
178 }
179 
GetStatusReport(void * status,uint16_t numStatus)180 MOS_STATUS JpegPipeline::GetStatusReport(void *status, uint16_t numStatus)
181 {
182     ENCODE_FUNC_CALL();
183 
184     ENCODE_CHK_STATUS_RETURN(m_statusReport->GetReport(numStatus, status));
185 
186     return MOS_STATUS_SUCCESS;
187 }
188 
Destroy()189 MOS_STATUS JpegPipeline::Destroy()
190 {
191     ENCODE_FUNC_CALL();
192 
193     ENCODE_CHK_STATUS_RETURN(Uninitialize());
194     return MOS_STATUS_SUCCESS;
195 }
196 
Init(void * settings)197 MOS_STATUS JpegPipeline::Init(void *settings)
198 {
199     ENCODE_FUNC_CALL();
200 
201     ENCODE_CHK_NULL_RETURN(settings);
202 
203     ENCODE_CHK_STATUS_RETURN(Initialize(settings));
204 
205     MediaTask *task = CreateTask(MediaTask::TaskType::cmdTask);
206     ENCODE_CHK_NULL_RETURN(task);
207 
208     JpegPkt *jpegPkt = MOS_New(JpegPkt, this, task, m_hwInterface);
209     ENCODE_CHK_STATUS_RETURN(RegisterPacket(baseJpegPacket, jpegPkt));
210     ENCODE_CHK_STATUS_RETURN(jpegPkt->Init());
211 
212     return MOS_STATUS_SUCCESS;
213 }
214 
ActivateVideoPackets()215 MOS_STATUS JpegPipeline::ActivateVideoPackets()
216 {
217     ENCODE_FUNC_CALL();
218 
219     bool immediateSubmit = !m_singleTaskPhaseSupported;
220 
221     ENCODE_CHK_STATUS_RETURN(ActivatePacket(baseJpegPacket, immediateSubmit, 0, 0));
222 
223     // Last element in m_activePacketList must be immediately submitted
224     m_activePacketList.back().immediateSubmit = true;
225 
226     return MOS_STATUS_SUCCESS;
227 }
228 
CreateBufferTracker()229 MOS_STATUS JpegPipeline::CreateBufferTracker()
230 {
231     return MOS_STATUS_SUCCESS;
232 }
233 
CreateStatusReport()234 MOS_STATUS JpegPipeline::CreateStatusReport()
235 {
236     return MOS_STATUS_SUCCESS;
237 }
238 
CreateFeatureManager()239 MOS_STATUS JpegPipeline::CreateFeatureManager()
240 {
241     ENCODE_FUNC_CALL();
242 
243     m_featureManager = MOS_New(EncodeJpegFeatureManager, m_allocator, m_hwInterface, m_trackedBuf, m_recycleBuf);
244     ENCODE_CHK_NULL_RETURN(m_featureManager);
245 
246     return MOS_STATUS_SUCCESS;
247 }
248 
ResetParams()249 MOS_STATUS JpegPipeline::ResetParams()
250 {
251     ENCODE_FUNC_CALL();
252 
253     auto feature = dynamic_cast<EncodeBasicFeature *>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
254     ENCODE_CHK_NULL_RETURN(feature);
255 
256     // Only update user features for first frame.
257     if (feature->m_frameNum == 0)
258     {
259         ENCODE_CHK_STATUS_RETURN(UserFeatureReport());
260     }
261 
262     feature->m_frameNum++;
263 
264     ENCODE_CHK_STATUS_RETURN(m_statusReport->Reset());
265 
266     return MOS_STATUS_SUCCESS;
267 }
268 
InitMmcState()269 MOS_STATUS JpegPipeline::InitMmcState()
270 {
271 #ifdef _MMC_SUPPORTED
272     ENCODE_CHK_NULL_RETURN(m_hwInterface);
273     m_mmcState = MOS_New(EncodeMemComp, m_hwInterface);
274     ENCODE_CHK_NULL_RETURN(m_mmcState);
275 #endif
276     return MOS_STATUS_SUCCESS;
277 }
278 
279 }
280