Diff
Modified: trunk/LayoutTests/ChangeLog (214805 => 214806)
--- trunk/LayoutTests/ChangeLog 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/LayoutTests/ChangeLog 2017-04-03 16:59:41 UTC (rev 214806)
@@ -1,3 +1,13 @@
+2017-04-03 Youenn Fablet <you...@apple.com>
+
+ captureStream is getting black frames with webgl canvas
+ https://bugs.webkit.org/show_bug.cgi?id=170325
+
+ Reviewed by Dean Jackson.
+
+ * fast/mediastream/captureStream/canvas3d-expected.txt: Added.
+ * fast/mediastream/captureStream/canvas3d.html: Added.
+
2017-04-03 Per Arne Vollan <pvol...@apple.com>
Implement stroke-miterlimit.
Added: trunk/LayoutTests/fast/mediastream/captureStream/canvas3d-expected.txt (0 => 214806)
--- trunk/LayoutTests/fast/mediastream/captureStream/canvas3d-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/mediastream/captureStream/canvas3d-expected.txt 2017-04-03 16:59:41 UTC (rev 214806)
@@ -0,0 +1,7 @@
+CONSOLE MESSAGE: line 23: Turning drawing buffer preservation for the WebGL canvas being captured
+
+
+
+PASS captureStream with 3d context drawing - not buffered initially
+PASS captureStream with 3d context drawing - buffered initially
+
Added: trunk/LayoutTests/fast/mediastream/captureStream/canvas3d.html (0 => 214806)
--- trunk/LayoutTests/fast/mediastream/captureStream/canvas3d.html (rev 0)
+++ trunk/LayoutTests/fast/mediastream/captureStream/canvas3d.html 2017-04-03 16:59:41 UTC (rev 214806)
@@ -0,0 +1,81 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+ <body>
+ <canvas id="canvas1" width=400px height=400px></canvas>
+ <video id="video1" controls autoplay width=400px height=400px></video>
+ <br>
+ <canvas id="canvas2" width=400px height=400px></canvas>
+ <video id="video2" controls autoplay width=400px height=400px></video>
+ <script src=""
+ <script src=""
+ <script>
+
+var canvas1 = document.getElementById("canvas1");
+var canvas2 = document.getElementById("canvas2");
+var video1 = document.getElementById("video1");
+var video2 = document.getElementById("video2");
+var gl1 = canvas1.getContext('webgl', { preserveDrawingBuffer: false } );
+var gl2 = canvas2.getContext('webgl', { preserveDrawingBuffer: true } );
+
+function modifyCanvas(gl, green)
+{
+ gl.clearColor(0, green ? 1 : 0, 0, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ setTimeout(() => { modifyCanvas(gl, !green) }, 500);
+}
+
+function checkGreenPixel(value, cptr)
+{
+ var index = cptr % 4;
+ if (index == 0)
+ return value == 0;
+ if (index == 1)
+ return value == 255;
+ if (index == 2)
+ return value == 0;
+ if (index == 3)
+ return value == 255;
+}
+
+promise_test((test) => {
+ var stream = canvas1.captureStream();
+ video1.srcObject = stream;
+
+ if (!window.internals)
+ var promise = Promise.resolve();
+ else {
+ internals.observeMediaStreamTrack(stream.getVideoTracks()[0]);
+ var promise = internals.grabNextMediaStreamTrackFrame().then((data) => {
+ data.data.forEach((value, cptr) => {
+ assert_true(checkGreenPixel(value, cptr), "expecting value " + cptr + " to be part of a green pixel");
+ });
+ })
+ }
+
+ modifyCanvas(gl1, true);
+ return promise;
+}, "captureStream with 3d context drawing - not buffered initially");
+
+promise_test((test) => {
+ var stream = canvas2.captureStream();
+ video2.srcObject = stream;
+
+ if (!window.internals)
+ var promise = Promise.resolve();
+ else {
+ internals.observeMediaStreamTrack(stream.getVideoTracks()[0]);
+ var promise = internals.grabNextMediaStreamTrackFrame().then((data) => {
+ data.data.forEach((value, cptr) => {
+ assert_true(checkGreenPixel(value, cptr), "expecting value " + cptr + " to be part of a green pixel");
+ });
+ })
+ }
+
+ modifyCanvas(gl2, true);
+ return promise;
+}, "captureStream with 3d context drawing - buffered initially");
+
+ </script>
+ </body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (214805 => 214806)
--- trunk/Source/WebCore/ChangeLog 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/ChangeLog 2017-04-03 16:59:41 UTC (rev 214806)
@@ -1,3 +1,60 @@
+2017-04-03 Youenn Fablet <you...@apple.com>
+
+ captureStream is getting black frames with webgl canvas
+ https://bugs.webkit.org/show_bug.cgi?id=170325
+
+ Reviewed by Dean Jackson.
+
+ Test: fast/mediastream/captureStream/canvas3d.html
+
+ Changing the webgl context to save buffers in case the canvas is captured.
+ Adding a canvas changed notification in case of clear.
+ In the future, we might want to change this notification and do it when endPaint or similar is called.
+
+ Adding an Internals API to grab the RGBA equivalent of the next track frame.
+ For that purpose, adding a bunch of WEBCORE_EXPORT.
+
+ * Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp:
+ (WebCore::CanvasCaptureMediaStreamTrack::Source::Source): Adding constraints support so that track settings
+ getter actually transmits the width and height of the source.
+ (WebCore::CanvasCaptureMediaStreamTrack::Source::canvasChanged): ensuring webgl canvas context keep their drawing buffer.
+ * Modules/mediastream/MediaStreamTrack.h:
+ * bindings/js/JSDOMGuardedObject.h:
+ * bindings/js/JSDOMPromise.h:
+ (WebCore::DeferredPromise::resolve):
+ (WebCore::DeferredPromise::reject):
+ * dom/ActiveDOMCallback.h:
+ * html/HTMLCanvasElement.cpp:
+ (WebCore::HTMLCanvasElement::captureStream):
+ * html/ImageData.h:
+ * html/ImageData.idl:
+ * html/canvas/WebGLRenderingContext.cpp:
+ (WebCore::WebGLRenderingContext::clear): ensuring canvas observers get notified in case of clear calls.
+ * html/canvas/WebGLRenderingContextBase.h:
+ (WebCore::WebGLRenderingContextBase::preserveDrawingBuffer): Added to allow canvas capture to update this property.
+ * platform/MediaSample.h:
+ (WebCore::MediaSample::getRGBAImageData): Added for internals API.
+ * platform/graphics/avfoundation/MediaSampleAVFObjC.h:
+ * platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm:
+ (WebCore::MediaSampleAVFObjC::getRGBAImageData):
+ * platform/graphics/cv/PixelBufferConformerCV.cpp:
+ (WebCore::PixelBufferConformerCV::convert): Helper routine for getRGBAImageData.
+ * platform/graphics/cv/PixelBufferConformerCV.h:
+ * platform/mediastream/RealtimeMediaSourceSettings.h:
+ (WebCore::RealtimeMediaSourceSettings::setSupportedConstraints):
+ (WebCore::RealtimeMediaSourceSettings::setSupportedConstraits): Deleted.
+ * platform/mediastream/mac/AVMediaCaptureSource.mm:
+ (WebCore::AVMediaCaptureSource::initializeSettings):
+ * platform/mediastream/openwebrtc/RealtimeAudioSourceOwr.h:
+ * platform/mediastream/openwebrtc/RealtimeVideoSourceOwr.h:
+ * platform/mock/MockRealtimeMediaSource.cpp:
+ (WebCore::MockRealtimeMediaSource::initializeSettings):
+ * testing/Internals.cpp:
+ (WebCore::Internals::grabNextMediaStreamTrackFrame):
+ (WebCore::Internals::videoSampleAvailable):
+ * testing/Internals.h:
+ * testing/Internals.idl:
+
2017-04-03 Per Arne Vollan <pvol...@apple.com>
Implement stroke-miterlimit.
Modified: trunk/Source/WebCore/Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp (214805 => 214806)
--- trunk/Source/WebCore/Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp 2017-04-03 16:59:41 UTC (rev 214806)
@@ -26,6 +26,7 @@
#include "CanvasCaptureMediaStreamTrack.h"
#include "GraphicsContext.h"
+#include "WebGLRenderingContextBase.h"
#if ENABLE(MEDIA_STREAM)
@@ -67,6 +68,10 @@
{
m_settings.setWidth(canvas.width());
m_settings.setHeight(canvas.height());
+ RealtimeMediaSourceSupportedConstraints constraints;
+ constraints.setSupportsWidth(true);
+ constraints.setSupportsHeight(true);
+ m_settings.setSupportedConstraints(constraints);
}
void CanvasCaptureMediaStreamTrack::Source::startProducingData()
@@ -124,6 +129,17 @@
{
ASSERT_UNUSED(canvas, m_canvas == &canvas);
+ // FIXME: We need to preserve drawing buffer as we are currently grabbing frames asynchronously.
+ // We should instead add an anchor point for both 2d and 3d contexts where canvas will actually paint.
+ // And call canvas observers from that point.
+ if (canvas.renderingContext() && canvas.renderingContext()->isWebGL()) {
+ auto& context = static_cast<WebGLRenderingContextBase&>(*canvas.renderingContext());
+ if (!context.isPreservingDrawingBuffer()) {
+ canvas.document().addConsoleMessage(MessageSource::JS, MessageLevel::Warning, ASCIILiteral("Turning drawing buffer preservation for the WebGL canvas being captured"));
+ context.setPreserveDrawingBuffer(true);
+ }
+ }
+
// FIXME: We should try to generate the frame at the time the screen is being updated.
if (m_canvasChangedTimer.isActive())
return;
Modified: trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h (214805 => 214806)
--- trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h 2017-04-03 16:59:41 UTC (rev 214806)
@@ -89,7 +89,7 @@
String deviceId;
String groupId;
};
- TrackSettings getSettings() const;
+ WEBCORE_EXPORT TrackSettings getSettings() const;
struct TrackCapabilities {
std::optional<LongRange> width;
Modified: trunk/Source/WebCore/bindings/js/JSDOMGuardedObject.h (214805 => 214806)
--- trunk/Source/WebCore/bindings/js/JSDOMGuardedObject.h 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/bindings/js/JSDOMGuardedObject.h 2017-04-03 16:59:41 UTC (rev 214806)
@@ -33,7 +33,7 @@
namespace WebCore {
-class DOMGuardedObject : public RefCounted<DOMGuardedObject>, public ActiveDOMCallback {
+class WEBCORE_EXPORT DOMGuardedObject : public RefCounted<DOMGuardedObject>, public ActiveDOMCallback {
public:
~DOMGuardedObject();
Modified: trunk/Source/WebCore/bindings/js/JSDOMPromise.h (214805 => 214806)
--- trunk/Source/WebCore/bindings/js/JSDOMPromise.h 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/bindings/js/JSDOMPromise.h 2017-04-03 16:59:41 UTC (rev 214806)
@@ -88,7 +88,7 @@
void reject();
void reject(std::nullptr_t);
void reject(Exception&&);
- void reject(ExceptionCode, const String& = { });
+ WEBCORE_EXPORT void reject(ExceptionCode, const String& = { });
void reject(const JSC::PrivateName&);
template<typename Callback>
@@ -122,7 +122,7 @@
JSC::JSPromiseDeferred* deferred() const { return guarded(); }
- void callFunction(JSC::ExecState&, JSC::JSValue function, JSC::JSValue resolution);
+ WEBCORE_EXPORT void callFunction(JSC::ExecState&, JSC::JSValue function, JSC::JSValue resolution);
void resolve(JSC::ExecState& state, JSC::JSValue resolution) { callFunction(state, deferred()->resolve(), resolution); }
void reject(JSC::ExecState& state, JSC::JSValue resolution) { callFunction(state, deferred()->reject(), resolution); }
};
@@ -212,7 +212,7 @@
void fulfillPromiseWithJSON(Ref<DeferredPromise>&&, const String&);
void fulfillPromiseWithArrayBuffer(Ref<DeferredPromise>&&, ArrayBuffer*);
void fulfillPromiseWithArrayBuffer(Ref<DeferredPromise>&&, const void*, size_t);
-void rejectPromiseWithExceptionIfAny(JSC::ExecState&, JSDOMGlobalObject&, JSC::JSPromiseDeferred&);
+WEBCORE_EXPORT void rejectPromiseWithExceptionIfAny(JSC::ExecState&, JSDOMGlobalObject&, JSC::JSPromiseDeferred&);
JSC::EncodedJSValue createRejectedPromiseWithTypeError(JSC::ExecState&, const String&);
using PromiseFunction = void(JSC::ExecState&, Ref<DeferredPromise>&&);
Modified: trunk/Source/WebCore/dom/ActiveDOMCallback.h (214805 => 214806)
--- trunk/Source/WebCore/dom/ActiveDOMCallback.h 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/dom/ActiveDOMCallback.h 2017-04-03 16:59:41 UTC (rev 214806)
@@ -46,7 +46,7 @@
ActiveDOMCallback(ScriptExecutionContext* context);
virtual ~ActiveDOMCallback();
- bool canInvokeCallback() const;
+ WEBCORE_EXPORT bool canInvokeCallback() const;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/html/HTMLCanvasElement.cpp (214805 => 214806)
--- trunk/Source/WebCore/html/HTMLCanvasElement.cpp 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/html/HTMLCanvasElement.cpp 2017-04-03 16:59:41 UTC (rev 214806)
@@ -603,7 +603,7 @@
if (frameRequestRate && frameRequestRate.value() < 0)
return Exception(NOT_SUPPORTED_ERR, ASCIILiteral("frameRequestRate is negative"));
-
+
auto track = CanvasCaptureMediaStreamTrack::create(context, *this, WTFMove(frameRequestRate));
auto stream = MediaStream::create(context);
stream->addTrack(track);
Modified: trunk/Source/WebCore/html/ImageData.h (214805 => 214806)
--- trunk/Source/WebCore/html/ImageData.h 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/html/ImageData.h 2017-04-03 16:59:41 UTC (rev 214806)
@@ -34,7 +34,7 @@
namespace WebCore {
-class ImageData : public RefCounted<ImageData> {
+class WEBCORE_EXPORT ImageData : public RefCounted<ImageData> {
public:
static ExceptionOr<Ref<ImageData>> create(unsigned sw, unsigned sh);
static RefPtr<ImageData> create(const IntSize&);
Modified: trunk/Source/WebCore/html/ImageData.idl (214805 => 214806)
--- trunk/Source/WebCore/html/ImageData.idl 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/html/ImageData.idl 2017-04-03 16:59:41 UTC (rev 214806)
@@ -31,6 +31,7 @@
Constructor(unsigned long sw, unsigned long sh),
ConstructorMayThrowException,
CustomToJSObject,
+ ExportMacro=WEBCORE_EXPORT,
Exposed=(Window,Worker),
ImplementationLacksVTable,
] interface ImageData {
Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp (214805 => 214806)
--- trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp 2017-04-03 16:59:41 UTC (rev 214806)
@@ -470,7 +470,7 @@
}
if (!clearIfComposited(mask))
m_context->clear(mask);
- markContextChanged();
+ markContextChangedAndNotifyCanvasObserver();
}
WebGLAny WebGLRenderingContext::getParameter(GC3Denum pname)
Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h (214805 => 214806)
--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h 2017-04-03 16:59:41 UTC (rev 214806)
@@ -207,6 +207,9 @@
WebGLAny getVertexAttrib(GC3Duint index, GC3Denum pname);
long long getVertexAttribOffset(GC3Duint index, GC3Denum pname);
+ bool isPreservingDrawingBuffer() const { return m_attributes.preserveDrawingBuffer; }
+ void setPreserveDrawingBuffer(bool value) { m_attributes.preserveDrawingBuffer = value; }
+
virtual void hint(GC3Denum target, GC3Denum mode) = 0;
GC3Dboolean isBuffer(WebGLBuffer*);
bool isContextLost() const;
Modified: trunk/Source/WebCore/platform/MediaSample.h (214805 => 214806)
--- trunk/Source/WebCore/platform/MediaSample.h 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/platform/MediaSample.h 2017-04-03 16:59:41 UTC (rev 214806)
@@ -27,6 +27,7 @@
#define MediaSample_h
#include "FloatSize.h"
+#include <runtime/TypedArrays.h>
#include <wtf/MediaTime.h>
#include <wtf/RefCounted.h>
#include <wtf/text/AtomicString.h>
@@ -69,6 +70,8 @@
virtual std::pair<RefPtr<MediaSample>, RefPtr<MediaSample>> divide(const MediaTime& presentationTime) = 0;
virtual Ref<MediaSample> createNonDisplayingCopy() const = 0;
+ virtual RefPtr<JSC::Uint8ClampedArray> getRGBAImageData() const { return nullptr; }
+
enum SampleFlags {
None = 0,
IsSync = 1 << 0,
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/MediaSampleAVFObjC.h (214805 => 214806)
--- trunk/Source/WebCore/platform/graphics/avfoundation/MediaSampleAVFObjC.h 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/MediaSampleAVFObjC.h 2017-04-03 16:59:41 UTC (rev 214806)
@@ -41,6 +41,8 @@
static RefPtr<MediaSampleAVFObjC> createImageSample(Ref<JSC::Uint8ClampedArray>&&, unsigned long width, unsigned long height);
static RefPtr<MediaSampleAVFObjC> createImageSample(Vector<uint8_t>&&, unsigned long width, unsigned long height);
+ RefPtr<JSC::Uint8ClampedArray> getRGBAImageData() const final;
+
private:
MediaSampleAVFObjC(CMSampleBufferRef sample)
: m_sample(sample)
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm (214805 => 214806)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm 2017-04-03 16:59:41 UTC (rev 214806)
@@ -26,6 +26,8 @@
#import "config.h"
#import "MediaSampleAVFObjC.h"
+#import "PixelBufferConformerCV.h"
+#import <runtime/TypedArrayInlines.h>
#import <wtf/PrintStream.h>
#import "CoreMediaSoftLink.h"
@@ -265,4 +267,28 @@
return MediaSampleAVFObjC::create(adoptCF(newSampleBuffer).get(), m_id);
}
+RefPtr<JSC::Uint8ClampedArray> MediaSampleAVFObjC::getRGBAImageData() const
+{
+ const OSType imageFormat = kCVPixelFormatType_32RGBA;
+ RetainPtr<CFNumberRef> imageFormatNumber = adoptCF(CFNumberCreate(nullptr, kCFNumberIntType, &imageFormat));
+
+ RetainPtr<CFMutableDictionaryRef> conformerOptions = adoptCF(CFDictionaryCreateMutable(0, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+ CFDictionarySetValue(conformerOptions.get(), kCVPixelBufferPixelFormatTypeKey, imageFormatNumber.get());
+ PixelBufferConformerCV pixelBufferConformer(conformerOptions.get());
+
+ auto pixelBuffer = static_cast<CVPixelBufferRef>(CMSampleBufferGetImageBuffer(m_sample.get()));
+ auto rgbaPixelBuffer = pixelBufferConformer.convert(pixelBuffer);
+ auto status = CVPixelBufferLockBaseAddress(rgbaPixelBuffer.get(), kCVPixelBufferLock_ReadOnly);
+ ASSERT(status == noErr);
+
+ void* data = "" 0);
+ size_t byteLength = CVPixelBufferGetHeight(pixelBuffer) * CVPixelBufferGetWidth(pixelBuffer) * 4;
+ auto result = JSC::Uint8ClampedArray::create(JSC::ArrayBuffer::create(data, byteLength), 0, byteLength);
+
+ status = CVPixelBufferUnlockBaseAddress(rgbaPixelBuffer.get(), kCVPixelBufferLock_ReadOnly);
+ ASSERT(status == noErr);
+
+ return result;
}
+
+}
Modified: trunk/Source/WebCore/platform/graphics/cv/PixelBufferConformerCV.cpp (214805 => 214806)
--- trunk/Source/WebCore/platform/graphics/cv/PixelBufferConformerCV.cpp 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/platform/graphics/cv/PixelBufferConformerCV.cpp 2017-04-03 16:59:41 UTC (rev 214806)
@@ -72,6 +72,24 @@
CFRelease(pixelBuffer);
}
+RetainPtr<CVPixelBufferRef> PixelBufferConformerCV::convert(CVPixelBufferRef rawBuffer)
+{
+#if USE(VIDEOTOOLBOX)
+ RetainPtr<CVPixelBufferRef> buffer { rawBuffer };
+
+ if (!VTPixelBufferConformerIsConformantPixelBuffer(m_pixelConformer.get(), buffer.get())) {
+ CVPixelBufferRef outputBuffer = nullptr;
+ OSStatus status = VTPixelBufferConformerCopyConformedPixelBuffer(m_pixelConformer.get(), buffer.get(), false, &outputBuffer);
+ if (status != noErr || !outputBuffer)
+ return nullptr;
+ return adoptCF(outputBuffer);
+ }
+#else
+ UNUSED_PARAM(rawBuffer);
+#endif
+ return nullptr;
+}
+
RetainPtr<CGImageRef> PixelBufferConformerCV::createImageFromPixelBuffer(CVPixelBufferRef rawBuffer)
{
RetainPtr<CVPixelBufferRef> buffer { rawBuffer };
Modified: trunk/Source/WebCore/platform/graphics/cv/PixelBufferConformerCV.h (214805 => 214806)
--- trunk/Source/WebCore/platform/graphics/cv/PixelBufferConformerCV.h 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/platform/graphics/cv/PixelBufferConformerCV.h 2017-04-03 16:59:41 UTC (rev 214806)
@@ -37,6 +37,7 @@
class PixelBufferConformerCV {
public:
PixelBufferConformerCV(CFDictionaryRef attributes);
+ RetainPtr<CVPixelBufferRef> convert(CVPixelBufferRef);
RetainPtr<CGImageRef> createImageFromPixelBuffer(CVPixelBufferRef);
private:
Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.h (214805 => 214806)
--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.h 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.h 2017-04-03 16:59:41 UTC (rev 214806)
@@ -92,7 +92,7 @@
const AtomicString& groupId() const { return m_groupId; }
void setGroupId(const AtomicString& groupId) { m_groupId = groupId; }
- void setSupportedConstraits(const RealtimeMediaSourceSupportedConstraints& supportedConstraints) { m_supportedConstraints = supportedConstraints; }
+ void setSupportedConstraints(const RealtimeMediaSourceSupportedConstraints& supportedConstraints) { m_supportedConstraints = supportedConstraints; }
template<class Encoder> void encode(Encoder&) const;
template<class Decoder> static bool decode(Decoder&, RealtimeMediaSourceSettings&);
Modified: trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm (214805 => 214806)
--- trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/platform/mediastream/mac/AVMediaCaptureSource.mm 2017-04-03 16:59:41 UTC (rev 214806)
@@ -204,7 +204,7 @@
void AVMediaCaptureSource::initializeSettings()
{
if (m_currentSettings.deviceId().isEmpty())
- m_currentSettings.setSupportedConstraits(supportedConstraints());
+ m_currentSettings.setSupportedConstraints(supportedConstraints());
m_currentSettings.setDeviceId(id());
updateSettings(m_currentSettings);
Modified: trunk/Source/WebCore/platform/mediastream/openwebrtc/RealtimeAudioSourceOwr.h (214805 => 214806)
--- trunk/Source/WebCore/platform/mediastream/openwebrtc/RealtimeAudioSourceOwr.h 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/platform/mediastream/openwebrtc/RealtimeAudioSourceOwr.h 2017-04-03 16:59:41 UTC (rev 214806)
@@ -59,7 +59,7 @@
protected:
void initializeSettings() final {
if (m_currentSettings.deviceId().isEmpty())
- m_currentSettings.setSupportedConstraits(supportedConstraints());
+ m_currentSettings.setSupportedConstraints(supportedConstraints());
m_currentSettings.setDeviceId(id());
}
Modified: trunk/Source/WebCore/platform/mediastream/openwebrtc/RealtimeVideoSourceOwr.h (214805 => 214806)
--- trunk/Source/WebCore/platform/mediastream/openwebrtc/RealtimeVideoSourceOwr.h 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/platform/mediastream/openwebrtc/RealtimeVideoSourceOwr.h 2017-04-03 16:59:41 UTC (rev 214806)
@@ -59,7 +59,7 @@
protected:
void initializeSettings() final {
if (m_currentSettings.deviceId().isEmpty())
- m_currentSettings.setSupportedConstraits(supportedConstraints());
+ m_currentSettings.setSupportedConstraints(supportedConstraints());
m_currentSettings.setDeviceId(id());
Modified: trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.cpp (214805 => 214806)
--- trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.cpp 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/platform/mock/MockRealtimeMediaSource.cpp 2017-04-03 16:59:41 UTC (rev 214806)
@@ -98,7 +98,7 @@
void MockRealtimeMediaSource::initializeSettings()
{
if (m_currentSettings.deviceId().isEmpty()) {
- m_currentSettings.setSupportedConstraits(supportedConstraints());
+ m_currentSettings.setSupportedConstraints(supportedConstraints());
m_currentSettings.setDeviceId(id());
}
Modified: trunk/Source/WebCore/testing/Internals.cpp (214805 => 214806)
--- trunk/Source/WebCore/testing/Internals.cpp 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/testing/Internals.cpp 2017-04-03 16:59:41 UTC (rev 214806)
@@ -85,6 +85,7 @@
#include "InstrumentingAgents.h"
#include "IntRect.h"
#include "InternalSettings.h"
+#include "JSImageData.h"
#include "Language.h"
#include "LibWebRTCProvider.h"
#include "MainFrame.h"
@@ -3895,6 +3896,33 @@
m_track = &track;
m_track->source().addObserver(*this);
}
+
+void Internals::grabNextMediaStreamTrackFrame(TrackFramePromise&& promise)
+{
+ m_nextTrackFramePromise = WTFMove(promise);
+}
+
+void Internals::videoSampleAvailable(MediaSample& sample)
+{
+ m_trackVideoSampleCount++;
+ if (!m_nextTrackFramePromise)
+ return;
+
+ auto videoSettings = m_track->getSettings();
+ if (!videoSettings.width || !videoSettings.height)
+ return;
+
+ auto rgba = sample.getRGBAImageData();
+ if (!rgba)
+ return;
+ auto imageData = ImageData::create(rgba.releaseNonNull(), *videoSettings.width, *videoSettings.height);
+ if (!imageData.hasException())
+ m_nextTrackFramePromise->resolve(imageData.releaseReturnValue().releaseNonNull());
+ else
+ m_nextTrackFramePromise->reject(imageData.exception().code());
+ m_nextTrackFramePromise = std::nullopt;
+}
+
#endif
} // namespace WebCore
Modified: trunk/Source/WebCore/testing/Internals.h (214805 => 214806)
--- trunk/Source/WebCore/testing/Internals.h 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/testing/Internals.h 2017-04-03 16:59:41 UTC (rev 214806)
@@ -29,9 +29,11 @@
#include "CSSComputedStyleDeclaration.h"
#include "ContextDestructionObserver.h"
#include "ExceptionOr.h"
+#include "JSDOMPromise.h"
#include "PageConsoleClient.h"
#include "RealtimeMediaSource.h"
#include <runtime/Float32Array.h>
+#include <wtf/Optional.h>
#if ENABLE(MEDIA_SESSION)
#include "MediaSessionInterruptionProvider.h"
@@ -54,6 +56,7 @@
class HTMLLinkElement;
class HTMLMediaElement;
class HTMLSelectElement;
+class ImageData;
class InspectorStubFrontend;
class InternalSettings;
class MallocStatistics;
@@ -562,6 +565,8 @@
unsigned long trackAudioSampleCount() const { return m_trackAudioSampleCount; }
unsigned long trackVideoSampleCount() const { return m_trackVideoSampleCount; }
void observeMediaStreamTrack(MediaStreamTrack&);
+ using TrackFramePromise = DOMPromise<IDLInterface<ImageData>>;
+ void grabNextMediaStreamTrackFrame(TrackFramePromise&&);
#endif
private:
@@ -573,12 +578,13 @@
// RealtimeMediaSource::Observer API
#if ENABLE(MEDIA_STREAM)
- void videoSampleAvailable(MediaSample&) final { m_trackVideoSampleCount++; }
+ void videoSampleAvailable(MediaSample&) final;
void audioSamplesAvailable(const MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t) final { m_trackAudioSampleCount++; }
unsigned long m_trackVideoSampleCount { 0 };
unsigned long m_trackAudioSampleCount { 0 };
RefPtr<MediaStreamTrack> m_track;
+ std::optional<TrackFramePromise> m_nextTrackFramePromise;
#endif
std::unique_ptr<InspectorStubFrontend> m_inspectorFrontend;
Modified: trunk/Source/WebCore/testing/Internals.idl (214805 => 214806)
--- trunk/Source/WebCore/testing/Internals.idl 2017-04-03 16:54:49 UTC (rev 214805)
+++ trunk/Source/WebCore/testing/Internals.idl 2017-04-03 16:59:41 UTC (rev 214806)
@@ -526,6 +526,7 @@
[Conditional=WEBGL] void simulateWebGLContextChanged(WebGLRenderingContextBase context);
[Conditional=MEDIA_STREAM] void observeMediaStreamTrack(MediaStreamTrack track);
+ [Conditional=MEDIA_STREAM] Promise<ImageData> grabNextMediaStreamTrackFrame();
[Conditional=MEDIA_STREAM] readonly attribute unsigned long trackAudioSampleCount;
[Conditional=MEDIA_STREAM] readonly attribute unsigned long trackVideoSampleCount;
};