- Revision
- 269243
- Author
- [email protected]
- Date
- 2020-11-02 00:32:56 -0800 (Mon, 02 Nov 2020)
Log Message
Set vpcC box for hardware WebRTC VP9 decoder
https://bugs.webkit.org/show_bug.cgi?id=218337
Reviewed by Eric Carlson.
Hardware VP9 decoder code path requires vpcC box information.
Provide it as part of the video format.
Initialize the vpcC box with a zeroed buffer.
Make sure WebKitVP9Decoder is able to handle dynamically 10 bits or 8 bits frames.
* Source/webrtc/sdk/WebKit/WebKitVP9Decoder.cpp:
(webrtc::createWebKitVP9Decoder):
(webrtc::startVP9DecoderSession):
(webrtc::WebKitVP9DecoderReceiver::initializeFromFormatDescription):
(webrtc::WebKitVP9DecoderReceiver::pixelBufferPool):
(webrtc::WebKitVP9DecoderReceiver::Decoded):
* Source/webrtc/sdk/objc/components/video_codec/RTCVideoDecoderVTBVP9.mm:
(-[RTCVideoDecoderVTBVP9 decodeData:size:timeStamp:]):
(-[RTCVideoDecoderVTBVP9 resetDecompressionSession]):
Modified Paths
Diff
Modified: trunk/Source/ThirdParty/libwebrtc/ChangeLog (269242 => 269243)
--- trunk/Source/ThirdParty/libwebrtc/ChangeLog 2020-11-02 03:50:42 UTC (rev 269242)
+++ trunk/Source/ThirdParty/libwebrtc/ChangeLog 2020-11-02 08:32:56 UTC (rev 269243)
@@ -1,3 +1,26 @@
+2020-11-02 Youenn Fablet <[email protected]>
+
+ Set vpcC box for hardware WebRTC VP9 decoder
+ https://bugs.webkit.org/show_bug.cgi?id=218337
+
+ Reviewed by Eric Carlson.
+
+ Hardware VP9 decoder code path requires vpcC box information.
+ Provide it as part of the video format.
+ Initialize the vpcC box with a zeroed buffer.
+
+ Make sure WebKitVP9Decoder is able to handle dynamically 10 bits or 8 bits frames.
+
+ * Source/webrtc/sdk/WebKit/WebKitVP9Decoder.cpp:
+ (webrtc::createWebKitVP9Decoder):
+ (webrtc::startVP9DecoderSession):
+ (webrtc::WebKitVP9DecoderReceiver::initializeFromFormatDescription):
+ (webrtc::WebKitVP9DecoderReceiver::pixelBufferPool):
+ (webrtc::WebKitVP9DecoderReceiver::Decoded):
+ * Source/webrtc/sdk/objc/components/video_codec/RTCVideoDecoderVTBVP9.mm:
+ (-[RTCVideoDecoderVTBVP9 decodeData:size:timeStamp:]):
+ (-[RTCVideoDecoderVTBVP9 resetDecompressionSession]):
+
2020-10-29 Youenn Fablet <[email protected]>
Add some logging to SequenceCheckerImpl::IsCurrent
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/WebKitVP9Decoder.cpp (269242 => 269243)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/WebKitVP9Decoder.cpp 2020-11-02 03:50:42 UTC (rev 269242)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/WebKitVP9Decoder.cpp 2020-11-02 08:32:56 UTC (rev 269243)
@@ -57,7 +57,7 @@
void setCurrentFrame(VTVideoDecoderFrame currentFrame) { m_currentFrame = currentFrame; }
OSStatus decoderFailed(int error);
- void createPixelBufferPoolForFormatDescription(CMFormatDescriptionRef);
+ void initializeFromFormatDescription(CMFormatDescriptionRef);
private:
int32_t Decoded(VideoFrame&) final;
@@ -64,10 +64,14 @@
int32_t Decoded(VideoFrame&, int64_t decode_time_ms) final;
void Decoded(VideoFrame&, absl::optional<int32_t> decode_time_ms, absl::optional<uint8_t> qp) final;
+ CVPixelBufferPoolRef pixelBufferPool(size_t pixelBufferWidth, size_t pixelBufferHeight, bool is10bit);
+
VTVideoDecoderSession m_session { nullptr };
VTVideoDecoderFrame m_currentFrame { nullptr };
size_t m_pixelBufferWidth { 0 };
size_t m_pixelBufferHeight { 0 };
+ bool m_is10bit { false };
+ bool m_isFullRange { false };
CVPixelBufferPoolRef m_pixelBufferPool { nullptr };
};
@@ -172,7 +176,7 @@
decoder->m_instance = std::make_unique<VP9DecoderImpl>();
decoder->m_receiver = std::make_unique<WebKitVP9DecoderReceiver>(session);
- decoder->m_receiver->createPixelBufferPoolForFormatDescription(formatDescription);
+ decoder->m_receiver->initializeFromFormatDescription(formatDescription);
decoder->m_instance->RegisterDecodeCompleteCallback(decoder->m_receiver.get());
@@ -257,14 +261,14 @@
CFRelease(m_pixelBufferPool);
}
-void WebKitVP9DecoderReceiver::createPixelBufferPoolForFormatDescription(CMFormatDescriptionRef formatDescription)
+void WebKitVP9DecoderReceiver::initializeFromFormatDescription(CMFormatDescriptionRef formatDescription)
{
// CoreAnimation doesn't support full-planar YUV, so we must convert the buffers output
// by libvpx to bi-planar YUV. Create pixel buffer attributes and give those to the
// decoder session for use in creating its own internal CVPixelBufferPool, which we
// will use post-decode.
- bool isFullRange = false;
- bool is10Bit = false;
+ m_isFullRange = false;
+ m_is10bit = false;
do {
auto extensions = CMFormatDescriptionGetExtensions(formatDescription);
@@ -287,17 +291,23 @@
auto bitDepthChromaAndRange = *(configurationRecordData + 6);
if ((bitDepthChromaAndRange >> 4) == 10)
- is10Bit = true;
+ m_is10bit = true;
if (bitDepthChromaAndRange & 0x1)
- isFullRange = true;
+ m_isFullRange = true;
} while (false);
+}
+CVPixelBufferPoolRef WebKitVP9DecoderReceiver::pixelBufferPool(size_t pixelBufferWidth, size_t pixelBufferHeight, bool is10bit)
+{
+ if (m_pixelBufferPool && m_pixelBufferWidth == pixelBufferWidth && m_pixelBufferHeight == pixelBufferHeight && m_is10bit == is10bit)
+ return m_pixelBufferPool;
+
OSType pixelFormat;
- if (is10Bit)
- pixelFormat = isFullRange ? kCVPixelFormatType_420YpCbCr10BiPlanarFullRange : kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange;
+ if (is10bit)
+ pixelFormat = m_isFullRange ? kCVPixelFormatType_420YpCbCr10BiPlanarFullRange : kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange;
else
- pixelFormat = isFullRange ? kCVPixelFormatType_420YpCbCr8BiPlanarFullRange : kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
+ pixelFormat = m_isFullRange ? kCVPixelFormatType_420YpCbCr8BiPlanarFullRange : kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
auto createPixelFormatAttributes = [] (OSType pixelFormat, int32_t borderPixels) {
auto createNumber = [] (int32_t format) -> CFNumberRef {
@@ -342,6 +352,12 @@
m_pixelBufferPool = VTDecoderSessionGetPixelBufferPool(m_session);
if (m_pixelBufferPool)
CFRetain(m_pixelBufferPool);
+
+ m_pixelBufferWidth = pixelBufferWidth;
+ m_pixelBufferHeight = pixelBufferHeight;
+ m_is10bit = is10bit;
+
+ return m_pixelBufferPool;
}
OSStatus WebKitVP9DecoderReceiver::decoderFailed(int error)
@@ -362,7 +378,11 @@
int32_t WebKitVP9DecoderReceiver::Decoded(VideoFrame& frame)
{
- auto pixelBuffer = pixelBufferFromFrame(frame, [this](size_t width, size_t height, BufferType) -> CVPixelBufferRef {
+ auto pixelBuffer = pixelBufferFromFrame(frame, [this](size_t width, size_t height, BufferType type) -> CVPixelBufferRef {
+ auto pixelBufferPool = this->pixelBufferPool(width, height, type == BufferType::I010);
+ if (!pixelBufferPool)
+ return nullptr;
+
CVPixelBufferRef pixelBuffer = nullptr;
if (CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, m_pixelBufferPool, &pixelBuffer) == kCVReturnSuccess)
return pixelBuffer;
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/components/video_codec/RTCVideoDecoderVTBVP9.mm (269242 => 269243)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/components/video_codec/RTCVideoDecoderVTBVP9.mm 2020-11-02 03:50:42 UTC (rev 269242)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/components/video_codec/RTCVideoDecoderVTBVP9.mm 2020-11-02 08:32:56 UTC (rev 269243)
@@ -45,6 +45,9 @@
#include "rtc_base/logging.h"
#include "rtc_base/time_utils.h"
+extern const CFStringRef kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms;
+#define VPCodecConfigurationContentsSize 12
+
// Struct that we pass to the decoder per frame to decode. We receive it again
// in the decoder callback.
struct RTCFrameDecodeParams {
@@ -147,9 +150,19 @@
return WEBRTC_VIDEO_CODEC_ERROR;
}
+ uint8_t record[VPCodecConfigurationContentsSize];
+ // FIXME: Initialize properly the vpcC decoding configuration.
+ memset((void*)record, 0, VPCodecConfigurationContentsSize);
+ auto configurationDict = @{
+ @"vpcC": (__bridge NSData *)CFDataCreate(kCFAllocatorDefault, record, VPCodecConfigurationContentsSize)
+ };
+ auto extensions = @{
+ (__bridge NSString *)kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms: configurationDict
+ };
+
CMVideoFormatDescriptionRef formatDescription = nullptr;
// Use kCMVideoCodecType_VP9 once added to CMFormatDescription.h
- if (noErr != CMVideoFormatDescriptionCreate(kCFAllocatorDefault, 'vp09', _width, _height, nullptr, &formatDescription))
+ if (noErr != CMVideoFormatDescriptionCreate(kCFAllocatorDefault, 'vp09', _width, _height, (__bridge CFDictionaryRef)extensions, &formatDescription))
return WEBRTC_VIDEO_CODEC_ERROR;
rtc::ScopedCFTypeRef<CMVideoFormatDescriptionRef> inputFormat = rtc::ScopedCF(formatDescription);
@@ -167,10 +180,7 @@
if (!_videoFormat) {
// We received a frame but we don't have format information so we can't
// decode it.
- // This can happen after backgrounding. We need to wait for the next
- // sps/pps before we can resume so we request a keyframe by returning an
- // error.
- RTC_LOG(LS_WARNING) << "Missing video format. Frame with sps/pps required.";
+ RTC_LOG(LS_WARNING) << "Missing video format.";
return WEBRTC_VIDEO_CODEC_ERROR;
}
auto sampleBuffer = rtc::ScopedCF(VP9BufferToCMSampleBuffer(data, size, _videoFormat));
@@ -224,7 +234,6 @@
- (int)resetDecompressionSession {
[self destroyDecompressionSession];
- // Need to wait for the first SPS to initialize decoder.
if (!_videoFormat) {
return WEBRTC_VIDEO_CODEC_OK;
}
@@ -261,18 +270,11 @@
pixelFormat = nullptr;
}
- // rdar://problem/70701816. Disable hardware decoding until working properly.
- auto videoDecoderSpecification = @{
-#if !defined(WEBRTC_IOS)
- (__bridge NSString *)kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder: @NO
-#endif
- };
-
VTDecompressionOutputCallbackRecord record = {
vp9DecompressionOutputCallback, (__bridge void *)self,
};
OSStatus status = VTDecompressionSessionCreate(
- nullptr, _videoFormat, (__bridge CFDictionaryRef)videoDecoderSpecification, attributes, &record, &_decompressionSession);
+ nullptr, _videoFormat, nullptr, attributes, &record, &_decompressionSession);
CFRelease(attributes);
if (status != noErr) {
RTC_LOG(LS_ERROR) << "Failed to create decompression session: " << status;