Skip to content

Commit 7a6ae69

Browse files
committed
encoder: move common encoder code to EncodeFrameCommon
Move common code from the codec-specific EncodeFrame to EncodeFrameCommon: - Assertions and basic encodeFrameInfo initialization - videoSession, videoSessionParameters, qualityLevel assignments - frameEncodeInputOrderNum increment and GOP position calculation - Control command handling (HandleCtrlCmd) - QP map processing (ProcessQpMap) - Intra refresh handling (FillIntraRefreshInfo) - Bitstream buffer acquisition (GetBitstreamBuffer) - Frame enqueuing (EnqueueFrame) Refactor rate control handling: - HandleCtrlCmd now returns bool indicating if rate control was sent - Add CodecHandleRateControlCmd pure virtual for codec-specific rate control chain setup (H264, H265, AV1 implement this) Remove bIsReference from AV1 codec-specific frame structure Additional changes: - Remove redundant bIsKeyFrame field from VkVideoEncodeFrameInfoAV1 (replaced by direct gopPosition.pictureType checks) - Extract maxEncodeQueueDepth calculation into named const variable Signed-off-by: Tony Zlatinski <[email protected]>
1 parent 9d60d37 commit 7a6ae69

File tree

8 files changed

+130
-228
lines changed

8 files changed

+130
-228
lines changed

vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoder.cpp

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,60 @@ VkResult VkVideoEncoder::EncodeFrameCommon(VkSharedBaseObj<VkVideoEncodeFrameInf
257257
{
258258
encodeFrameInfo->constQp = m_encoderConfig->constQp;
259259

260+
assert(encodeFrameInfo);
261+
assert(m_encoderConfig);
262+
assert(encodeFrameInfo->srcEncodeImageResource);
263+
264+
encodeFrameInfo->videoSession = m_videoSession;
265+
encodeFrameInfo->videoSessionParameters = m_videoSessionParameters;
266+
encodeFrameInfo->qualityLevel = m_encoderConfig->qualityLevel;
267+
268+
encodeFrameInfo->frameEncodeInputOrderNum = m_encodeInputFrameNum++;
269+
270+
// GetPositionInGOP() method returns display position of the picture relative to last key frame picture.
271+
const bool isIdr = m_encoderConfig->gopStructure.GetPositionInGOP(m_gopState,
272+
encodeFrameInfo->gopPosition,
273+
(encodeFrameInfo->frameEncodeInputOrderNum == 0),
274+
uint32_t(m_encoderConfig->numFrames - encodeFrameInfo->frameEncodeInputOrderNum));
275+
if (isIdr) {
276+
assert(encodeFrameInfo->gopPosition.pictureType == VkVideoGopStructure::FRAME_TYPE_IDR);
277+
}
278+
const bool isReference = m_encoderConfig->gopStructure.IsFrameReference(encodeFrameInfo->gopPosition);
279+
260280
// and encode the input frame with the encoder next
261-
return EncodeFrame(encodeFrameInfo);
281+
VkResult result = EncodeFrame(encodeFrameInfo);
282+
if (result != VK_SUCCESS) {
283+
assert(!"EncodeFrame error!!!");
284+
return result;
285+
}
286+
287+
// Handles the generic portion of the control command, if enabled
288+
if (HandleCtrlCmd(encodeFrameInfo)) {
289+
// Handles the codec-specific rate control command if enabled
290+
CodecHandleRateControlCmd(encodeFrameInfo);
291+
}
292+
293+
if (m_encoderConfig->enableQpMap) {
294+
ProcessQpMap(encodeFrameInfo);
295+
}
296+
297+
const bool isIntraRefreshFrame = m_encoderConfig->gopStructure.IsIntraRefreshFrame(encodeFrameInfo->gopPosition);
298+
if (m_encoderConfig->enableIntraRefresh && isIntraRefreshFrame) {
299+
FillIntraRefreshInfo(encodeFrameInfo);
300+
}
301+
302+
// NOTE: dstBuffer resource acquisition can be deferred at the last moment before submit
303+
VkDeviceSize size = GetBitstreamBuffer(encodeFrameInfo->outputBitstreamBuffer);
304+
assert((size > 0) && (encodeFrameInfo->outputBitstreamBuffer != nullptr));
305+
if ((size == 0) || (encodeFrameInfo->outputBitstreamBuffer == nullptr)) {
306+
return VK_ERROR_INITIALIZATION_FAILED;
307+
}
308+
encodeFrameInfo->encodeInfo.dstBuffer = encodeFrameInfo->outputBitstreamBuffer->GetBuffer();
309+
encodeFrameInfo->encodeInfo.dstBufferOffset = 0;
310+
311+
EnqueueFrame(encodeFrameInfo, isIdr, isReference);
312+
313+
return VK_SUCCESS;
262314
}
263315

264316
VkResult VkVideoEncoder::StageInputFrame(VkSharedBaseObj<VkVideoEncodeFrameInfo>& encodeFrameInfo)
@@ -1180,9 +1232,10 @@ VkResult VkVideoEncoder::InitEncoder(VkSharedBaseObj<EncoderConfig>& encoderConf
11801232
return result;
11811233
}
11821234

1183-
uint32_t numEncodeImagesInFlight = std::max<uint32_t>(m_holdRefFramesInQueue + m_holdRefFramesInQueue * m_encoderConfig->gopStructure.GetConsecutiveBFrameCount(), 4);
1235+
const uint32_t numEncodeImagesInFlight = std::max<uint32_t>(m_holdRefFramesInQueue + m_holdRefFramesInQueue * m_encoderConfig->gopStructure.GetConsecutiveBFrameCount(), 4);
1236+
const uint32_t maxEncodeQueueDepth = std::max<uint32_t>(maxDpbPicturesCount, maxActiveReferencePicturesCount) + numEncodeImagesInFlight;
11841237
result = m_dpbImagePool->Configure(m_vkDevCtx,
1185-
std::max<uint32_t>(maxDpbPicturesCount, maxActiveReferencePicturesCount) + numEncodeImagesInFlight,
1238+
maxEncodeQueueDepth,
11861239
m_imageDpbFormat,
11871240
imageExtent,
11881241
dpbImageUsage,
@@ -1646,8 +1699,11 @@ void VkVideoEncoder::FillIntraRefreshInfo(VkSharedBaseObj<VkVideoEncodeFrameInfo
16461699
vk::ChainNextVkStruct(encodeFrameInfo->encodeInfo, encodeFrameInfo->intraRefreshInfo);
16471700
}
16481701

1649-
VkResult VkVideoEncoder::HandleCtrlCmd(VkSharedBaseObj<VkVideoEncodeFrameInfo>& encodeFrameInfo)
1702+
bool VkVideoEncoder::HandleCtrlCmd(VkSharedBaseObj<VkVideoEncodeFrameInfo>& encodeFrameInfo)
16501703
{
1704+
if (m_sendControlCmd == 0) {
1705+
return false;
1706+
}
16511707
m_sendControlCmd = false;
16521708
encodeFrameInfo->sendControlCmd = true;
16531709

@@ -1676,6 +1732,7 @@ VkResult VkVideoEncoder::HandleCtrlCmd(VkSharedBaseObj<VkVideoEncodeFrameInfo>&
16761732
pNext = (VkBaseInStructure*)&encodeFrameInfo->qualityLevelInfo;
16771733
}
16781734

1735+
const bool sendRateControlCmd = m_sendRateControlCmd;
16791736
if (m_sendRateControlCmd == true) {
16801737

16811738
m_sendRateControlCmd = false;
@@ -1703,7 +1760,7 @@ VkResult VkVideoEncoder::HandleCtrlCmd(VkSharedBaseObj<VkVideoEncodeFrameInfo>&
17031760

17041761
encodeFrameInfo->pControlCmdChain = pNext;
17051762

1706-
return VK_SUCCESS;
1763+
return sendRateControlCmd;
17071764
}
17081765

17091766
VkResult VkVideoEncoder::RecordVideoCodingCmd(VkSharedBaseObj<VkVideoEncodeFrameInfo>& encodeFrameInfo,

vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoder.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,9 @@ class VkVideoEncoder : public VkVideoRefCountBase {
536536
VkResult SubmitStagedQpMap(VkSharedBaseObj<VkVideoEncodeFrameInfo>& encodeFrameInfo);
537537
VkResult EncodeFrameCommon(VkSharedBaseObj<VkVideoEncodeFrameInfo>& encodeFrameInfo);
538538
virtual VkResult EncodeFrame(VkSharedBaseObj<VkVideoEncodeFrameInfo>& encodeFrameInfo) = 0; // Must be implemented by the codec
539-
virtual VkResult HandleCtrlCmd(VkSharedBaseObj<VkVideoEncodeFrameInfo>& encodeFrameInfo);
539+
virtual bool HandleCtrlCmd(VkSharedBaseObj<VkVideoEncodeFrameInfo>& encodeFrameInfo);
540+
541+
virtual VkResult CodecHandleRateControlCmd(VkSharedBaseObj<VkVideoEncodeFrameInfo>& encodeFrameInfo) = 0; // Must be implemented by the codec
540542

541543
virtual VkResult RecordVideoCodingCmd(VkSharedBaseObj<VkVideoEncodeFrameInfo>& encodeFrameInfo,
542544
uint32_t frameIdx, uint32_t ofTotalFrames);

vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoderAV1.cpp

Lines changed: 17 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,8 @@ VkResult VkVideoEncoderAV1::ProcessDpb(VkSharedBaseObj<VkVideoEncodeFrameInfo>&
204204
(1 << STD_VIDEO_AV1_REFERENCE_NAME_ALTREF_FRAME));
205205
}
206206
}
207-
StdVideoAV1ReferenceName refName = m_dpbAV1->AssignReferenceFrameType(pFrameInfo->gopPosition.pictureType, flags, pFrameInfo->bIsReference);
207+
const bool isReference = m_encoderConfig->gopStructure.IsFrameReference(encodeFrameInfo->gopPosition);
208+
StdVideoAV1ReferenceName refName = m_dpbAV1->AssignReferenceFrameType(pFrameInfo->gopPosition.pictureType, flags, isReference);
208209
InitializeFrameHeader(&m_stateAV1.m_sequenceHeader, pFrameInfo, refName);
209210
if (!pFrameInfo->bShowExistingFrame) {
210211
m_dpbAV1->SetupReferenceFrameGroups(pFrameInfo->gopPosition.pictureType, pFrameInfo->stdPictureInfo.frame_type, pFrameInfo->picOrderCntVal);
@@ -470,22 +471,7 @@ VkResult VkVideoEncoderAV1::EncodeFrame(VkSharedBaseObj<VkVideoEncodeFrameInfo>&
470471
{
471472
VkVideoEncodeFrameInfoAV1* pFrameInfo = GetEncodeFrameInfoAV1(encodeFrameInfo);
472473

473-
assert(encodeFrameInfo);
474-
assert(m_encoderConfig);
475-
assert(encodeFrameInfo->srcEncodeImageResource);
476-
477-
pFrameInfo->videoSession = m_videoSession;
478-
pFrameInfo->videoSessionParameters = m_videoSessionParameters;
479-
480-
encodeFrameInfo->frameEncodeInputOrderNum = m_encodeInputFrameNum++;
481-
482-
// GetPositionInGOP() method returns display position of the picture relative to last key frame picture.
483-
bool isIdr = m_encoderConfig->gopStructure.GetPositionInGOP(m_gopState,
484-
encodeFrameInfo->gopPosition,
485-
(encodeFrameInfo->frameEncodeInputOrderNum == 0),
486-
uint32_t(m_encoderConfig->numFrames - encodeFrameInfo->frameEncodeInputOrderNum));
487-
if (isIdr) {
488-
assert(encodeFrameInfo->gopPosition.pictureType == VkVideoGopStructure::FRAME_TYPE_IDR);
474+
if (encodeFrameInfo->gopPosition.pictureType == VkVideoGopStructure::FRAME_TYPE_IDR) {
489475
VkResult result = EncodeVideoSessionParameters(encodeFrameInfo);
490476
if (result != VK_SUCCESS) {
491477
return result;
@@ -494,14 +480,12 @@ VkResult VkVideoEncoderAV1::EncodeFrame(VkSharedBaseObj<VkVideoEncodeFrameInfo>&
494480

495481
encodeFrameInfo->picOrderCntVal = encodeFrameInfo->gopPosition.inputOrder;
496482

497-
pFrameInfo->bIsKeyFrame = (encodeFrameInfo->gopPosition.pictureType == VkVideoGopStructure::FRAME_TYPE_IDR);
498-
pFrameInfo->bIsReference = m_encoderConfig->gopStructure.IsFrameReference(encodeFrameInfo->gopPosition);
499483
pFrameInfo->bShowExistingFrame = false;
500484
pFrameInfo->bOverlayFrame = false;
501485
if (encodeFrameInfo->gopPosition.pictureType == VkVideoGopStructure::FRAME_TYPE_B) {
502486
m_numBFramesToEncode++;
503487
}
504-
if (pFrameInfo->bIsKeyFrame) {
488+
if (encodeFrameInfo->gopPosition.pictureType == VkVideoGopStructure::FRAME_TYPE_IDR) {
505489
assert(encodeFrameInfo->picOrderCntVal == 0);
506490
m_lastKeyFrameOrderHint = encodeFrameInfo->picOrderCntVal;
507491
}
@@ -527,21 +511,10 @@ VkResult VkVideoEncoderAV1::EncodeFrame(VkSharedBaseObj<VkVideoEncodeFrameInfo>&
527511
pFrameInfo->encodeInfo.srcPictureResource.imageViewBinding = pSrcPictureResource->imageViewBinding;
528512
pFrameInfo->encodeInfo.srcPictureResource.baseArrayLayer = pSrcPictureResource->baseArrayLayer;
529513

530-
pFrameInfo->qualityLevel = m_encoderConfig->qualityLevel;
531-
532514
//if (encodeFrameInfo->frameEncodeInputOrderNum == 0) {
533515
// pFrameInfo->encodeInfo.flags |= VK_VIDEO_CODING_CONTROL_RESET_BIT_KHR;
534516
//}
535517

536-
VkDeviceSize size = GetBitstreamBuffer(encodeFrameInfo->outputBitstreamBuffer);
537-
assert((size > 0) && (encodeFrameInfo->outputBitstreamBuffer != nullptr));
538-
if ((size == 0) || (encodeFrameInfo->outputBitstreamBuffer == nullptr)) {
539-
return VK_ERROR_INITIALIZATION_FAILED;
540-
}
541-
pFrameInfo->encodeInfo.dstBuffer = encodeFrameInfo->outputBitstreamBuffer->GetBuffer();
542-
543-
pFrameInfo->encodeInfo.dstBufferOffset = 0;
544-
545518
if (m_rateControlInfo.rateControlMode == VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR) {
546519
switch (encodeFrameInfo->gopPosition.pictureType) {
547520
case VkVideoGopStructure::FRAME_TYPE_IDR:
@@ -564,52 +537,30 @@ VkResult VkVideoEncoderAV1::EncodeFrame(VkSharedBaseObj<VkVideoEncodeFrameInfo>&
564537
}
565538
}
566539

567-
if (m_sendControlCmd == true) {
568-
HandleCtrlCmd(encodeFrameInfo);
569-
}
570-
571-
if (m_encoderConfig->enableQpMap) {
572-
ProcessQpMap(encodeFrameInfo);
573-
}
574-
575-
const bool isIntraRefreshFrame = m_encoderConfig->gopStructure.IsIntraRefreshFrame(encodeFrameInfo->gopPosition);
576-
if (m_encoderConfig->enableIntraRefresh && isIntraRefreshFrame) {
577-
FillIntraRefreshInfo(encodeFrameInfo);
578-
}
579-
580-
EnqueueFrame(encodeFrameInfo, pFrameInfo->bIsKeyFrame, pFrameInfo->bIsReference);
581-
582540
return VK_SUCCESS;
583541
}
584542

585-
VkResult VkVideoEncoderAV1::HandleCtrlCmd(VkSharedBaseObj<VkVideoEncodeFrameInfo>& encodeFrameInfo)
543+
VkResult VkVideoEncoderAV1::CodecHandleRateControlCmd(VkSharedBaseObj<VkVideoEncodeFrameInfo>& encodeFrameInfo)
586544
{
587545
VkVideoEncodeFrameInfoAV1* pFrameInfo = GetEncodeFrameInfoAV1(encodeFrameInfo);
588546

589-
// Save the RateControlCmd request
590-
const bool sendRateControlCmd = m_sendRateControlCmd;
591-
// Call the base class first to cover the bases
592-
VkVideoEncoder::HandleCtrlCmd(encodeFrameInfo);
593-
594547
// Fill-in the codec-specific parts next
595-
if (sendRateControlCmd) {
596-
for (uint32_t layerIndx = 0; layerIndx < ARRAYSIZE(m_stateAV1.m_rateControlLayersInfoAV1); layerIndx++) {
597-
pFrameInfo->rateControlLayersInfoAV1[layerIndx] = m_stateAV1.m_rateControlLayersInfoAV1[layerIndx];
598-
pFrameInfo->rateControlLayersInfoAV1[layerIndx].sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_RATE_CONTROL_LAYER_INFO_KHR;
599-
pFrameInfo->rateControlLayersInfo[layerIndx].pNext = &pFrameInfo->rateControlLayersInfoAV1[layerIndx];
600-
}
601-
602-
pFrameInfo->rateControlInfoAV1 = m_stateAV1.m_rateControlInfoAV1;
603-
pFrameInfo->rateControlInfoAV1.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_RATE_CONTROL_INFO_KHR;
604-
pFrameInfo->rateControlInfoAV1.temporalLayerCount = m_encoderConfig->gopStructure.GetTemporalLayerCount();
548+
for (uint32_t layerIndx = 0; layerIndx < ARRAYSIZE(m_stateAV1.m_rateControlLayersInfoAV1); layerIndx++) {
549+
pFrameInfo->rateControlLayersInfoAV1[layerIndx] = m_stateAV1.m_rateControlLayersInfoAV1[layerIndx];
550+
pFrameInfo->rateControlLayersInfoAV1[layerIndx].sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_RATE_CONTROL_LAYER_INFO_KHR;
551+
pFrameInfo->rateControlLayersInfo[layerIndx].pNext = &pFrameInfo->rateControlLayersInfoAV1[layerIndx];
552+
}
605553

606-
if (pFrameInfo->pControlCmdChain != nullptr) {
607-
pFrameInfo->rateControlInfoAV1.pNext = pFrameInfo->pControlCmdChain;
608-
}
554+
pFrameInfo->rateControlInfoAV1 = m_stateAV1.m_rateControlInfoAV1;
555+
pFrameInfo->rateControlInfoAV1.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_RATE_CONTROL_INFO_KHR;
556+
pFrameInfo->rateControlInfoAV1.temporalLayerCount = m_encoderConfig->gopStructure.GetTemporalLayerCount();
609557

610-
pFrameInfo->pControlCmdChain = (VkBaseInStructure*)&pFrameInfo->rateControlInfoAV1;
558+
if (pFrameInfo->pControlCmdChain != nullptr) {
559+
pFrameInfo->rateControlInfoAV1.pNext = pFrameInfo->pControlCmdChain;
611560
}
612561

562+
pFrameInfo->pControlCmdChain = (VkBaseInStructure*)&pFrameInfo->rateControlInfoAV1;
563+
613564
return VK_SUCCESS;
614565
}
615566

vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoderAV1.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,8 @@ class VkVideoEncoderAV1 : public VkVideoEncoder
3939
StdVideoAV1LoopRestoration stdLrInfo;
4040
bool bShowExistingFrame;
4141
int32_t frameToShowBufId;
42-
bool bIsKeyFrame;
4342
bool bShownKeyFrameOrSwitch;
4443
bool bOverlayFrame;
45-
bool bIsReference;
4644
StdVideoEncodeAV1ReferenceInfo stdReferenceInfo[STD_VIDEO_AV1_REFS_PER_FRAME];
4745
VkVideoEncodeAV1DpbSlotInfoKHR dpbSlotInfo[STD_VIDEO_AV1_REFS_PER_FRAME];
4846
VkVideoEncodeAV1RateControlInfoKHR rateControlInfoAV1;
@@ -59,10 +57,8 @@ class VkVideoEncoderAV1 : public VkVideoEncoder
5957
, stdLrInfo{}
6058
, bShowExistingFrame{}
6159
, frameToShowBufId{-1}
62-
, bIsKeyFrame{}
6360
, bShownKeyFrameOrSwitch{}
6461
, bOverlayFrame{}
65-
, bIsReference{}
6662
, rateControlInfoAV1{ VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_RATE_CONTROL_INFO_KHR }
6763
, rateControlLayersInfoAV1{{ VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_RATE_CONTROL_LAYER_INFO_KHR }}
6864
{
@@ -155,8 +151,6 @@ class VkVideoEncoderAV1 : public VkVideoEncoder
155151
return success;
156152
}
157153

158-
virtual VkResult EncodeFrame(VkSharedBaseObj<VkVideoEncodeFrameInfo>& encodeFrameInfo);
159-
virtual VkResult HandleCtrlCmd(VkSharedBaseObj<VkVideoEncodeFrameInfo>& encodeFrameInfo);
160154
virtual VkResult StartOfVideoCodingEncodeOrder(VkSharedBaseObj<VkVideoEncodeFrameInfo>& encodeFrameInfo, uint32_t frameIdx, uint32_t ofTotalFrames);
161155
virtual VkResult RecordVideoCodingCmd(VkSharedBaseObj<VkVideoEncodeFrameInfo>& encodeFrameInfo,
162156
uint32_t frameIdx, uint32_t ofTotalFrames);
@@ -185,6 +179,9 @@ class VkVideoEncoderAV1 : public VkVideoEncoder
185179
}
186180
}
187181

182+
// Must be called from VkVideoEncoder::EncodeFrameCommon only
183+
virtual VkResult EncodeFrame(VkSharedBaseObj<VkVideoEncodeFrameInfo>& encodeFrameInfo);
184+
virtual VkResult CodecHandleRateControlCmd(VkSharedBaseObj<VkVideoEncodeFrameInfo>& encodeFrameInfo);
188185
private:
189186
VkVideoEncodeFrameInfoAV1* GetEncodeFrameInfoAV1(VkSharedBaseObj<VkVideoEncodeFrameInfo>& encodeFrameInfo) {
190187
assert(VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR == encodeFrameInfo->GetType());

0 commit comments

Comments
 (0)