Title: [269306] trunk/Source
Revision
269306
Author
[email protected]
Date
2020-11-03 08:43:44 -0800 (Tue, 03 Nov 2020)

Log Message

Add support for WebRTC VP9 decoder in GPU process
https://bugs.webkit.org/show_bug.cgi?id=218445

Reviewed by Eric Carlson.

Source/ThirdParty/libwebrtc:

Allow creating a VTB VP9 decoder from WebCore.
VTB VP9 decoder currently needs key frame width and height information so we provide it as part of the decode callback.

* Configurations/libwebrtc.iOS.exp:
* Configurations/libwebrtc.iOSsim.exp:
* Configurations/libwebrtc.mac.exp:
* Source/webrtc/sdk/WebKit/WebKitDecoder.h:
* Source/webrtc/sdk/WebKit/WebKitDecoder.mm:
(-[WK_RTCLocalVideoH264H265VP9Decoder initVP9DecoderWithCallback:]):
(-[WK_RTCLocalVideoH264H265VP9Decoder decodeData:size:timeStamp:]):
(-[WK_RTCLocalVideoH264H265VP9Decoder setWidth:height:]):
(-[WK_RTCLocalVideoH264H265VP9Decoder releaseDecoder]):
(webrtc::RemoteVideoDecoder::Decode):
(webrtc::RemoteVideoDecoderFactory::GetSupportedFormats const):
(webrtc::createLocalH264Decoder):
(webrtc::createLocalH265Decoder):
(webrtc::createLocalVP9Decoder):
(webrtc::releaseLocalDecoder):
(webrtc::decodeFrame):
(webrtc::setDecoderFrameSize):
* Source/webrtc/sdk/objc/components/video_codec/RTCVideoDecoderVTBVP9.h:
* Source/webrtc/sdk/objc/components/video_codec/RTCVideoDecoderVTBVP9.mm:
(-[RTCVideoDecoderVTBVP9 decode:missingFrames:codecSpecificInfo:renderTimeMs:]):
(-[RTCVideoDecoderVTBVP9 setWidth:height:]):

Source/WebKit:

Add support for VP9 decoder, send key frame size as IPC message specifically for VP9 hardware decoder.
If GPU process does not enable either SW or HW VP9 decoder, we fall back to in process VP9 decoder.

Manually tested by enabling WebRTC codec in GPU process.
Will be covered by existing VP9 tests in GPU process mode once canvas in GPUProcess is fully supported.

* GPUProcess/webrtc/LibWebRTCCodecsProxy.h:
* GPUProcess/webrtc/LibWebRTCCodecsProxy.messages.in:
* GPUProcess/webrtc/LibWebRTCCodecsProxy.mm:
(WebKit::LibWebRTCCodecsProxy::createVP9Decoder):
(WebKit::LibWebRTCCodecsProxy::setFrameSize):
* WebProcess/GPU/GPUProcessConnection.h:
(WebKit::GPUProcessConnection::isVP9DecoderEnabled const):
(WebKit::GPUProcessConnection::isVPSWDecoderEnabled const):
* WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp:
(WebKit::createVideoDecoder):
(WebKit::decodeVideoFrame):
(WebKit::LibWebRTCCodecs::setCallbacks):
(WebKit::LibWebRTCCodecs::createDecoder):
(WebKit::LibWebRTCCodecs::decodeFrame):
(WebKit::formatNameFromCodecType):
* WebProcess/GPU/webrtc/LibWebRTCCodecs.h:
(WebKit::LibWebRTCCodecs::setVP9VTBSupport):
(WebKit::LibWebRTCCodecs::supportVP9VTB const):

Modified Paths

Diff

Modified: trunk/Source/ThirdParty/libwebrtc/ChangeLog (269305 => 269306)


--- trunk/Source/ThirdParty/libwebrtc/ChangeLog	2020-11-03 16:21:49 UTC (rev 269305)
+++ trunk/Source/ThirdParty/libwebrtc/ChangeLog	2020-11-03 16:43:44 UTC (rev 269306)
@@ -1,5 +1,37 @@
 2020-11-03  Youenn Fablet  <[email protected]>
 
