Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/RTCVideoEncoderH264.mm (231166 => 231167)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/RTCVideoEncoderH264.mm 2018-04-30 20:22:08 UTC (rev 231166)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/RTCVideoEncoderH264.mm 2018-04-30 20:28:22 UTC (rev 231167)
@@ -607,15 +607,14 @@
CFRelease(pixelFormat);
pixelFormat = nullptr;
}
- CFMutableDictionaryRef encoder_specs = nullptr;
+ CFDictionaryRef encoderSpecs = nullptr;
#if defined(WEBRTC_MAC) && !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.
- encoder_specs = CFDictionaryCreateMutable(
- nullptr, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- CFDictionarySetValue(encoder_specs,
- kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder,
- webrtc::isH264HardwareEncoderAllowed() ? kCFBooleanTrue : kCFBooleanFalse);
+ CFTypeRef sessionKeys[] = {kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder, kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder, kVTCompressionPropertyKey_RealTime };
+ CFTypeRef sessionValues[] = { useHardwareEncoder, useHardwareEncoder, kCFBooleanTrue };
+ encoderSpecs = CFDictionaryCreate(kCFAllocatorDefault, sessionKeys, sessionValues, 3, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
#endif
OSStatus status =
CompressionSessionCreate(nullptr, // use default allocator
@@ -622,7 +621,7 @@
_width,
_height,
kCodecTypeH264,
- encoder_specs, // use hardware accelerated encoder if available
+ encoderSpecs, // use hardware accelerated encoder if available
sourceAttributes,
nullptr, // use default compressed data allocator
compressionOutputCallback,
@@ -632,20 +631,25 @@
CFRelease(sourceAttributes);
sourceAttributes = nullptr;
}
- if (encoder_specs) {
- CFRelease(encoder_specs);
- encoder_specs = nullptr;
+ if (encoderSpecs) {
+ CFRelease(encoderSpecs);
+ encoderSpecs = nullptr;
}
+
+#if ENABLE_VCP_ENCODER || defined(WEBRTC_IOS)
if (status != noErr) {
RTC_LOG(LS_ERROR) << "Failed to create compression session: " << status;
return WEBRTC_VIDEO_CODEC_ERROR;
}
+#endif
#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
CFBooleanRef hwaccl_enabled = nullptr;
- status = VTSessionCopyProperty(_compressionSession,
+ if (status == noErr) {
+ status = VTSessionCopyProperty(_compressionSession,
kVTCompressionPropertyKey_UsingHardwareAcceleratedVideoEncoder,
nullptr,
&hwaccl_enabled);
+ }
if (status == noErr && (CFBooleanGetValue(hwaccl_enabled))) {
RTC_LOG(LS_INFO) << "Compression session created with hw accl enabled";
} else {
@@ -714,9 +718,9 @@
CFRelease(sourceAttributes);
sourceAttributes = nullptr;
}
- if (encoder_specs) {
- CFRelease(encoder_specs);
- encoder_specs = nullptr;
+ if (encoderSpecs) {
+ CFRelease(encoderSpecs);
+ encoderSpecs = nullptr;
}
if (status != noErr) {
return WEBRTC_VIDEO_CODEC_ERROR;
Added: trunk/Source/ThirdParty/libwebrtc/WebKit/0001-Update-RTCVideoEncoderH264.mm-for-WebKit.patch (0 => 231167)
--- trunk/Source/ThirdParty/libwebrtc/WebKit/0001-Update-RTCVideoEncoderH264.mm-for-WebKit.patch (rev 0)
+++ trunk/Source/ThirdParty/libwebrtc/WebKit/0001-Update-RTCVideoEncoderH264.mm-for-WebKit.patch 2018-04-30 20:28:22 UTC (rev 231167)
@@ -0,0 +1,274 @@
+From 6526d1daf054748cd0983f994ec0f988df235dc1 Mon Sep 17 00:00:00 2001
+From: Youenn Fablet <you...@apple.com>
+Date: Mon, 30 Apr 2018 11:26:26 -0700
+Subject: [PATCH] Update RTCVideoEncoderH264 for WebKit
+
+---
+ .../Classes/VideoToolbox/RTCVideoEncoderH264.mm | 159 ++++++++++++++++++---
+ 1 file changed, 140 insertions(+), 19 deletions(-)
+
+diff --git a/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/RTCVideoEncoderH264.mm b/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/RTCVideoEncoderH264.mm
+index a818c27d1e6..68118f8f56a 100644
+--- a/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/RTCVideoEncoderH264.mm
++++ b/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/RTCVideoEncoderH264.mm
+@@ -35,6 +35,43 @@
+ #include "system_wrappers/include/clock.h"
+ #include "third_party/libyuv/include/libyuv/convert_from.h"
+
++#include "sdk/WebKit/EncoderUtilities.h"
++#include "sdk/WebKit/WebKitUtilities.h"
++
++#import <dlfcn.h>
++#import <objc/runtime.h>
++
++SOFT_LINK_FRAMEWORK_OPTIONAL(VideoToolBox)
++SOFT_LINK_POINTER_OPTIONAL(VideoToolBox, kVTVideoEncoderSpecification_Usage, NSString *)
++
++#if !ENABLE_VCP_ENCODER && !defined(WEBRTC_IOS)
++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
+@@ -285,7 +322,7 @@ @implementation RTCVideoEncoderH264 {
+ RTCVideoEncoderCallback _callback;
+ int32_t _width;
+ int32_t _height;
+- VTCompressionSessionRef _compressionSession;
++ CompressionSessionRef _compressionSession;
+ RTCVideoCodecMode _mode;
+
+ webrtc::H264BitstreamParser _h264BitstreamParser;
+@@ -318,6 +355,10 @@ - (instancetype)initWithCodecInfo:(RTCVideoCodecInfo *)codecInfo {
+
+ - (void)dealloc {
+ [self destroyCompressionSession];
++ if (_callback) {
++ Block_release(_callback);
++ }
++ [super dealloc];
+ }
+
+ - (NSInteger)startEncodeWithSettings:(RTCVideoEncoderSettings *)settings
+@@ -358,9 +399,9 @@ - (NSInteger)encode:(RTCVideoFrame *)frame
+
+ // Get a pixel buffer from the pool and copy frame data over.
+ CVPixelBufferPoolRef pixelBufferPool =
+- VTCompressionSessionGetPixelBufferPool(_compressionSession);
++ CompressionSessionGetPixelBufferPool(_compressionSession);
+ if ([self resetCompressionSessionIfNeededForPool:pixelBufferPool withFrame:frame]) {
+- pixelBufferPool = VTCompressionSessionGetPixelBufferPool(_compressionSession);
++ pixelBufferPool = CompressionSessionGetPixelBufferPool(_compressionSession);
+ isKeyframeRequired = YES;
+ }
+
+@@ -442,7 +483,7 @@ - (NSInteger)encode:(RTCVideoFrame *)frame
+ // Update the bitrate if needed.
+ [self setBitrateBps:_bitrateAdjuster->GetAdjustedBitrateBps()];
+
+- OSStatus status = VTCompressionSessionEncodeFrame(_compressionSession,
++ OSStatus status = CompressionSessionEncodeFrame(_compressionSession,
+ pixelBuffer,
+ presentationTimeStamp,
+ kCMTimeInvalid,
+@@ -463,7 +504,7 @@ - (NSInteger)encode:(RTCVideoFrame *)frame
+ }
+
+ - (void)setCallback:(RTCVideoEncoderCallback)callback {
+- _callback = callback;
++ _callback = Block_copy(callback);
+ }
+
+ - (int)setBitrate:(uint32_t)bitrateKbit framerate:(uint32_t)framerate {
+@@ -480,6 +521,7 @@ - (NSInteger)releaseEncoder {
+ // callback anymore. Do not remove callback until the session is invalidated
+ // since async encoder callbacks can occur until invalidation.
+ [self destroyCompressionSession];
++ Block_release(_callback);
+ _callback = nullptr;
+ return WEBRTC_VIDEO_CODEC_OK;
+ }
+@@ -565,22 +607,21 @@ - (int)resetCompressionSessionWithPixelFormat:(OSType)framePixelFormat {
+ CFRelease(pixelFormat);
+ pixelFormat = nullptr;
+ }
+- CFMutableDictionaryRef encoder_specs = nullptr;
++ CFDictionaryRef encoderSpecs = nullptr;
+ #if defined(WEBRTC_MAC) && !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.
+- encoder_specs = CFDictionaryCreateMutable(
+- nullptr, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+- CFDictionarySetValue(encoder_specs,
+- kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder,
+- kCFBooleanTrue);
++ CFTypeRef sessionKeys[] = {kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder, kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder, kVTCompressionPropertyKey_RealTime };
++ CFTypeRef sessionValues[] = { useHardwareEncoder, useHardwareEncoder, kCFBooleanTrue };
++ encoderSpecs = CFDictionaryCreate(kCFAllocatorDefault, sessionKeys, sessionValues, 3, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ #endif
+ OSStatus status =
+- VTCompressionSessionCreate(nullptr, // use default allocator
++ CompressionSessionCreate(nullptr, // use default allocator
+ _width,
+ _height,
+- kCMVideoCodecType_H264,
+- encoder_specs, // use hardware accelerated encoder if available
++ kCodecTypeH264,
++ encoderSpecs, // use hardware accelerated encoder if available
+ sourceAttributes,
+ nullptr, // use default compressed data allocator
+ compressionOutputCallback,
+@@ -590,24 +631,101 @@ - (int)resetCompressionSessionWithPixelFormat:(OSType)framePixelFormat {
+ CFRelease(sourceAttributes);
+ sourceAttributes = nullptr;
+ }
+- if (encoder_specs) {
+- CFRelease(encoder_specs);
+- encoder_specs = nullptr;
++ if (encoderSpecs) {
++ CFRelease(encoderSpecs);
++ encoderSpecs = nullptr;
+ }
++
++#if ENABLE_VCP_ENCODER || defined(WEBRTC_IOS)
+ if (status != noErr) {
+ RTC_LOG(LS_ERROR) << "Failed to create compression session: " << status;
+ return WEBRTC_VIDEO_CODEC_ERROR;
+ }
++#endif
+ #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
+ CFBooleanRef hwaccl_enabled = nullptr;
+- status = VTSessionCopyProperty(_compressionSession,
++ if (status == noErr) {
++ status = VTSessionCopyProperty(_compressionSession,
+ kVTCompressionPropertyKey_UsingHardwareAcceleratedVideoEncoder,
+ nullptr,
+ &hwaccl_enabled);
++ }
+ if (status == noErr && (CFBooleanGetValue(hwaccl_enabled))) {
+ 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 (encoderSpecs) {
++ CFRelease(encoderSpecs);
++ encoderSpecs = nullptr;
++ }
++ if (status != noErr) {
++ return WEBRTC_VIDEO_CODEC_ERROR;
++ }
++#endif
+ }
+ #endif
+ [self configureCompressionSession];
+@@ -619,6 +737,9 @@ - (void)configureCompressionSession {
+ SetVTSessionProperty(_compressionSession, kVTCompressionPropertyKey_RealTime, true);
+ SetVTSessionProperty(_compressionSession, kVTCompressionPropertyKey_ProfileLevel, _profile);
+ SetVTSessionProperty(_compressionSession, kVTCompressionPropertyKey_AllowFrameReordering, false);
++#if ENABLE_VCP_ENCODER
++ SetVTSessionProperty(_compressionSession, (__bridge CFStringRef)getkVTVideoEncoderSpecification_Usage(), 1);
++#endif
+ [self setEncoderBitrateBps:_targetBitrateBps];
+ // TODO(tkchin): Look at entropy mode and colorspace matrices.
+ // TODO(tkchin): Investigate to see if there's any way to make this work.
+@@ -636,7 +757,7 @@ - (void)configureCompressionSession {
+
+ - (void)destroyCompressionSession {
+ if (_compressionSession) {
+- VTCompressionSessionInvalidate(_compressionSession);
++ CompressionSessionInvalidate(_compressionSession);
+ CFRelease(_compressionSession);
+ _compressionSession = nullptr;
+ }
+--
+2.16.1 (Apple Git-102)
+