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