+        Add support for WebRTC VP9 decoder in GPU process
+        https://bugs.webkit.org/show_bug.cgi?id=218445
+
+        Reviewed by Eric Carlson.
+
+        Allow creating a VTB VP9 decoder from WebCore.
+        VTB VP9 decoder currently needs key frame width and height information so we provide it as part of the decode callback.
+
+        * Configurations/libwebrtc.iOS.exp:
+        * Configurations/libwebrtc.iOSsim.exp:
+        * Configurations/libwebrtc.mac.exp:
+        * Source/webrtc/sdk/WebKit/WebKitDecoder.h:
+        * Source/webrtc/sdk/WebKit/WebKitDecoder.mm:
+        (-[WK_RTCLocalVideoH264H265VP9Decoder initVP9DecoderWithCallback:]):
+        (-[WK_RTCLocalVideoH264H265VP9Decoder decodeData:size:timeStamp:]):
+        (-[WK_RTCLocalVideoH264H265VP9Decoder setWidth:height:]):
+        (-[WK_RTCLocalVideoH264H265VP9Decoder releaseDecoder]):
+        (webrtc::RemoteVideoDecoder::Decode):
+        (webrtc::RemoteVideoDecoderFactory::GetSupportedFormats const):
+        (webrtc::createLocalH264Decoder):
+        (webrtc::createLocalH265Decoder):
+        (webrtc::createLocalVP9Decoder):
+        (webrtc::releaseLocalDecoder):
+        (webrtc::decodeFrame):
+        (webrtc::setDecoderFrameSize):
+        * Source/webrtc/sdk/objc/components/video_codec/RTCVideoDecoderVTBVP9.h:
+        * Source/webrtc/sdk/objc/components/video_codec/RTCVideoDecoderVTBVP9.mm:
+        (-[RTCVideoDecoderVTBVP9 decode:missingFrames:codecSpecificInfo:renderTimeMs:]):
+        (-[RTCVideoDecoderVTBVP9 setWidth:height:]):
+
+2020-11-03  Youenn Fablet  <[email protected]>
+
         Update WebRTC boringssl to M87
         https://bugs.webkit.org/show_bug.cgi?id=218431
 

Modified: trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOS.exp (269305 => 269306)


--- trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOS.exp	2020-11-03 16:21:49 UTC (rev 269305)
+++ trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOS.exp	2020-11-03 16:43:44 UTC (rev 269306)
@@ -239,13 +239,13 @@
 __ZNK6webrtc23RtpTransceiverInterface17codec_preferencesEv
 __ZN6webrtc22createLocalH264DecoderEU13block_pointerFvP10__CVBufferjjE
 __ZN6webrtc22createLocalH265DecoderEU13block_pointerFvP10__CVBufferjjE
+__ZN6webrtc21createLocalVP9DecoderEU13block_pointerFvP10__CVBufferjjE
 __ZN6webrtc19releaseLocalDecoderEPv
 __ZN6webrtc11decodeFrameEPvjPKhm
 __ZN6webrtc24videoDecoderTaskCompleteEPvjP10__CVBufferj
-__ZN6webrtc24setVideoDecoderCallbacksEPFPvRKNS_14SdpVideoFormatEEPFiS0_EPFiS0_jPKhmEPFiS0_S0_E
+__ZN6webrtc24setVideoDecoderCallbacksEPFPvRKNS_14SdpVideoFormatEEPFiS0_EPFiS0_jPKhmttEPFiS0_S0_E
+__ZN6webrtc19setDecoderFrameSizeEPvtt
 __ZN6webrtc18RtpCodecCapabilityC1Ev
-__ZN6webrtc24setVideoDecoderCallbacksEPFPvRKNS_14SdpVideoFormatEEPFiS0_EPFiS0_jPKhmEPFiS0_S0_E
-__ZN6webrtc18RtpCodecCapabilityC1Ev
 __ZN6webrtc22RTPFragmentationHeaderD1Ev
 __ZN6webrtc22RTPFragmentationHeaderC1Ev
 __ZN6webrtc18RemoteVideoEncoder14encodeCompleteEPvPhmRKNS_22WebKitEncodedFrameInfoEPKNS_22RTPFragmentationHeaderE

Modified: trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOSsim.exp (269305 => 269306)


--- trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOSsim.exp	2020-11-03 16:21:49 UTC (rev 269305)
+++ trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.iOSsim.exp	2020-11-03 16:43:44 UTC (rev 269306)
@@ -239,13 +239,13 @@
 __ZNK6webrtc23RtpTransceiverInterface17codec_preferencesEv
 __ZN6webrtc22createLocalH264DecoderEU13block_pointerFvP10__CVBufferjjE
 __ZN6webrtc22createLocalH265DecoderEU13block_pointerFvP10__CVBufferjjE
+__ZN6webrtc21createLocalVP9DecoderEU13block_pointerFvP10__CVBufferjjE
 __ZN6webrtc19releaseLocalDecoderEPv
 __ZN6webrtc11decodeFrameEPvjPKhm
 __ZN6webrtc24videoDecoderTaskCompleteEPvjP10__CVBufferj
-__ZN6webrtc24setVideoDecoderCallbacksEPFPvRKNS_14SdpVideoFormatEEPFiS0_EPFiS0_jPKhmEPFiS0_S0_E
+__ZN6webrtc24setVideoDecoderCallbacksEPFPvRKNS_14SdpVideoFormatEEPFiS0_EPFiS0_jPKhmttEPFiS0_S0_E
+__ZN6webrtc19setDecoderFrameSizeEPvtt
 __ZN6webrtc18RtpCodecCapabilityC1Ev
