supervision 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -5106,7 +5106,7 @@ function presentVideoFrame(presented, targets) {
5106
5106
  try {
5107
5107
  at(targets.adoptMediaTime, mediaTime, presented);
5108
5108
  targets.fitMediaScene();
5109
- targets.uploadFrame(presented.frame);
5109
+ targets.uploadFrame(presented);
5110
5110
  const { boxState, regionState } = drawFramePresentLayers(layers, mediaTime, presented);
5111
5111
  targets.render();
5112
5112
  targets.completePresentation(mediaTime, boxState, regionState);
@@ -13561,8 +13561,8 @@ async function createPixiMediaScene(options) {
13561
13561
  app.ticker.add(drawAnnotationOverlayNow);
13562
13562
  app.ticker.add(tickFocusLayer);
13563
13563
  }
13564
- const uploadFrameToStagingCanvas = (frame) => {
13565
- stagingContext.drawImage(frame, 0, 0, mediaWidth, mediaHeight);
13564
+ const uploadFrameToStagingCanvas = (frame, rotation = 0) => {
13565
+ drawPresentedVideoFrame(stagingContext, frame, rotation, mediaWidth, mediaHeight);
13566
13566
  stagingTextureSource?.update();
13567
13567
  stagingTexture?.update();
13568
13568
  };
@@ -13605,14 +13605,14 @@ async function createPixiMediaScene(options) {
13605
13605
  ? measureFramePresentLayers(presentLayers, measureDrawStep)
13606
13606
  : presentLayers,
13607
13607
  render: renderPresent,
13608
- uploadFrame: (frame) => {
13608
+ uploadFrame: (presented) => {
13609
13609
  if (!collectFrameTimings) {
13610
- mediaCompositor?.upload(frame);
13610
+ mediaCompositor?.upload(presented.frame, presented.rotation ?? 0);
13611
13611
  presentedSampleTimestamp = currentMediaTime;
13612
13612
  return;
13613
13613
  }
13614
13614
  presentMediaUploadMs += measure(() => {
13615
- mediaCompositor?.upload(frame);
13615
+ mediaCompositor?.upload(presented.frame, presented.rotation ?? 0);
13616
13616
  presentedSampleTimestamp = currentMediaTime;
13617
13617
  });
13618
13618
  },
@@ -14943,13 +14943,13 @@ function createMediaCompositor(options) {
14943
14943
  const { device } = options;
14944
14944
  let gpuTexture = createFrameTexture(device, options.width, options.height);
14945
14945
  const textureSource = options.attach(gpuTexture);
14946
+ let rotationCanvas;
14946
14947
  return {
14947
14948
  destroy() {
14948
14949
  gpuTexture.destroy();
14949
14950
  },
14950
- upload(frame) {
14951
- const width = frame.displayWidth;
14952
- const height = frame.displayHeight;
14951
+ upload(frame, rotation = 0) {
14952
+ const [width, height] = presentedFrameSize(frame, rotation);
14953
14953
  if (width !== gpuTexture.width || height !== gpuTexture.height) {
14954
14954
  const replacement = createFrameTexture(device, width, height);
14955
14955
  const retired = gpuTexture;
@@ -14976,9 +14976,47 @@ function createMediaCompositor(options) {
14976
14976
  options.onTextureReplaced();
14977
14977
  retired.destroy();
14978
14978
  }
14979
- device.queue.copyExternalImageToTexture({ source: frame }, { texture: gpuTexture }, { height, width });
14979
+ device.queue.copyExternalImageToTexture({ source: uploadSource(frame, rotation) }, { texture: gpuTexture }, { height, width });
14980
14980
  },
14981
14981
  };
14982
+ function uploadSource(frame, rotation) {
14983
+ if (rotation === 0)
14984
+ return frame;
14985
+ const [width, height] = presentedFrameSize(frame, rotation);
14986
+ if (!rotationCanvas)
14987
+ rotationCanvas = new OffscreenCanvas(width, height);
14988
+ rotationCanvas.width = width;
14989
+ rotationCanvas.height = height;
14990
+ const context = rotationCanvas.getContext("2d");
14991
+ if (!context) {
14992
+ throw new Error("Unable to create a rotation canvas context.");
14993
+ }
14994
+ drawPresentedVideoFrame(context, frame, rotation, width, height);
14995
+ return rotationCanvas;
14996
+ }
14997
+ }
14998
+ /**
14999
+ * Draws raw decoded pixels in their display orientation. A `VideoFrame` does
15000
+ * not carry a track display matrix to a canvas or GPU upload, so a pushed
15001
+ * frame has to be transformed before it joins the already-oriented cache path.
15002
+ */
15003
+ function drawPresentedVideoFrame(context, frame, rotation, width, height) {
15004
+ if (rotation === 0) {
15005
+ context.drawImage(frame, 0, 0, width, height);
15006
+ return;
15007
+ }
15008
+ context.save();
15009
+ context.translate(width / 2, height / 2);
15010
+ context.rotate((rotation * Math.PI) / 180);
15011
+ const aspectRatioChange = rotation % 180 === 0 ? 1 : width / height;
15012
+ context.scale(1 / aspectRatioChange, aspectRatioChange);
15013
+ context.drawImage(frame, -width / 2, -height / 2, width, height);
15014
+ context.restore();
15015
+ }
15016
+ function presentedFrameSize(frame, rotation) {
15017
+ return rotation % 180 === 0
15018
+ ? [frame.displayWidth, frame.displayHeight]
15019
+ : [frame.displayHeight, frame.displayWidth];
14982
15020
  }
14983
15021
  /**
14984
15022
  * Whether this device's queue takes a decoded frame as a copy source.