Adopt new VCP SPI
authoryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 29 Jan 2019 19:13:25 +0000 (19:13 +0000)
committeryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 29 Jan 2019 19:13:25 +0000 (19:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=193357
<rdar://problem/43656651>

Reviewed by Eric Carlson.

Enable VCP through VTB API with specific encoder id.
If encoder id is not supported, fallback to VCP.
A specific routine is added to check for encoder id presence.

* Source/webrtc/sdk/WebKit/EncoderUtilities.h:
* Source/webrtc/sdk/WebKit/VideoProcessingSoftLink.cpp:
* Source/webrtc/sdk/WebKit/VideoProcessingSoftLink.h:
* Source/webrtc/sdk/WebKit/WebKitUtilities.mm:
(webrtc::setApplicationStatus):
* Source/webrtc/sdk/objc/components/video_codec/RTCVideoEncoderH264.mm:
(-[RTCSingleVideoEncoderH264 resetCompressionSessionWithPixelFormat:]):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240665 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/ThirdParty/libwebrtc/ChangeLog
Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/EncoderUtilities.h
Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/VideoProcessingSoftLink.cpp
Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/VideoProcessingSoftLink.h
Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/WebKitUtilities.mm
Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/components/video_codec/RTCVideoEncoderH264.mm

index f97a53a..9bccbbe 100644 (file)
@@ -1,3 +1,23 @@
+2019-01-29  Youenn Fablet  <youenn@apple.com>
+
+        Adopt new VCP SPI
+        https://bugs.webkit.org/show_bug.cgi?id=193357
+        <rdar://problem/43656651>
+
+        Reviewed by Eric Carlson.
+
+        Enable VCP through VTB API with specific encoder id.
+        If encoder id is not supported, fallback to VCP.
+        A specific routine is added to check for encoder id presence.
+
+        * Source/webrtc/sdk/WebKit/EncoderUtilities.h:
+        * Source/webrtc/sdk/WebKit/VideoProcessingSoftLink.cpp:
+        * Source/webrtc/sdk/WebKit/VideoProcessingSoftLink.h:
+        * Source/webrtc/sdk/WebKit/WebKitUtilities.mm:
+        (webrtc::setApplicationStatus):
+        * Source/webrtc/sdk/objc/components/video_codec/RTCVideoEncoderH264.mm:
+        (-[RTCSingleVideoEncoderH264 resetCompressionSessionWithPixelFormat:]):
+
 2019-01-25  Keith Rollin  <krollin@apple.com>
 
         Update WebKitAdditions.xcconfig with correct order of variable definitions
index 5b9bdfd..25f56e7 100644 (file)
@@ -30,6 +30,7 @@
 #if ENABLE_VCP_ENCODER
 
 #define CompressionSessionRef VCPCompressionSessionRef
+
 #define CompressionSessionSetProperty webrtc::VCPCompressionSessionSetProperty
 #define CompressionSessionGetPixelBufferPool webrtc::VCPCompressionSessionGetPixelBufferPool
 #define CompressionSessionEncodeFrame webrtc::VCPCompressionSessionEncodeFrame
 #define kCodecTypeH264 kVCPCodecType4CC_H264
 #define CompressionSessionInvalidate webrtc::VCPCompressionSessionInvalidate
 
+#elif ENABLE_VCP_VTB_ENCODER
+
+bool isSupportingH264RTVC();
+
+#define CompressionSessionRef VCPCompressionSessionRef
+
+#define CompressionSessionSetProperty(compressionSession, ...) (isSupportingH264RTVC() ? VTSessionSetProperty(reinterpret_cast<VTCompressionSessionRef>(compressionSession), __VA_ARGS__) : webrtc::VCPCompressionSessionSetProperty(compressionSession, __VA_ARGS__))
+#define CompressionSessionGetPixelBufferPool(compressionSession, ...) (isSupportingH264RTVC() ? VTCompressionSessionGetPixelBufferPool(reinterpret_cast<VTCompressionSessionRef>(compressionSession), __VA_ARGS__) : webrtc::VCPCompressionSessionSetProperty(compressionSession, __VA_ARGS__))
+#define CompressionSessionEncodeFrame(compressionSession, ...) (isSupportingH264RTVC() ? VTCompressionSessionEncodeFrame(reinterpret_cast<VTCompressionSessionRef>(compressionSession), __VA_ARGS__) : webrtc::VCPCompressionSessionEncodeFrame(compressionSession, __VA_ARGS__))
+#define CompressionSessionCreate(a, b, c, d, e, f, g, h, i, compressionSession) (isSupportingH264RTVC() ? VTCompressionSessionCreate(a, b, c, d, e, f, g, h, i, reinterpret_cast<VTCompressionSessionRef*>(compressionSession)) : webrtc::VCPCompressionSessionCreate(a, b, c, d, e, f, g, h, i, compressionSession))
+#define kCodecTypeH264 (isSupportingH264RTVC() ? kCMVideoCodecType_H264 : kVCPCodecType4CC_H264)
+#define CompressionSessionInvalidate(compressionSession) (isSupportingH264RTVC() ? VTCompressionSessionInvalidate(reinterpret_cast<VTCompressionSessionRef>(compressionSession)) : webrtc::VCPCompressionSessionInvalidate(compressionSession))
+
 #else
 
 #define CompressionSessionRef VTCompressionSessionRef
+
 #define CompressionSessionSetProperty VTSessionSetProperty
 #define CompressionSessionGetPixelBufferPool VTCompressionSessionGetPixelBufferPool
 #define CompressionSessionEncodeFrame VTCompressionSessionEncodeFrame
index 101e87c..2e4be53 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "VideoProcessingSoftLink.h"
 
-#if ENABLE_VCP_ENCODER
+#if ENABLE_VCP_ENCODER || ENABLE_VCP_VTB_ENCODER
 
 #include "rtc_base/logging.h"
 #import <dlfcn.h>
 }
 
 SOFT_LINK_PRIVATE_FRAMEWORK_FOR_SOURCE(webrtc, VideoProcessing)