-__ZN6webrtc24setVideoDecoderCallbacksEPFPvRKNS_14SdpVideoFormatEEPFiS0_EPFiS0_jPKhmEPFiS0_S0_E
-__ZN6webrtc18RtpCodecCapabilityC1Ev
 __ZN6webrtc22RTPFragmentationHeaderD1Ev
 __ZN6webrtc22RTPFragmentationHeaderC1Ev
 __ZN6webrtc18RemoteVideoEncoder14encodeCompleteEPvPhmRKNS_22WebKitEncodedFrameInfoEPKNS_22RTPFragmentationHeaderE

Modified: trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.mac.exp (269305 => 269306)


--- trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.mac.exp	2020-11-03 16:21:49 UTC (rev 269305)
+++ trunk/Source/ThirdParty/libwebrtc/Configurations/libwebrtc.mac.exp	2020-11-03 16:43:44 UTC (rev 269306)
@@ -239,10 +239,12 @@
 __ZNK6webrtc23RtpTransceiverInterface17codec_preferencesEv
 __ZN6webrtc22createLocalH264DecoderEU13block_pointerFvP10__CVBufferjjE
 __ZN6webrtc22createLocalH265DecoderEU13block_pointerFvP10__CVBufferjjE
+__ZN6webrtc21createLocalVP9DecoderEU13block_pointerFvP10__CVBufferjjE
 __ZN6webrtc19releaseLocalDecoderEPv
 __ZN6webrtc11decodeFrameEPvjPKhm
 __ZN6webrtc24videoDecoderTaskCompleteEPvjP10__CVBufferj
-__ZN6webrtc24setVideoDecoderCallbacksEPFPvRKNS_14SdpVideoFormatEEPFiS0_EPFiS0_jPKhmEPFiS0_S0_E
+__ZN6webrtc24setVideoDecoderCallbacksEPFPvRKNS_14SdpVideoFormatEEPFiS0_EPFiS0_jPKhmttEPFiS0_S0_E
+__ZN6webrtc19setDecoderFrameSizeEPvtt
 __ZN6webrtc18RtpCodecCapabilityC1Ev
 __ZN6webrtc22RTPFragmentationHeaderD1Ev
 __ZN6webrtc22RTPFragmentationHeaderC1Ev

Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/WebKitDecoder.h (269305 => 269306)


--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/WebKitDecoder.h	2020-11-03 16:21:49 UTC (rev 269305)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/WebKitDecoder.h	2020-11-03 16:43:44 UTC (rev 269306)
@@ -38,7 +38,7 @@
 using WebKitVideoDecoder = void*;
 using VideoDecoderCreateCallback = WebKitVideoDecoder(*)(const SdpVideoFormat& format);
 using VideoDecoderReleaseCallback = int32_t(*)(WebKitVideoDecoder);
-using VideoDecoderDecodeCallback = int32_t(*)(WebKitVideoDecoder, uint32_t timeStamp, const uint8_t*, size_t length);
+using VideoDecoderDecodeCallback = int32_t(*)(WebKitVideoDecoder, uint32_t timeStamp, const uint8_t*, size_t length, uint16_t width, uint16_t height);
 using VideoDecoderRegisterDecodeCompleteCallback = int32_t(*)(WebKitVideoDecoder, void* decodedImageCallback);
 
 void setVideoDecoderCallbacks(VideoDecoderCreateCallback, VideoDecoderReleaseCallback, VideoDecoderDecodeCallback, VideoDecoderRegisterDecodeCompleteCallback);
@@ -51,7 +51,9 @@
 using LocalDecoderCallback = void (^)(CVPixelBufferRef, uint32_t timeStamp, uint32_t timeStampNs);
 void* createLocalH264Decoder(LocalDecoderCallback);
 void* createLocalH265Decoder(LocalDecoderCallback);
+void* createLocalVP9Decoder(LocalDecoderCallback);
 void releaseLocalDecoder(LocalDecoder);
 int32_t decodeFrame(LocalDecoder, uint32_t timeStamp, const uint8_t*, size_t);
+void setDecoderFrameSize(LocalDecoder, uint16_t width, uint16_t height);
 
 }

Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/WebKitDecoder.mm (269305 => 269306)


--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/WebKitDecoder.mm	2020-11-03 16:21:49 UTC (rev 269305)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/WebKitDecoder.mm	2020-11-03 16:43:44 UTC (rev 269306)
@@ -35,8 +35,9 @@
 #import "modules/video_coding/include/video_error_codes.h"
 #import "sdk/objc/components/video_codec/RTCVideoDecoderH264.h"
 #import "sdk/objc/components/video_codec/RTCVideoDecoderH265.h"
+#import "sdk/objc/components/video_codec/RTCVideoDecoderVTBVP9.h"
 
