From c2cea14deaa3ca5db88d8bbc11fb533f01d30372 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Cerveau?= Date: Mon, 28 Oct 2024 14:49:24 +0100 Subject: [PATCH] EncoderConfig: introduce GetMaxBFrameCount MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The default value for B Frame count is 3 but some implementation does not support B frames. Set the value to the max B Frame count supported by the implementation if it exceeds the value. Signed-off-by: Stéphane Cerveau --- vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfig.h | 2 ++ vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfigH264.cpp | 1 + vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfigH264.h | 2 ++ vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfigH265.cpp | 1 + vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfigH265.h | 2 ++ vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoder.cpp | 5 +++++ 6 files changed, 13 insertions(+) diff --git a/vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfig.h b/vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfig.h index 9d2b1c7d..03123434 100644 --- a/vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfig.h +++ b/vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfig.h @@ -618,6 +618,8 @@ struct EncoderConfig : public VkVideoRefCountBase { virtual int8_t InitDpbCount() { return 16; }; virtual bool InitRateControl(); + + virtual uint8_t GetMaxBFrameCount() { return 0;} }; // Create codec configuration for H.264 encoder diff --git a/vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfigH264.cpp b/vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfigH264.cpp index e8054dcf..acc2b2a0 100644 --- a/vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfigH264.cpp +++ b/vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfigH264.cpp @@ -369,6 +369,7 @@ VkResult EncoderConfigH264::InitDeviceCapabilities(const VulkanDeviceContext* vk std::cout << "\t\t\t" << "maxExtent: " << videoCapabilities.maxCodedExtent.width << " x " << videoCapabilities.maxCodedExtent.height << std::endl; std::cout << "\t\t\t" << "maxDpbSlots: " << videoCapabilities.maxDpbSlots << std::endl; std::cout << "\t\t\t" << "maxActiveReferencePictures: " << videoCapabilities.maxActiveReferencePictures << std::endl; + std::cout << "\t\t\t" << "maxBPictureL0ReferenceCount: " << h264EncodeCapabilities.maxBPictureL0ReferenceCount << std::endl; } return VK_SUCCESS; diff --git a/vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfigH264.h b/vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfigH264.h index 71c94b37..5d2c61c1 100644 --- a/vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfigH264.h +++ b/vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfigH264.h @@ -184,6 +184,8 @@ struct EncoderConfigH264 : public EncoderConfig { // 2. First h.264 determine the rate control parameters virtual bool InitRateControl(); + virtual uint8_t GetMaxBFrameCount() { return h264EncodeCapabilities.maxBPictureL0ReferenceCount; } + bool GetRateControlParameters(VkVideoEncodeRateControlInfoKHR *rcInfo, VkVideoEncodeRateControlLayerInfoKHR *pRcLayerInfo, VkVideoEncodeH264RateControlInfoKHR *rcInfoH264, diff --git a/vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfigH265.cpp b/vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfigH265.cpp index 99ed0cec..9bc38f1a 100644 --- a/vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfigH265.cpp +++ b/vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfigH265.cpp @@ -89,6 +89,7 @@ VkResult EncoderConfigH265::InitDeviceCapabilities(const VulkanDeviceContext* vk std::cout << "\t\t\t" << "maxExtent: " << videoCapabilities.maxCodedExtent.width << " x " << videoCapabilities.maxCodedExtent.height << std::endl; std::cout << "\t\t\t" << "maxDpbSlots: " << videoCapabilities.maxDpbSlots << std::endl; std::cout << "\t\t\t" << "maxActiveReferencePictures: " << videoCapabilities.maxActiveReferencePictures << std::endl; + std::cout << "\t\t\t" << "maxBPictureL0ReferenceCount: " << h265EncodeCapabilities.maxBPictureL0ReferenceCount << std::endl; } return VK_SUCCESS; diff --git a/vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfigH265.h b/vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfigH265.h index 7d179c9c..66ba2a58 100644 --- a/vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfigH265.h +++ b/vk_video_encoder/libs/VkVideoEncoder/VkEncoderConfigH265.h @@ -158,6 +158,8 @@ struct EncoderConfigH265 : public EncoderConfig { // 2. First h.265 determine the rate control parameters virtual bool InitRateControl(); + virtual uint8_t GetMaxBFrameCount() { return h265EncodeCapabilities.maxBPictureL0ReferenceCount; } + bool GetRateControlParameters(VkVideoEncodeRateControlInfoKHR *rcInfo, VkVideoEncodeRateControlLayerInfoKHR *pRcLayerInfo, VkVideoEncodeH265RateControlInfoKHR *rcInfoH265, diff --git a/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoder.cpp b/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoder.cpp index a1f7ea5c..4929a017 100644 --- a/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoder.cpp +++ b/vk_video_encoder/libs/VkVideoEncoder/VkVideoEncoder.cpp @@ -359,6 +359,11 @@ VkResult VkVideoEncoder::InitEncoder(VkSharedBaseObj& encoderConf // specific GOP structure. For example it may not support B-frames. // gopStructure.Init() should be called after encoderConfig->InitDeviceCapabilities(). m_encoderConfig->gopStructure.Init(m_encoderConfig->numFrames); + if (encoderConfig->GetMaxBFrameCount() < m_encoderConfig->gopStructure.GetConsecutiveBFrameCount()) { + std::cout << "Max consecutive B frames: " << (uint32_t)encoderConfig->GetMaxBFrameCount() << " lower than the configured one: " << (uint32_t)m_encoderConfig->gopStructure.GetConsecutiveBFrameCount() << std::endl; + std::cout << "Fallback to the max value: " << (uint32_t)m_encoderConfig->gopStructure.GetConsecutiveBFrameCount() << std::endl; + m_encoderConfig->gopStructure.SetConsecutiveBFrameCount(encoderConfig->GetMaxBFrameCount()); + } std::cout << std::endl << "GOP frame count: " << (uint32_t)m_encoderConfig->gopStructure.GetGopFrameCount(); std::cout << ", IDR period: " << (uint32_t)m_encoderConfig->gopStructure.GetIdrPeriod(); std::cout << ", Consecutive B frames: " << (uint32_t)m_encoderConfig->gopStructure.GetConsecutiveBFrameCount();