1 /*
2 * Copyright (c) 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_av1_vdenc_fullenc.cpp
24 //! \brief    Defines the common interface for full-enc features
25 //!
26 
27 #include "encode_av1_basic_feature.h"
28 #include "encode_av1_vdenc_fullenc.h"
29 
30 namespace encode
31 {
Av1VdencFullEnc(MediaFeatureManager * featureManager,EncodeAllocator * allocator,CodechalHwInterfaceNext * hwInterface,void * constSettings)32     Av1VdencFullEnc::Av1VdencFullEnc(
33         MediaFeatureManager *featureManager,
34         EncodeAllocator *    allocator,
35         CodechalHwInterfaceNext *hwInterface,
36         void *               constSettings) :
37         MediaFeature(constSettings, hwInterface ? hwInterface->GetOsInterface() : nullptr)
38 
39     {
40         ENCODE_FUNC_CALL();
41 
42         ENCODE_CHK_NULL_NO_STATUS_RETURN(hwInterface);
43         CODEC_HW_ASSERT(hwInterface->GetOsInterface());
44         m_osInterface = hwInterface->GetOsInterface();
45 
46         m_allocator = allocator;
47 
48         m_basicFeature = dynamic_cast<Av1BasicFeature*>(featureManager->GetFeature(Av1FeatureIDs::basicFeature));
49         ENCODE_CHK_NULL_NO_STATUS_RETURN(m_basicFeature);
50         m_preEncFeature = dynamic_cast<Av1VdencPreEnc *>(featureManager->GetFeature(FeatureIDs::preEncFeature));
51         ENCODE_CHK_NULL_NO_STATUS_RETURN(m_preEncFeature);
52     }
53 
~Av1VdencFullEnc()54     Av1VdencFullEnc::~Av1VdencFullEnc()
55     {
56 #if USE_CODECHAL_DEBUG_TOOL
57         if (pfile0 != nullptr)
58         {
59             fclose(pfile0);
60             pfile0 = nullptr;
61         }
62         if (pfile1 != nullptr)
63         {
64             fclose(pfile1);
65             pfile1 = nullptr;
66         }
67 #endif
68     }
69 
Init(void * settings)70     MOS_STATUS Av1VdencFullEnc::Init(void *settings)
71     {
72         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
73 
74         ENCODE_FUNC_CALL();
75 
76 #if USE_CODECHAL_DEBUG_TOOL
77         CodechalSetting* codecSettings = (CodechalSetting *)settings;
78         MediaUserSetting::Value outValue;
79         ReadUserSetting(
80             m_userSettingPtr,
81             outValue,
82             "Set Media Encode Mode",
83             MediaUserSetting::Group::Sequence,
84             m_osInterface->pOsContext);
85         m_encodeMode = outValue.Get<uint32_t>();
86 #endif
87 
88         if (((m_encodeMode & FULL_ENC_PASS) == FULL_ENC_PASS))
89         {
90             m_enabled = true;
91         }
92 
93         return MOS_STATUS_SUCCESS;
94     }
95 
UpdatePreEncSize()96     MOS_STATUS Av1VdencFullEnc::UpdatePreEncSize()
97     {
98         ENCODE_FUNC_CALL();
99 
100         PreEncInfo preEncInfo = {};
101 
102         ENCODE_CHK_NULL_RETURN(m_preEncFeature);
103         MOS_STATUS status = m_preEncFeature->GetPreEncInfo(preEncInfo);
104 
105 #if USE_CODECHAL_DEBUG_TOOL
106         // if pre-enc is not enable (only fullEnc), GetPreEncInfo failed: recalculate
107         if (status != MOS_STATUS_SUCCESS)
108         {
109             ENCODE_CHK_NULL_RETURN(m_basicFeature);
110             uint32_t m_frameWidth  = m_basicFeature->m_frameWidth;
111             uint32_t m_frameHeight = m_basicFeature->m_frameHeight;
112             ENCODE_CHK_STATUS_RETURN(m_preEncFeature->CalculatePreEncInfo(m_frameWidth, m_frameHeight, preEncInfo));
113         }
114 #endif
115         EncodeFullencMember2 = preEncInfo.EncodePreEncInfo2;
116         EncodeFullencMember3 = preEncInfo.EncodePreEncInfo3;
117         EncodeFullencMember4 = preEncInfo.EncodePreEncInfo0;
118         EncodeFullencMember5 = preEncInfo.EncodePreEncInfo1;
119 
120         return MOS_STATUS_SUCCESS;
121     }
122 
UpdateTrackedBufferParameters()123     MOS_STATUS Av1VdencFullEnc::UpdateTrackedBufferParameters()
124     {
125         MOS_ALLOC_GFXRES_PARAMS allocParams;
126         MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
127         allocParams.Type     = MOS_GFXRES_BUFFER;
128         allocParams.TileType = MOS_TILE_LINEAR;
129         allocParams.Format   = Format_Buffer;
130 
131 #if USE_CODECHAL_DEBUG_TOOL
132         if (EncodeFullencMember5 > 0 && m_encodeMode == MediaEncodeMode::MANUAL_FULL_ENC)
133         {
134             allocParams.dwBytes  = EncodeFullencMember5 * sizeof(EncodePreencDef1);
135             allocParams.pBufName = "preencRef0";
136             allocParams.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE;
137             ENCODE_CHK_STATUS_RETURN(m_basicFeature->m_trackedBuf->RegisterParam(encode::BufferType::preencRef0, allocParams));
138             allocParams.pBufName = "preencRef1";
139             allocParams.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE;
140             ENCODE_CHK_STATUS_RETURN(m_basicFeature->m_trackedBuf->RegisterParam(encode::BufferType::preencRef1, allocParams));
141         }
142 #endif
143 
144         return MOS_STATUS_SUCCESS;
145     }
146 
Update(void * params)147     MOS_STATUS Av1VdencFullEnc::Update(void *params)
148     {
149         ENCODE_FUNC_CALL();
150 
151         if (!m_enabled)
152             return MOS_STATUS_SUCCESS;
153 
154         ENCODE_CHK_NULL_RETURN(m_basicFeature);
155 
156         ENCODE_CHK_STATUS_RETURN(UpdatePreEncSize());
157 
158         if (m_encodeMode == MediaEncodeMode::SINGLE_PRE_FULL_ENC)
159         {
160             m_preEncFeature->EncodePreencBasicFuntion0(EncodeFullencMember0, EncodeFullencMember1);
161         }
162         else
163         {
164             if (m_basicFeature->m_resolutionChanged)
165             {
166                 ENCODE_CHK_STATUS_RETURN(UpdateTrackedBufferParameters());
167             }
168             EncodeFullencMember0 = m_basicFeature->m_trackedBuf->GetBuffer(BufferType::preencRef0, m_basicFeature->m_trackedBuf->GetCurrIndex());
169             EncodeFullencMember1 = m_basicFeature->m_trackedBuf->GetBuffer(BufferType::preencRef1, m_basicFeature->m_trackedBuf->GetCurrIndex());
170 #if USE_CODECHAL_DEBUG_TOOL
171             ENCODE_CHK_STATUS_RETURN(EncodeFullencFuntion1());
172 #endif
173         }
174         return MOS_STATUS_SUCCESS;
175     }
176 
MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT,Av1VdencFullEnc)177     MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT, Av1VdencFullEnc)
178     {
179         if (!m_enabled)
180             return MOS_STATUS_SUCCESS;
181 
182         auto av1Feature = dynamic_cast<Av1BasicFeature*>(m_basicFeature);
183         ENCODE_CHK_NULL_RETURN(av1Feature);
184 
185         params.VdencPipeModeSelectPar2 = FULL_ENC_PASS;
186         // 0-No preencRef read/write, 1-preencRef read/write for ref0 only, 2-preencRef read/write for ref1 only, 3-preencRef read/write for both ref0 and ref1
187         if (av1Feature->m_pictureCodingType != I_TYPE && !av1Feature->m_ref.IsLowDelay())
188         {
189             params.VdencPipeModeSelectPar3 = 3;
190         }
191         else
192         {
193             params.VdencPipeModeSelectPar3 = 1;
194         }
195         params.VdencPipeModeSelectPar5 = EncodeFullencMember3;
196         params.VdencPipeModeSelectPar7 = EncodeFullencMember2;
197         params.VdencPipeModeSelectPar6 = EncodeFullencMember4;
198 
199         if (av1Feature->m_pictureCodingType == I_TYPE)
200         {
201             params.VdencPipeModeSelectPar2 = 0;
202             params.VdencPipeModeSelectPar4 = 0;
203             params.VdencPipeModeSelectPar3 = 0;
204             params.VdencPipeModeSelectPar5 = 0;
205             params.VdencPipeModeSelectPar7 = 0;
206             params.VdencPipeModeSelectPar6 = 0;
207         }
208 
209         return MOS_STATUS_SUCCESS;
210     }
211 
MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE,Av1VdencFullEnc)212     MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE, Av1VdencFullEnc)
213     {
214         if (!m_enabled)
215             return MOS_STATUS_SUCCESS;
216 
217         params.vdencPipeBufAddrStatePar0 = EncodeFullencMember0;
218         params.vdencPipeBufAddrStatePar1 = EncodeFullencMember1;
219 
220         return MOS_STATUS_SUCCESS;
221     }
222 
223 #if USE_CODECHAL_DEBUG_TOOL
EncodeFullencFuntion1()224     MOS_STATUS Av1VdencFullEnc::EncodeFullencFuntion1()
225     {
226         MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
227 
228         ENCODE_FUNC_CALL();
229 
230         if (!m_enabled)
231             return MOS_STATUS_SUCCESS;
232 
233         MediaUserSetting::Value outValue;
234         outValue = std::string();
235         eStatus = ReadUserSetting(
236             m_userSettingPtr,
237             outValue,
238             "Fullenc file0 path",
239             MediaUserSetting::Group::Sequence);
240 
241         int size = outValue.Size();
242         if (eStatus != MOS_STATUS_SUCCESS || size < 2)
243         {
244             ENCODE_NORMALMESSAGE("read Fullenc file0 path failed.");
245             return MOS_STATUS_SUCCESS;
246         }
247 
248         std::string path_file = outValue.Get<std::string>();
249         if (path_file[size - 2] != MOS_DIRECTORY_DELIMITER)
250         {
251             path_file.push_back('\0');
252         }
253         std::string filePath0 = path_file;
254 
255         outValue = std::string();
256         eStatus = ReadUserSetting(
257             m_userSettingPtr,
258             outValue,
259             "Fullenc file1 path",
260             MediaUserSetting::Group::Sequence);
261 
262         size = outValue.Size();
263 
264         if (eStatus != MOS_STATUS_SUCCESS || size < 2)
265         {
266             ENCODE_NORMALMESSAGE("read Fullenc file1 path failed.");
267             return MOS_STATUS_SUCCESS;
268         }
269 
270         path_file = outValue.Get<std::string>();
271         if (path_file[size - 2] != MOS_DIRECTORY_DELIMITER)
272         {
273             path_file.push_back('\0');
274         }
275         std::string filePath1 = path_file;
276 
277         auto av1Feature = dynamic_cast<Av1BasicFeature*>(m_basicFeature);
278         ENCODE_CHK_NULL_RETURN(av1Feature);
279         if (av1Feature->m_pictureCodingType > I_TYPE)
280         {
281             if (pfile0 == nullptr)
282             {
283                 ENCODE_CHK_STATUS_RETURN(MosUtilities::MosSecureFileOpen(&pfile0, filePath0.c_str(), "rb"));
284             }
285             void *data0 = m_allocator->LockResourceForWrite(EncodeFullencMember0);
286             if (pfile0 != nullptr)
287             {
288                 if (fread(data0, sizeof(EncodePreencDef1), EncodeFullencMember5, pfile0) != EncodeFullencMember5)
289                 {
290                     ENCODE_ASSERTMESSAGE("Error of reading file 0");
291                     ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(EncodeFullencMember0));
292                     return MOS_STATUS_FILE_READ_FAILED;
293                 }
294             }
295             ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(EncodeFullencMember0));
296         }
297         if (av1Feature->m_pictureCodingType != I_TYPE && !av1Feature->m_ref.IsLowDelay())
298         {
299             if (pfile1 == nullptr)
300             {
301                 ENCODE_CHK_STATUS_RETURN(MosUtilities::MosSecureFileOpen(&pfile1, filePath1.c_str(), "rb"));
302             }
303             void *data1 = m_allocator->LockResourceForWrite(EncodeFullencMember1);
304             if (pfile1 != nullptr)
305             {
306                 if (fread(data1, sizeof(EncodePreencDef1), EncodeFullencMember5, pfile1) != EncodeFullencMember5)
307                 {
308                     ENCODE_ASSERTMESSAGE("Error of reading file 1");
309                     ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(EncodeFullencMember0));
310                     return MOS_STATUS_FILE_READ_FAILED;
311                 }
312             }
313             ENCODE_CHK_STATUS_RETURN(m_allocator->UnLock(EncodeFullencMember1));
314         }
315 
316         return MOS_STATUS_SUCCESS;
317     }
318 #endif
319 }  // namespace encode
320