-@interface WK_RTCLocalVideoH264H265Decoder : NSObject
+@interface WK_RTCLocalVideoH264H265VP9Decoder : NSObject
 - (instancetype)initH264DecoderWithCallback:(webrtc::LocalDecoderCallback)callback;
 - (instancetype)initH265DecoderWithCallback:(webrtc::LocalDecoderCallback)callback;
 - (NSInteger)decodeData:(const uint8_t *)data size:(size_t)size timeStamp:(uint32_t)timeStamp;
@@ -43,9 +44,10 @@
 - (NSInteger)releaseDecoder;
 @end
 
-@implementation WK_RTCLocalVideoH264H265Decoder {
+@implementation WK_RTCLocalVideoH264H265VP9Decoder {
     RTCVideoDecoderH264 *m_h264Decoder;
     RTCVideoDecoderH265 *m_h265Decoder;
+    RTCVideoDecoderVTBVP9 *m_vp9Decoder;
 }
 
 - (instancetype)initH264DecoderWithCallback:(webrtc::LocalDecoderCallback)callback {
@@ -70,18 +72,39 @@
     return self;
 }
 
+- (instancetype)initVP9DecoderWithCallback:(webrtc::LocalDecoderCallback)callback {
+    if (self = [super init]) {
+        m_vp9Decoder = [[RTCVideoDecoderVTBVP9 alloc] init];
+        [m_vp9Decoder setCallback:^(RTCVideoFrame *frame) {
+            auto *buffer = (RTCCVPixelBuffer *)frame.buffer;
+            callback(buffer.pixelBuffer, frame.timeStampNs, frame.timeStamp);
+        }];
+    }
+    return self;
+}
+
 - (NSInteger)decodeData:(const uint8_t *)data size:(size_t)size timeStamp:(uint32_t)timeStamp {
     if (m_h264Decoder)
         return [m_h264Decoder decodeData:data size:size timeStamp:timeStamp];
     if (m_h265Decoder)
         return [m_h265Decoder decodeData:data size:size timeStamp:timeStamp];
+    if (m_vp9Decoder)
+        return [m_vp9Decoder decodeData:data size:size timeStamp:timeStamp];
     return 0;
 }
 
+- (void)setWidth:(uint16_t)width height:(uint16_t)height {
+    if (!m_vp9Decoder)
+        return;
+    [m_vp9Decoder setWidth:width height:height];
+}
+
 - (NSInteger)releaseDecoder {
     if (m_h264Decoder)
         return [m_h264Decoder releaseDecoder];
-    return [m_h265Decoder releaseDecoder];
+    if (m_h265Decoder)
+        return [m_h265Decoder releaseDecoder];
+    return [m_vp9Decoder releaseDecoder];
 }
 @end
 
@@ -159,7 +182,13 @@
 
 int32_t RemoteVideoDecoder::Decode(const EncodedImage& input_image, bool missing_frames, int64_t render_time_ms)
 {
-    return videoDecoderCallbacks().decodeCallback(m_internalDecoder, input_image.Timestamp(), input_image.data(), input_image.size());
+    uint16_t encodedWidth = 0;
+    uint16_t encodedHeight = 0;
+    if (input_image._frameType == VideoFrameType::kVideoFrameKey) {
+        encodedWidth = rtc::dchecked_cast<uint16_t>(input_image._encodedWidth);
+        encodedHeight = rtc::dchecked_cast<uint16_t>(input_image._encodedHeight);
+    }
+    return videoDecoderCallbacks().decodeCallback(m_internalDecoder, input_image.Timestamp(), input_image.data(), input_image.size(), encodedWidth, encodedHeight);
 }
 
 int32_t RemoteVideoDecoder::RegisterDecodeCompleteCallback(DecodedImageCallback* callback)
@@ -179,11 +208,7 @@
 
 std::vector<SdpVideoFormat> RemoteVideoDecoderFactory::GetSupportedFormats() const
 {
-    std::vector<SdpVideoFormat> supported_formats;
-    supported_formats.push_back(SdpVideoFormat { "H264" });
-    supported_formats.push_back(SdpVideoFormat { "H265" });
-    supported_formats.push_back(SdpVideoFormat { "VP8" });
-    return supported_formats;
+    return m_internalFactory->GetSupportedFormats();
 }
 
 std::unique_ptr<VideoDecoder> RemoteVideoDecoderFactory::CreateVideoDecoder(const SdpVideoFormat& format)
@@ -208,26 +233,38 @@
 
 void* createLocalH264Decoder(LocalDecoderCallback callback)
 {
-    auto decoder = [[WK_RTCLocalVideoH264H265Decoder alloc] initH264DecoderWithCallback: callback];
+    auto decoder = [[WK_RTCLocalVideoH264H265VP9Decoder alloc] initH264DecoderWithCallback: callback];
     return (__bridge_retained void*)decoder;
 }
 
 void* createLocalH265Decoder(LocalDecoderCallback callback)
 {
-    auto decoder = [[WK_RTCLocalVideoH264H265Decoder alloc] initH265DecoderWithCallback: callback];
+    auto decoder = [[WK_RTCLocalVideoH264H265VP9Decoder alloc] initH265DecoderWithCallback: callback];
     return (__bridge_retained void*)decoder;
 }
 
+void* createLocalVP9Decoder(LocalDecoderCallback callback)
+{
+    auto decoder = [[WK_RTCLocalVideoH264H265VP9Decoder alloc] initVP9DecoderWithCallback: callback];
+    return (__bridge_retained void*)decoder;
+}
+
 void releaseLocalDecoder(LocalDecoder localDecoder)
 {
-    auto* decoder = (__bridge_transfer WK_RTCLocalVideoH264H265Decoder *)(localDecoder);
+    auto* decoder = (__bridge_transfer WK_RTCLocalVideoH264H265VP9Decoder *)(localDecoder);
     [decoder releaseDecoder];
 }
 
 int32_t decodeFrame(LocalDecoder localDecoder, uint32_t timeStamp, const uint8_t* data, size_t size)
 {
-    auto* decoder = (__bridge WK_RTCLocalVideoH264H265Decoder *)(localDecoder);
-    return [decoder decodeData: data size: size timeStamp: timeStamp];
+    auto* decoder = (__bridge WK_RTCLocalVideoH264H265VP9Decoder *)(localDecoder);
+    return [decoder decodeData:data size:size timeStamp:timeStamp];
 }
 
+void setDecoderFrameSize(LocalDecoder localDecoder, uint16_t width, uint16_t height)
+{
+    auto* decoder = (__bridge WK_RTCLocalVideoH264H265VP9Decoder *)(localDecoder);
+    [decoder setWidth:width height:height];
 }
+
+}

Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/components/video_codec/RTCVideoDecoderVTBVP9.h (269305 => 269306)


