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_hevc_vdenc_422_packet.cpp
24 //! \brief Defines the interface to adapt to HEVC VDENC pipeline
25 //!
26
27 #include "encode_hevc_vdenc_422_packet.h"
28
29 namespace encode
30 {
AllocateResources()31 MOS_STATUS HevcVdencPkt422::AllocateResources()
32 {
33 ENCODE_FUNC_CALL();
34
35 ENCODE_CHK_STATUS_RETURN(HevcVdencPkt::AllocateResources());
36
37 const uint32_t picWidthInLCU = MOS_ROUNDUP_DIVIDE(m_basicFeature->m_frameWidth, 64);
38 const uint32_t picHeightInLCU = MOS_ROUNDUP_DIVIDE(m_basicFeature->m_frameHeight, 64);
39 m_422maxNumLCUs = picWidthInLCU * picHeightInLCU;
40 m_422mvOffset = MOS_ALIGN_CEIL((m_422maxNumLCUs * (MOS_BYTES_TO_DWORDS(sizeof(PakRSVD1))) * sizeof(uint32_t)), CODECHAL_PAGE_SIZE);
41 m_422mbCodeSize = m_422mvOffset + MOS_ALIGN_CEIL((m_422maxNumLCUs * 64 * sizeof(PakRSVD2)), CODECHAL_PAGE_SIZE);
42
43 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
44 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
45 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
46 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
47 allocParamsForBufferLinear.Format = Format_Buffer;
48 allocParamsForBufferLinear.dwMemType = MOS_MEMPOOL_SYSTEMMEMORY;
49 allocParamsForBufferLinear.Flags.bCacheable = true;
50 // for now we set ResUsageType to MOS_HW_RESOURCE_USAGE_ENCODE_OUTPUT_BITSTREAM rather than
51 // MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE to enable coherency in gmm
52 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_OUTPUT_BITSTREAM;
53
54 allocParamsForBufferLinear.dwBytes = m_422mbCodeSize;
55 allocParamsForBufferLinear.pBufName = "Standalone PAK Input Buffer";
56 m_res422MbCodeBuffer = m_allocator->AllocateResource(allocParamsForBufferLinear, false);
57 ENCODE_CHK_NULL_RETURN(m_res422MbCodeBuffer);
58
59 return MOS_STATUS_SUCCESS;
60 }
61
Conversion()62 MOS_STATUS HevcVdencPkt422::Conversion()
63 {
64 ENCODE_FUNC_CALL();
65
66 MOS_LOCK_PARAMS lockFlags;
67 MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
68 lockFlags.ReadOnly = 1;
69 uint8_t *mbCode420Buffer = (uint8_t *)m_osInterface->pfnLockResource(m_osInterface, m_basicFeature->m_resMbCodeBuffer, &lockFlags);
70 ENCODE_CHK_NULL_RETURN(mbCode420Buffer);
71 lockFlags.ReadOnly = 0;
72 lockFlags.WriteOnly = 1;
73 uint8_t *mbCode422Buffer = (uint8_t *)m_osInterface->pfnLockResource(m_osInterface, m_res422MbCodeBuffer, &lockFlags);
74 ENCODE_CHK_NULL_RETURN(mbCode422Buffer);
75
76 uint8_t *data = mbCode420Buffer;
77 uint8_t *tempPakRsvd1 = mbCode422Buffer;
78 uint8_t *tempPakRsvd2 = mbCode422Buffer + m_422mvOffset;
79
80 uint32_t opcode = 0x73A10000;
81 while ((uint32_t)(data - mbCode420Buffer) < m_basicFeature->m_mbCodeSize)
82 {
83 if (*((uint32_t *)data) == opcode)
84 break;
85 else
86 data += 4;
87 }
88
89 for (uint32_t i = 0; i < m_422maxNumLCUs; i++)
90 {
91 if (*((uint32_t *)data) != opcode)
92 {
93 ENCODE_ASSERTMESSAGE("VDEnc 420 pass not finished.");
94 break;
95 }
96
97 StreamoutRSVD1 *streamoutRsvd1 = (StreamoutRSVD1 *)data;
98 data += sizeof(StreamoutRSVD1);
99 for (int j = 0; j < 5; j++)
100 {
101 uint32_t *tempdata = (uint32_t *)tempPakRsvd1 + j;
102 *tempdata = j ? streamoutRsvd1->DW[j].DW0 : 0x73A10003;
103 }
104 PakRSVD1 *pakRsvd1 = (PakRSVD1 *)tempPakRsvd1;
105 tempPakRsvd1 += sizeof(PakRSVD1);
106
107 if ((pakRsvd1->DW1>>31)&0x01)
108 {
109 pakRsvd1->DW5 = 0x05000000;
110 }
111
112 uint32_t cuCount = 0;
113 for (; cuCount < 64; cuCount++)
114 {
115 StreamoutRSVD2 *streamoutRsvd2 = (StreamoutRSVD2 *)data;
116 data += sizeof(StreamoutRSVD2);
117 for (int j = 0; j < 8; j++)
118 {
119 uint32_t *tempdata = (uint32_t *)tempPakRsvd2 + j;
120 *tempdata = streamoutRsvd2->DW[j].DW0;
121 }
122 PakRSVD2 *pakRsvd2 = (PakRSVD2 *)tempPakRsvd2;
123 tempPakRsvd2 += sizeof(PakRSVD2);
124 pakRsvd2->DW7 &= 0xFF7FFFFF;
125
126 pakRsvd2->DW6 &= 0xFFBFFFFF;
127 pakRsvd2->DW4 &= 0x0000FFFF;
128
129 if(((pakRsvd2->DW6>>23)&0X01) || cuCount == 63)
130 {
131 pakRsvd1->DW1 &=0xC0FFFFFF;
132 pakRsvd1->DW1 += ((cuCount&0x3F)<<24);
133 pakRsvd2->DW6 &= 0xFF7FFFFF;
134 break;
135 }
136 pakRsvd2->DW6 &= 0xFF7FFFFF;
137 }
138 tempPakRsvd2 += (63 - cuCount) * sizeof(PakRSVD2);
139 }
140 PakRSVD1 *pakRsvd1 = (PakRSVD1 *)tempPakRsvd1;
141 pakRsvd1--;
142 pakRsvd1->DW5 = 0x05000000;
143
144 ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource(m_osInterface, m_basicFeature->m_resMbCodeBuffer));
145 ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnUnlockResource(m_osInterface, m_res422MbCodeBuffer));
146
147 return MOS_STATUS_SUCCESS;
148 }
149
Prepare()150 MOS_STATUS HevcVdencPkt422::Prepare()
151 {
152 ENCODE_FUNC_CALL();
153
154 ENCODE_CHK_NULL_RETURN(m_basicFeature);
155 ENCODE_CHK_NULL_RETURN(m_basicFeature->m_422State);
156 ENCODE_CHK_STATUS_RETURN(m_basicFeature->m_422State->Revert422Format(m_basicFeature->m_hevcSeqParams,
157 m_basicFeature->m_outputChromaFormat,
158 m_basicFeature->m_reconSurface.Format,
159 m_basicFeature->m_is10Bit));
160
161 ENCODE_CHK_STATUS_RETURN(HevcVdencPkt::Prepare());
162 ENCODE_CHK_STATUS_RETURN(Conversion());
163
164 return MOS_STATUS_SUCCESS;
165 }
166
Completed(void * mfxStatus,void * rcsStatus,void * statusReport)167 MOS_STATUS HevcVdencPkt422::Completed(void *mfxStatus, void *rcsStatus, void *statusReport)
168 {
169 ENCODE_FUNC_CALL();
170
171 ENCODE_CHK_NULL_RETURN(m_basicFeature);
172 ENCODE_CHK_NULL_RETURN(m_basicFeature->m_422State);
173
174 if (m_basicFeature->m_422State && m_basicFeature->m_422State->GetFeature422Flag())
175 {
176 ENCODE_CHK_STATUS_RETURN(HevcVdencPkt::Completed(mfxStatus, rcsStatus, statusReport));
177 }
178 else
179 {
180 // When 422 wa feature is not enabled, not need above complete options
181 return MOS_STATUS_SUCCESS;
182 }
183
184 return MOS_STATUS_SUCCESS;
185 }
186
PatchPictureLevelCommands(const uint8_t & packetPhase,MOS_COMMAND_BUFFER & cmdBuffer)187 MOS_STATUS HevcVdencPkt422::PatchPictureLevelCommands(const uint8_t &packetPhase, MOS_COMMAND_BUFFER &cmdBuffer)
188 {
189 ENCODE_FUNC_CALL();
190
191 ENCODE_CHK_STATUS_RETURN(m_miItf->SetWatchdogTimerThreshold(m_basicFeature->m_frameWidth, m_basicFeature->m_frameHeight, true));
192
193 SetPerfTag();
194
195 ENCODE_CHK_STATUS_RETURN(AddForceWakeup(cmdBuffer));
196
197 // Send command buffer header at the beginning (OS dependent)
198 ENCODE_CHK_STATUS_RETURN(SendPrologCmds(cmdBuffer));
199
200 ENCODE_CHK_STATUS_RETURN(StartStatusReport(statusReportMfx, &cmdBuffer));
201
202 ENCODE_CHK_STATUS_RETURN(AddPictureHcpCommands(cmdBuffer));
203
204 ENCODE_CHK_STATUS_RETURN(AddPicStateWithNoTile(cmdBuffer));
205
206 return MOS_STATUS_SUCCESS;
207 }
208
PatchSliceLevelCommands(MOS_COMMAND_BUFFER & cmdBuffer,uint8_t packetPhase)209 MOS_STATUS HevcVdencPkt422::PatchSliceLevelCommands(MOS_COMMAND_BUFFER &cmdBuffer, uint8_t packetPhase)
210 {
211 ENCODE_FUNC_CALL();
212
213 if (m_hevcPicParams->tiles_enabled_flag)
214 {
215 return MOS_STATUS_SUCCESS;
216 }
217 ENCODE_CHK_STATUS_RETURN(SetBatchBufferForPakSlices());
218
219 PCODEC_ENCODER_SLCDATA slcData = m_basicFeature->m_slcData;
220 for (uint32_t startLcu = 0, slcCount = 0; slcCount < m_basicFeature->m_numSlices; slcCount++)
221 {
222 if (m_pipeline->IsFirstPass())
223 {
224 slcData[slcCount].CmdOffset = startLcu * (m_hcpItf->GetHcpPakObjSize()) * sizeof(uint32_t);
225 }
226
227 m_basicFeature->m_curNumSlices = slcCount;
228
229 ENCODE_CHK_STATUS_RETURN(SendHwSliceEncodeCommand(slcData, slcCount, cmdBuffer));
230
231 startLcu += m_hevcSliceParams[slcCount].NumLCUsInSlice;
232
233 m_batchBufferForPakSlicesStartOffset = (uint32_t)m_batchBufferForPakSlices[m_basicFeature->m_currPakSliceIdx].iCurrent;
234 }
235
236 if (m_useBatchBufferForPakSlices)
237 {
238 ENCODE_CHK_STATUS_RETURN(Mhw_UnlockBb(
239 m_osInterface,
240 &m_batchBufferForPakSlices[m_basicFeature->m_currPakSliceIdx],
241 m_lastTaskInPhase));
242 }
243
244 // Insert end of sequence/stream if set
245 if (m_basicFeature->m_lastPicInSeq || m_basicFeature->m_lastPicInStream)
246 {
247 ENCODE_CHK_STATUS_RETURN(InsertSeqStreamEnd(cmdBuffer));
248 }
249
250 ENCODE_CHK_STATUS_RETURN(ReadHcpStatus(m_vdboxIndex, m_statusReport, cmdBuffer));
251 ENCODE_CHK_STATUS_RETURN(ReadExtStatistics(cmdBuffer));
252 ENCODE_CHK_STATUS_RETURN(ReadSliceSize(cmdBuffer));
253
254 ENCODE_CHK_STATUS_RETURN(EndStatusReport(statusReportMfx, &cmdBuffer));
255
256 if (m_osInterface->bInlineCodecStatusUpdate)
257 {
258 ENCODE_CHK_STATUS_RETURN(UpdateStatusReportNext(statusReportGlobalCount, &cmdBuffer));
259 }
260
261 CODECHAL_DEBUG_TOOL(
262 if (m_mmcState) {
263 m_mmcState->UpdateUserFeatureKey(&(m_basicFeature->m_reconSurface));
264 })
265 // Reset parameters for next PAK execution
266 if (false == m_pipeline->IsFrameTrackingEnabled() && m_pipeline->IsLastPass() && m_pipeline->IsLastPipe())
267 {
268 UpdateParameters();
269 }
270
271 return MOS_STATUS_SUCCESS;
272 }
273
AddPicStateWithNoTile(MOS_COMMAND_BUFFER & cmdBuffer)274 MOS_STATUS HevcVdencPkt422::AddPicStateWithNoTile(MOS_COMMAND_BUFFER &cmdBuffer)
275 {
276 ENCODE_FUNC_CALL();
277
278 bool tileEnabled = false;
279 RUN_FEATURE_INTERFACE_RETURN(HevcEncodeTile, HevcFeatureIDs::encodeTile, IsEnabled, tileEnabled);
280 if (tileEnabled)
281 {
282 return MOS_STATUS_SUCCESS;
283 }
284
285 SETPAR_AND_ADDCMD(HCP_PIC_STATE, m_hcpItf, &cmdBuffer);
286
287 SETPAR_AND_ADDCMD(HEVC_VP9_RDOQ_STATE, m_hcpItf, &cmdBuffer);
288
289 return MOS_STATUS_SUCCESS;
290 }
291
SendHwSliceEncodeCommand(const PCODEC_ENCODER_SLCDATA slcData,const uint32_t currSlcIdx,MOS_COMMAND_BUFFER & cmdBuffer)292 MOS_STATUS HevcVdencPkt422::SendHwSliceEncodeCommand(const PCODEC_ENCODER_SLCDATA slcData, const uint32_t currSlcIdx, MOS_COMMAND_BUFFER &cmdBuffer)
293 {
294 ENCODE_FUNC_CALL();
295
296 PMHW_BATCH_BUFFER batchBufferInUse = nullptr;
297 PMOS_COMMAND_BUFFER cmdBufferInUse = nullptr;
298
299 if (m_useBatchBufferForPakSlices)
300 {
301 batchBufferInUse = &m_batchBufferForPakSlices[m_basicFeature->m_currPakSliceIdx];
302 ENCODE_CHK_NULL_RETURN(batchBufferInUse);
303 }
304 else
305 {
306 cmdBufferInUse = &cmdBuffer;
307 }
308
309 ENCODE_CHK_STATUS_RETURN(AddAllCmds_HCP_REF_IDX_STATE(&cmdBuffer));
310
311 ENCODE_CHK_STATUS_RETURN(AddAllCmds_HCP_WEIGHTOFFSET_STATE(&cmdBuffer));
312
313 m_basicFeature->m_useDefaultRoundingForHcpSliceState = true;
314 SETPAR_AND_ADDCMD(HCP_SLICE_STATE, m_hcpItf, &cmdBuffer);
315
316 ENCODE_CHK_STATUS_RETURN(AddAllCmds_HCP_PAK_INSERT_OBJECT(&cmdBuffer));
317
318 if (m_useBatchBufferForPakSlices && batchBufferInUse)
319 {
320 ENCODE_CHK_STATUS_RETURN(m_miItf->AddMiBatchBufferEnd(nullptr, batchBufferInUse));
321
322 MHW_BATCH_BUFFER secondLevelBatchBuffer;
323 MOS_ZeroMemory(&secondLevelBatchBuffer, sizeof(MHW_BATCH_BUFFER));
324 secondLevelBatchBuffer.OsResource = batchBufferInUse->OsResource;
325 secondLevelBatchBuffer.dwOffset = m_batchBufferForPakSlicesStartOffset;
326 secondLevelBatchBuffer.bSecondLevel = true;
327 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_BATCH_BUFFER_START(&cmdBuffer, &secondLevelBatchBuffer)));
328 }
329
330 // Insert Batch Buffer Start command to send HCP_PAK_OBJ data for LCUs in this slice
331 MHW_BATCH_BUFFER secondLevelBatchBuffer;
332 MOS_ZeroMemory(&secondLevelBatchBuffer, sizeof(MHW_BATCH_BUFFER));
333 secondLevelBatchBuffer.OsResource = *m_res422MbCodeBuffer;
334 secondLevelBatchBuffer.dwOffset = slcData[currSlcIdx].CmdOffset;
335 secondLevelBatchBuffer.bSecondLevel = true;
336 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_BATCH_BUFFER_START(&cmdBuffer, &secondLevelBatchBuffer)));
337
338 return MOS_STATUS_SUCCESS;
339 }
340
AddForceWakeup(MOS_COMMAND_BUFFER & cmdBuffer)341 MOS_STATUS HevcVdencPkt422::AddForceWakeup(MOS_COMMAND_BUFFER &cmdBuffer)
342 {
343 ENCODE_FUNC_CALL();
344
345 auto &forceWakeupParams = m_miItf->MHW_GETPAR_F(MI_FORCE_WAKEUP)();
346 forceWakeupParams = {};
347 forceWakeupParams.bMFXPowerWellControl = false;
348 forceWakeupParams.bMFXPowerWellControlMask = true;
349 forceWakeupParams.bHEVCPowerWellControl = true;
350 forceWakeupParams.bHEVCPowerWellControlMask = true;
351
352 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MI_FORCE_WAKEUP)(&cmdBuffer));
353
354 return MOS_STATUS_SUCCESS;
355 }
356
AddHcpPipeModeSelect(MOS_COMMAND_BUFFER & cmdBuffer)357 MOS_STATUS HevcVdencPkt422::AddHcpPipeModeSelect(MOS_COMMAND_BUFFER &cmdBuffer)
358 {
359 ENCODE_FUNC_CALL();
360
361 auto &vdControlStateParams = m_miItf->MHW_GETPAR_F(VD_CONTROL_STATE)();
362 vdControlStateParams = {};
363 vdControlStateParams.initialization = true;
364
365 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(VD_CONTROL_STATE)(&cmdBuffer));
366
367 // for Gen11+, we need to add MFX wait for both KIN and VRT before and after HCP Pipemode select...
368 auto &mfxWaitParams = m_miItf->MHW_GETPAR_F(MFX_WAIT)();
369 mfxWaitParams = {};
370 mfxWaitParams.iStallVdboxPipeline = true;
371 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MFX_WAIT)(&cmdBuffer));
372
373 SETPAR_AND_ADDCMD(HCP_PIPE_MODE_SELECT, m_hcpItf, &cmdBuffer);
374
375 mfxWaitParams = {};
376 mfxWaitParams.iStallVdboxPipeline = true;
377 ENCODE_CHK_STATUS_RETURN(m_miItf->MHW_ADDCMD_F(MFX_WAIT)(&cmdBuffer));
378
379 return MOS_STATUS_SUCCESS;
380 }
381
MHW_SETPAR_DECL_SRC(HCP_PIPE_MODE_SELECT,HevcVdencPkt422)382 MHW_SETPAR_DECL_SRC(HCP_PIPE_MODE_SELECT, HevcVdencPkt422)
383 {
384 ENCODE_FUNC_CALL();
385
386 ENCODE_CHK_STATUS_RETURN(HevcVdencPkt::MHW_SETPAR_F(HCP_PIPE_MODE_SELECT)(params));
387
388 params.bVdencEnabled = false;
389 params.bBRCEnabled = false;
390 params.bAdvancedRateControlEnable = false;
391
392 ENCODE_CHK_NULL_RETURN(m_basicFeature);
393 ENCODE_CHK_NULL_RETURN(m_basicFeature->m_hevcSeqParams);
394 params.bStreamOutEnabled = m_basicFeature->m_hevcSeqParams->RateControlMethod != RATECONTROL_CQP;
395
396 return MOS_STATUS_SUCCESS;
397 }
398
MHW_SETPAR_DECL_SRC(HCP_SLICE_STATE,HevcVdencPkt422)399 MHW_SETPAR_DECL_SRC(HCP_SLICE_STATE, HevcVdencPkt422)
400 {
401 ENCODE_FUNC_CALL();
402
403 ENCODE_CHK_NULL_RETURN(m_basicFeature);
404 uint32_t currSlcIdx = m_basicFeature->m_curNumSlices;
405 PCODEC_HEVC_ENCODE_PICTURE_PARAMS hevcPicParams = (CODEC_HEVC_ENCODE_PICTURE_PARAMS *)m_hevcPicParams;
406
407 params.cabaczerowordinsertionenable = 1;
408 params.intrareffetchdisable = false;
409 params.tailInsertionEnable = (hevcPicParams->bLastPicInSeq || hevcPicParams->bLastPicInStream) && ((currSlcIdx == m_basicFeature->m_numSlices - 1));
410 params.roundintra = m_basicFeature->m_roundingIntra;
411 params.roundinter = m_basicFeature->m_roundingInter;
412 return MOS_STATUS_SUCCESS;
413 }
414
MHW_SETPAR_DECL_SRC(HCP_IND_OBJ_BASE_ADDR_STATE,HevcVdencPkt422)415 MHW_SETPAR_DECL_SRC(HCP_IND_OBJ_BASE_ADDR_STATE, HevcVdencPkt422)
416 {
417 ENCODE_FUNC_CALL();
418
419 params.presMvObjectBuffer = m_res422MbCodeBuffer;
420 params.dwMvObjectOffset = m_422mvOffset;
421 params.dwMvObjectSize = m_422mbCodeSize - m_422mvOffset;
422 params.presPakBaseObjectBuffer = &m_basicFeature->m_resBitstreamBuffer;
423 params.dwPakBaseObjectSize = m_basicFeature->m_bitstreamSize;
424
425 return MOS_STATUS_SUCCESS;
426 }
427
MHW_SETPAR_DECL_SRC(HCP_PIC_STATE,HevcVdencPkt422)428 MHW_SETPAR_DECL_SRC(HCP_PIC_STATE, HevcVdencPkt422)
429 {
430 params.sseEnable = false;
431 params.rhodomainRateControlEnable = false;
432 params.fractionalQpAdjustmentEnable = false;
433
434 ENCODE_CHK_NULL_RETURN(m_basicFeature);
435 ENCODE_CHK_NULL_RETURN(m_basicFeature->m_hevcSeqParams);
436 if (m_basicFeature->m_hevcSeqParams->RateControlMethod == RATECONTROL_CBR)
437 {
438 auto brcFeature = dynamic_cast<HEVCEncodeBRC *>(m_featureManager->GetFeature(HevcFeatureIDs::hevcBrcFeature));
439 ENCODE_CHK_NULL_RETURN(brcFeature);
440
441 auto vdenc2ndLevelBatchBuffer = brcFeature->GetVdenc2ndLevelBatchBuffer(m_pipeline->m_currRecycledBufIdx);
442 ENCODE_CHK_NULL_RETURN(vdenc2ndLevelBatchBuffer);
443
444 MOS_LOCK_PARAMS lockFlags;
445 MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
446 lockFlags.ReadOnly = 1;
447 uint32_t *data = (uint32_t *)m_osInterface->pfnLockResource(m_osInterface, &(vdenc2ndLevelBatchBuffer->OsResource), &lockFlags);
448 ENCODE_CHK_NULL_RETURN(data);
449
450 uint32_t value = *(data + m_basicFeature->m_picStateCmdStartInBytes / 4 + MINFRAMESIZE_OFFSET);
451 params.minframesize = (uint16_t)value;
452 params.minframesizeunits = (uint8_t)(value >> 30);
453
454 m_osInterface->pfnUnlockResource(m_osInterface, &(vdenc2ndLevelBatchBuffer->OsResource));
455 }
456
457 return MOS_STATUS_SUCCESS;
458 }
459
460
461 } // namespace encode
462