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