--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/components/video_codec/RTCVideoDecoderVTBVP9.h	2020-11-03 16:21:49 UTC (rev 269305)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/components/video_codec/RTCVideoDecoderVTBVP9.h	2020-11-03 16:43:44 UTC (rev 269306)
@@ -31,6 +31,7 @@
 RTC_OBJC_EXPORT
 __attribute__((objc_runtime_name("WK_RTCVideoDecoderVTBVP9")))
 @interface RTCVideoDecoderVTBVP9 : NSObject <RTCVideoDecoder>
+- (void)setWidth:(uint16_t)width height:(uint16_t)height;
 - (NSInteger)decodeData:(const uint8_t *)data
     size:(size_t)size
     timeStamp:(uint32_t)timeStamp;

Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/components/video_codec/RTCVideoDecoderVTBVP9.mm (269305 => 269306)


--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/components/video_codec/RTCVideoDecoderVTBVP9.mm	2020-11-03 16:21:49 UTC (rev 269305)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/components/video_codec/RTCVideoDecoderVTBVP9.mm	2020-11-03 16:43:44 UTC (rev 269306)
@@ -134,12 +134,16 @@
          renderTimeMs:(int64_t)renderTimeMs {
   RTC_DCHECK(inputImage.buffer);
   if (inputImage.frameType == RTCFrameTypeVideoFrameKey) {
-      _width = inputImage.encodedWidth;
-      _height = inputImage.encodedHeight;
+    [self setWidth:inputImage.encodedWidth height: inputImage.encodedHeight];
   }
   return [self decodeData: (uint8_t *)inputImage.buffer.bytes size: inputImage.buffer.length timeStamp: inputImage.timeStamp];
 }
 
