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