Diff
Modified: trunk/LayoutTests/ChangeLog (270289 => 270290)
--- trunk/LayoutTests/ChangeLog 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/LayoutTests/ChangeLog 2020-12-01 09:43:00 UTC (rev 270290)
@@ -1,3 +1,13 @@
+2020-12-01 Youenn Fablet <[email protected]>
+
+ Add support for readable/writable to RTCRtpSFrameTransform
+ https://bugs.webkit.org/show_bug.cgi?id=219298
+
+ Reviewed by Eric Carlson.
+
+ * http/wpt/webrtc/sframe-transform-expected.txt:
+ * http/wpt/webrtc/sframe-transform.html:
+
2020-12-01 Diego Pino Garcia <[email protected]>
[WPE] Unreviewed test gardening. Update baselines after r270284.
Modified: trunk/LayoutTests/http/wpt/webrtc/sframe-transform-expected.txt (270289 => 270290)
--- trunk/LayoutTests/http/wpt/webrtc/sframe-transform-expected.txt 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/LayoutTests/http/wpt/webrtc/sframe-transform-expected.txt 2020-12-01 09:43:00 UTC (rev 270290)
@@ -1,3 +1,8 @@
PASS Cannot reuse attached transforms
+PASS RTCRtpSFrameTransform exposes readable and writable
+PASS readable/writable are locked when attached and after being attached
+PASS SFrame with array buffer - authentication size 10
+PASS SFrame decryption with array buffer that is too small
+PASS SFrame transform gets errored if trying to process unexpected value types
Modified: trunk/LayoutTests/http/wpt/webrtc/sframe-transform.html (270289 => 270290)
--- trunk/LayoutTests/http/wpt/webrtc/sframe-transform.html 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/LayoutTests/http/wpt/webrtc/sframe-transform.html 2020-12-01 09:43:00 UTC (rev 270290)
@@ -28,6 +28,114 @@
sender1.transform = null;
receiver1.transform = null;
}, "Cannot reuse attached transforms");
+
+test(() => {
+ const senderTransform = new RTCRtpSFrameTransform();
+
+ assert_true(senderTransform.readable instanceof ReadableStream);
+ assert_true(senderTransform.writable instanceof WritableStream);
+}, "RTCRtpSFrameTransform exposes readable and writable");
+
+promise_test(async (test) => {
+ const pc = new RTCPeerConnection();
+ const senderTransform = new RTCRtpSFrameTransform();
+ const receiverTransform = new RTCRtpSFrameTransform();
+ const sender1 = pc.addTransceiver('audio').sender;
+ const sender2 = pc.addTransceiver('video').sender;
+ const receiver1 = pc.getReceivers()[0];
+ const receiver2 = pc.getReceivers()[1];
+
+ assert_false(senderTransform.readable.locked, "sender readable before");
+ assert_false(senderTransform.writable.locked, "sender writable before");
+ assert_false(receiverTransform.readable.locked, "receiver readable before");
+ assert_false(receiverTransform.writable.locked, "receiver writable before");
+
+ sender1.transform = senderTransform;
+ receiver1.transform = receiverTransform;
+
+ assert_true(senderTransform.readable.locked, "sender readable during");
+ assert_true(senderTransform.writable.locked, "sender writable during");
+ assert_true(receiverTransform.readable.locked, "receiver readable during");
+ assert_true(receiverTransform.writable.locked, "receiver writable during");
+
+ sender1.transform = null;
+ receiver1.transform = null;
+
+ assert_true(senderTransform.readable.locked, "sender readable after");
+ assert_true(senderTransform.writable.locked, "sender writable after");
+ assert_true(receiverTransform.readable.locked, "receiver readable after");
+ assert_true(receiverTransform.writable.locked, "receiver writable after");
+}, "readable/writable are locked when attached and after being attached");
+
+promise_test(async (test) => {
+ const key = await crypto.subtle.importKey("raw", new Uint8Array([143, 77, 43, 10, 72, 19, 37, 67, 236, 219, 24, 93, 26, 165, 91, 178]), "HKDF", false, ["deriveBits", "deriveKey"]);
+
+ const senderTransform = new RTCRtpSFrameTransform({ role : 'encrypt', authenticationSize: 10 });
+ senderTransform.setEncryptionKey(key);
+
+ const receiverTransform = new RTCRtpSFrameTransform({ role : 'decrypt', authenticationSize: 10 });
+ receiverTransform.setEncryptionKey(key);
+
+ const writer = senderTransform.writable.getWriter();
+ const reader = receiverTransform.readable.getReader();
+
+ senderTransform.readable.pipeTo(receiverTransform.writable);
+
+ const sent = new ArrayBuffer(8);
+ const view = new Int8Array(sent);
+ for (let cptr = 0; cptr < sent.byteLength; ++cptr)
+ view[cptr] = cptr;
+
+ writer.write(sent);
+ const received = await reader.read();
+
+ assert_equals(received.value.byteLength, 8);
+ const view2 = new Int8Array(received.value);
+ for (let cptr = 0; cptr < sent.byteLength; ++cptr)
+ assert_equals(view2[cptr], view[cptr]);
+}, "SFrame with array buffer - authentication size 10");
+
+promise_test(async (test) => {
+ const key = await crypto.subtle.importKey("raw", new Uint8Array([143, 77, 43, 10, 72, 19, 37, 67, 236, 219, 24, 93, 26, 165, 91, 178]), "HKDF", false, ["deriveBits", "deriveKey"]);
+
+ const senderTransform = new RTCRtpSFrameTransform({ role : 'encrypt', authenticationSize: 10 });
+ const senderWriter = senderTransform.writable.getWriter();
+ const senderReader = senderTransform.readable.getReader();
+
+ const receiverTransform = new RTCRtpSFrameTransform({ role : 'decrypt', authenticationSize: 10 });
+ const receiverWriter = receiverTransform.writable.getWriter();
+ const receiverReader = receiverTransform.readable.getReader();
+
+ senderTransform.setEncryptionKey(key);
+ receiverTransform.setEncryptionKey(key);
+
+ const chunk = new ArrayBuffer(8);
+
+ // decryption should fail, leading to an empty array buffer.
+ await receiverWriter.write(chunk);
+ let received = await receiverReader.read();
+ assert_equals(received.value.byteLength, 0);
+
+ // We write again but this time with a chunk we can decrypt.
+ await senderWriter.write(chunk);
+ const encrypted = await senderReader.read();
+ await receiverWriter.write(encrypted.value);
+ received = await receiverReader.read();
+ assert_equals(received.value.byteLength, 8);
+}, "SFrame decryption with array buffer that is too small");
+
+promise_test(async (test) => {
+ const key = await crypto.subtle.importKey("raw", new Uint8Array([143, 77, 43, 10, 72, 19, 37, 67, 236, 219, 24, 93, 26, 165, 91, 178]), "HKDF", false, ["deriveBits", "deriveKey"]);
+
+ const receiverTransform = new RTCRtpSFrameTransform({ role : 'decrypt', authenticationSize: 10 });
+ const receiverWriter = receiverTransform.writable.getWriter();
+ receiverTransform.setEncryptionKey(key);
+
+ // decryption should fail, leading to erroring the transform.
+ await promise_rejects_js(test, TypeError, receiverWriter.write({ }));
+ await promise_rejects_js(test, TypeError, receiverWriter.closed);
+}, "SFrame transform gets errored if trying to process unexpected value types");
+
</script>
</body>
</html>
Modified: trunk/Source/WebCore/ChangeLog (270289 => 270290)
--- trunk/Source/WebCore/ChangeLog 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/ChangeLog 2020-12-01 09:43:00 UTC (rev 270290)
@@ -1,3 +1,88 @@
+2020-12-01 Youenn Fablet <[email protected]>
+
+ Add support for readable/writable to RTCRtpSFrameTransform
+ https://bugs.webkit.org/show_bug.cgi?id=219298
+
+ Reviewed by Eric Carlson.
+
+ Add support for locking WritableStream and checking locked state.
+ Add readable/writable getters so that RTCRtpSFrameTransform can be used as a TransformStream.
+ Make a refactoring to allow reuse of SimpleReadableStreamSource and SimpleWritableStreamSink.
+
+ In case of encryption/decryption error, we do not error the transform as this is final.
+ Instead, we output empty buffers.
+ In case of trying to encrypt unexpected objects, we error the transform.
+
+ Move RTCRtpTransformableFrame to be ref counted.
+ This allows to keep a RTCRtpTransformableFrame for each RTCEncodedFrame even though the underlying
+ webrtc frame (which is a unique ptr) is given back to the webrtc backend after processing.
+
+ Covered by updated test.
+
+ * Modules/mediastream/RTCEncodedAudioFrame.cpp:
+ (WebCore::RTCEncodedAudioFrame::RTCEncodedAudioFrame):
+ * Modules/mediastream/RTCEncodedAudioFrame.h:
+ (WebCore::RTCEncodedAudioFrame::create):
+ * Modules/mediastream/RTCEncodedFrame.cpp:
+ (WebCore::RTCEncodedFrame::RTCEncodedFrame):
+ * Modules/mediastream/RTCEncodedFrame.h:
+ (WebCore::RTCEncodedFrame::rtcFrame):
+ * Modules/mediastream/RTCEncodedVideoFrame.cpp:
+ (WebCore::RTCEncodedVideoFrame::RTCEncodedVideoFrame):
+ * Modules/mediastream/RTCEncodedVideoFrame.h:
+ (WebCore::RTCEncodedVideoFrame::create):
+ * Modules/mediastream/RTCRtpSFrameTransform.cpp:
+ (WebCore::RTCRtpSFrameTransform::RTCRtpSFrameTransform):
+ (WebCore::RTCRtpSFrameTransform::isAttached const):
+ (WebCore::RTCRtpSFrameTransform::initializeTransformer):
+ (WebCore::RTCRtpSFrameTransform::willClearBackend):
+ (WebCore::transformFrame):
+ (WebCore::RTCRtpSFrameTransform::createStreams):
+ (WebCore::RTCRtpSFrameTransform::readable):
+ (WebCore::RTCRtpSFrameTransform::writable):
+ * Modules/mediastream/RTCRtpSFrameTransform.h:
+ (WebCore::RTCRtpSFrameTransform::create):
+ * Modules/mediastream/RTCRtpSFrameTransform.idl:
+ * Modules/mediastream/RTCRtpSFrameTransformer.cpp:
+ (WebCore::RTCRtpSFrameTransformer::setEncryptionKey):
+ (WebCore::RTCRtpSFrameTransformer::decryptFrame):
+ (WebCore::RTCRtpSFrameTransformer::encryptFrame):
+ (WebCore::RTCRtpSFrameTransformer::transform):
+ (WebCore::RTCRtpSFrameTransformer::updateAuthenticationSize):
+ * Modules/mediastream/RTCRtpSFrameTransformer.h:
+ (WebCore::RTCRtpSFrameTransformer::setIsEncrypting):
+ (WebCore::RTCRtpSFrameTransformer::setAuthenticationSize):
+ * Modules/mediastream/RTCRtpSFrameTransformerCocoa.cpp:
+ (WebCore::RTCRtpSFrameTransformer::updateAuthenticationSize):
+ * Modules/mediastream/RTCRtpScriptTransformer.cpp:
+ (WebCore::RTCRtpScriptTransformer::startStreams):
+ * Modules/mediastream/RTCRtpScriptTransformer.h:
+ * Modules/mediastream/RTCRtpTransformBackend.h:
+ * Modules/mediastream/RTCRtpTransformableFrame.h:
+ * Modules/mediastream/libwebrtc/LibWebRTCRtpSenderTransformBackend.cpp:
+ * Modules/mediastream/libwebrtc/LibWebRTCRtpTransformBackend.cpp:
+ (WebCore::LibWebRTCRtpTransformBackend::processTransformedFrame):
+ (WebCore::LibWebRTCRtpTransformBackend::Transform):
+ * Modules/mediastream/libwebrtc/LibWebRTCRtpTransformBackend.h:
+ * Modules/mediastream/libwebrtc/LibWebRTCRtpTransformableFrame.cpp: Added.
+ * Modules/mediastream/libwebrtc/LibWebRTCRtpTransformableFrame.h:
+ * Modules/streams/ReadableStreamSource.h:
+ (WebCore::SimpleReadableStreamSource::create):
+ (WebCore::SimpleReadableStreamSource::close):
+ (WebCore::SimpleReadableStreamSource::enqueue):
+ * Modules/streams/WritableStreamSink.h:
+ (WebCore::SimpleWritableStreamSink::create):
+ (WebCore::SimpleWritableStreamSink::SimpleWritableStreamSink):
+ (WebCore::SimpleWritableStreamSink::write):
+ * bindings/js/WritableStream.cpp:
+ (WebCore::WritableStreamInternal::callFunction):
+ (WebCore::checkWritableStream):
+ (WebCore::WritableStream::lock):
+ (WebCore::WritableStream::isLocked const):
+ * bindings/js/WritableStream.h:
+ * bindings/scripts/CodeGeneratorJS.pm:
+ (AddToIncludesForIDLType):
+
2020-12-01 Sergio Villar Senin <[email protected]>
[css-flexbox] WebKit doesn't preserve aspect ratio when computing cross size of flexed images in auto-height flex container
Modified: trunk/Source/WebCore/Modules/mediastream/RTCEncodedAudioFrame.cpp (270289 => 270290)
--- trunk/Source/WebCore/Modules/mediastream/RTCEncodedAudioFrame.cpp 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Modules/mediastream/RTCEncodedAudioFrame.cpp 2020-12-01 09:43:00 UTC (rev 270290)
@@ -30,7 +30,7 @@
namespace WebCore {
-RTCEncodedAudioFrame::RTCEncodedAudioFrame(UniqueRef<RTCRtpTransformableFrame>&& frame)
+RTCEncodedAudioFrame::RTCEncodedAudioFrame(Ref<RTCRtpTransformableFrame>&& frame)
: RTCEncodedFrame(WTFMove(frame))
{
}
Modified: trunk/Source/WebCore/Modules/mediastream/RTCEncodedAudioFrame.h (270289 => 270290)
--- trunk/Source/WebCore/Modules/mediastream/RTCEncodedAudioFrame.h 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Modules/mediastream/RTCEncodedAudioFrame.h 2020-12-01 09:43:00 UTC (rev 270290)
@@ -33,11 +33,11 @@
class RTCEncodedAudioFrame : public RTCEncodedFrame {
public:
- static Ref<RTCEncodedAudioFrame> create(UniqueRef<RTCRtpTransformableFrame>&& frame) { return adoptRef(*new RTCEncodedAudioFrame(WTFMove(frame))); }
+ static Ref<RTCEncodedAudioFrame> create(Ref<RTCRtpTransformableFrame>&& frame) { return adoptRef(*new RTCEncodedAudioFrame(WTFMove(frame))); }
~RTCEncodedAudioFrame();
private:
- explicit RTCEncodedAudioFrame(UniqueRef<RTCRtpTransformableFrame>&&);
+ explicit RTCEncodedAudioFrame(Ref<RTCRtpTransformableFrame>&&);
};
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/mediastream/RTCEncodedFrame.cpp (270289 => 270290)
--- trunk/Source/WebCore/Modules/mediastream/RTCEncodedFrame.cpp 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Modules/mediastream/RTCEncodedFrame.cpp 2020-12-01 09:43:00 UTC (rev 270290)
@@ -33,7 +33,7 @@
namespace WebCore {
-RTCEncodedFrame::RTCEncodedFrame(UniqueRef<RTCRtpTransformableFrame>&& frame)
+RTCEncodedFrame::RTCEncodedFrame(Ref<RTCRtpTransformableFrame>&& frame)
: m_frame(WTFMove(frame))
{
}
Modified: trunk/Source/WebCore/Modules/mediastream/RTCEncodedFrame.h (270289 => 270290)
--- trunk/Source/WebCore/Modules/mediastream/RTCEncodedFrame.h 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Modules/mediastream/RTCEncodedFrame.h 2020-12-01 09:43:00 UTC (rev 270290)
@@ -43,12 +43,12 @@
RefPtr<JSC::ArrayBuffer> data() const;
void setData(JSC::ArrayBuffer&);
- UniqueRef<RTCRtpTransformableFrame> takeRTCFrame() { return WTFMove(m_frame); }
+ RTCRtpTransformableFrame& rtcFrame() { return m_frame.get(); }
protected:
- explicit RTCEncodedFrame(UniqueRef<RTCRtpTransformableFrame>&&);
+ explicit RTCEncodedFrame(Ref<RTCRtpTransformableFrame>&&);
- UniqueRef<RTCRtpTransformableFrame> m_frame;
+ Ref<RTCRtpTransformableFrame> m_frame;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/mediastream/RTCEncodedVideoFrame.cpp (270289 => 270290)
--- trunk/Source/WebCore/Modules/mediastream/RTCEncodedVideoFrame.cpp 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Modules/mediastream/RTCEncodedVideoFrame.cpp 2020-12-01 09:43:00 UTC (rev 270290)
@@ -30,7 +30,7 @@
namespace WebCore {
-RTCEncodedVideoFrame::RTCEncodedVideoFrame(UniqueRef<RTCRtpTransformableFrame>&& frame)
+RTCEncodedVideoFrame::RTCEncodedVideoFrame(Ref<RTCRtpTransformableFrame>&& frame)
: RTCEncodedFrame(WTFMove(frame))
{
}
Modified: trunk/Source/WebCore/Modules/mediastream/RTCEncodedVideoFrame.h (270289 => 270290)
--- trunk/Source/WebCore/Modules/mediastream/RTCEncodedVideoFrame.h 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Modules/mediastream/RTCEncodedVideoFrame.h 2020-12-01 09:43:00 UTC (rev 270290)
@@ -33,11 +33,11 @@
class RTCEncodedVideoFrame : public RTCEncodedFrame {
public:
- static Ref<RTCEncodedVideoFrame> create(UniqueRef<RTCRtpTransformableFrame>&& frame) { return adoptRef(*new RTCEncodedVideoFrame(WTFMove(frame))); }
+ static Ref<RTCEncodedVideoFrame> create(Ref<RTCRtpTransformableFrame>&& frame) { return adoptRef(*new RTCEncodedVideoFrame(WTFMove(frame))); }
~RTCEncodedVideoFrame();
private:
- explicit RTCEncodedVideoFrame(UniqueRef<RTCRtpTransformableFrame>&&);
+ explicit RTCEncodedVideoFrame(Ref<RTCRtpTransformableFrame>&&);
};
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.cpp (270289 => 270290)
--- trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.cpp 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.cpp 2020-12-01 09:43:00 UTC (rev 270290)
@@ -29,16 +29,27 @@
#if ENABLE(WEB_RTC)
#include "CryptoKeyRaw.h"
+#include "JSDOMConvertBufferSource.h"
#include "Logging.h"
+#include "RTCEncodedAudioFrame.h"
+#include "RTCEncodedVideoFrame.h"
#include "RTCRtpSFrameTransformer.h"
#include "RTCRtpTransformBackend.h"
#include "RTCRtpTransformableFrame.h"
+#include "ReadableStream.h"
+#include "ReadableStreamSource.h"
+#include "SharedBuffer.h"
+#include "WritableStream.h"
+#include "WritableStreamSink.h"
namespace WebCore {
-RTCRtpSFrameTransform::RTCRtpSFrameTransform()
- : m_transformer(RTCRtpSFrameTransformer::create())
+RTCRtpSFrameTransform::RTCRtpSFrameTransform(ScriptExecutionContext& context, Options options)
+ : ContextDestructionObserver(&context)
+ , m_transformer(RTCRtpSFrameTransformer::create())
{
+ m_transformer->setIsEncrypting(options.role == Role::Encrypt);
+ m_transformer->setAuthenticationSize(options.authenticationSize);
}
RTCRtpSFrameTransform::~RTCRtpSFrameTransform()
@@ -67,12 +78,24 @@
return m_transformer->counter();
}
+bool RTCRtpSFrameTransform::isAttached() const
+{
+ return m_isAttached || (m_readable && m_readable->isLocked()) || (m_writable && m_writable->isLocked());
+}
+
void RTCRtpSFrameTransform::initializeTransformer(RTCRtpTransformBackend& backend, Side side)
{
+ ASSERT(!isAttached());
+
m_isAttached = true;
- m_transformer->setIsSending(side == Side::Sender);
- m_transformer->setIsProcessingAudio(backend.mediaType() == RTCRtpTransformBackend::MediaType::Audio);
+ if (m_readable)
+ m_readable->lock();
+ if (m_writable)
+ m_writable->lock();
+ m_transformer->setIsEncrypting(side == Side::Sender);
+ m_transformer->setAuthenticationSize(backend.mediaType() == RTCRtpTransformBackend::MediaType::Audio ? 4 : 10);
+
backend.setTransformableFrameCallback([transformer = m_transformer, backend = makeRef(backend)](auto&& frame) {
auto chunk = frame->data();
auto result = transformer->transform(chunk.data, chunk.size);
@@ -84,11 +107,10 @@
frame->setData({ result.returnValue().data(), result.returnValue().size() });
- backend->processTransformedFrame(WTFMove(frame.get()));
+ backend->processTransformedFrame(frame.get());
});
}
-
void RTCRtpSFrameTransform::initializeBackendForReceiver(RTCRtpTransformBackend& backend)
{
initializeTransformer(backend, Side::Receiver);
@@ -102,9 +124,96 @@
void RTCRtpSFrameTransform::willClearBackend(RTCRtpTransformBackend& backend)
{
backend.clearTransformableFrameCallback();
- m_isAttached = false;
}
+template<typename Frame>
+void transformFrame(Frame& frame, JSDOMGlobalObject& globalObject, RTCRtpSFrameTransformer& transformer, SimpleReadableStreamSource& source)
+{
+ auto chunk = frame.rtcFrame().data();
+ auto result = transformer.transform(chunk.data, chunk.size);
+ RELEASE_LOG_ERROR_IF(result.hasException(), WebRTC, "RTCRtpSFrameTransform failed transforming a frame");
+
+ RTCRtpTransformableFrame::Data transformedChunk;
+ // In case of error, we just pass along the frame with empty data.
+ if (!result.hasException())
+ transformedChunk = { result.returnValue().data(), result.returnValue().size() };
+
+ frame.rtcFrame().setData(transformedChunk);
+ source.enqueue(toJS(&globalObject, &globalObject, frame));
+}
+
+template<>
+void transformFrame(JSC::ArrayBuffer& value, JSDOMGlobalObject& globalObject, RTCRtpSFrameTransformer& transformer, SimpleReadableStreamSource& source)
+{
+ auto result = transformer.transform(static_cast<const uint8_t*>(value.data()), value.byteLength());
+ RELEASE_LOG_ERROR_IF(result.hasException(), WebRTC, "RTCRtpSFrameTransform failed transforming a frame");
+
+ auto buffer = result.hasException() ? SharedBuffer::create() : SharedBuffer::create(result.returnValue().data(), result.returnValue().size());
+ source.enqueue(toJS(&globalObject, &globalObject, buffer->tryCreateArrayBuffer().get()));
+}
+
+void RTCRtpSFrameTransform::createStreams()
+{
+ auto& globalObject = *scriptExecutionContext()->globalObject();
+
+ m_readableStreamSource = SimpleReadableStreamSource::create();
+ auto readable = ReadableStream::create(globalObject, m_readableStreamSource.copyRef());
+ if (readable.hasException())
+ return;
+
+ auto writable = WritableStream::create(globalObject, SimpleWritableStreamSink::create([transformer = m_transformer, readableStreamSource = m_readableStreamSource](auto& context, auto value) -> ExceptionOr<void> {
+ auto& globalObject = *JSC::jsCast<JSDOMGlobalObject*>(context.globalObject());
+ auto scope = DECLARE_THROW_SCOPE(globalObject.vm());
+
+ auto frame = convert<IDLUnion<IDLArrayBuffer, IDLInterface<RTCEncodedAudioFrame>, IDLInterface<RTCEncodedVideoFrame>>>(globalObject, value);
+ if (scope.exception())
+ return Exception { ExistingExceptionError };
+
+ // We do not want to throw any exception in the transform to make sure we do not error the transform.
+ WTF::switchOn(frame, [&](RefPtr<RTCEncodedAudioFrame>& value) {
+ transformFrame(*value, globalObject, transformer.get(), *readableStreamSource);
+ }, [&](RefPtr<RTCEncodedVideoFrame>& value) {
+ transformFrame(*value, globalObject, transformer.get(), *readableStreamSource);
+ }, [&](RefPtr<ArrayBuffer>& value) {
+ transformFrame(*value, globalObject, transformer.get(), *readableStreamSource);
+ });
+ return { };
+ }));
+ if (writable.hasException())
+ return;
+
+ m_readable = readable.releaseReturnValue();
+ m_writable = writable.releaseReturnValue();
+ if (m_isAttached) {
+ m_readable->lock();
+ m_writable->lock();
+ }
+}
+
+ExceptionOr<RefPtr<ReadableStream>> RTCRtpSFrameTransform::readable()
+{
+ auto* context = scriptExecutionContext();
+ if (!context)
+ return Exception { InvalidStateError };
+
+ if (!m_readable)
+ createStreams();
+
+ return m_readable.copyRef();
+}
+
+ExceptionOr<RefPtr<WritableStream>> RTCRtpSFrameTransform::writable()
+{
+ auto* context = scriptExecutionContext();
+ if (!context)
+ return Exception { InvalidStateError };
+
+ if (!m_writable)
+ createStreams();
+
+ return m_writable.copyRef();
+}
+
} // namespace WebCore
#endif // ENABLE(WEB_RTC)
Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.h (270289 => 270290)
--- trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.h 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.h 2020-12-01 09:43:00 UTC (rev 270290)
@@ -27,6 +27,7 @@
#if ENABLE(WEB_RTC)
+#include "ContextDestructionObserver.h"
#include "JSDOMPromiseDeferred.h"
namespace WebCore {
@@ -34,15 +35,24 @@
class CryptoKey;
class RTCRtpSFrameTransformer;
class RTCRtpTransformBackend;
+class ReadableStream;
+class SimpleReadableStreamSource;
+class WritableStream;
-class RTCRtpSFrameTransform : public RefCounted<RTCRtpSFrameTransform> {
+class RTCRtpSFrameTransform : public RefCounted<RTCRtpSFrameTransform>, private ContextDestructionObserver {
public:
- static Ref<RTCRtpSFrameTransform> create() { return adoptRef(*new RTCRtpSFrameTransform); }
+ enum class Role { Encrypt, Decrypt };
+ struct Options {
+ Role role { Role::Encrypt };
+ uint64_t authenticationSize { 10 };
+ };
+
+ static Ref<RTCRtpSFrameTransform> create(ScriptExecutionContext& context, Options options) { return adoptRef(*new RTCRtpSFrameTransform(context, options)); }
~RTCRtpSFrameTransform();
void setEncryptionKey(CryptoKey&, Optional<uint64_t>, DOMPromiseDeferred<void>&&);
- bool isAttached() const { return m_isAttached; }
+ bool isAttached() const;
void initializeBackendForReceiver(RTCRtpTransformBackend&);
void initializeBackendForSender(RTCRtpTransformBackend&);
void willClearBackend(RTCRtpTransformBackend&);
@@ -49,14 +59,21 @@
WEBCORE_EXPORT uint64_t counterForTesting() const;
+ ExceptionOr<RefPtr<ReadableStream>> readable();
+ ExceptionOr<RefPtr<WritableStream>> writable();
+
private:
- RTCRtpSFrameTransform();
+ RTCRtpSFrameTransform(ScriptExecutionContext&, Options);
enum class Side { Sender, Receiver };
void initializeTransformer(RTCRtpTransformBackend&, Side);
+ void createStreams();
bool m_isAttached { false };
Ref<RTCRtpSFrameTransformer> m_transformer;
+ RefPtr<ReadableStream> m_readable;
+ RefPtr<WritableStream> m_writable;
+ RefPtr<SimpleReadableStreamSource> m_readableStreamSource;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.idl (270289 => 270290)
--- trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.idl 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransform.idl 2020-12-01 09:43:00 UTC (rev 270290)
@@ -23,18 +23,30 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+enum RTCRtpSFrameTransformRole {
+ "encrypt",
+ "decrypt"
+};
+
+dictionary RTCRtpSFrameTransformOptions {
+ RTCRtpSFrameTransformRole role = "encrypt";
+ unsigned long authenticationSize = 10;
+};
+
[
Conditional=WEB_RTC,
EnabledBySetting=WebRTCInsertableStreams,
ExportMacro=WEBCORE_EXPORT,
Exposed=Window,
- ImplementationLacksVTable,
JSGenerateToNativeObject,
] interface RTCRtpSFrameTransform {
- constructor();
+ [CallWith=ScriptExecutionContext] constructor(optional RTCRtpSFrameTransformOptions options);
Promise<undefined> setEncryptionKey(CryptoKey key, optional unsigned long long keyID);
// FIXME: Add support for missing methods.
// Promise<undefined> ratchetEncryptionKey();
// Promise<undefined> setSigningKey(CryptoKey key);
+
+ [MayThrowException] readonly attribute ReadableStream readable;
+ [MayThrowException] readonly attribute WritableStream writable;
};
Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformer.cpp (270289 => 270290)
--- trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformer.cpp 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformer.cpp 2020-12-01 09:43:00 UTC (rev 270290)
@@ -167,14 +167,14 @@
if (keyId)
m_keyId = *keyId;
+ updateAuthenticationSize();
m_hasKey = true;
+
return { };
}
ExceptionOr<Vector<uint8_t>> RTCRtpSFrameTransformer::decryptFrame(const uint8_t* frameData, size_t frameSize)
{
- // FIXME: Support signature.
-
auto locker = holdLock(m_keyLock);
auto header = parseSFrameHeader(frameData, frameSize);
@@ -191,6 +191,9 @@
return Exception { NotSupportedError };
}
+ if (frameSize < (header->size + m_authenticationSize))
+ return Exception { DataError, "Chunk is too small for authentication size" };
+
// Compute signature
auto* transmittedSignature = frameData + frameSize - m_authenticationSize;
auto signature = computeEncryptedDataSignature(frameData, frameSize - m_authenticationSize, m_authenticationKey);
@@ -214,8 +217,6 @@
ExceptionOr<Vector<uint8_t>> RTCRtpSFrameTransformer::encryptFrame(const uint8_t* frameData, size_t frameSize)
{
- // FIXME: Support signature.
-
static const unsigned MaxHeaderSize = 17;
auto locker = holdLock(m_keyLock);
@@ -259,9 +260,9 @@
ExceptionOr<Vector<uint8_t>> RTCRtpSFrameTransformer::transform(const uint8_t* data, size_t size)
{
if (!m_hasKey)
- return Exception { InvalidStateError };
+ return Exception { InvalidStateError, "Key is not initialized"_s };
- return m_isSending ? encryptFrame(data, size) : decryptFrame(data, size);
+ return m_isEncrypting ? encryptFrame(data, size) : decryptFrame(data, size);
}
#if !PLATFORM(COCOA)
@@ -294,6 +295,10 @@
{
return { };
}
+
+void RTCRtpSFrameTransformer::updateAuthenticationSize()
+{
+}
#endif // !PLATFORM(COCOA)
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformer.h (270289 => 270290)
--- trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformer.h 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformer.h 2020-12-01 09:43:00 UTC (rev 270290)
@@ -40,8 +40,8 @@
WEBCORE_EXPORT static Ref<RTCRtpSFrameTransformer> create();
WEBCORE_EXPORT ~RTCRtpSFrameTransformer();
- void setIsSending(bool);
- void setIsProcessingAudio(bool);
+ void setIsEncrypting(bool);
+ void setAuthenticationSize(uint64_t);
WEBCORE_EXPORT ExceptionOr<void> setEncryptionKey(const Vector<uint8_t>& rawKey, Optional<uint64_t>);
WEBCORE_EXPORT ExceptionOr<Vector<uint8_t>> transform(const uint8_t*, size_t);
@@ -66,6 +66,7 @@
ExceptionOr<Vector<uint8_t>> encryptData(const uint8_t*, size_t, const Vector<uint8_t>& iv, const Vector<uint8_t>& key);
ExceptionOr<Vector<uint8_t>> decryptData(const uint8_t*, size_t, const Vector<uint8_t>& iv, const Vector<uint8_t>& key);
Vector<uint8_t> computeEncryptedDataSignature(const uint8_t*, size_t, const Vector<uint8_t>& key);
+ void updateAuthenticationSize();
Lock m_keyLock;
bool m_hasKey { false };
@@ -73,20 +74,20 @@
Vector<uint8_t> m_encryptionKey;
Vector<uint8_t> m_saltKey;
- bool m_isSending { false };
+ bool m_isEncrypting { false };
uint64_t m_authenticationSize { 10 };
uint64_t m_keyId { 0 };
uint64_t m_counter { 0 };
};
-inline void RTCRtpSFrameTransformer::setIsSending(bool isSending)
+inline void RTCRtpSFrameTransformer::setIsEncrypting(bool isEncrypting)
{
- m_isSending = isSending;
+ m_isEncrypting = isEncrypting;
}
-inline void RTCRtpSFrameTransformer::setIsProcessingAudio(bool isProcessingAudio)
+inline void RTCRtpSFrameTransformer::setAuthenticationSize(uint64_t size)
{
- m_authenticationSize = isProcessingAudio ? 4 : 10;
+ m_authenticationSize = size;
}
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformerCocoa.cpp (270289 => 270290)
--- trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformerCocoa.cpp 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpSFrameTransformerCocoa.cpp 2020-12-01 09:43:00 UTC (rev 270290)
@@ -68,6 +68,12 @@
return result;
}
+void RTCRtpSFrameTransformer::updateAuthenticationSize()
+{
+ if (m_authenticationSize > CC_SHA256_DIGEST_LENGTH)
+ m_authenticationSize = CC_SHA256_DIGEST_LENGTH;
+}
+
} // namespace WebCore
#endif // ENABLE(WEB_RTC)
Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.cpp (270289 => 270290)
--- trunk/Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.cpp 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.cpp 2020-12-01 09:43:00 UTC (rev 270290)
@@ -40,63 +40,6 @@
namespace WebCore {
-class RTCRtpReadableStreamSource
- : public ReadableStreamSource
- , public CanMakeWeakPtr<RTCRtpReadableStreamSource> {
-public:
- static Ref<RTCRtpReadableStreamSource> create() { return adoptRef(*new RTCRtpReadableStreamSource); }
-
- void close() { controller().close(); }
- void enqueue(JSC::JSValue value) { controller().enqueue(value); }
-
-private:
- RTCRtpReadableStreamSource() = default;
-
- // ReadableStreamSource
- void setActive() final { }
- void setInactive() final { }
- void doStart() final { }
- void doPull() final { }
- void doCancel() final { }
-};
-
-class RTCRtpWritableStreamSink : public WritableStreamSink {
-public:
- static Ref<RTCRtpWritableStreamSink> create(Function<void(UniqueRef<RTCRtpTransformableFrame>&&)>&& enqueueFunction) { return adoptRef(*new RTCRtpWritableStreamSink(WTFMove(enqueueFunction))); }
-
-private:
- explicit RTCRtpWritableStreamSink(Function<void(UniqueRef<RTCRtpTransformableFrame>&&)>&& enqueueFunction)
- : m_enqueueFunction(WTFMove(enqueueFunction))
- {
- }
-
- void write(ScriptExecutionContext& context, JSC::JSValue value, DOMPromiseDeferred<void>&& promise)
- {
- auto& globalObject = *context.globalObject();
-
- auto scope = DECLARE_THROW_SCOPE(globalObject.vm());
- auto frame = convert<IDLUnion<IDLInterface<RTCEncodedAudioFrame>, IDLInterface<RTCEncodedVideoFrame>>>(globalObject, value);
-
- if (scope.exception()) {
- promise.reject(Exception { ExistingExceptionError }, RejectAsHandled::Yes);
- return;
- }
-
- WTF::switchOn(frame, [&](RefPtr<RTCEncodedAudioFrame>& value) {
- m_enqueueFunction(value->takeRTCFrame());
- }, [&](RefPtr<RTCEncodedVideoFrame>& value) {
- m_enqueueFunction(value->takeRTCFrame());
- });
- promise.resolve();
- }
-
- // FIXME: Decide whether clearing all pending frames.
- void close() final { }
- void error(String&&) final { }
-
- Function<void(UniqueRef<RTCRtpTransformableFrame>&&)> m_enqueueFunction;
-};
-
ExceptionOr<Ref<RTCRtpScriptTransformer>> RTCRtpScriptTransformer::create(ScriptExecutionContext& context)
{
auto port = downcast<DedicatedWorkerGlobalScope>(context).takePendingRTCTransfomerMessagePort();
@@ -118,7 +61,7 @@
{
}
-RefPtr<RTCRtpReadableStreamSource> RTCRtpScriptTransformer::startStreams(RTCRtpTransformBackend& backend)
+RefPtr<SimpleReadableStreamSource> RTCRtpScriptTransformer::startStreams(RTCRtpTransformBackend& backend)
{
auto callback = WTFMove(m_callback);
if (!callback)
@@ -130,13 +73,27 @@
auto& vm = globalObject.vm();
JSC::JSLockHolder lock(vm);
- auto readableStreamSource = RTCRtpReadableStreamSource::create();
+ auto readableStreamSource = SimpleReadableStreamSource::create();
auto readableStream = ReadableStream::create(globalObject, readableStreamSource.copyRef());
if (readableStream.hasException())
return nullptr;
- auto writableStream = WritableStream::create(globalObject, RTCRtpWritableStreamSink::create([backend = makeRef(backend)](auto&& frame) {
- backend->processTransformedFrame(WTFMove(frame.get()));
+ auto writableStream = WritableStream::create(globalObject, SimpleWritableStreamSink::create([backend = makeRef(backend)](auto& context, auto value) -> ExceptionOr<void> {
+ auto& globalObject = *context.globalObject();
+
+ auto scope = DECLARE_THROW_SCOPE(globalObject.vm());
+ auto frame = convert<IDLUnion<IDLInterface<RTCEncodedAudioFrame>, IDLInterface<RTCEncodedVideoFrame>>>(globalObject, value);
+
+ if (scope.exception())
+ return Exception { ExistingExceptionError };
+
+ auto rtcFrame = WTF::switchOn(frame, [&](RefPtr<RTCEncodedAudioFrame>& value) {
+ return makeRef(value->rtcFrame());
+ }, [&](RefPtr<RTCEncodedVideoFrame>& value) {
+ return makeRef(value->rtcFrame());
+ });
+ backend->processTransformedFrame(rtcFrame.get());
+ return { };
}));
if (writableStream.hasException())
return nullptr;
Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.h (270289 => 270290)
--- trunk/Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.h 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.h 2020-12-01 09:43:00 UTC (rev 270290)
@@ -38,7 +38,7 @@
class MessagePort;
class ScriptExecutionContext;
class RTCRtpTransformBackend;
-class RTCRtpReadableStreamSource;
+class SimpleReadableStreamSource;
class RTCRtpScriptTransformer
: public RefCounted<RTCRtpScriptTransformer>
@@ -59,7 +59,7 @@
private:
RTCRtpScriptTransformer(ScriptExecutionContext&, Ref<MessagePort>&&);
- RefPtr<RTCRtpReadableStreamSource> startStreams(RTCRtpTransformBackend&);
+ RefPtr<SimpleReadableStreamSource> startStreams(RTCRtpTransformBackend&);
// ActiveDOMObject
const char* activeDOMObjectName() const { return "RTCRtpScriptTransformer"; }
Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpTransformBackend.h (270289 => 270290)
--- trunk/Source/WebCore/Modules/mediastream/RTCRtpTransformBackend.h 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpTransformBackend.h 2020-12-01 09:43:00 UTC (rev 270290)
@@ -36,15 +36,15 @@
public:
virtual ~RTCRtpTransformBackend() = default;
- using Callback = Function<void(UniqueRef<RTCRtpTransformableFrame>&&)>;
+ using Callback = Function<void(Ref<RTCRtpTransformableFrame>&&)>;
virtual void setTransformableFrameCallback(Callback&&) = 0;
virtual void clearTransformableFrameCallback() = 0;
- virtual void processTransformedFrame(RTCRtpTransformableFrame&&) = 0;
+ virtual void processTransformedFrame(RTCRtpTransformableFrame&) = 0;
enum class MediaType { Audio, Video };
virtual MediaType mediaType() const = 0;
- enum class Side { Sender, Receiver };
+ enum class Side { Receiver, Sender };
virtual Side side() const = 0;
};
Modified: trunk/Source/WebCore/Modules/mediastream/RTCRtpTransformableFrame.h (270289 => 270290)
--- trunk/Source/WebCore/Modules/mediastream/RTCRtpTransformableFrame.h 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Modules/mediastream/RTCRtpTransformableFrame.h 2020-12-01 09:43:00 UTC (rev 270290)
@@ -26,16 +26,17 @@
#if ENABLE(WEB_RTC)
+#include <wtf/RefCounted.h>
+
namespace WebCore {
-class RTCRtpTransformableFrame {
- WTF_MAKE_FAST_ALLOCATED;
+class RTCRtpTransformableFrame : public RefCounted<RTCRtpTransformableFrame> {
public:
virtual ~RTCRtpTransformableFrame() = default;
struct Data {
- const uint8_t* data;
- size_t size;
+ const uint8_t* data { nullptr };
+ size_t size { 0 };
};
virtual Data data() const = 0;
virtual void setData(Data) = 0;
Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderTransformBackend.cpp (270289 => 270290)
--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderTransformBackend.cpp 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderTransformBackend.cpp 2020-12-01 09:43:00 UTC (rev 270290)
@@ -52,7 +52,6 @@
m_rtcSender->SetEncoderToPacketizerFrameTransformer(this);
}
-
} // namespace WebCore
#endif // ENABLE(WEB_RTC) && USE(LIBWEBRTC)
Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpTransformBackend.cpp (270289 => 270290)
--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpTransformBackend.cpp 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpTransformBackend.cpp 2020-12-01 09:43:00 UTC (rev 270290)
@@ -28,7 +28,6 @@
#if ENABLE(WEB_RTC) && USE(LIBWEBRTC)
#include "LibWebRTCRtpTransformableFrame.h"
-#include <wtf/UniqueRef.h>
namespace WebCore {
@@ -49,11 +48,11 @@
m_outputCallback = WTFMove(callback);
}
-void LibWebRTCRtpTransformBackend::processTransformedFrame(RTCRtpTransformableFrame&& frame)
+void LibWebRTCRtpTransformBackend::processTransformedFrame(RTCRtpTransformableFrame& frame)
{
auto locker = holdLock(m_outputCallbackLock);
if (m_outputCallback)
- m_outputCallback->OnTransformedFrame(LibWebRTCRtpTransformableFrame::toRTCFrame(WTFMove(static_cast<LibWebRTCRtpTransformableFrame&>(frame))));
+ m_outputCallback->OnTransformedFrame(static_cast<LibWebRTCRtpTransformableFrame&>(frame).takeRTCFrame());
}
void LibWebRTCRtpTransformBackend::Transform(std::unique_ptr<webrtc::TransformableFrameInterface> rtcFrame)
@@ -61,7 +60,7 @@
{
auto locker = holdLock(m_inputCallbackLock);
if (m_inputCallback) {
- m_inputCallback(makeUniqueRef<LibWebRTCRtpTransformableFrame>(WTFMove(rtcFrame)));
+ m_inputCallback(LibWebRTCRtpTransformableFrame::create(WTFMove(rtcFrame)));
return;
}
}
Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpTransformBackend.h (270289 => 270290)
--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpTransformBackend.h 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpTransformBackend.h 2020-12-01 09:43:00 UTC (rev 270290)
@@ -46,13 +46,15 @@
LibWebRTCRtpTransformBackend(MediaType, Side);
void setInputCallback(Callback&&);
+protected:
+ MediaType mediaType() const final { return m_mediaType; }
+
private:
void setOutputCallback(rtc::scoped_refptr<webrtc::TransformedFrameCallback>&&);
// RTCRtpTransformBackend
- void processTransformedFrame(RTCRtpTransformableFrame&&) final;
+ void processTransformedFrame(RTCRtpTransformableFrame&) final;
void clearTransformableFrameCallback() final;
- MediaType mediaType() const final { return m_mediaType; }
Side side() const final { return m_side; }
// webrtc::FrameTransformerInterface
Copied: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpTransformableFrame.cpp (from rev 270289, trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderTransformBackend.cpp) (0 => 270290)
--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpTransformableFrame.cpp (rev 0)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpTransformableFrame.cpp 2020-12-01 09:43:00 UTC (rev 270290)
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2020 Apple Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "LibWebRTCRtpTransformableFrame.h"
+
+#if ENABLE(WEB_RTC) && USE(LIBWEBRTC)
+
+ALLOW_UNUSED_PARAMETERS_BEGIN
+ALLOW_DEPRECATED_DECLARATIONS_BEGIN
+
+#include <webrtc/api/frame_transformer_interface.h>
+
+ALLOW_DEPRECATED_DECLARATIONS_END
+ALLOW_UNUSED_PARAMETERS_END
+
+namespace WebCore {
+
+LibWebRTCRtpTransformableFrame::LibWebRTCRtpTransformableFrame(std::unique_ptr<webrtc::TransformableFrameInterface>&& frame)
+ : m_rtcFrame(WTFMove(frame))
+{
+}
+
+LibWebRTCRtpTransformableFrame::~LibWebRTCRtpTransformableFrame()
+{
+}
+
+std::unique_ptr<webrtc::TransformableFrameInterface> LibWebRTCRtpTransformableFrame::takeRTCFrame()
+{
+ return WTFMove(m_rtcFrame);
+}
+
+RTCRtpTransformableFrame::Data LibWebRTCRtpTransformableFrame::data() const
+{
+ if (!m_rtcFrame)
+ return { nullptr, 0 };
+ auto data = ""
+ return { data.begin(), data.size() };
+}
+
+void LibWebRTCRtpTransformableFrame::setData(Data data)
+{
+ if (m_rtcFrame)
+ m_rtcFrame->SetData({ data.data, data.size });
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC) && USE(LIBWEBRTC)
Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpTransformableFrame.h (270289 => 270290)
--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpTransformableFrame.h 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpTransformableFrame.h 2020-12-01 09:43:00 UTC (rev 270290)
@@ -27,40 +27,31 @@
#if ENABLE(WEB_RTC)
#include "RTCRtpTransformableFrame.h"
+#include <wtf/Ref.h>
+namespace webrtc {
+class TransformableFrameInterface;
+}
+
namespace WebCore {
class LibWebRTCRtpTransformableFrame final : public RTCRtpTransformableFrame {
WTF_MAKE_FAST_ALLOCATED;
public:
- explicit LibWebRTCRtpTransformableFrame(std::unique_ptr<webrtc::TransformableFrameInterface>&&);
- virtual ~LibWebRTCRtpTransformableFrame() = default;
+ static Ref<LibWebRTCRtpTransformableFrame> create(std::unique_ptr<webrtc::TransformableFrameInterface>&& frame) { return adoptRef(*new LibWebRTCRtpTransformableFrame(WTFMove(frame))); }
+ ~LibWebRTCRtpTransformableFrame();
- static std::unique_ptr<webrtc::TransformableFrameInterface> toRTCFrame(LibWebRTCRtpTransformableFrame&&);
+ std::unique_ptr<webrtc::TransformableFrameInterface> takeRTCFrame();
private:
+ explicit LibWebRTCRtpTransformableFrame(std::unique_ptr<webrtc::TransformableFrameInterface>&&);
+
Data data() const final;
- void setData(Data data) final { m_rtcFrame->SetData({ data.data, data.size }); }
+ void setData(Data) final;
std::unique_ptr<webrtc::TransformableFrameInterface> m_rtcFrame;
};
-inline LibWebRTCRtpTransformableFrame::LibWebRTCRtpTransformableFrame(std::unique_ptr<webrtc::TransformableFrameInterface>&& frame)
- : m_rtcFrame(WTFMove(frame))
-{
-}
-
-inline std::unique_ptr<webrtc::TransformableFrameInterface> LibWebRTCRtpTransformableFrame::toRTCFrame(LibWebRTCRtpTransformableFrame&& frame)
-{
- return WTFMove(frame.m_rtcFrame);
-}
-
-inline RTCRtpTransformableFrame::Data LibWebRTCRtpTransformableFrame::data() const
-{
- auto data = ""
- return { data.begin(), data.size() };
-}
-
} // namespace WebCore
#endif // ENABLE(WEB_RTC)
Modified: trunk/Source/WebCore/Modules/streams/ReadableStreamSource.cpp (270289 => 270290)
--- trunk/Source/WebCore/Modules/streams/ReadableStreamSource.cpp 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Modules/streams/ReadableStreamSource.cpp 2020-12-01 09:43:00 UTC (rev 270290)
@@ -27,8 +27,6 @@
#include "config.h"
#include "ReadableStreamSource.h"
-#include "JSDOMPromiseDeferred.h"
-
namespace WebCore {
ReadableStreamSource::~ReadableStreamSource() = default;
Modified: trunk/Source/WebCore/Modules/streams/ReadableStreamSource.h (270289 => 270290)
--- trunk/Source/WebCore/Modules/streams/ReadableStreamSource.h 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Modules/streams/ReadableStreamSource.h 2020-12-01 09:43:00 UTC (rev 270290)
@@ -28,13 +28,13 @@
#pragma once
+#include "JSDOMPromiseDeferred.h"
#include "ReadableStreamDefaultController.h"
#include <wtf/Optional.h>
+#include <wtf/WeakPtr.h>
namespace WebCore {
-template<typename IDLType> class DOMPromiseDeferred;
-
class ReadableStreamSource : public RefCounted<ReadableStreamSource> {
public:
virtual ~ReadableStreamSource();
@@ -66,4 +66,24 @@
Optional<ReadableStreamDefaultController> m_controller;
};
+class SimpleReadableStreamSource
+ : public ReadableStreamSource
+ , public CanMakeWeakPtr<SimpleReadableStreamSource> {
+public:
+ static Ref<SimpleReadableStreamSource> create() { return adoptRef(*new SimpleReadableStreamSource); }
+
+ void close() { controller().close(); }
+ void enqueue(JSC::JSValue value) { controller().enqueue(value); }
+
+private:
+ SimpleReadableStreamSource() = default;
+
+ // ReadableStreamSource
+ void setActive() final { }
+ void setInactive() final { }
+ void doStart() final { }
+ void doPull() final { }
+ void doCancel() final { }
+};
+
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/streams/WritableStreamSink.h (270289 => 270290)
--- trunk/Source/WebCore/Modules/streams/WritableStreamSink.h 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Modules/streams/WritableStreamSink.h 2020-12-01 09:43:00 UTC (rev 270290)
@@ -45,4 +45,29 @@
virtual void error(String&&) = 0;
};
+class SimpleWritableStreamSink : public WritableStreamSink {
+public:
+ using WriteCallback = Function<ExceptionOr<void>(ScriptExecutionContext&, JSC::JSValue)>;
+ static Ref<SimpleWritableStreamSink> create(WriteCallback&& writeCallback) { return adoptRef(*new SimpleWritableStreamSink(WTFMove(writeCallback))); }
+
+private:
+ explicit SimpleWritableStreamSink(WriteCallback&&);
+
+ void write(ScriptExecutionContext&, JSC::JSValue, DOMPromiseDeferred<void>&&) final;
+ void close() final { }
+ void error(String&&) final { }
+
+ WriteCallback m_writeCallback;
+};
+
+inline SimpleWritableStreamSink::SimpleWritableStreamSink(WriteCallback&& writeCallback)
+ : m_writeCallback(WTFMove(writeCallback))
+{
+}
+
+inline void SimpleWritableStreamSink::write(ScriptExecutionContext& context, JSC::JSValue value, DOMPromiseDeferred<void>&& promise)
+{
+ promise.settle(m_writeCallback(context, value));
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/Sources.txt (270289 => 270290)
--- trunk/Source/WebCore/Sources.txt 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/Sources.txt 2020-12-01 09:43:00 UTC (rev 270290)
@@ -182,6 +182,7 @@
Modules/mediastream/libwebrtc/LibWebRTCRtpReceiverTransformBackend.cpp
Modules/mediastream/libwebrtc/LibWebRTCRtpSenderTransformBackend.cpp
Modules/mediastream/libwebrtc/LibWebRTCRtpTransformBackend.cpp
+Modules/mediastream/libwebrtc/LibWebRTCRtpTransformableFrame.cpp
Modules/model-element/HTMLModelElement.cpp
Modules/notifications/Notification.cpp
Modules/notifications/NotificationController.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (270289 => 270290)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2020-12-01 09:43:00 UTC (rev 270290)
@@ -7537,6 +7537,7 @@
410A8EF824F8F47A004F9070 /* TextEncoderStreamEncoder.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TextEncoderStreamEncoder.cpp; sourceTree = "<group>"; };
410A8EF924F8F47B004F9070 /* TextEncoderStreamEncoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TextEncoderStreamEncoder.h; sourceTree = "<group>"; };
410B7E711045FAB000D8224F /* JSMessageEventCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMessageEventCustom.cpp; sourceTree = "<group>"; };
+ 410BA1312570FE57002E2F8A /* LibWebRTCRtpTransformableFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibWebRTCRtpTransformableFrame.cpp; path = libwebrtc/LibWebRTCRtpTransformableFrame.cpp; sourceTree = "<group>"; };
410E445F234373AD000173D4 /* LibWebRTCSocketIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LibWebRTCSocketIdentifier.h; path = libwebrtc/LibWebRTCSocketIdentifier.h; sourceTree = "<group>"; };
410F565524FCF70500A2E50C /* RTCSessionDescriptionInit.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = RTCSessionDescriptionInit.idl; sourceTree = "<group>"; };
410F565724FCF7C700A2E50C /* RTCIceCandidateInit.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = RTCIceCandidateInit.idl; sourceTree = "<group>"; };
@@ -19285,6 +19286,7 @@
4181C5BE2553EB6E00AEB0FF /* LibWebRTCRtpSenderTransformBackend.h */,
4186BD4D2140B9E80001826F /* LibWebRTCRtpTransceiverBackend.cpp */,
4186BD4B2140A8050001826F /* LibWebRTCRtpTransceiverBackend.h */,
+ 410BA1312570FE57002E2F8A /* LibWebRTCRtpTransformableFrame.cpp */,
4181C5CC2555836800AEB0FF /* LibWebRTCRtpTransformableFrame.h */,
4181C5CE2555895500AEB0FF /* LibWebRTCRtpTransformBackend.cpp */,
4181C5CF2555895600AEB0FF /* LibWebRTCRtpTransformBackend.h */,
Modified: trunk/Source/WebCore/bindings/js/WritableStream.cpp (270289 => 270290)
--- trunk/Source/WebCore/bindings/js/WritableStream.cpp 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/bindings/js/WritableStream.cpp 2020-12-01 09:43:00 UTC (rev 270290)
@@ -36,6 +36,30 @@
namespace WebCore {
using namespace JSC;
+namespace WritableStreamInternal {
+static inline JSC::JSValue callFunction(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue jsFunction, JSC::JSValue thisValue, const JSC::ArgList& arguments)
+{
+ VM& vm = lexicalGlobalObject.vm();
+ auto scope = DECLARE_CATCH_SCOPE(vm);
+ auto callData = JSC::getCallData(vm, jsFunction);
+ ASSERT(callData.type != JSC::CallData::Type::None);
+ auto result = call(&lexicalGlobalObject, jsFunction, callData, thisValue, arguments);
+ scope.assertNoException();
+ return result;
+}
+}
+
+static inline bool checkWritableStream(JSDOMGlobalObject& globalObject, JSWritableStream* writableStream, JSC::JSValue function)
+{
+ auto& lexicalGlobalObject = globalObject;
+
+ ASSERT(function);
+ JSC::MarkedArgumentBuffer arguments;
+ arguments.append(writableStream);
+ ASSERT(!arguments.hasOverflowed());
+ return WritableStreamInternal::callFunction(lexicalGlobalObject, function, JSC::jsUndefined(), arguments).isTrue();
+}
+
ExceptionOr<Ref<WritableStream>> WritableStream::create(JSC::JSGlobalObject& lexicalGlobalObject, RefPtr<WritableStreamSink>&& sink)
{
VM& vm = lexicalGlobalObject.vm();
@@ -60,4 +84,30 @@
return create(globalObject, *jsCast<JSWritableStream*>(object));
}
+void WritableStream::lock()
+{
+ auto& lexicalGlobalObject = *m_globalObject;
+ VM& vm = lexicalGlobalObject.vm();
+ auto scope = DECLARE_CATCH_SCOPE(vm);
+
+ auto& clientData = *static_cast<JSVMClientData*>(vm.clientData);
+
+ auto* constructor = JSC::asObject(m_globalObject->get(&lexicalGlobalObject, clientData.builtinNames().WritableStreamDefaultWriterPrivateName()));
+
+ auto constructData = getConstructData(vm, constructor);
+ ASSERT(constructData.type != CallData::Type::None);
+
+ MarkedArgumentBuffer args;
+ args.append(writableStream());
+ ASSERT(!args.hasOverflowed());
+
+ JSC::construct(&lexicalGlobalObject, constructor, constructData, args);
+ scope.assertNoException();
}
+
+bool WritableStream::isLocked() const
+{
+ return checkWritableStream(*globalObject(), writableStream(), globalObject()->builtinInternalFunctions().writableStreamInternals().m_isWritableStreamLockedFunction.get());
+}
+
+}
Modified: trunk/Source/WebCore/bindings/js/WritableStream.h (270289 => 270290)
--- trunk/Source/WebCore/bindings/js/WritableStream.h 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/bindings/js/WritableStream.h 2020-12-01 09:43:00 UTC (rev 270290)
@@ -42,6 +42,9 @@
static ExceptionOr<Ref<WritableStream>> create(JSC::JSGlobalObject&, RefPtr<WritableStreamSink>&&);
JSWritableStream* writableStream() const { return guarded(); }
+ void lock();
+ bool isLocked() const;
+
private:
WritableStream(JSDOMGlobalObject&, JSWritableStream&);
};
Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (270289 => 270290)
--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm 2020-12-01 09:43:00 UTC (rev 270290)
@@ -638,6 +638,11 @@
return;
}
+ if ($type->name eq "WritableStream") {
+ AddToIncludes("WritableStream.h", $includesRef, $conditional);
+ return;
+ }
+
if ($type->name eq "XPathNSResolver") {
AddToIncludes("JSXPathNSResolver.h", $includesRef, $conditional);
AddToIncludes("JSDOMConvertXPathNSResolver.h", $includesRef, $conditional);
Modified: trunk/Tools/ChangeLog (270289 => 270290)
--- trunk/Tools/ChangeLog 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Tools/ChangeLog 2020-12-01 09:43:00 UTC (rev 270290)
@@ -1,3 +1,13 @@
+2020-12-01 Youenn Fablet <[email protected]>
+
+ Add support for readable/writable to RTCRtpSFrameTransform
+ https://bugs.webkit.org/show_bug.cgi?id=219298
+
+ Reviewed by Eric Carlson.
+
+ * TestWebKitAPI/Tests/WebCore/RTCRtpSFrameTransformerTests.cpp:
+ (TestWebKitAPI::createVideoTransformer):
+
2020-11-30 Wenson Hsieh <[email protected]>
check-webkit-style should allow WebKitAdditions headers to appear after soft linking headers
Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/RTCRtpSFrameTransformerTests.cpp (270289 => 270290)
--- trunk/Tools/TestWebKitAPI/Tests/WebCore/RTCRtpSFrameTransformerTests.cpp 2020-12-01 09:31:22 UTC (rev 270289)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/RTCRtpSFrameTransformerTests.cpp 2020-12-01 09:43:00 UTC (rev 270290)
@@ -70,11 +70,11 @@
);
}
-static Ref<WebCore::RTCRtpSFrameTransformer> createVideoTransformer(bool isSending = true)
+static Ref<WebCore::RTCRtpSFrameTransformer> createVideoTransformer(bool isEncrypting = true)
{
auto transformer = WebCore::RTCRtpSFrameTransformer::create();
- transformer->setIsSending(isSending);
- transformer->setIsProcessingAudio(false);
+ transformer->setIsEncrypting(isEncrypting);
+ transformer->setAuthenticationSize(10);
auto keyId = Vector<uint8_t>::from(198, 31, 251, 197, 48, 139, 91, 51);
uint64_t keyIdValue = 0;