+- (void)setWidth:(uint16_t)width height:(uint16_t)height {
+  _width = width;
+  _height = height;
+}
+
 - (NSInteger)decodeData:(const uint8_t *)data
         size:(size_t)size
         timeStamp:(uint32_t)timeStamp {

Modified: trunk/Source/WebKit/ChangeLog (269305 => 269306)


--- trunk/Source/WebKit/ChangeLog	2020-11-03 16:21:49 UTC (rev 269305)
+++ trunk/Source/WebKit/ChangeLog	2020-11-03 16:43:44 UTC (rev 269306)
@@ -1,5 +1,37 @@
 2020-11-03  Youenn Fablet  <[email protected]>
 
+        Add support for WebRTC VP9 decoder in GPU process
+        https://bugs.webkit.org/show_bug.cgi?id=218445
+
+        Reviewed by Eric Carlson.
+
+        Add support for VP9 decoder, send key frame size as IPC message specifically for VP9 hardware decoder.
+        If GPU process does not enable either SW or HW VP9 decoder, we fall back to in process VP9 decoder.
+
+        Manually tested by enabling WebRTC codec in GPU process.
+        Will be covered by existing VP9 tests in GPU process mode once canvas in GPUProcess is fully supported.
+
+        * GPUProcess/webrtc/LibWebRTCCodecsProxy.h:
+        * GPUProcess/webrtc/LibWebRTCCodecsProxy.messages.in:
+        * GPUProcess/webrtc/LibWebRTCCodecsProxy.mm:
+        (WebKit::LibWebRTCCodecsProxy::createVP9Decoder):
+        (WebKit::LibWebRTCCodecsProxy::setFrameSize):
+        * WebProcess/GPU/GPUProcessConnection.h:
+        (WebKit::GPUProcessConnection::isVP9DecoderEnabled const):
+        (WebKit::GPUProcessConnection::isVPSWDecoderEnabled const):
+        * WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp:
+        (WebKit::createVideoDecoder):
+        (WebKit::decodeVideoFrame):
+        (WebKit::LibWebRTCCodecs::setCallbacks):
+        (WebKit::LibWebRTCCodecs::createDecoder):
+        (WebKit::LibWebRTCCodecs::decodeFrame):
+        (WebKit::formatNameFromCodecType):
+        * WebProcess/GPU/webrtc/LibWebRTCCodecs.h:
+        (WebKit::LibWebRTCCodecs::setVP9VTBSupport):
+        (WebKit::LibWebRTCCodecs::supportVP9VTB const):
+
+2020-11-03  Youenn Fablet  <[email protected]>
+
         Allow low latency H264 encoder in GPUProcess
         https://bugs.webkit.org/show_bug.cgi?id=218442
 

Modified: trunk/Source/WebKit/GPUProcess/webrtc/LibWebRTCCodecsProxy.h (269305 => 269306)


--- trunk/Source/WebKit/GPUProcess/webrtc/LibWebRTCCodecsProxy.h	2020-11-03 16:21:49 UTC (rev 269305)
+++ trunk/Source/WebKit/GPUProcess/webrtc/LibWebRTCCodecsProxy.h	2020-11-03 16:43:44 UTC (rev 269306)
@@ -69,8 +69,10 @@
     void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
     void createH264Decoder(RTCDecoderIdentifier);
     void createH265Decoder(RTCDecoderIdentifier);
+    void createVP9Decoder(RTCDecoderIdentifier);
     void releaseDecoder(RTCDecoderIdentifier);
     void decodeFrame(RTCDecoderIdentifier, uint32_t timeStamp, const IPC::DataReference&);
+    void setFrameSize(RTCDecoderIdentifier, uint16_t width, uint16_t height);
 
     void createEncoder(RTCEncoderIdentifier, const String&, const Vector<std::pair<String, String>>&, bool useLowLatency);
     void releaseEncoder(RTCEncoderIdentifier);

Modified: trunk/Source/WebKit/GPUProcess/webrtc/LibWebRTCCodecsProxy.messages.in (269305 => 269306)


--- trunk/Source/WebKit/GPUProcess/webrtc/LibWebRTCCodecsProxy.messages.in	2020-11-03 16:21:49 UTC (rev 269305)
+++ trunk/Source/WebKit/GPUProcess/webrtc/LibWebRTCCodecsProxy.messages.in	2020-11-03 16:43:44 UTC (rev 269306)
@@ -26,8 +26,10 @@
 messages -> LibWebRTCCodecsProxy NotRefCounted {
     CreateH264Decoder(WebKit::RTCDecoderIdentifier id)
     CreateH265Decoder(WebKit::RTCDecoderIdentifier id)
+    CreateVP9Decoder(WebKit::RTCDecoderIdentifier id)
     ReleaseDecoder(WebKit::RTCDecoderIdentifier id)
     DecodeFrame(WebKit::RTCDecoderIdentifier id, uint32_t timeStamp, IPC::DataReference data)
+    SetFrameSize(WebKit::RTCDecoderIdentifier id, uint16_t width, uint16_t height)
 
     CreateEncoder(WebKit::RTCEncoderIdentifier id, String formatName, Vector<std::pair<String, String>> parameters, bool useLowLatency);
     ReleaseEncoder(WebKit::RTCEncoderIdentifier id)

Modified: trunk/Source/WebKit/GPUProcess/webrtc/LibWebRTCCodecsProxy.mm (269305 => 269306)


--- trunk/Source/WebKit/GPUProcess/webrtc/LibWebRTCCodecsProxy.mm	2020-11-03 16:21:49 UTC (rev 269305)
+++ trunk/Source/WebKit/GPUProcess/webrtc/LibWebRTCCodecsProxy.mm	2020-11-03 16:43:44 UTC (rev 269306)
@@ -88,6 +88,15 @@
     }));
 }
 
