Repository: WebKit/WebKit
Pull request #43641: RTcRtpScriptTransformer.generateKeyFrame can take a rid parameter
Author: login: youennf
Labels: name: WebRTC
description: For bugs in WebRTC
Created: 2025-04-04T14:29:24Z | Merged: 2025-04-12T19:47:34Z

#### a24b100fb04d585bfea2ff5b972e44fc3e63951d
<pre>
RTcRtpScriptTransformer.generateKeyFrame can take a rid parameter
<a href="https://rdar.apple.com/148592676">rdar://148592676</a>
<a href="https://bugs.webkit.org/show_bug.cgi?id=291082">https://bugs.webkit.org/show_bug.cgi?id=291082</a>

Reviewed by Eric Carlson.

The spec allows passing rid as a parameter.
We implement this and pass the rid value, after validation to the libwebrtc engine.
We reject with NotAllowedError to match WPT and Firefox, not the spec.
A follow-up might change this.

We should also resolve the promise based on key frames for that particular rid.
A follow-up will fix this.

* LayoutTests/imported/w3c/web-platform-tests/webrtc-encoded-transform/script-transform-generateKeyFrame.https-expected.txt:
* Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.cpp:
(WebCore::RTCRtpScriptTransformer::enqueueFrame):
(WebCore::validateRid):
(WebCore::RTCRtpScriptTransformer::generateKeyFrame):
(WebCore::RTCRtpScriptTransformer::sendKeyFrameRequest):
* Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.h:
* Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.idl:
* Source/WebCore/Modules/mediastream/RTCRtpTransformBackend.h:
* Source/WebCore/Modules/mediastream/gstreamer/GStreamerRtpReceiverTransformBackend.cpp:
(WebCore::GStreamerRtpReceiverTransformBackend::requestKeyFrame):
* Source/WebCore/Modules/mediastream/gstreamer/GStreamerRtpReceiverTransformBackend.h:
* Source/WebCore/Modules/mediastream/gstreamer/GStreamerRtpSenderTransformBackend.cpp:
(WebCore::GStreamerRtpSenderTransformBackend::requestKeyFrame):
* Source/WebCore/Modules/mediastream/gstreamer/GStreamerRtpSenderTransformBackend.h:
* Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpReceiverTransformBackend.cpp:
(WebCore::LibWebRTCRtpReceiverTransformBackend::requestKeyFrame):
* Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpReceiverTransformBackend.h:
* Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderTransformBackend.cpp:
(WebCore::LibWebRTCRtpSenderTransformBackend::requestKeyFrame):
* Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderTransformBackend.h:

Canonical link: <a href="https://commits.webkit.org/293633@main">https://commits.webkit.org/293633@main</a>
</pre>
<!--EWS-Status-Bubble-Start-->
https://github.com/WebKit/WebKit/commit/4000cd4466351a3047c88891b8201dad0545501b

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [✅ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/99460 "Passed style check") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/19110 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/9363 "Built successfully") | [✅ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/104591 "Built successfully") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/50062 "Built successfully") 
| [✅ 🧪 bindings](https://ews-build.webkit.org/#/builders/9/builds/101501 "Passed tests") | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/19398 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/27543 "Built successfully") | [✅ 🧪 wpe-wk2](https://ews-build.webkit.org/#/builders/34/builds/75702 "Passed tests") | [✅ 🧪 win-tests](https://ews-build.webkit.org/#/builders/60/builds/32803 "Passed tests") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/102467 "Passed tests") | [✅ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/132/builds/14765 "Passed tests") | [✅ 🧪 api-mac](https://ews-build.webkit.org/#/builders/18/builds/89807 "Passed tests") | [✅ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/41/builds/56061 "Passed tests") | 
| | [✅ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/133/builds/14561 "Passed tests") | [✅ 🧪 mac-wk1](https://ews-build.webkit.org/#/builders/135/builds/7790 "Passed tests") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/49421 "Built successfully") | 
| | [✅ 🧪 api-ios](https://ews-build.webkit.org/#/builders/13/builds/84485 "Passed tests") | [✅ 🧪 mac-wk2](https://ews-build.webkit.org/#/builders/136/builds/7878 "Passed tests") | [✅ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/106949 "Built successfully") | 
| | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/26574 "Built successfully") | [  ~~🧪 mac-AS-debug-wk2~~](https://ews-build.webkit.org/#/builders/122/builds/19389 "The change is no longer eligible for processing. Pull Request was already closed when EWS attempted to process it.") | [✅ 🧪 gtk-wk2](https://ews-build.webkit.org/#/builders/1/builds/84659 "Passed tests") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/26936 "Built successfully") | [✅ 🧪 mac-wk2-stress](https://ews-build.webkit.org/#/builders/8/builds/86011 "Passed tests") | [✅ 🧪 api-gtk](https://ews-build.webkit.org/#/builders/21/builds/84177 "Passed tests") | 
| [✅ 🛠 🧪 merge](https://ews-build.webkit.org/#/builders/19/builds/21356 "Built successfully and passed tests") | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/28851 "Passed tests") | [✅ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/137/builds/6547 "Passed tests") | [✅ 🛠 playstation](https://ews-build.webkit.org/#/builders/134/builds/20342 "Built successfully") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/26514 "Built successfully") | [✅ 🛠 mac-safer-cpp](https://ews-build.webkit.org/#/builders/120/builds/31715 "Built successfully") | | 
| | [✅ 🛠 tv-sim](https://ews-build.webkit.org/#/builders/125/builds/26334 "Built successfully") | | | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/29647 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/27901 "Built successfully") | | | 
<!--EWS-Status-Bubble-End-->


Diff:
diff --git a/LayoutTests/imported/w3c/web-platform-tests/webrtc-encoded-transform/script-transform-generateKeyFrame.https-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/webrtc-encoded-transform/script-transform-generateKeyFrame.https-expected.txt
index 16d7d27704c1..cc6d8d010c37 100644
--- a/LayoutTests/imported/w3c/web-platform-tests/webrtc-encoded-transform/script-transform-generateKeyFrame.https-expected.txt
+++ b/LayoutTests/imported/w3c/web-platform-tests/webrtc-encoded-transform/script-transform-generateKeyFrame.https-expected.txt
@@ -2,8 +2,8 @@
 
 PASS generateKeyFrame() throws for audio
 PASS generateKeyFrame(null) resolves for video sender, and throws for video receiver
-FAIL generateKeyFrame throws NotAllowedError for invalid rid assert_equals: expected "failure" but got "success"
-FAIL generateKeyFrame throws NotFoundError for unknown rid assert_equals: expected "failure" but got "success"
+PASS generateKeyFrame throws NotAllowedError for invalid rid
+PASS generateKeyFrame throws NotFoundError for unknown rid
 PASS generateKeyFrame throws for unset transforms
 PASS generateKeyFrame timestamp should advance
 PASS await generateKeyFrame, await generateKeyFrame should see an increase in count of keyframes
diff --git a/Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.cpp b/Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.cpp
index 6c95305df375..75eb87726380 100644
--- a/Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.cpp
+++ b/Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.cpp
@@ -171,6 +171,7 @@ void RTCRtpScriptTransformer::enqueueFrame(ScriptExecutionContext& context, Ref<
 
     bool isVideo = m_backend->mediaType() == RTCRtpTransformBackend::MediaType::Video;
     if (isVideo && !m_pendingKeyFramePromises.isEmpty() && frame->isKeyFrame()) {
+        // FIXME: We should take into account rids to resolve promises.
         for (auto& promise : std::exchange(m_pendingKeyFramePromises, { }))
             promise->resolve<IDLUnsignedLongLong>(frame->timestamp());
     }
@@ -190,7 +191,28 @@ void RTCRtpScriptTransformer::enqueueFrame(ScriptExecutionContext& context, Ref<
     m_readableSource->enqueue(value);
 }
 
-void RTCRtpScriptTransformer::generateKeyFrame(Ref<DeferredPromise>&& promise)
+static std::optional<Exception> validateRid(const String& rid)
+{
+    if (rid.isNull())
+        return { };
+
+    if (rid.isEmpty())
+        return Exception { ExceptionCode::NotAllowedError, "rid is empty"_s };
+
+    constexpr unsigned maxRidLength = 255;
+    if (rid.length() > maxRidLength)
+        return Exception { ExceptionCode::NotAllowedError, "rid is too long"_s };
+
+    auto foundBadCharacters = rid.find([](auto character) -> bool {
+        return !isASCIIDigit(character) && !isASCIIAlpha(character);
+    });
+    if (foundBadCharacters != notFound)
+        return Exception { ExceptionCode::NotAllowedError, "rid has a character that is not alpha numeric"_s };
+
+    return { };
+}
+
+void RTCRtpScriptTransformer::generateKeyFrame(const String& rid, Ref<DeferredPromise>&& promise)
 {
     RefPtr context = scriptExecutionContext();
     if (!context || !m_backend || m_backend->side() != RTCRtpTransformBackend::Side::Sender || m_backend->mediaType() != RTCRtpTransformBackend::MediaType::Video) {
@@ -198,10 +220,19 @@ void RTCRtpScriptTransformer::generateKeyFrame(Ref<DeferredPromise>&& promise)
         return;
     }
 
-    bool shouldRequestKeyFrame = m_pendingKeyFramePromises.isEmpty();
+    if (auto exception = validateRid(rid)) {
+        promise->reject(WTFMove(*exception));
+        return;
+    }
+
+    if (!m_backend->requestKeyFrame(rid)) {
+        context->eventLoop().queueTask(TaskSource::Networking, [promise = WTFMove(promise)]() mutable {
+            promise->reject(Exception { ExceptionCode::NotFoundError, "rid was not found or is empty"_s });
+        });
+        return;
+    }
+
     m_pendingKeyFramePromises.append(WTFMove(promise));
-    if (shouldRequestKeyFrame)
-        m_backend->requestKeyFrame();
 }
 
 void RTCRtpScriptTransformer::sendKeyFrameRequest(Ref<DeferredPromise>&& promise)
@@ -213,7 +244,7 @@ void RTCRtpScriptTransformer::sendKeyFrameRequest(Ref<DeferredPromise>&& promise
     }
 
     // FIXME: We should be able to know when the FIR request is sent to resolve the promise at this exact time.
-    m_backend->requestKeyFrame();
+    m_backend->requestKeyFrame({ });
 
     context->eventLoop().queueTask(TaskSource::Networking, [promise = WTFMove(promise)]() mutable {
         promise->resolve();
diff --git a/Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.h b/Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.h
index beb44d680b3a..303223cd66ca 100644
--- a/Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.h
+++ b/Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.h
@@ -68,7 +68,7 @@ class RTCRtpScriptTransformer
     ExceptionOr<Ref<WritableStream>> writable();
     JSC::JSValue options(JSC::JSGlobalObject&);
 
-    void generateKeyFrame(Ref<DeferredPromise>&&);
+    void generateKeyFrame(const String&, Ref<DeferredPromise>&&);
     void sendKeyFrameRequest(Ref<DeferredPromise>&&);
 
     void startPendingActivity() { m_pendingActivity = makePendingActivity(*this); }
diff --git a/Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.idl b/Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.idl
index 9cefcdfacaf2..875c315254d2 100644
--- a/Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.idl
+++ b/Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.idl
@@ -35,6 +35,6 @@
     [CallWith=CurrentGlobalObject, CachedAttribute] readonly attribute any options;
 
     // FIXME: Add support for RID options.
-    Promise<unsigned long long> generateKeyFrame();
+    Promise<unsigned long long> generateKeyFrame(optional DOMString rid);
     Promise<undefined> sendKeyFrameRequest();
 };
diff --git a/Source/WebCore/Modules/mediastream/RTCRtpTransformBackend.h b/Source/WebCore/Modules/mediastream/RTCRtpTransformBackend.h
index 4807f787a0ec..9351b978eada 100644
--- a/Source/WebCore/Modules/mediastream/RTCRtpTransformBackend.h
+++ b/Source/WebCore/Modules/mediastream/RTCRtpTransformBackend.h
@@ -30,6 +30,7 @@
 
 namespace WebCore {
 
+class Exception;
 class RTCRtpTransformableFrame;
 
 class RTCRtpTransformBackend : public ThreadSafeRefCounted<RTCRtpTransformBackend, WTF::DestructionThread::Main> {
@@ -47,7 +48,7 @@ class RTCRtpTransformBackend : public ThreadSafeRefCounted<RTCRtpTransformBacken
     enum class Side { Receiver, Sender };
     virtual Side side() const = 0;
 
-    virtual void requestKeyFrame() = 0;
+    virtual bool requestKeyFrame(const String&) = 0;
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/Modules/mediastream/gstreamer/GStreamerRtpReceiverTransformBackend.cpp b/Source/WebCore/Modules/mediastream/gstreamer/GStreamerRtpReceiverTransformBackend.cpp
index e29082feca4d..f0bfee95cb2a 100644
--- a/Source/WebCore/Modules/mediastream/gstreamer/GStreamerRtpReceiverTransformBackend.cpp
+++ b/Source/WebCore/Modules/mediastream/gstreamer/GStreamerRtpReceiverTransformBackend.cpp
@@ -48,10 +48,11 @@ void GStreamerRtpReceiverTransformBackend::setTransformableFrameCallback(Callbac
     notImplemented();
 }
 
-void GStreamerRtpReceiverTransformBackend::requestKeyFrame()
+bool GStreamerRtpReceiverTransformBackend::requestKeyFrame(const String&)
 {
     ASSERT(mediaType() == MediaType::Video);
     notImplemented();
+    return true;
 }
 
 } // namespace WebCore
diff --git a/Source/WebCore/Modules/mediastream/gstreamer/GStreamerRtpReceiverTransformBackend.h b/Source/WebCore/Modules/mediastream/gstreamer/GStreamerRtpReceiverTransformBackend.h
index 8586676a06b7..f96503a7d9a9 100644
--- a/Source/WebCore/Modules/mediastream/gstreamer/GStreamerRtpReceiverTransformBackend.h
+++ b/Source/WebCore/Modules/mediastream/gstreamer/GStreamerRtpReceiverTransformBackend.h
@@ -38,7 +38,7 @@ class GStreamerRtpReceiverTransformBackend final : public GStreamerRtpTransformB
 
     // RTCRtpTransformBackend
     void setTransformableFrameCallback(Callback&&) final;
-    void requestKeyFrame() final;
+    bool requestKeyFrame(const String&) final;
 
     GRefPtr<GstWebRTCRTPReceiver> m_rtcReceiver;
 };
diff --git a/Source/WebCore/Modules/mediastream/gstreamer/GStreamerRtpSenderTransformBackend.cpp b/Source/WebCore/Modules/mediastream/gstreamer/GStreamerRtpSenderTransformBackend.cpp
index 4716ecbdd560..945f27cb4008 100644
--- a/Source/WebCore/Modules/mediastream/gstreamer/GStreamerRtpSenderTransformBackend.cpp
+++ b/Source/WebCore/Modules/mediastream/gstreamer/GStreamerRtpSenderTransformBackend.cpp
@@ -51,10 +51,11 @@ void GStreamerRtpSenderTransformBackend::setTransformableFrameCallback(Callback&
     notImplemented();
 }
 
-void GStreamerRtpSenderTransformBackend::requestKeyFrame()
+bool GStreamerRtpSenderTransformBackend::requestKeyFrame(const String&)
 {
     ASSERT(mediaType() == MediaType::Video);
     notImplemented();
+    return true;
 }
 
 } // namespace WebCore
diff --git a/Source/WebCore/Modules/mediastream/gstreamer/GStreamerRtpSenderTransformBackend.h b/Source/WebCore/Modules/mediastream/gstreamer/GStreamerRtpSenderTransformBackend.h
index 5873ec5520d7..9df4f16f3bf6 100644
--- a/Source/WebCore/Modules/mediastream/gstreamer/GStreamerRtpSenderTransformBackend.h
+++ b/Source/WebCore/Modules/mediastream/gstreamer/GStreamerRtpSenderTransformBackend.h
@@ -42,7 +42,7 @@ class GStreamerRtpSenderTransformBackend final : public GStreamerRtpTransformBac
 
     // RTCRtpTransformBackend
     void setTransformableFrameCallback(Callback&&) final;
-    void requestKeyFrame() final;
+    bool requestKeyFrame(const String&) final;
 
     GRefPtr<GstWebRTCRTPSender> m_rtcSender;
 };
diff --git a/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpReceiverTransformBackend.cpp b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpReceiverTransformBackend.cpp
index 1440ca9594e7..91774745302b 100644
--- a/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpReceiverTransformBackend.cpp
+++ b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpReceiverTransformBackend.cpp
@@ -56,10 +56,12 @@ void LibWebRTCRtpReceiverTransformBackend::setTransformableFrameCallback(Callbac
     m_rtcReceiver->SetDepacketizerToDecoderFrameTransformer(rtc::scoped_refptr<webrtc::FrameTransformerInterface>(this));
 }
 
-void LibWebRTCRtpReceiverTransformBackend::requestKeyFrame()
+bool LibWebRTCRtpReceiverTransformBackend::requestKeyFrame(const String& rid)
 {
     ASSERT(mediaType() == MediaType::Video);
+    ASSERT_UNUSED(rid, rid.isEmpty());
     m_rtcReceiver->GenerateKeyFrame();
+    return true;
 }
 
 } // namespace WebCore
diff --git a/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpReceiverTransformBackend.h b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpReceiverTransformBackend.h
index 770ac1c1c141..8c7165b5af43 100644
--- a/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpReceiverTransformBackend.h
+++ b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpReceiverTransformBackend.h
@@ -53,7 +53,7 @@ class LibWebRTCRtpReceiverTransformBackend final : public LibWebRTCRtpTransformB
 
     // RTCRtpTransformBackend
     void setTransformableFrameCallback(Callback&&) final;
-    void requestKeyFrame() final;
+    bool requestKeyFrame(const String&) final;
 
     bool m_isRegistered { false };
     rtc::scoped_refptr<webrtc::RtpReceiverInterface> m_rtcReceiver;
diff --git a/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderTransformBackend.cpp b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderTransformBackend.cpp
index 4195cf4395d6..0d600721c200 100644
--- a/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderTransformBackend.cpp
+++ b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderTransformBackend.cpp
@@ -59,10 +59,13 @@ void LibWebRTCRtpSenderTransformBackend::setTransformableFrameCallback(Callback&
     m_rtcSender->SetEncoderToPacketizerFrameTransformer(rtc::scoped_refptr<webrtc::FrameTransformerInterface>(this));
 }
 
-void LibWebRTCRtpSenderTransformBackend::requestKeyFrame()
+bool LibWebRTCRtpSenderTransformBackend::requestKeyFrame(const String& rid)
 {
+    std::vector<std::string> rtcRids;
+    if (!rid.isEmpty())
+        rtcRids.push_back(rid.utf8().toStdString());
     ASSERT(mediaType() == MediaType::Video);
-    m_rtcSender->GenerateKeyFrame({ });
+    return m_rtcSender->GenerateKeyFrame(rtcRids).ok();
 }
 
 } // namespace WebCore
diff --git a/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderTransformBackend.h b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderTransformBackend.h
index cc2dce0fdf4c..18a2d808ee27 100644
--- a/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderTransformBackend.h
+++ b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpSenderTransformBackend.h
@@ -57,7 +57,7 @@ class LibWebRTCRtpSenderTransformBackend final : public LibWebRTCRtpTransformBac
 
     // RTCRtpTransformBackend
     void setTransformableFrameCallback(Callback&&) final;
-    void requestKeyFrame() final;
+    bool requestKeyFrame(const String&) final;
 
     bool m_isRegistered { false };
     rtc::scoped_refptr<webrtc::RtpSenderInterface> m_rtcSender;


Reviews:
user: login: eric-carlson
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-05T15:38:38Z
user: login: youennf
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-12T17:52:58Z

Review comments:
diff_hunk: @@ -190,18 +191,47 @@ void RTCRtpScriptTransformer::enqueueFrame(ScriptExecutionContext& context, Ref<
     m_readableSource->enqueue(value);
 }
 
-void RTCRtpScriptTransformer::generateKeyFrame(Ref<DeferredPromise>&& promise)
+static std::optional<Exception> validateRid(const String& rid)
+{
+    if (rid.isNull())
+        return { };
+
+    if (rid.isEmpty())
+        return Exception { ExceptionCode::NotAllowedError, "rid is empty"_s };
+
+    if (rid.length() > 255)
path: Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.cpp
user: login: eric-carlson
body: Nit: it would be nice to have and use a named constant 
created_at: 2025-04-05T15:35:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -190,18 +191,47 @@ void RTCRtpScriptTransformer::enqueueFrame(ScriptExecutionContext& context, Ref<
     m_readableSource->enqueue(value);
 }
 
-void RTCRtpScriptTransformer::generateKeyFrame(Ref<DeferredPromise>&& promise)
+static std::optional<Exception> validateRid(const String& rid)
+{
+    if (rid.isNull())
+        return { };
+
+    if (rid.isEmpty())
+        return Exception { ExceptionCode::NotAllowedError, "rid is empty"_s };
+
+    if (rid.length() > 255)
path: Source/WebCore/Modules/mediastream/RTCRtpScriptTransformer.cpp
user: login: youennf
body: Done
created_at: 2025-04-12T17:52:58Z
author_association: CONTRIBUTOR

PR comments:
user: login: webkit-early-warning-system
created_at: 2025-04-04T14:29:30Z
body: EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/f022d06524a10d34b755395d5b1a8dad7876951e)<details>

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [✅ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/98335 "Passed style check") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/17966 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/8194 "Built successfully") | [❌ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/103455 "Hash f022d065 for PR 43641 does not build (failure)") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/48864 "Built successfully") 
| [✅ 🧪 bindings](https://ews-build.webkit.org/#/builders/9/builds/100380 "Passed tests") | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/18258 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/26417 "Built successfully") | [❌ 🧪 wpe-wk2](https://ews-build.webkit.org/#/builders/5/builds/103455 "Hash f022d065 for PR 43641 does not build (failure)") | [✅ 🧪 win-tests](https://ews-build.webkit.org/#/builders/60/builds/32019 "Passed tests") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/101339 "Passed tests") | [✅ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/132/builds/13829 "Passed tests") | [✅ 🧪 api-mac](https://ews-build.webkit.org/#/builders/18/builds/88812 "Passed tests") | [❌ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/5/builds/103455 "Hash f022d065 for PR 43641 does not build (failure)") | 
| | [✅ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/133/builds/13612 "Passed tests") | [✅ 🧪 mac-wk1](https://ews-build.webkit.org/#/builders/135/builds/6773 "Passed tests") | [❌ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/48306 "Hash f022d065 for PR 43641 does not build (failure)") | 
| | [✅ 🧪 api-ios](https://ews-build.webkit.org/#/builders/13/builds/83589 "Passed tests") | [✅ 🧪 mac-wk2](https://ews-build.webkit.org/#/builders/136/builds/6847 "Passed tests") | [❌ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/105830 "Hash f022d065 for PR 43641 does not build (failure)") | 
| | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/25422 "Built successfully") | [✅ 🧪 mac-AS-debug-wk2](https://ews-build.webkit.org/#/builders/122/builds/18510 "Passed tests") | [❌ 🧪 gtk-wk2](https://ews-build.webkit.org/#/builders/2/builds/105830 "Hash f022d065 for PR 43641 does not build (failure)") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/25795 "Built successfully") | [✅ 🧪 mac-wk2-stress](https://ews-build.webkit.org/#/builders/8/builds/85014 "Passed tests") | [❌ 🧪 api-gtk](https://ews-build.webkit.org/#/builders/2/builds/105830 "Hash f022d065 for PR 43641 does not build (failure)") | 
| | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/27943 "Passed tests") | [✅ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/137/builds/5618 "Passed tests") | [✅ 🛠 playstation](https://ews-build.webkit.org/#/builders/134/builds/19068 "Built successfully") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/25380 "Built successfully") | [✅ 🛠 mac-safer-cpp](https://ews-build.webkit.org/#/builders/120/builds/30560 "Built successfully") | | 
| | [✅ 🛠 tv-sim](https://ews-build.webkit.org/#/builders/125/builds/25200 "Built successfully") | | | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/28516 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/26775 "Built successfully") | | | </details>
author_association: COLLABORATOR
user: login: webkit-early-warning-system
created_at: 2025-04-05T07:59:23Z
body: EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/e378dfb627ba1392a8e21a5e95e7d8496bbdb0f4)<details>

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [✅ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/98482 "Passed style check") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/18115 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/8347 "Built successfully") | [✅ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/103603 "Built successfully") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/49014 "Built successfully") 
| [✅ 🧪 bindings](https://ews-build.webkit.org/#/builders/9/builds/100526 "Passed tests") | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/18408 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/26566 "Built successfully") | [✅ 🧪 wpe-wk2](https://ews-build.webkit.org/#/builders/34/builds/74964 "Passed tests") | [✅ 🧪 win-tests](https://ews-build.webkit.org/#/builders/60/builds/32123 "Passed tests") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/101486 "Passed tests") | [✅ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/132/builds/13962 "Passed tests") | [✅ 🧪 api-mac](https://ews-build.webkit.org/#/builders/18/builds/88946 "Passed tests") | [✅ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/41/builds/55324 "Passed tests") | 
| | [✅ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/133/builds/13742 "Passed tests") | [✅ 🧪 mac-wk1](https://ews-build.webkit.org/#/builders/135/builds/6910 "Passed tests") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/48452 "Built successfully") | 
| | [✅ 🧪 api-ios](https://ews-build.webkit.org/#/builders/13/builds/83698 "Passed tests") | [✅ 🧪 mac-wk2](https://ews-build.webkit.org/#/builders/136/builds/6988 "Passed tests") | [✅ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/105976 "Built successfully") | 
| | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/25572 "Built successfully") | [✅ 🧪 mac-AS-debug-wk2](https://ews-build.webkit.org/#/builders/122/builds/18617 "Passed tests") | [✅ 🧪 gtk-wk2](https://ews-build.webkit.org/#/builders/1/builds/83937 "Passed tests") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/25948 "Built successfully") | [✅ 🧪 mac-wk2-stress](https://ews-build.webkit.org/#/builders/8/builds/85146 "Passed tests") | [✅ 🧪 api-gtk](https://ews-build.webkit.org/#/builders/21/builds/83421 "Passed tests") | 
| | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/28071 "Passed tests") | [✅ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/137/builds/5739 "Passed tests") | [✅ 🛠 playstation](https://ews-build.webkit.org/#/builders/134/builds/19228 "Built successfully") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/25530 "Built successfully") | [✅ 🛠 mac-safer-cpp](https://ews-build.webkit.org/#/builders/120/builds/30711 "Built successfully") | | 
| | [✅ 🛠 tv-sim](https://ews-build.webkit.org/#/builders/125/builds/25348 "Built successfully") | | | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/28668 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/26923 "Built successfully") | | | </details>
author_association: COLLABORATOR
user: login: webkit-early-warning-system
created_at: 2025-04-12T17:01:55Z
body: EWS run on current version of this PR (hash https://github.com/WebKit/WebKit/commit/4000cd4466351a3047c88891b8201dad0545501b)<details>

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [✅ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/99460 "Passed style check") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/19110 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/9363 "Built successfully") | [✅ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/104591 "Built successfully") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/50062 "Built successfully") 
| [✅ 🧪 bindings](https://ews-build.webkit.org/#/builders/9/builds/101501 "Passed tests") | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/19398 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/27543 "Built successfully") | [✅ 🧪 wpe-wk2](https://ews-build.webkit.org/#/builders/34/builds/75702 "Passed tests") | [✅ 🧪 win-tests](https://ews-build.webkit.org/#/builders/60/builds/32803 "Passed tests") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/102467 "Passed tests") | [✅ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/132/builds/14765 "Passed tests") | [✅ 🧪 api-mac](https://ews-build.webkit.org/#/builders/18/builds/89807 "Passed tests") | [✅ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/41/builds/56061 "Passed tests") | 
| | [✅ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/133/builds/14561 "Passed tests") | [✅ 🧪 mac-wk1](https://ews-build.webkit.org/#/builders/135/builds/7790 "Passed tests") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/49421 "Built successfully") | 
| | [✅ 🧪 api-ios](https://ews-build.webkit.org/#/builders/13/builds/84485 "Passed tests") | [✅ 🧪 mac-wk2](https://ews-build.webkit.org/#/builders/136/builds/7878 "Passed tests") | [✅ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/106949 "Built successfully") | 
| | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/26574 "Built successfully") | [  ~~🧪 mac-AS-debug-wk2~~](https://ews-build.webkit.org/#/builders/122/builds/19389 "The change is no longer eligible for processing. Pull Request was already closed when EWS attempted to process it.") | [✅ 🧪 gtk-wk2](https://ews-build.webkit.org/#/builders/1/builds/84659 "Passed tests") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/26936 "Built successfully") | [✅ 🧪 mac-wk2-stress](https://ews-build.webkit.org/#/builders/8/builds/86011 "Passed tests") | [✅ 🧪 api-gtk](https://ews-build.webkit.org/#/builders/21/builds/84177 "Passed tests") | 
| [✅ 🛠 🧪 merge](https://ews-build.webkit.org/#/builders/19/builds/21356 "Built successfully and passed tests") | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/28851 "Passed tests") | [✅ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/137/builds/6547 "Passed tests") | [✅ 🛠 playstation](https://ews-build.webkit.org/#/builders/134/builds/20342 "Built successfully") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/26514 "Built successfully") | [✅ 🛠 mac-safer-cpp](https://ews-build.webkit.org/#/builders/120/builds/31715 "Built successfully") | | 
| | [✅ 🛠 tv-sim](https://ews-build.webkit.org/#/builders/125/builds/26334 "Built successfully") | | | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/29647 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/27901 "Built successfully") | | | </details>
author_association: COLLABORATOR
user: login: webkit-commit-queue
created_at: 2025-04-12T19:47:34Z
body: Committed 293633@main (a24b100fb04d): <https://commits.webkit.org/293633@main>

Reviewed commits have been landed. Closing PR #43641 and removing active labels.
author_association: COLLABORATOR