From 5c5a6d3dffbadd37e20d145705c4b5c5629ccb29 Mon Sep 17 00:00:00 2001 From: Jan-Ivar Bruaroey Date: Mon, 7 Jul 2025 17:54:24 -0400 Subject: [PATCH 1/2] Update generateKeyFrame to take single rid and remove timestamp --- index.bs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/index.bs b/index.bs index e47097a..8980563 100644 --- a/index.bs +++ b/index.bs @@ -889,7 +889,7 @@ partial interface DedicatedWorkerGlobalScope { interface RTCRtpScriptTransformer : EventTarget { // Attributes and methods related to the transformer source readonly attribute ReadableStream readable; - Promise<unsigned long long> generateKeyFrame(optional DOMString rid); + Promise<undefined> generateKeyFrame(optional DOMString rid); Promise<undefined> sendKeyFrameRequest(); // Attributes and methods related to the transformer sink readonly attribute WritableStream writable; @@ -1039,16 +1039,16 @@ An additional API on {{RTCRtpSender}} is added to complement the generation of k
 partial interface RTCRtpSender {
-    Promise<undefined> generateKeyFrame(optional sequence <DOMString> rids);
+    Promise<undefined> generateKeyFrame(optional DOMString rid);
 };
 
## Extension operation ## {#sender-operation} -The generateKeyFrame(|rids|) method steps are: +The generateKeyFrame(|rid|) method steps are: 1. Let |promise| be a new promise. -1. [=In parallel=], run the [$generate key frame algorithm$] with |promise|, |this|'s encoder and |rids|. +1. [=In parallel=], run the [$generate key frame algorithm$] with |promise|, |this|'s encoder and |rid|. 1. Return |promise|. # Privacy and security considerations # {#privacy} From 50e06dba0145fc502efe5b136220f72fbb71a022 Mon Sep 17 00:00:00 2001 From: Jan-Ivar Bruaroey Date: Mon, 7 Jul 2025 20:32:44 -0400 Subject: [PATCH 2/2] Update generate key frame algorithm to treat absence of rid as all rids. --- index.bs | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/index.bs b/index.bs index 8980563..0d36aeb 100644 --- a/index.bs +++ b/index.bs @@ -997,32 +997,34 @@ The generate key frame algorithm, given |promise|, |encod in Section 10 of [[!RFC8851]], then reject |promise| with {{TypeError}} and abort these steps. 1. [=In parallel=], run the following steps: - 1. Gather a list of video encoders, named |videoEncoders| from |encoder|, ordered according negotiated RIDs if any. - 1. If |rid| is defined, remove from |videoEncoders| any video encoder that does not match |rid|. - 1. If |rid| is undefined, remove from |videoEncoders| all video encoders except the first one. + 1. Let |videoEncoders| be a list of video encoders from |encoder|, ordered according to their negotiated RIDs if any. + 1. If |rid| is not undefined, remove from |videoEncoders| any video encoder that does not match |rid|. 1. If |videoEncoders| is empty, [=queue a task=] to reject |promise| with {{NotFoundError}} and abort these steps. - |videoEncoders| is expected to be empty if the corresponding {{RTCRtpSender}} is not active, or the corresponding {{RTCRtpSender}} track is ended. - 1. Let |videoEncoder| be the first encoder in |videoEncoders|. - 1. If |rid| is undefined, set |rid| to the RID value corresponding to |videoEncoder|. + + Note: |videoEncoders| is expected to be empty if the corresponding {{RTCRtpSender}} encoding is not + {{RTCRtpEncodingParameters/active}}, or the corresponding {{RTCRtpSender}} track is ended. + 1. Create a pending key frame task called |task| with |task|.`[[rid]]` set to rid and |task|.`[[promise]]`| set to |promise|. 1. If |encoder|.`[[pendingKeyFrameTasks]]` is undefined, initialize |encoder|.`[[pendingKeyFrameTasks]]` to an empty set. 1. Let |shouldTriggerKeyFrame| be false if |encoder|.`[[pendingKeyFrameTasks]]` contains a task whose `[[rid]]` - value is equal to |rid|, and true otherwise. + value is either undefined or equal to |rid|, and true otherwise. 1. Add |task| to |encoder|.`[[pendingKeyFrameTasks]]`. - 1. If |shouldTriggerKeyFrame| is true, instruct |videoEncoder| to generate a key frame for the next provided video frame. + 1. If |shouldTriggerKeyFrame| is true, then for each |videoEncoder| in |videoEncoders|, instruct + |videoEncoder| to generate a key frame for its next provided video frame. For any {{RTCRtpScriptTransformer}} named |transformer|, the following steps are run just before any |frame| is enqueued in |transformer|.`[[readable]]`: 1. Let |encoder| be |transformer|.`[[encoder]]`. -1. If |encoder| or |encoder|.`[[pendingKeyFrameTasks]]` is undefined, abort these steps. +1. If |encoder| or |encoder|.`[[pendingKeyFrameTasks]]` are undefined, abort these steps. 1. If |frame| is not a video {{RTCEncodedVideoFrameType/"key"}} frame, abort these steps. 1. For each |task| in |encoder|.`[[pendingKeyFrameTasks]]`, run the following steps: - 1. If |frame| was generated by a video encoder identified by |task|.`[[rid]]`, run the following steps: + 1. If |frame| was generated by a video encoder identified by |task|.`[[rid]]`, or |task|.`[[rid]]` is undefined and + all video encoders have generated one frame since the generation of |frame| was triggered, run the following steps: 1. Remove |task| from |encoder|.`[[pendingKeyFrameTasks]]`. - 1. Resolve |task|.`[[promise]]` with |frame|'s timestamp. + 1. Resolve |task|.`[[promise]]` with undefined. By resolving the promises just before enqueuing the corresponding key frame in a {{RTCRtpScriptTransformer}}'s readable, the resolution callbacks of the promises are always executed just before the corresponding key frame is exposed. -If the promise is associated to several rid values, it will be resolved when the first key frame corresponding to one the rid value is enqueued. +If the promise is associated with several video encoders, it is resolved when all of them have generated a key frame. The send request key frame algorithm, given |promise| and |depacketizer|, is defined by running these steps: 1. If |depacketizer| is undefined, reject |promise| with {{InvalidStateError}}, abort these steps.