+void LibWebRTCCodecsProxy::createVP9Decoder(RTCDecoderIdentifier identifier)
+{
+    ASSERT(!m_decoders.contains(identifier));
+    m_decoders.add(identifier, webrtc::createLocalVP9Decoder(^(CVPixelBufferRef pixelBuffer, uint32_t timeStampNs, uint32_t timeStamp) {
+        if (auto sample = WebCore::RemoteVideoSample::create(pixelBuffer, MediaTime(timeStampNs, 1)))
+            m_gpuConnectionToWebProcess.connection().send(Messages::LibWebRTCCodecs::CompletedDecoding { identifier, timeStamp, *sample }, 0);
+    }));
+}
+
 void LibWebRTCCodecsProxy::releaseDecoder(RTCDecoderIdentifier identifier)
 {
     ASSERT(m_decoders.contains(identifier));
@@ -106,6 +115,16 @@
         m_gpuConnectionToWebProcess.connection().send(Messages::LibWebRTCCodecs::FailedDecoding { identifier }, 0);
 }
 
+void LibWebRTCCodecsProxy::setFrameSize(RTCDecoderIdentifier identifier, uint16_t width, uint16_t height)
+{
+    ASSERT(m_decoders.contains(identifier));
+    auto decoder = m_decoders.get(identifier);
+    if (!decoder)
+        return;
+
+    webrtc::setDecoderFrameSize(decoder, width, height);
+}
+
 void LibWebRTCCodecsProxy::createEncoder(RTCEncoderIdentifier identifier, const String& formatName, const Vector<std::pair<String, String>>& parameters, bool useLowLatency)
 {
     ASSERT(!m_encoders.contains(identifier));

Modified: trunk/Source/WebKit/WebProcess/GPU/GPUProcessConnection.h (269305 => 269306)


--- trunk/Source/WebKit/WebProcess/GPU/GPUProcessConnection.h	2020-11-03 16:21:49 UTC (rev 269305)
+++ trunk/Source/WebKit/WebProcess/GPU/GPUProcessConnection.h	2020-11-03 16:43:44 UTC (rev 269306)
@@ -81,6 +81,11 @@
 
     void updateParameters(const WebPageCreationParameters&);
 
+#if ENABLE(VP9)
+    bool isVP9DecoderEnabled() const { return m_enableVP9Decoder; }
+    bool isVPSWDecoderEnabled() const { return m_enableVP9SWDecoder; }
+#endif
+
 private:
     GPUProcessConnection(IPC::Connection::Identifier);
 

Modified: trunk/Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp (269305 => 269306)


--- trunk/Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp	2020-11-03 16:21:49 UTC (rev 269305)
+++ trunk/Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp	2020-11-03 16:43:44 UTC (rev 269306)
@@ -37,6 +37,7 @@
 #include <WebCore/RealtimeVideoUtilities.h>
 #include <WebCore/RemoteVideoSample.h>
 #include <WebCore/RuntimeEnabledFeatures.h>
+#include <WebCore/VP9UtilitiesCocoa.h>
 #include <webrtc/sdk/WebKit/WebKitDecoder.h>
 #include <webrtc/sdk/WebKit/WebKitEncoder.h>
 #include <wtf/MainThread.h>
@@ -54,6 +55,9 @@
     if (format.name == "H265")
         return WebProcess::singleton().libWebRTCCodecs().createDecoder(LibWebRTCCodecs::Type::H265);
 
+    if (format.name == "VP9" && WebProcess::singleton().libWebRTCCodecs().supportVP9VTB())
+        return WebProcess::singleton().libWebRTCCodecs().createDecoder(LibWebRTCCodecs::Type::VP9);
+
     return nullptr;
 }
 
@@ -62,9 +66,9 @@
     return WebProcess::singleton().libWebRTCCodecs().releaseDecoder(*static_cast<LibWebRTCCodecs::Decoder*>(decoder));
 }
 
-static int32_t decodeVideoFrame(webrtc::WebKitVideoDecoder decoder, uint32_t timeStamp, const uint8_t* data, size_t size)
+static int32_t decodeVideoFrame(webrtc::WebKitVideoDecoder decoder, uint32_t timeStamp, const uint8_t* data, size_t size, uint16_t width,  uint16_t height)
 {
-    return WebProcess::singleton().libWebRTCCodecs().decodeFrame(*static_cast<LibWebRTCCodecs::Decoder*>(decoder), timeStamp, data, size);
+    return WebProcess::singleton().libWebRTCCodecs().decodeFrame(*static_cast<LibWebRTCCodecs::Decoder*>(decoder), timeStamp, data, size, width, height);
 }
 
 static int32_t registerDecodeCompleteCallback(webrtc::WebKitVideoDecoder decoder, void* decodedImageCallback)
@@ -159,8 +163,16 @@
         webrtc::setVideoEncoderCallbacks(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
         return;
     }
+
+#if ENABLE(VP9)
     // Let's create WebProcess libWebRTCCodecs since it may be called from various threads.
