1 /*
2 * Copyright (c) 2018-2022, 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_vp9_vdenc_pipeline.cpp
24 //! \brief Defines the interface for vp9 vdenc encode pipeline
25 //!
26 #include "encode_vp9_brc.h"
27 #include "encode_vp9_hpu.h"
28 #include "encode_vp9_tile.h"
29 #include "encode_vp9_vdenc_pipeline.h"
30 #include "encode_vp9_vdenc_feature_manager.h"
31 #include "encode_utils.h"
32
33 namespace encode
34 {
Vp9VdencPipeline(CodechalHwInterfaceNext * hwInterface,CodechalDebugInterface * debugInterface)35 Vp9VdencPipeline::Vp9VdencPipeline(
36 CodechalHwInterfaceNext * hwInterface,
37 CodechalDebugInterface *debugInterface)
38 : Vp9Pipeline(hwInterface, debugInterface)
39 {
40
41 }
42
Initialize(void * settings)43 MOS_STATUS Vp9VdencPipeline::Initialize(void *settings)
44 {
45 ENCODE_FUNC_CALL();
46 ENCODE_CHK_STATUS_RETURN(Vp9Pipeline::Initialize(settings));
47
48 return MOS_STATUS_SUCCESS;
49 }
50
Uninitialize()51 MOS_STATUS Vp9VdencPipeline::Uninitialize()
52 {
53 ENCODE_FUNC_CALL();
54 return Vp9Pipeline::Uninitialize();
55 }
56
UserFeatureReport()57 MOS_STATUS Vp9VdencPipeline::UserFeatureReport()
58 {
59 ENCODE_FUNC_CALL();
60 ENCODE_CHK_STATUS_RETURN(Vp9Pipeline::UserFeatureReport());
61
62 auto basicFeature = dynamic_cast<Vp9BasicFeature *>(m_featureManager->GetFeature(Vp9FeatureIDs::basicFeature));
63 ENCODE_CHK_NULL_RETURN(basicFeature);
64 auto brcFeature = dynamic_cast<Vp9EncodeBrc *>(m_featureManager->GetFeature(Vp9FeatureIDs::vp9BrcFeature));
65 ENCODE_CHK_NULL_RETURN(brcFeature);
66 auto hpuFeature = dynamic_cast<Vp9EncodeHpu *>(m_featureManager->GetFeature(Vp9FeatureIDs::vp9HpuFeature));
67 ENCODE_CHK_NULL_RETURN(hpuFeature);
68
69 ENCODE_CHK_STATUS_RETURN(
70 ReportUserSettingValue("VP9 Encode Multipass BRC In Use",
71 brcFeature->IsMultipassBrcSupported(),
72 MediaUserSetting::Group::Sequence));
73
74 ENCODE_CHK_STATUS_RETURN(
75 ReportUserSettingValue("VP9 Encode Adaptive RePAK In Use",
76 basicFeature->m_adaptiveRepakSupported,
77 MediaUserSetting::Group::Sequence));
78
79 ENCODE_CHK_STATUS_RETURN(
80 ReportUserSettingValue("VP9 Encode HME",
81 basicFeature->m_hmeSupported,
82 MediaUserSetting::Group::Sequence));
83
84 ENCODE_CHK_STATUS_RETURN(
85 ReportUserSettingValue("VP9 Encode SuperHME",
86 basicFeature->m_16xMeSupported,
87 MediaUserSetting::Group::Sequence));
88
89 ENCODE_CHK_STATUS_RETURN(
90 ReportUserSettingValue("VP9 Encode HUC Enable",
91 basicFeature->m_hucEnabled,
92 MediaUserSetting::Group::Sequence));
93
94 ENCODE_CHK_STATUS_RETURN(
95 ReportUserSettingValue("Encode BRC In Use",
96 brcFeature->IsBrcEnabled(),
97 MediaUserSetting::Group::Sequence));
98
99 ENCODE_CHK_STATUS_RETURN(
100 ReportUserSettingValue("VDENC In Use",
101 1,
102 MediaUserSetting::Group::Sequence));
103
104 ENCODE_CHK_STATUS_RETURN(
105 ReportUserSettingValue("Disable Media Encode Scalability",
106 !basicFeature->m_scalableMode,
107 MediaUserSetting::Group::Sequence));
108
109 ENCODE_CHK_STATUS_RETURN(
110 ReportUserSettingValue("Enable Media Encode Scalability",
111 basicFeature->m_scalableMode,
112 MediaUserSetting::Group::Sequence));
113
114 ENCODE_CHK_STATUS_RETURN(
115 ReportUserSettingValue("VP9 Encode Mode",
116 basicFeature->m_codecFunction,
117 MediaUserSetting::Group::Sequence));
118
119 return MOS_STATUS_SUCCESS;
120 }
121
Prepare(void * params)122 MOS_STATUS Vp9VdencPipeline::Prepare(void *params)
123 {
124 EncoderParams *encodeParams = (EncoderParams *)params;
125
126 ENCODE_CHK_NULL_RETURN(encodeParams);
127
128 // TODO: Should check with m_codecFunction
129 if (encodeParams->ExecCodecFunction != CODECHAL_FUNCTION_ENC_VDENC_PAK)
130 {
131 return MOS_STATUS_INVALID_PARAMETER;
132 }
133
134 ENCODE_CHK_STATUS_RETURN(Vp9Pipeline::Prepare(params));
135
136 return MOS_STATUS_SUCCESS;
137 }
138
ActivateVdencVideoPackets()139 MOS_STATUS Vp9VdencPipeline::ActivateVdencVideoPackets()
140 {
141 ENCODE_FUNC_CALL();
142 ENCODE_CHK_NULL_RETURN(m_featureManager);
143
144 auto basicFeature = dynamic_cast<Vp9BasicFeature *>(m_featureManager->GetFeature(Vp9FeatureIDs::basicFeature));
145 ENCODE_CHK_NULL_RETURN(basicFeature);
146 auto brcFeature = dynamic_cast<Vp9EncodeBrc *>(m_featureManager->GetFeature(Vp9FeatureIDs::vp9BrcFeature));
147 ENCODE_CHK_NULL_RETURN(brcFeature);
148 bool immediateSubmit = !m_singleTaskPhaseSupported;
149
150 auto dysRefFrameFlags = basicFeature->m_ref.DysRefFrameFlags();
151
152 if (dysRefFrameFlags != DYS_REF_NONE && !basicFeature->m_dysVdencMultiPassEnabled)
153 {
154 ENCODE_CHK_STATUS_RETURN(ActivatePacket(Vp9DynamicScal, true, 0, 0));
155 m_activePacketList.back().frameTrackingRequested = false;
156 }
157
158 if (brcFeature->IsBrcInitRequired())
159 {
160 ENCODE_CHK_STATUS_RETURN(ActivatePacket(HucBrcInit, immediateSubmit, 0, 0))
161 }
162
163 bool tileEnabled = false;
164 RUN_FEATURE_INTERFACE_RETURN(Vp9EncodeTile, Vp9FeatureIDs::encodeTile, IsEnabled, tileEnabled);
165
166 for (uint8_t curPass = 0; curPass < GetPassNum(); curPass++)
167 {
168 auto isFirstPass = (curPass == 0);
169 auto isLastPass = (curPass == GetPassNum() - 1);
170
171 if (brcFeature->IsBrcUpdateRequired())
172 {
173 if (!isLastPass || (curPass == 0 && GetPassNum() == 0))
174 {
175 if (basicFeature->m_dysBrc && dysRefFrameFlags != DYS_REF_NONE)
176 {
177 ENCODE_CHK_STATUS_RETURN(ActivatePacket(HucBrcUpdate, true, curPass, 0));
178 m_activePacketList.back().frameTrackingRequested = false;
179 }
180 else
181 {
182 ENCODE_CHK_STATUS_RETURN(ActivatePacket(HucBrcUpdate, immediateSubmit, curPass, 0));
183 }
184 }
185 }
186
187 if (basicFeature->m_resolutionChanged && !brcFeature->IsBrcInit() && curPass == 0)
188 {
189 brcFeature->BrcReset(true);
190 ENCODE_CHK_STATUS_RETURN(ActivatePacket(HucBrcInit, immediateSubmit, 0, 0))
191 }
192
193 if (basicFeature->m_hucEnabled)
194 {
195 if (isFirstPass || isLastPass || brcFeature->IsVdencBrcEnabled())
196 {
197 ENCODE_CHK_STATUS_RETURN(ActivatePacket(Vp9HucProb, immediateSubmit, curPass, 0));
198 }
199 }
200
201 for (uint8_t curPipe = 0; curPipe < GetPipeNum(); curPipe++)
202 {
203 ENCODE_CHK_STATUS_RETURN(ActivatePacket(Vp9VdencPacket, immediateSubmit, curPass, curPipe, GetPipeNum()));
204 }
205
206 if (basicFeature->m_hucEnabled && tileEnabled && basicFeature->m_scalableMode)
207 {
208 ENCODE_CHK_STATUS_RETURN(ActivatePacket(Vp9PakIntegrate, immediateSubmit, curPass, 0));
209 }
210 }
211
212 SetFrameTrackingForMultiTaskPhase();
213
214 // Last element in m_activePacketList must be immediately submitted
215 m_activePacketList.back().immediateSubmit = true;
216 // In the case of Temporal Scalability, we need wait to request frame tracking until the last submission, in the super frame pass
217 if (dysRefFrameFlags == DYS_REF_NONE)
218 {
219 m_activePacketList.front().frameTrackingRequested = !basicFeature->m_vp9PicParams->PicFlags.fields.super_frame;
220 }
221
222 if (basicFeature->m_hucEnabled)
223 {
224 // For Temporal scaling, super frame pass need to explicitly submit the command buffer here to call HuC
225 if (basicFeature->m_vp9PicParams->PicFlags.fields.super_frame && basicFeature->m_tsEnabled)
226 {
227 ENCODE_CHK_STATUS_RETURN(ActivatePacket(Vp9HucSuperFrame, true, GetPassNum() - 1, GetPipeNum() - 1));
228 }
229 }
230
231 return MOS_STATUS_SUCCESS;
232 }
233
CreateFeatureManager()234 MOS_STATUS Vp9VdencPipeline::CreateFeatureManager()
235 {
236 ENCODE_FUNC_CALL();
237 m_featureManager = MOS_New(EncodeVp9VdencFeatureManager, m_allocator, m_hwInterface, m_trackedBuf, m_recycleBuf);
238 ENCODE_CHK_NULL_RETURN(m_featureManager);
239
240 return MOS_STATUS_SUCCESS;
241 }
242
243 } // namespace encode
244