+SOFT_LINK_FUNCTION_FOR_SOURCE(webrtc, VideoProcessing, VPModuleInitialize, void, (), ())
 
 SOFT_LINK_FUNCTION_FOR_SOURCE(webrtc, VideoProcessing, VCPCompressionSessionSetProperty, OSStatus, (VCPCompressionSessionRef session, CFStringRef key, CFTypeRef value), (session, key, value))
 SOFT_LINK_FUNCTION_FOR_SOURCE(webrtc, VideoProcessing, VCPCompressionSessionGetPixelBufferPool, CVPixelBufferPoolRef, (VCPCompressionSessionRef session), (session))
 SOFT_LINK_FUNCTION_FOR_SOURCE(webrtc, VideoProcessing, VCPCompressionSessionEncodeFrame, OSStatus, (VCPCompressionSessionRef session, CVImageBufferRef buffer, CMTime timestamp, CMTime time, CFDictionaryRef dictionary, void* data, VTEncodeInfoFlags* flags), (session, buffer, timestamp, time, dictionary, data, flags))
 SOFT_LINK_FUNCTION_FOR_SOURCE(webrtc, VideoProcessing, VCPCompressionSessionCreate, OSStatus, (CFAllocatorRef allocator1, int32_t value1 , int32_t value2, CMVideoCodecType type, CFDictionaryRef dictionary1, CFDictionaryRef dictionary2, CFAllocatorRef allocator3, VTCompressionOutputCallback callback, void* data, VCPCompressionSessionRef* session), (allocator1, value1, value2, type, dictionary1, dictionary2, allocator3, callback, data, session))
 SOFT_LINK_FUNCTION_FOR_SOURCE(webrtc, VideoProcessing, VCPCompressionSessionInvalidate, void, (VCPCompressionSessionRef session), (session))
-SOFT_LINK_FUNCTION_FOR_SOURCE(webrtc, VideoProcessing, VPModuleInitialize, void, (), ())
 
-#endif // ENABLE_VCP_ENCODER
+#endif // ENABLE_VCP_ENCODER || ENABLE_VCP_VTB_ENCODER
index cf866d8..7c2225b 100644 (file)
 
 #if (defined(TARGET_IPHONE_SIMULATOR)  && TARGET_IPHONE_SIMULATOR)
 #define ENABLE_VCP_ENCODER 0
+#define ENABLE_VCP_VTB_ENCODER 0
 #elif (defined(TARGET_OS_IPHONE)  && TARGET_OS_IPHONE)
-#define ENABLE_VCP_ENCODER 1
+#define ENABLE_VCP_ENCODER __MAC_OS_X_VERSION_MAX_ALLOWED < 101500
+#define ENABLE_VCP_VTB_ENCODER __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500
 #elif (defined(TARGET_OS_MAC) && TARGET_OS_MAC)
-#define ENABLE_VCP_ENCODER (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101300 && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101304)
+#define ENABLE_VCP_ENCODER (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101300 && __MAC_OS_X_VERSION_MAX_ALLOWED < 101500)
+#define ENABLE_VCP_VTB_ENCODER __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500
 #endif
 
 #endif
 #define ENABLE_VCP_ENCODER 0
 #endif
 
