Signatur
Beschreibung
allocationSize() berechnet, wie viele Bytes die Pixeldaten eines VideoFrame brauchen, wenn man sie mit copyTo() in einen ArrayBuffer, ein TypedArray oder eine DataView kopiert. Die Methode sieht sich dafür das Pixelformat an (etwa I420, NV12, RGBA, BGRA), außerdem die Farbebenen (Planes), ihre Unterabtastung und die übergebenen Optionen.
Man ruft sie typischerweise direkt vor copyTo() auf, um einen passend großen Zielpuffer anzulegen. Das kommt vor, wenn man Rohpixel an WebAssembly übergeben, per postMessage() weiterreichen, analysieren oder selbst weiterverarbeiten will. Damit die Größe stimmt, übergibt man an allocationSize() und copyTo() dasselbe Optionsobjekt.
Mit rect kopiert man nur einen Bildausschnitt. Mit layout legt man für jede Ebene einen eigenen Versatz (offset) und eine eigene Zeilenlänge in Bytes (stride) fest, z. B. mit Auffüllbytes für Speicherausrichtung. In neueren Implementierungen lassen format und colorSpace eine Umwandlung nach RGB zu. Die berechnete Größe richtet sich dann nach dem Zielformat.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $options | object | {} | Optionales Objekt, das beschreibt, wie kopiert werden soll. Es muss mit den Optionen des späteren copyTo()-Aufrufs übereinstimmen. |
| $options.rect | DOMRectInit | visibleRect des Frames | Ausschnitt { x, y, width, height }, der kopiert werden soll. Bei unterabgetasteten Formaten wie I420 müssen die Werte zur Unterabtastung passen (meist gerade Zahlen). |
| $options.layout | Array<{ offset: number, stride: number }> | dicht gepackt | Ein Eintrag pro Farbebene: offset ist der Startversatz in Bytes, stride die Bytes pro Zeile. Die Anzahl der Einträge muss der Anzahl der Ebenen des Formats entsprechen. |
| $options.format | "RGBA" | "RGBX" | "BGRA" | "BGRX" | Format des Frames | Zielformat für eine Umwandlung nach RGB beim Kopieren. Neuere Ergänzung der Spezifikation, noch nicht überall unterstützt. |
| $options.colorSpace | "srgb" | "display-p3" | "srgb" | Ziel-Farbraum für die RGB-Umwandlung. Gilt nur zusammen mit format. |
Rückgabewert
layout.Beispiele
Puffer passender Größe anlegen und Pixel kopieren
// I420-Frame aus Rohdaten erzeugen (Y + U + V)
const width = 1920;
const height = 1080;
const raw = new Uint8Array(width * height * 1.5);
const frame = new VideoFrame(raw, {
format: 'I420',
codedWidth: width,
codedHeight: height,
timestamp: 0,
});
const size = frame.allocationSize();
console.log('Benötigte Bytes:', size);
const buffer = new Uint8Array(size);
const layout = await frame.copyTo(buffer);
console.log(layout);
frame.close(); // Speicher sofort freigeben
Nur einen Bildausschnitt kopieren
const frame = new VideoFrame(new Uint8Array(1280 * 720 * 1.5), {
format: 'I420',
codedWidth: 1280,
codedHeight: 720,
timestamp: 0,
});
// Dasselbe Optionsobjekt für allocationSize() und copyTo() verwenden!
const options = { rect: { x: 0, y: 0, width: 320, height: 240 } };
const size = frame.allocationSize(options);
const crop = new Uint8Array(size);
await frame.copyTo(crop, options);
console.log(size); // 320*240 + 2 * (160*120)
frame.close();
Eigenes Layout mit ausgerichteten Zeilen (Stride)
const frame = new VideoFrame(new Uint8Array(100 * 100 * 4), {
format: 'RGBA',
codedWidth: 100,
codedHeight: 100,
timestamp: 0,
});
// Zeilen auf 512 Bytes auffüllen (100 px * 4 B = 400 B Nutzdaten)
const options = { layout: [{ offset: 0, stride: 512 }] };
console.log(frame.allocationSize()); // dicht gepackt
console.log(frame.allocationSize(options)); // mit Auffüllbytes
const buf = new ArrayBuffer(frame.allocationSize(options));
await frame.copyTo(buf, options);
frame.close();
Kamerabild als RGBA auslesen (mit Rückfallebene)
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
const [track] = stream.getVideoTracks();
const reader = new MediaStreamTrackProcessor({ track }).readable.getReader();
const { value: frame } = await reader.read();
const options = { format: 'RGBA', colorSpace: 'srgb' };
let size;
try {
size = frame.allocationSize(options); // RGB-Umwandlung (neuere Browser)
} catch (err) {
console.warn('RGB-Umwandlung nicht unterstützt:', err.name);
delete options.format;
delete options.colorSpace;
size = frame.allocationSize();
}
const pixels = new Uint8Array(size);
await frame.copyTo(pixels, options);
console.log(frame.format, frame.displayWidth, frame.displayHeight, size);
frame.close();
track.stop();