Modified: trunk/Source/ThirdParty/libwebrtc/ChangeLog (230450 => 230451)
--- trunk/Source/ThirdParty/libwebrtc/ChangeLog 2018-04-09 20:26:16 UTC (rev 230450)
+++ trunk/Source/ThirdParty/libwebrtc/ChangeLog 2018-04-09 21:09:54 UTC (rev 230451)
@@ -1,3 +1,16 @@
+2018-04-09 Youenn Fablet <you...@apple.com>
+
+ Use special software encoder mode in case there is no VCP not hardware encoder
+ https://bugs.webkit.org/show_bug.cgi?id=183961
+
+ Reviewed by Eric Carlson.
+
+ In case a compression session is not using a hardware encoder and VCP is not active
+ use a specific mode if the resolution is standard.
+
+ * Source/webrtc/sdk/WebKit/VideoProcessingSoftLink.cpp:
+ * Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/RTCVideoEncoderH264.mm:
+
2018-04-05 Alejandro G. Castro <a...@igalia.com>
[GTK] Add CMake package search for vpx and libevent libraries
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/VideoProcessingSoftLink.h (230450 => 230451)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/VideoProcessingSoftLink.h 2018-04-09 20:26:16 UTC (rev 230450)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/WebKit/VideoProcessingSoftLink.h 2018-04-09 21:09:54 UTC (rev 230451)
@@ -43,10 +43,6 @@
#endif
-#if ENABLE_VCP_ENCODER
-
-#include <VideoProcessing/VideoProcessing.h>
-
#define ALWAYS_INLINE inline
#ifdef __cplusplus
@@ -83,6 +79,36 @@
return functionNamespace::softLink##framework##functionName parameterNames; \
}
+#define SOFT_LINK_FRAMEWORK_OPTIONAL(framework) \
+ static void* framework##Library() \
+ { \
+ static void* frameworkLibrary = dlopen("/System/Library/Frameworks/" #framework ".framework/" #framework, RTLD_NOW); \
+ return frameworkLibrary; \
+ }
+
+#define SOFT_LINK_POINTER_OPTIONAL(framework, name, type) \
+ static type init##name(); \
+ static type (*get##name)() = init##name; \
+ static type pointer##name; \
+ \
+ static type name##Function() \
+ { \
+ return pointer##name; \
+ } \
+ \
+ static type init##name() \
+ { \
+ void** pointer = static_cast<void**>(dlsym(framework##Library(), #name)); \
+ if (pointer) \
+ pointer##name = static_cast<type>(*pointer); \
+ get##name = name##Function; \
+ return pointer##name; \
+ }
+
+#if ENABLE_VCP_ENCODER
+
+#include <VideoProcessing/VideoProcessing.h>
+
SOFT_LINK_FRAMEWORK_FOR_HEADER(webrtc, VideoProcessing)
SOFT_LINK_FUNCTION_FOR_HEADER(webrtc, VideoProcessing, VCPCompressionSessionSetProperty, OSStatus, (VCPCompressionSessionRef session, CFStringRef key, CFTypeRef value), (session, key, value))
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/RTCVideoEncoderH264.mm (230450 => 230451)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/RTCVideoEncoderH264.mm 2018-04-09 20:26:16 UTC (rev 230450)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/RTCVideoEncoderH264.mm 2018-04-09 21:09:54 UTC (rev 230451)
@@ -38,6 +38,40 @@
#include "sdk/WebKit/EncoderUtilities.h"
#include "sdk/WebKit/WebKitUtilities.h"
+#if !ENABLE_VCP_ENCODER && !defined(WEBRTC_IOS)
+#import <dlfcn.h>
+#import <objc/runtime.h>
+
+SOFT_LINK_FRAMEWORK_OPTIONAL(VideoToolBox)
+SOFT_LINK_POINTER_OPTIONAL(VideoToolBox, kVTVideoEncoderSpecification_Usage, NSString *)
+
+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.
+ if (width == 1280)
+ return height == 720;
+ if (width == 720)
+ return height == 1280;
+ if (width == 960)
+ return height == 540;
+ if (width == 540)
+ return height == 960;
+ if (width == 640)
+ return height == 480;
+ if (width == 480)
+ return height == 640;
+ if (width == 288)
+ return height == 352;
+ if (width == 352)
+ return height == 288;
+ if (width == 320)
+ return height == 240;
+ if (width == 240)
+ return height == 320;
+ return false;
+}
+#endif
+
@interface RTCVideoEncoderH264 ()
- (void)frameWasEncoded:(OSStatus)status
@@ -616,6 +650,78 @@
RTC_LOG(LS_INFO) << "Compression session created with hw accl enabled";
} else {
RTC_LOG(LS_INFO) << "Compression session created with hw accl disabled";
+
+#if !ENABLE_VCP_ENCODER && !defined(WEBRTC_IOS)
+ if (!isStandardFrameSize(_width, _height)) {
+ RTC_LOG(LS_ERROR) << "Using H264 software encoder with non standard size is not supported";
+ return WEBRTC_VIDEO_CODEC_ERROR;
+ }
+
+ if (!getkVTVideoEncoderSpecification_Usage()) {
+ RTC_LOG(LS_ERROR) << "RTCVideoEncoderH264 cannot create a H264 software encoder";
+ return WEBRTC_VIDEO_CODEC_ERROR;
+ }
+
+ CFDictionaryRef ioSurfaceValue = CreateCFTypeDictionary(nullptr, nullptr, 0);
+ int64_t pixelFormatType = framePixelFormat;
+ CFNumberRef pixelFormat = CFNumberCreate(nullptr, kCFNumberLongType, &pixelFormatType);
+
+ const size_t attributesSize = 3;
+ CFTypeRef keys[attributesSize] = {
+ kCVPixelBufferOpenGLCompatibilityKey,
+ kCVPixelBufferIOSurfacePropertiesKey,
+ kCVPixelBufferPixelFormatTypeKey
+ };
+ CFTypeRef values[attributesSize] = {
+ kCFBooleanTrue,
+ ioSurfaceValue,
+ pixelFormat};
+ CFDictionaryRef sourceAttributes = CreateCFTypeDictionary(keys, values, attributesSize);
+
+ if (ioSurfaceValue) {
+ CFRelease(ioSurfaceValue);
+ ioSurfaceValue = nullptr;
+ }
+ if (pixelFormat) {
+ CFRelease(pixelFormat);
+ pixelFormat = nullptr;
+ }
+
+ CFMutableDictionaryRef encoderSpecs = CFDictionaryCreateMutable(nullptr, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFDictionarySetValue(encoderSpecs, kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder, kCFBooleanFalse);
+ int usageValue = 1;
+ CFNumberRef usage = CFNumberCreate(nullptr, kCFNumberIntType, &usageValue);
+ CFDictionarySetValue(encoderSpecs, getkVTVideoEncoderSpecification_Usage(), usage);
+ if (usage) {
+ CFRelease(usage);
+ usage = nullptr;
+ }
+
+ [self destroyCompressionSession];
+
+ OSStatus status =
+ CompressionSessionCreate(nullptr, // use default allocator
+ _width,
+ _height,
+ kCodecTypeH264,
+ encoderSpecs,
+ sourceAttributes,
+ nullptr, // use default compressed data allocator
+ compressionOutputCallback,
+ nullptr,
+ &_compressionSession);
+ if (sourceAttributes) {
+ CFRelease(sourceAttributes);
+ sourceAttributes = nullptr;
+ }
+ if (encoder_specs) {
+ CFRelease(encoder_specs);
+ encoder_specs = nullptr;
+ }
+ if (status != noErr) {
+ return WEBRTC_VIDEO_CODEC_ERROR;
+ }
+#endif
}
#endif
[self configureCompressionSession];