From 940826697c2b65a1b98fa6214552e17386e1d8cd Mon Sep 17 00:00:00 2001
From: dumbmoron <log@riseup.net>
Date: Mon, 12 Aug 2024 18:06:59 +0000
Subject: [PATCH] web/libav: preallocate memory for output when remuxing

---
 web/src/lib/libav.ts | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/web/src/lib/libav.ts b/web/src/lib/libav.ts
index 2f2b9f16..4a5b2ac7 100644
--- a/web/src/lib/libav.ts
+++ b/web/src/lib/libav.ts
@@ -57,12 +57,16 @@ export default class LibAVWrapper {
 
         // https://github.com/Yahweasel/libav.js/blob/7d359f69/docs/IO.md#block-writer-devices
         await this.libav.mkwriterdev(outputName);
-        let writtenData = new Uint8Array(0);
+
+        // since we expect the output file to be roughly the same size
+        // as the original, preallocate its size for the output
+        let writtenData = new Uint8Array(blob.size), actualSize = 0;
 
         this.libav.onwrite = (name, pos, data) => {
             if (name !== outputName) return;
 
-            const newLen = Math.max(writtenData.length, pos + data.length);
+            actualSize = Math.max(pos + data.length, actualSize);
+            const newLen = Math.max(pos + data.length, writtenData.length);
             if (newLen > writtenData.length) {
                 const newData = new Uint8Array(newLen);
                 newData.set(writtenData);
@@ -71,6 +75,12 @@ export default class LibAVWrapper {
             writtenData.set(data, pos);
         };
 
+        // if we didn't need as much space as we allocated for some reason,
+        // shrink the buffer so that we don't inflate the file with zeros
+        if (writtenData.length > actualSize) {
+            writtenData = writtenData.slice(0, actualSize);
+        }
+
         await this.libav.ffmpeg([
             '-nostdin', '-y',
             '-threads', this.concurrency.toString(),