+#if !defined(ENABLE_VCP_VTB_ENCODER)
+#define ENABLE_VCP_VTB_ENCODER 0
+#endif
+
 #if !defined(ALWAYS_INLINE)
 #define ALWAYS_INLINE inline
 #endif
         return pointer##name; \
     }
 
-#if ENABLE_VCP_ENCODER
+#if ENABLE_VCP_ENCODER || ENABLE_VCP_VTB_ENCODER
 
 #include <VideoProcessing/VideoProcessing.h>
 
 SOFT_LINK_FRAMEWORK_FOR_HEADER(webrtc, VideoProcessing)
 
+SOFT_LINK_FUNCTION_FOR_HEADER(webrtc, VideoProcessing, VPModuleInitialize, void, (), ())
+#define VPModuleInitialize softLink_VideoProcessing_VPModuleInitialize
+
 SOFT_LINK_FUNCTION_FOR_HEADER(webrtc, VideoProcessing, VCPCompressionSessionSetProperty, OSStatus, (VCPCompressionSessionRef session, CFStringRef key, CFTypeRef value), (session, key, value))
 #define VCPCompressionSessionSetProperty softLink_VideoProcessing_VCPCompressionSessionSetProperty
 
@@ -132,9 +142,6 @@ SOFT_LINK_FUNCTION_FOR_HEADER(webrtc, VideoProcessing, VCPCompressionSessionCrea
 SOFT_LINK_FUNCTION_FOR_HEADER(webrtc, VideoProcessing, VCPCompressionSessionInvalidate, void, (VCPCompressionSessionRef session), (session))
 #define VCPCompressionSessionInvalidate softLink_VideoProcessing_VCPCompressionSessionInvalidate
 
-SOFT_LINK_FUNCTION_FOR_HEADER(webrtc, VideoProcessing, VPModuleInitialize, void, (), ())
-#define VPModuleInitialize softLink_VideoProcessing_VPModuleInitialize
-
-#endif // ENABLE_VCP_ENCODER
+#endif // ENABLE_VCP_ENCODER || ENABLE_VCP_VTB_ENCODER
 
 #endif // __APPLE__
index f6cebf7..ace8a89 100644 (file)
@@ -105,7 +105,7 @@ void setApplicationStatus(bool isActive)
 
 std::unique_ptr<webrtc::VideoEncoderFactory> createWebKitEncoderFactory(WebKitCodecSupport codecSupport)
 {
-#if ENABLE_VCP_ENCODER
+#if ENABLE_VCP_ENCODER || ENABLE_VCP_VTB_ENCODER
     static std::once_flag onceFlag;
     std::call_once(onceFlag, [] {
         webrtc::VPModuleInitialize();
index 543f4fb..4499e1c 100644 (file)
 VT_EXPORT const CFStringRef kVTVideoEncoderSpecification_Usage;
 VT_EXPORT const CFStringRef kVTCompressionPropertyKey_Usage;
 
-#if !ENABLE_VCP_ENCODER && !defined(WEBRTC_IOS)
+#if ENABLE_VCP_VTB_ENCODER
+
+void testCompressionOutputCallback(void *, void *, OSStatus, VTEncodeInfoFlags, CMSampleBufferRef)
+{
+}
+
+static bool isSupportingH264RTVCValue = false;
+bool isSupportingH264RTVC()
+{
+    static std::once_flag onceFlag;
+    std::call_once(onceFlag, [] {
+        const size_t attributesSize = 3;
+        CFTypeRef keys[attributesSize] = {
+#if defined(WEBRTC_IOS)
+            kCVPixelBufferOpenGLESCompatibilityKey,
+#elif defined(WEBRTC_MAC)
+            kCVPixelBufferOpenGLCompatibilityKey,
+#endif
+            kCVPixelBufferIOSurfacePropertiesKey,
+            kCVPixelBufferPixelFormatTypeKey
+        };
+        CFDictionaryRef ioSurfaceValue = CreateCFTypeDictionary(nullptr, nullptr, 0);
+        int64_t pixelFormatType = kCVPixelFormatType_420YpCbCr8BiPlanarFullRange;
+        CFNumberRef pixelFormat = CFNumberCreate(nullptr, kCFNumberLongType, &pixelFormatType);
+        CFTypeRef values[attributesSize] = {kCFBooleanTrue, ioSurfaceValue, pixelFormat};
+        CFDictionaryRef sourceAttributes = CreateCFTypeDictionary(keys, values, attributesSize);
+
+        CFRelease(ioSurfaceValue);
+        CFRelease(pixelFormat);
+
+        CFMutableDictionaryRef encoderSpecs = CFDictionaryCreateMutable(nullptr, 5, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+#if !defined(WEBRTC_IOS)
+        auto useHardwareEncoder = webrtc::isH264HardwareEncoderAllowed() ? kCFBooleanTrue : kCFBooleanFalse;
+        // Currently hw accl is supported above 360p on mac, below 360p
+        // the compression session will be created with hw accl disabled.
+        CFDictionarySetValue(encoderSpecs, kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder, useHardwareEncoder);
+        CFDictionarySetValue(encoderSpecs, kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder, useHardwareEncoder);
+#endif
+        CFDictionarySetValue(encoderSpecs, kVTCompressionPropertyKey_RealTime, kCFBooleanTrue);
+
+        int usageValue = 1;
+        auto usage = CFNumberCreate(nullptr, kCFNumberIntType, &usageValue);
+        CFDictionarySetValue(encoderSpecs, kVTCompressionPropertyKey_Usage, usage);
+        CFRelease(usage);
+
+        CFDictionarySetValue(encoderSpecs, kVTVideoEncoderList_EncoderID, CFSTR("com.apple.videotoolbox.videoencoder.h264.rtvc"));
+
+        CompressionSessionRef compressionSession = nullptr;
+        OSStatus status = VTCompressionSessionCreate(nullptr, 320, 240, kCMVideoCodecType_H264,
+            encoderSpecs, sourceAttributes, nullptr, testCompressionOutputCallback, nullptr, reinterpret_cast<VTCompressionSessionRef*>(&compressionSession));
+
+        if (compressionSession) {
+            CompressionSessionInvalidate(compressionSession);
+            CFRelease(compressionSession);
+        }
+
+        CFRelease(sourceAttributes);
+        CFRelease(encoderSpecs);
+
+        isSupportingH264RTVCValue = status == noErr;
+    });
+    return isSupportingH264RTVCValue;
+}
+#endif
+
+#if !ENABLE_VCP_ENCODER && !defined(WEBRTC_IOS) && !ENABLE_VCP_VTB_ENCODER
 static inline bool isStandardFrameSize(int32_t width, int32_t height)
 {
     // FIXME: Envision relaxing this rule, something like width and height dividable by 4 or 8 should be good enough.
@@ -608,7 +673,7 @@ CFStringRef ExtractProfile(webrtc::SdpVideoFormat videoFormat) {
     CFRelease(pixelFormat);
     pixelFormat = nullptr;
   }
-  CFMutableDictionaryRef encoderSpecs = CFDictionaryCreateMutable(nullptr, 4, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+  CFMutableDictionaryRef encoderSpecs = CFDictionaryCreateMutable(nullptr, 5, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
 #if !defined(WEBRTC_IOS)
   auto useHardwareEncoder = webrtc::isH264HardwareEncoderAllowed() ? kCFBooleanTrue : kCFBooleanFalse;
   // Currently hw accl is supported above 360p on mac, below 360p
@@ -618,12 +683,16 @@ CFStringRef ExtractProfile(webrtc::SdpVideoFormat videoFormat) {
 #endif
   CFDictionarySetValue(encoderSpecs, kVTCompressionPropertyKey_RealTime, kCFBooleanTrue);
 
-#if ENABLE_VCP_ENCODER
+#if ENABLE_VCP_ENCODER || ENABLE_VCP_VTB_ENCODER
   int usageValue = 1;
   auto usage = CFNumberCreate(nullptr, kCFNumberIntType, &usageValue);
   CFDictionarySetValue(encoderSpecs, kVTCompressionPropertyKey_Usage, usage);
   CFRelease(usage);
 #endif
+#if ENABLE_VCP_VTB_ENCODER
+    if (isSupportingH264RTVC())
+        CFDictionarySetValue(encoderSpecs, kVTVideoEncoderList_EncoderID, CFSTR("com.apple.videotoolbox.videoencoder.h264.rtvc"));
+#endif
   OSStatus status =
       CompressionSessionCreate(nullptr,  // use default allocator
                                  _width,
@@ -663,7 +732,7 @@ CFStringRef ExtractProfile(webrtc::SdpVideoFormat videoFormat) {
   } else {
     RTC_LOG(LS_INFO) << "Compression session created with hw accl disabled";
 
-#if !ENABLE_VCP_ENCODER && !defined(WEBRTC_IOS)
+#if !ENABLE_VCP_ENCODER && !ENABLE_VCP_VTB_ENCODER && !defined(WEBRTC_IOS)
     if (!isStandardFrameSize(_width, _height)) {
       _disableEncoding = true;
       RTC_LOG(LS_ERROR) << "Using H264 software encoder with non standard size is not supported";