Diff
Modified: trunk/LayoutTests/ChangeLog (218698 => 218699)
--- trunk/LayoutTests/ChangeLog 2017-06-22 15:22:00 UTC (rev 218698)
+++ trunk/LayoutTests/ChangeLog 2017-06-22 15:29:14 UTC (rev 218699)
@@ -1,3 +1,17 @@
+2017-06-22 Youenn Fablet <[email protected]>
+
+ [WebRTC] Prevent capturing at unconventional resolutions when using the SW encoder on Mac
+ https://bugs.webkit.org/show_bug.cgi?id=172602
+ <rdar://problem/32407693>
+
+ Reviewed by Eric Carlson.
+
+ * platform/mac-wk1/TestExpectations: Mark captureCanvas as flaky due to AVDCreateGPUAccelerator: Error loading GPU renderer" appearing on some bots.
+ * platform/mac/webrtc/captureCanvas-webrtc-software-encoder-expected.txt: Copied from LayoutTests/webrtc/captureCanvas-webrtc-expected.txt.
+ * platform/mac/webrtc/captureCanvas-webrtc-software-encoder.html: Added.
+ * webrtc/captureCanvas-webrtc-expected.txt:
+ * webrtc/captureCanvas-webrtc.html:
+
2017-06-22 Joseph Pecoraro <[email protected]>
LayoutTests/inspector/indexeddb/requestDatabaseNames.html: Sort database names to prevent flakiness
Added: trunk/LayoutTests/platform/mac/webrtc/captureCanvas-webrtc-software-encoder-expected.txt (0 => 218699)
--- trunk/LayoutTests/platform/mac/webrtc/captureCanvas-webrtc-software-encoder-expected.txt (rev 0)
+++ trunk/LayoutTests/platform/mac/webrtc/captureCanvas-webrtc-software-encoder-expected.txt 2017-06-22 15:29:14 UTC (rev 218699)
@@ -0,0 +1,4 @@
+
+
+PASS captureStream with webrtc
+
Added: trunk/LayoutTests/platform/mac/webrtc/captureCanvas-webrtc-software-encoder.html (0 => 218699)
--- trunk/LayoutTests/platform/mac/webrtc/captureCanvas-webrtc-software-encoder.html (rev 0)
+++ trunk/LayoutTests/platform/mac/webrtc/captureCanvas-webrtc-software-encoder.html 2017-06-22 15:29:14 UTC (rev 218699)
@@ -0,0 +1,99 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+ <head>
+ <canvas id="canvas0" width=320px height=240px></canvas>
+ <canvas id="canvas1" width=100px height=100px></canvas>
+ <video id="video" autoplay width=320px height=240px></video>
+ <canvas id="canvas2" width=320px height=240px></canvas>
+ <script src=""
+ <script src=""
+ <script src=""
+ <script>
+
+function printRectangle(canvas)
+{
+ var context = canvas.getContext("2d");
+ context.fillStyle = canvas.color;
+ context.fillRect(0, 0, 100, 100);
+ setTimeout(() => printRectangle(canvas), 50);
+}
+
+if (window.internals)
+ internals.setH264HardwareEncoderAllowed(false);
+
+function testCanvas(testName, array1, isSame, count)
+{
+ if (count === undefined)
+ count = 0;
+ canvas2.getContext("2d").drawImage(video, 0 ,0);
+ array2 = canvas2.getContext("2d").getImageData(20, 20, 60, 60).data;
+ var isEqual = true;
+ for (var index = 0; index < array1.length; ++index) {
+ // Rough comparison since we are compressing data.
+ // This test still catches errors since we are going from green to blue to red.
+ if (Math.abs(array1[index] - array2[index]) > 40) {
+ isEqual = false;
+ continue;
+ }
+ }
+ if (isEqual === isSame)
+ return;
+
+ if (count === 20)
+ return Promise.reject(testName + " failed");
+
+ return waitFor(50).then(() => {
+ return testCanvas(testName, array1, isSame, ++count);
+ });
+}
+
+var canvas0Track;
+var sender;
+promise_test((test) => {
+ canvas0.color = "green";
+ printRectangle(canvas0);
+ return new Promise((resolve, reject) => {
+ createConnections((firstConnection) => {
+ var stream = canvas0.captureStream();
+ canvas0Track = stream.getVideoTracks()[0];
+ sender = firstConnection.addTrack(canvas0Track, stream);
+ }, (secondConnection) => {
+ secondConnection._ontrack_ = (trackEvent) => {
+ resolve(trackEvent.streams[0]);
+ };
+ });
+ setTimeout(() => reject("Test timed out"), 5000);
+ }).then((stream) => {
+ video.srcObject = stream;
+ return video.play();
+ }).then(() => {
+ return testCanvas("test1", canvas0.getContext("2d").getImageData(20 ,20, 60, 60).data, true);
+ }).then(() => {
+ canvas1.color = "blue";
+ printRectangle(canvas1);
+ var stream = canvas1.captureStream();
+ return sender.replaceTrack(stream.getVideoTracks()[0]);
+ }).then(() => {
+ return waitFor(200);
+ }).then(() => {
+ return testCanvas("test2", canvas1.getContext("2d").getImageData(20 ,20, 60, 60).data, false);
+ }).then(() => {
+ return testCanvas("test3", canvas0.getContext("2d").getImageData(20 ,20, 60, 60).data, true);
+ }).then(() => {
+ return sender.replaceTrack(canvas0Track);
+ }).then(() => {
+ canvas0.color = "red";
+ // Let's wait for red color to be printed on canvas0
+ return waitFor(200);
+ }).then(() => {
+ return testCanvas("test4", canvas0.getContext("2d").getImageData(20 ,20, 60, 60).data, true);
+ }).catch((error) => {
+ if (window.internals)
+ internals.setH264HardwareEncoderAllowed(true);
+ return Promise.reject(error);
+ });
+}, "captureStream with webrtc");
+
+ </script>
+ </head>
+</html>
Modified: trunk/LayoutTests/platform/mac-wk1/TestExpectations (218698 => 218699)
--- trunk/LayoutTests/platform/mac-wk1/TestExpectations 2017-06-22 15:22:00 UTC (rev 218698)
+++ trunk/LayoutTests/platform/mac-wk1/TestExpectations 2017-06-22 15:29:14 UTC (rev 218699)
@@ -98,7 +98,7 @@
imported/w3c/web-platform-tests/webrtc [ Skip ]
webrtc [ Skip ]
webrtc/datachannel [ Pass ]
-webrtc/captureCanvas-webrtc.html [ Pass ]
+webrtc/captureCanvas-webrtc.html [ Failure Pass ]
# These tests test the Shadow DOM based HTML form validation UI but Mac WK1 is using native dialogs instead.
fast/forms/validation-message-on-listbox.html
Modified: trunk/LayoutTests/webrtc/captureCanvas-webrtc-expected.txt (218698 => 218699)
--- trunk/LayoutTests/webrtc/captureCanvas-webrtc-expected.txt 2017-06-22 15:22:00 UTC (rev 218698)
+++ trunk/LayoutTests/webrtc/captureCanvas-webrtc-expected.txt 2017-06-22 15:29:14 UTC (rev 218699)
@@ -1,7 +1,8 @@
-
+
PASS Setting up the connection
PASS Checking canvas is green
PASS Checking canvas is red
PASS Checking canvas is green again
+PASS Checking canvas size change
Modified: trunk/LayoutTests/webrtc/captureCanvas-webrtc.html (218698 => 218699)
--- trunk/LayoutTests/webrtc/captureCanvas-webrtc.html 2017-06-22 15:22:00 UTC (rev 218698)
+++ trunk/LayoutTests/webrtc/captureCanvas-webrtc.html 2017-06-22 15:29:14 UTC (rev 218699)
@@ -1,27 +1,50 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
- <canvas id="canvas1" width=100px height=100px></canvas>
- <video id="video" autoplay width=100px height=100px></video>
- <canvas id="canvas2" width=100px height=100px></canvas>
+ <canvas id="canvas1" width=320px height=240px></canvas>
+ <video id="video" autoplay></video>
+ <canvas id="canvas2" width=320px height=240px></canvas>
<script src=""
<script src=""
<script src =""
<script>
-var canvas1 = document.getElementById("canvas1");
-var canvas2 = document.getElementById("canvas2");
-var video = document.getElementById("video");
-
var color = "green";
function printRectangle()
{
var context = canvas1.getContext("2d");
context.fillStyle = color;
- context.fillRect(0, 0, 100, 100);
+ context.fillRect(0, 0, 320, 240);
setTimeout(printRectangle, 50);
}
+function testCanvas(testName, array1, isSame, count)
+{
+ if (count === undefined)
+ count = 0;
+ canvas2.getContext("2d").drawImage(video, 0 ,0);
+ array2 = canvas2.getContext("2d").getImageData(20, 20, 60, 60).data;
+ var isEqual = true;
+ var index = 0;
+ for (index = 0; index < array1.length; ++index) {
+ // Rough comparison since we are compressing data.
+ // This test still catches errors since we are going from green to blue to red.
+ if (Math.abs(array1[index] - array2[index]) > 40) {
+ isEqual = false;
+ continue;
+ }
+ }
+ if (isEqual === isSame)
+ return;
+
+ if (count === 20)
+ return Promise.reject(testName + " failed, expected " + JSON.stringify(array1) + " but got " + JSON.stringify(array2));
+
+ return waitFor(50).then(() => {
+ return testCanvas(testName, array1, isSame, ++count);
+ });
+}
+
promise_test((test) => {
printRectangle();
return new Promise((resolve, reject) => {
@@ -46,8 +69,7 @@
promise_test((test) => {
return waitFor(100).then(() => {
- canvas2.getContext("2d").drawImage(video, 0 ,0);
- assert_array_equals(canvas2.getContext("2d").getImageData(20 ,20, 60, 60), canvas1.getContext("2d").getImageData(20, 20, 60, 60));
+ return testCanvas("test 1", canvas1.getContext("2d").getImageData(20, 20, 60, 60).data, true);
});
}, "Checking canvas is green");
@@ -54,8 +76,7 @@
promise_test((test) => {
color = "red";
return waitFor(300).then(() => {
- canvas2.getContext("2d").drawImage(video, 0 ,0);
- assert_array_equals(canvas2.getContext("2d").getImageData(20 ,20, 60, 60), canvas1.getContext("2d").getImageData(20, 20, 60, 60));
+ return testCanvas("test 2", canvas1.getContext("2d").getImageData(20, 20, 60, 60).data, true);
});
}, "Checking canvas is red");
@@ -63,10 +84,15 @@
promise_test((test) => {
color = "green";
return waitFor(300).then(() => {
- canvas2.getContext("2d").drawImage(video, 0 ,0);
- assert_array_equals(canvas2.getContext("2d").getImageData(20 ,20, 60, 60), canvas1.getContext("2d").getImageData(20, 20, 60, 60));
+ return testCanvas("test 3", canvas1.getContext("2d").getImageData(20, 20, 60, 60).data, true);
});
}, "Checking canvas is green again");
+
+promise_test((test) => {
+ canvas1.width = 640;
+ canvas1.height = 480;
+ return waitForVideoSize(video, 640, 480);
+}, "Checking canvas size change");
</script>
</head>
</html>
Modified: trunk/LayoutTests/webrtc/routines.js (218698 => 218699)
--- trunk/LayoutTests/webrtc/routines.js 2017-06-22 15:22:00 UTC (rev 218698)
+++ trunk/LayoutTests/webrtc/routines.js 2017-06-22 15:29:14 UTC (rev 218699)
@@ -141,7 +141,7 @@
if (count === undefined)
count = 0;
if (++count > 20)
- return Promise.reject("waitForVideoSize timed out");
+ return Promise.reject("waitForVideoSize timed out, expected " + width + "x"+ height + " but got " + video.videoWidth + "x" + video.videoHeight);
return waitFor(50).then(() => {
return waitForVideoSize(video, width, height, count);
Modified: trunk/LayoutTests/webrtc/video.html (218698 => 218699)
--- trunk/LayoutTests/webrtc/video.html 2017-06-22 15:22:00 UTC (rev 218698)
+++ trunk/LayoutTests/webrtc/video.html 2017-06-22 15:29:14 UTC (rev 218699)
@@ -43,7 +43,7 @@
if (window.testRunner)
testRunner.setUserMediaPermission(true);
- return navigator.mediaDevices.getUserMedia({ video: true}).then((stream) => {
+ return navigator.mediaDevices.getUserMedia({video: {advanced: [{width:{min:1280}}, {height:{min:720} } ]}}).then((stream) => {
return new Promise((resolve, reject) => {
createConnections((firstConnection) => {
var track = stream.getVideoTracks()[0];
Modified: trunk/Source/ThirdParty/libwebrtc/ChangeLog (218698 => 218699)
--- trunk/Source/ThirdParty/libwebrtc/ChangeLog 2017-06-22 15:22:00 UTC (rev 218698)
+++ trunk/Source/ThirdParty/libwebrtc/ChangeLog 2017-06-22 15:29:14 UTC (rev 218699)
@@ -1,3 +1,17 @@
+2017-06-22 Youenn Fablet <[email protected]>
+
+ [WebRTC] Prevent capturing at unconventional resolutions when using the SW encoder on Mac
+ https://bugs.webkit.org/show_bug.cgi?id=172602
+ <rdar://problem/32407693>
+
+ Reviewed by Eric Carlson.
+
+ Adding a parameter to disable hardware encoder.
+
+ * Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/encoder.h:
+ * Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/encoder.mm:
+ (webrtc::H264VideoToolboxEncoder::CreateCompressionSession):
+
2017-06-21 Youenn Fablet <[email protected]>
Update libyuv to 8cab2e31d76246263206318f3568d452e7f3ff3e
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/encoder.h (218698 => 218699)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/encoder.h 2017-06-22 15:22:00 UTC (rev 218698)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/encoder.h 2017-06-22 15:29:14 UTC (rev 218699)
@@ -70,12 +70,12 @@
ScalingSettings GetScalingSettings() const override;
protected:
- virtual int CreateCompressionSession(VTCompressionSessionRef&, VTCompressionOutputCallback, int32_t width, int32_t height);
+ virtual int CreateCompressionSession(VTCompressionSessionRef&, VTCompressionOutputCallback, int32_t width, int32_t height, bool useHardwareEncoder = true);
+ void DestroyCompressionSession();
private:
int ResetCompressionSession();
void ConfigureCompressionSession();
- void DestroyCompressionSession();
rtc::scoped_refptr<VideoFrameBuffer> GetScaledBufferOnEncode(
const rtc::scoped_refptr<VideoFrameBuffer>& frame);
void SetBitrateBps(uint32_t bitrate_bps);
Modified: trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/encoder.mm (218698 => 218699)
--- trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/encoder.mm 2017-06-22 15:22:00 UTC (rev 218698)
+++ trunk/Source/ThirdParty/libwebrtc/Source/webrtc/sdk/objc/Framework/Classes/VideoToolbox/encoder.mm 2017-06-22 15:29:14 UTC (rev 218699)
@@ -533,7 +533,7 @@
return WEBRTC_VIDEO_CODEC_OK;
}
-int H264VideoToolboxEncoder::CreateCompressionSession(VTCompressionSessionRef& compressionSession, VTCompressionOutputCallback outputCallback, int32_t width, int32_t height) {
+int H264VideoToolboxEncoder::CreateCompressionSession(VTCompressionSessionRef& compressionSession, VTCompressionOutputCallback outputCallback, int32_t width, int32_t height, bool useHardwareEncoder) {
// Set source image buffer attributes. These attributes will be present on
// buffers retrieved from the encoder's pixel buffer pool.
@@ -567,7 +567,7 @@
#if defined(WEBRTC_USE_VTB_HARDWARE_ENCODER)
CFTypeRef sessionKeys[] = {kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder};
- CFTypeRef sessionValues[] = { kCFBooleanTrue };
+ CFTypeRef sessionValues[] = { useHardwareEncoder ? kCFBooleanTrue : kCFBooleanFalse };
CFDictionaryRef encoderSpecification = internal::CreateCFDictionary(sessionKeys, sessionValues, 1);
#else
CFDictionaryRef encoderSpecification = nullptr;
Modified: trunk/Source/WebCore/ChangeLog (218698 => 218699)
--- trunk/Source/WebCore/ChangeLog 2017-06-22 15:22:00 UTC (rev 218698)
+++ trunk/Source/WebCore/ChangeLog 2017-06-22 15:29:14 UTC (rev 218699)
@@ -1,3 +1,35 @@
+2017-06-22 Youenn Fablet <[email protected]>
+
+ [WebRTC] Prevent capturing at unconventional resolutions when using the SW encoder on Mac
+ https://bugs.webkit.org/show_bug.cgi?id=172602
+ <rdar://problem/32407693>
+
+ Reviewed by Eric Carlson.
+
+ Test: platform/mac/webrtc/captureCanvas-webrtc-software-encoder.html
+
+ Add internal API to switch on/off hardware H264 encoder.
+ Add checks for standard size. If using a software encoder and frame size is not standard,
+ the session is destroyed and no frame is sent at all.
+
+ Added tests based on captureStream.
+ Fixed the case of capturing a canvas which size is changing.
+
+ * Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp:
+ (WebCore::CanvasCaptureMediaStreamTrack::Source::canvasResized):
+ * platform/mediastream/libwebrtc/H264VideoToolBoxEncoder.h:
+ * platform/mediastream/libwebrtc/H264VideoToolBoxEncoder.mm:
+ (WebCore::H264VideoToolboxEncoder::setHardwareEncoderForWebRTCAllowed):
+ (WebCore::H264VideoToolboxEncoder::hardwareEncoderForWebRTCAllowed):
+ (WebCore::isUsingSoftwareEncoder):
+ (WebCore::H264VideoToolboxEncoder::CreateCompressionSession):
+ (isStandardFrameSize): Added.
+ (isUsingSoftwareEncoder): Added.
+ * testing/Internals.cpp:
+ (WebCore::Internals::setH264HardwareEncoderAllowed):
+ * testing/Internals.h:
+ * testing/Internals.idl:
+
2017-06-21 Youenn Fablet <[email protected]>
[Fetch API] TypeError when called with body === {}
Modified: trunk/Source/WebCore/Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp (218698 => 218699)
--- trunk/Source/WebCore/Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp 2017-06-22 15:22:00 UTC (rev 218698)
+++ trunk/Source/WebCore/Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp 2017-06-22 15:29:14 UTC (rev 218699)
@@ -115,6 +115,8 @@
m_settings.setWidth(m_canvas->width());
m_settings.setHeight(m_canvas->height());
+
+ settingsDidChange();
}
void CanvasCaptureMediaStreamTrack::Source::canvasChanged(HTMLCanvasElement& canvas, const FloatRect&)
Modified: trunk/Source/WebCore/platform/mediastream/libwebrtc/H264VideoToolBoxEncoder.h (218698 => 218699)
--- trunk/Source/WebCore/platform/mediastream/libwebrtc/H264VideoToolBoxEncoder.h 2017-06-22 15:22:00 UTC (rev 218698)
+++ trunk/Source/WebCore/platform/mediastream/libwebrtc/H264VideoToolBoxEncoder.h 2017-06-22 15:29:14 UTC (rev 218699)
@@ -35,9 +35,11 @@
class H264VideoToolboxEncoder final : public webrtc::H264VideoToolboxEncoder {
public:
explicit H264VideoToolboxEncoder(const cricket::VideoCodec& codec) : webrtc::H264VideoToolboxEncoder(codec) { }
+ WEBCORE_EXPORT static void setHardwareEncoderForWebRTCAllowed(bool);
+ static bool hardwareEncoderForWebRTCAllowed();
private:
- int CreateCompressionSession(VTCompressionSessionRef&, VTCompressionOutputCallback, int32_t width, int32_t height) final;
+ int CreateCompressionSession(VTCompressionSessionRef&, VTCompressionOutputCallback, int32_t width, int32_t height, bool useHardwareAcceleratedVideoEncoder) final;
};
}
Modified: trunk/Source/WebCore/platform/mediastream/libwebrtc/H264VideoToolBoxEncoder.mm (218698 => 218699)
--- trunk/Source/WebCore/platform/mediastream/libwebrtc/H264VideoToolBoxEncoder.mm 2017-06-22 15:22:00 UTC (rev 218698)
+++ trunk/Source/WebCore/platform/mediastream/libwebrtc/H264VideoToolBoxEncoder.mm 2017-06-22 15:29:14 UTC (rev 218699)
@@ -26,20 +26,111 @@
#include "config.h"
#include "H264VideoToolBoxEncoder.h"
+#include "Logging.h"
+#include "SoftLinking.h"
+#include <wtf/RetainPtr.h>
+
+SOFT_LINK_FRAMEWORK_OPTIONAL(VideoToolBox)
+SOFT_LINK_POINTER_OPTIONAL(VideoToolBox, kVTVideoEncoderSpecification_Usage, NSString *)
+
#if USE(LIBWEBRTC) && PLATFORM(COCOA)
-#if ENABLE(MAC_VIDEO_TOOLBOX) && USE(APPLE_INTERNAL_SDK) && __has_include(<WebKitAdditions/VideoToolBoxEncoderMac.mm>)
-#import <WebKitAdditions/VideoToolBoxEncoderMac.mm>
-#else
-
namespace WebCore {
-int H264VideoToolboxEncoder::CreateCompressionSession(VTCompressionSessionRef& compressionSession, VTCompressionOutputCallback outputCallback, int32_t width, int32_t height)
+static bool isHardwareEncoderForWebRTCAllowed = true;
+
+void H264VideoToolboxEncoder::setHardwareEncoderForWebRTCAllowed(bool allowed)
{
- return webrtc::H264VideoToolboxEncoder::CreateCompressionSession(compressionSession, outputCallback, width, height);
+ isHardwareEncoderForWebRTCAllowed = allowed;
}
-
+
+bool H264VideoToolboxEncoder::hardwareEncoderForWebRTCAllowed()
+{
+ return isHardwareEncoderForWebRTCAllowed;
}
+
+#if PLATFORM(MAC) && ENABLE(MAC_VIDEO_TOOLBOX)
+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
+int H264VideoToolboxEncoder::CreateCompressionSession(VTCompressionSessionRef& compressionSession, VTCompressionOutputCallback outputCallback, int32_t width, int32_t height, bool useHardwareEncoder)
+{
+#if PLATFORM(MAC) && ENABLE(MAC_VIDEO_TOOLBOX)
+ // This code is deriving from libwebrtc h264_video_toolbox_encoder.h
+ // Set source image buffer attributes. These attributes will be present on
+ // buffers retrieved from the encoder's pixel buffer pool.
+ const size_t attributesSize = 3;
+ CFTypeRef keys[attributesSize] = {
+ kCVPixelBufferOpenGLCompatibilityKey,
+ kCVPixelBufferIOSurfacePropertiesKey,
+ kCVPixelBufferPixelFormatTypeKey
+ };
+ auto ioSurfaceValue = adoptCF(CFDictionaryCreate(kCFAllocatorDefault, nullptr, nullptr, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+ int64_t nv12type = kCVPixelFormatType_420YpCbCr8BiPlanarFullRange;
+ auto pixelFormat = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberLongType, &nv12type));
+ CFTypeRef values[attributesSize] = {kCFBooleanTrue, ioSurfaceValue.get(), pixelFormat.get()};
+ auto sourceAttributes = adoptCF(CFDictionaryCreate(kCFAllocatorDefault, keys, values, attributesSize, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+
+ OSStatus status = -1;
+ if (useHardwareEncoder) {
+ NSDictionary* encoderSpecification = @{ (NSString*)kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder : @true };
+ status = VTCompressionSessionCreate(kCFAllocatorDefault, width, height, kCMVideoCodecType_H264,
+ (__bridge CFDictionaryRef)encoderSpecification, sourceAttributes.get(), nullptr, outputCallback, this, &compressionSession);
+ }
+
+ if (status == noErr && compressionSession) {
+ RELEASE_LOG(WebRTC, "H264VideoToolboxEncoder: Using H264 hardware encoder");
+ return noErr;
+ }
+
+ if (!isStandardFrameSize(width, height)) {
+ RELEASE_LOG(WebRTC, "Using H264 software encoder with non standard size is not supported");
+ DestroyCompressionSession();
+ return -1;
+ }
+
+ if (!getkVTVideoEncoderSpecification_Usage()) {
+ RELEASE_LOG(WebRTC, "H264VideoToolboxEncoder: Cannot create a H264 software encoder");
+ return -1;
+ }
+
+ RELEASE_LOG(WebRTC, "H264VideoToolboxEncoder: Using H264 software encoder");
+
+ NSDictionary* encoderSpecification = @{ (NSString*)kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder : @false, (NSString*)getkVTVideoEncoderSpecification_Usage() : @1 };
+ status = VTCompressionSessionCreate(kCFAllocatorDefault, width, height, kCMVideoCodecType_H264,
+ (__bridge CFDictionaryRef)encoderSpecification, sourceAttributes.get(), nullptr, outputCallback, this, &compressionSession);
+
+ return status;
+#else
+ UNUSED_PARAM(useHardwareEncoder);
+ return webrtc::H264VideoToolboxEncoder::CreateCompressionSession(compressionSession, outputCallback, width, height, hardwareEncoderForWebRTCAllowed() ? useHardwareEncoder : false);
#endif
+}
+
+}
+
+#endif
Modified: trunk/Source/WebCore/testing/Internals.cpp (218698 => 218699)
--- trunk/Source/WebCore/testing/Internals.cpp 2017-06-22 15:22:00 UTC (rev 218698)
+++ trunk/Source/WebCore/testing/Internals.cpp 2017-06-22 15:29:14 UTC (rev 218699)
@@ -210,6 +210,10 @@
#include "MockMediaPlayerMediaSource.h"
#endif
+#if USE(LIBWEBRTC) && PLATFORM(COCOA)
+#include "H264VideoToolboxEncoder.h"
+#endif
+
#if PLATFORM(MAC)
#include "DictionaryLookup.h"
#endif
@@ -4039,6 +4043,17 @@
page.setActivityState(state);
}
+#if ENABLE(WEB_RTC)
+void Internals::setH264HardwareEncoderAllowed(bool allowed)
+{
+#if PLATFORM(MAC)
+ H264VideoToolboxEncoder::setHardwareEncoderForWebRTCAllowed(allowed);
+#else
+ UNUSED_PARAM(allowed);
+#endif
+}
+#endif
+
#if ENABLE(MEDIA_STREAM)
void Internals::setCameraMediaStreamTrackOrientation(MediaStreamTrack& track, int orientation)
Modified: trunk/Source/WebCore/testing/Internals.h (218698 => 218699)
--- trunk/Source/WebCore/testing/Internals.h 2017-06-22 15:22:00 UTC (rev 218698)
+++ trunk/Source/WebCore/testing/Internals.h 2017-06-22 15:29:14 UTC (rev 218699)
@@ -579,6 +579,10 @@
void setPageVisibility(bool isVisible);
+#if ENABLE(WEB_RTC)
+ void setH264HardwareEncoderAllowed(bool allowed);
+#endif
+
#if ENABLE(MEDIA_STREAM)
void setCameraMediaStreamTrackOrientation(MediaStreamTrack&, int orientation);
ExceptionOr<void> setMediaDeviceState(const String& id, const String& property, bool value);
Modified: trunk/Source/WebCore/testing/Internals.idl (218698 => 218699)
--- trunk/Source/WebCore/testing/Internals.idl 2017-06-22 15:22:00 UTC (rev 218698)
+++ trunk/Source/WebCore/testing/Internals.idl 2017-06-22 15:29:14 UTC (rev 218699)
@@ -537,6 +537,7 @@
void setPageVisibility(boolean isVisible);
+ [Conditional=WEB_RTC] void setH264HardwareEncoderAllowed(boolean allowed);
[Conditional=WEB_RTC] void applyRotationForOutgoingVideoSources(RTCPeerConnection connection);
[Conditional=MEDIA_STREAM] void setCameraMediaStreamTrackOrientation(MediaStreamTrack track, short orientation);