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