From 66892d00a815c50ec56a7cde455b3048bff8c339 Mon Sep 17 00:00:00 2001
From: Dale Curtis <dalecurtis@chromium.org>
Date: Thu, 13 Mar 2025 23:33:51 +0000
Subject: [PATCH 1/2] Implement orientation support for VideoEncoder.

This implements the algorithm as discussed in the Media WG:
* Orientation is locked-in upon the first call to encode().
* Mismatched orientation will trigger a non-fatal error by throwing
  an exception during encode().
* The orientation of the first frame is emitted on the
  VideoDecoderConfig attached to EncodedVideoChunkMetadata.

Fixes: https://github.com/w3c/webcodecs/issues/351
---
 index.src.html | 28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/index.src.html b/index.src.html
index 843d6bd8..7ab7283d 100644
--- a/index.src.html
+++ b/index.src.html
@@ -1402,6 +1402,10 @@
 : <dfn attribute for=VideoEncoder>[[dequeue event scheduled]]</dfn>
 :: A boolean indicating whether a {{VideoEncoder/dequeue}} event is already
     scheduled to fire. Used to avoid event spam.
+: <dfn attribute for=VideoEncoder>[[active orientation]]</dfn>
+:: An integer and boolean pair indicating the {{VideoFrame/[[flip]]}} and
+    {{VideoFrame/[[rotation]]}} of the first {{VideoFrame}} given to
+    {{VideoEncoder/encode()}} after {{VideoEncoder/configure()}}.
 
 Constructors {#videoencoder-constructors}
 -----------------------------------------
@@ -1461,8 +1465,9 @@
     2. If {{VideoEncoder/[[state]]}} is `"closed"`, throw an
         {{InvalidStateError}}.
     3. Set {{VideoEncoder/[[state]]}} to `"configured"`.
-    4. [=Queue a control message=] to configure the encoder using |config|.
-    5. [=Process the control message queue=].
+    4. Set {{VideoEncoder/[[active orientation]]}} to `null`.
+    5. [=Queue a control message=] to configure the encoder using |config|.
+    6. [=Process the control message queue=].
 
     [=Running a control message=] to configure the encoder means performing
     these steps:
@@ -1491,11 +1496,16 @@
         is `true`, throw a {{TypeError}}.
     2. If {{VideoEncoder/[[state]]}} is not `"configured"`, throw an
         {{InvalidStateError}}.
-    3. Let |frameClone| hold the result of running the [=Clone VideoFrame=]
+    3. If {{VideoEncoder/[[active orientation]]}} is not `null` and does not match
+        |frame|'s {{VideoFrame/[[rotation]]}} and {{VideoFrame/[[flip]]}} throw a
+        {{DataError}}.
+    4. If {{VideoEncoder/[[active orientation]]}} is `null`, assign |frame|'s
+        {{VideoFrame/[[rotation]]}} and {{VideoFrame/[[flip]]}} to it.
+    5. Let |frameClone| hold the result of running the [=Clone VideoFrame=]
         algorithm with |frame|.
-    4. Increment {{VideoEncoder/[[encodeQueueSize]]}}.
-    5. [=Queue a control message=] to encode |frameClone|.
-    6. [=Process the control message queue=].
+    6. Increment {{VideoEncoder/[[encodeQueueSize]]}}.
+    7. [=Queue a control message=] to encode |frameClone|.
+    8. [=Process the control message queue=].
 
     [=Running a control message=] to encode the frame means performing these
     steps:
@@ -1646,7 +1656,11 @@
                 `outputConfig.displayAspectWidth`.
             5. Assign `encoderConfig.displayHeight` to
                 `outputConfig.displayAspectHeight`.
-            6. Assign the remaining keys of `outputConfig` as determined by
+            6. Assign {{VideoFrame/[[rotation]]}} from the {{VideoFrame}}
+                associated with |output| to `outputConfig.rotation`.
+            7. Assign {{VideoFrame/[[flip]]}} from the {{VideoFrame}}
+                associated with |output| to `outputConfig.flip`.
+            8. Assign the remaining keys of `outputConfig` as determined by
                 {{VideoEncoder/[[codec implementation]]}}. The User Agent
                 <em class="rfc2119">MUST</em> ensure that the configuration is
                 completely described such that |outputConfig| could be used to

From e3bd4010d70e15564424374012a95c6cfd9c68eb Mon Sep 17 00:00:00 2001
From: Dale Curtis <dalecurtis@chromium.org>
Date: Fri, 14 Mar 2025 12:01:56 -0700
Subject: [PATCH 2/2] Accept suggestion to clarify active orientation setting.

Co-authored-by: Paul Adenot <paul@paul.cx>
---
 index.src.html | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/index.src.html b/index.src.html
index 7ab7283d..e571e6a6 100644
--- a/index.src.html
+++ b/index.src.html
@@ -1499,8 +1499,8 @@
     3. If {{VideoEncoder/[[active orientation]]}} is not `null` and does not match
         |frame|'s {{VideoFrame/[[rotation]]}} and {{VideoFrame/[[flip]]}} throw a
         {{DataError}}.
-    4. If {{VideoEncoder/[[active orientation]]}} is `null`, assign |frame|'s
-        {{VideoFrame/[[rotation]]}} and {{VideoFrame/[[flip]]}} to it.
+    4. If {{VideoEncoder/[[active orientation]]}} is `null`, set it to |frame|'s
+        {{VideoFrame/[[rotation]]}} and {{VideoFrame/[[flip]]}}.
     5. Let |frameClone| hold the result of running the [=Clone VideoFrame=]
         algorithm with |frame|.
     6. Increment {{VideoEncoder/[[encodeQueueSize]]}}.