-    WebProcess::singleton().libWebRTCCodecs();
+    auto& codecs = WebProcess::singleton().libWebRTCCodecs();
+    auto& gpuConnection = WebProcess::singleton().ensureGPUProcessConnection();
+
+    // FIMXE: We should disable VP9VTB if VP9 hardware decoding is enabled but there is no support for it.
+    codecs.setVP9VTBSupport(gpuConnection.isVP9DecoderEnabled() || gpuConnection.isVPSWDecoderEnabled());
+#endif
+
     webrtc::setVideoDecoderCallbacks(createVideoDecoder, releaseVideoDecoder, decodeVideoFrame, registerDecodeCompleteCallback);
     webrtc::setVideoEncoderCallbacks(createVideoEncoder, releaseVideoEncoder, initializeVideoEncoder, encodeVideoFrame, registerEncodeCompleteCallback, setEncodeRatesCallback);
 }
@@ -170,6 +182,7 @@
     auto decoder = makeUnique<Decoder>();
     auto* result = decoder.get();
     decoder->identifier = RTCDecoderIdentifier::generateThreadSafe();
+    decoder->type = type;
 
     callOnMainRunLoop([this, decoder = WTFMove(decoder), type]() mutable {
         decoder->connection = &WebProcess::singleton().ensureGPUProcessConnection().connection();
@@ -182,6 +195,9 @@
         case Type::H265:
             decoder->connection->send(Messages::LibWebRTCCodecsProxy::CreateH265Decoder { decoderIdentifier }, 0);
             break;
+        case Type::VP9:
+            decoder->connection->send(Messages::LibWebRTCCodecsProxy::CreateVP9Decoder { decoderIdentifier }, 0);
+            break;
         }
 
         ASSERT(!m_decoders.contains(decoderIdentifier));
@@ -204,7 +220,7 @@
     return 0;
 }
 
-int32_t LibWebRTCCodecs::decodeFrame(Decoder& decoder, uint32_t timeStamp, const uint8_t* data, size_t size)
+int32_t LibWebRTCCodecs::decodeFrame(Decoder& decoder, uint32_t timeStamp, const uint8_t* data, size_t size, uint16_t width, uint16_t height)
 {
     if (!decoder.connection || decoder.hasError) {
         decoder.hasError = false;
@@ -211,6 +227,9 @@
         return WEBRTC_VIDEO_CODEC_ERROR;
     }
 
+    if (decoder.type == Type::VP9 && (width || height))
+        decoder.connection->send(Messages::LibWebRTCCodecsProxy::SetFrameSize { decoder.identifier, width, height }, 0);
+
     decoder.connection->send(Messages::LibWebRTCCodecsProxy::DecodeFrame { decoder.identifier, timeStamp, IPC::DataReference { data, size } }, 0);
     return WEBRTC_VIDEO_CODEC_OK;
 }
@@ -269,6 +288,8 @@
         return "H264"_s;
     case LibWebRTCCodecs::Type::H265:
         return "H265"_s;
+    case LibWebRTCCodecs::Type::VP9:
+        return "VP9"_s;
     }
 }
 

Modified: trunk/Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.h (269305 => 269306)


--- trunk/Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.h	2020-11-03 16:21:49 UTC (rev 269305)
+++ trunk/Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.h	2020-11-03 16:43:44 UTC (rev 269306)
@@ -62,10 +62,12 @@
 
     static void setCallbacks(bool useGPUProcess);
 
+    enum class Type { H264, H265, VP9 };
     struct Decoder {
         WTF_MAKE_FAST_ALLOCATED;
     public:
         RTCDecoderIdentifier identifier;
+        Type type;
         void* decodedImageCallback { nullptr };
         Lock decodedImageCallbackLock;
         bool hasError { false };
@@ -72,10 +74,9 @@
         RefPtr<IPC::Connection> connection;
     };
 
-    enum class Type { H264, H265 };
     Decoder* createDecoder(Type);
     int32_t releaseDecoder(Decoder&);
-    int32_t decodeFrame(Decoder&, uint32_t timeStamp, const uint8_t*, size_t);
+    int32_t decodeFrame(Decoder&, uint32_t timeStamp, const uint8_t*, size_t, uint16_t width, uint16_t height);
     void registerDecodeFrameCallback(Decoder&, void* decodedImageCallback);
 
     struct Encoder {
@@ -98,6 +99,9 @@
 
     void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
 
+    void setVP9VTBSupport(bool supportVP9VTB) { m_supportVP9VTB = supportVP9VTB; }
+    bool supportVP9VTB() const { return m_supportVP9VTB; }
+
 private:
     void failedDecoding(RTCDecoderIdentifier);
     void completedDecoding(RTCDecoderIdentifier, uint32_t timeStamp, WebCore::RemoteVideoSample&&);
@@ -113,6 +117,7 @@
     RetainPtr<CVPixelBufferPoolRef> m_pixelBufferPool;
     size_t m_pixelBufferPoolWidth { 0 };
     size_t m_pixelBufferPoolHeight { 0 };
+    bool m_supportVP9VTB { false };
 };
 
 } // namespace WebKit
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to