summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorLibravatar kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com>2024-11-06 13:38:13 +0000
committerLibravatar GitHub <noreply@github.com>2024-11-06 14:38:13 +0100
commitb84637801ae9e9cf330d91ce7e2e7734a7c6130c (patch)
treee7518f95e0a44506c24c298dd88c654c0a4bdae5 /internal
parent[bugfix] sets the max value placeholders to MaxInt32 instead of MaxInt (#3517) (diff)
downloadgotosocial-b84637801ae9e9cf330d91ce7e2e7734a7c6130c.tar.xz
[chore] update go ffmpreg to v0.6.0 (#3515)
* pull in go-ffmpreg v0.6.0 * add code comment * grrr linter * set empty module name when calling ffmpeg / ffprobe
Diffstat (limited to 'internal')
-rw-r--r--internal/media/ffmpeg.go8
-rw-r--r--internal/media/ffmpeg/ffmpeg.go18
-rw-r--r--internal/media/ffmpeg/ffprobe.go18
-rw-r--r--internal/media/ffmpeg/wasm.go133
4 files changed, 110 insertions, 67 deletions
diff --git a/internal/media/ffmpeg.go b/internal/media/ffmpeg.go
index 1d7b01905..c225d4378 100644
--- a/internal/media/ffmpeg.go
+++ b/internal/media/ffmpeg.go
@@ -181,6 +181,10 @@ func ffmpeg(ctx context.Context, inpath string, outpath string, args ...string)
}
fscfg = fscfg.WithFSMount(shared, path.Dir(inpath))
+ // Set anonymous module name.
+ modcfg = modcfg.WithName("")
+
+ // Update with prepared fs config.
return modcfg.WithFSConfig(fscfg)
},
})
@@ -247,6 +251,10 @@ func ffprobe(ctx context.Context, filepath string) (*result, error) {
}
fscfg = fscfg.WithFSMount(in, path.Dir(filepath))
+ // Set anonymous module name.
+ modcfg = modcfg.WithName("")
+
+ // Update with prepared fs config.
return modcfg.WithFSConfig(fscfg)
},
})
diff --git a/internal/media/ffmpeg/ffmpeg.go b/internal/media/ffmpeg/ffmpeg.go
index 0571c029a..b978201c1 100644
--- a/internal/media/ffmpeg/ffmpeg.go
+++ b/internal/media/ffmpeg/ffmpeg.go
@@ -21,6 +21,7 @@ package ffmpeg
import (
"context"
+ "errors"
"codeberg.org/gruf/go-ffmpreg/wasm"
)
@@ -35,12 +36,25 @@ var ffmpegRunner runner
// prepares the runner to only allow max given concurrent running instances.
func InitFfmpeg(ctx context.Context, max int) error {
ffmpegRunner.Init(max)
- return compileFfmpeg(ctx)
+ return initWASM(ctx)
}
// Ffmpeg runs the given arguments with an instance of ffmpeg.
func Ffmpeg(ctx context.Context, args Args) (uint32, error) {
return ffmpegRunner.Run(ctx, func() (uint32, error) {
- return wasm.Run(ctx, runtime, ffmpeg, args)
+
+ // Load WASM rt and module.
+ ffmpreg := ffmpreg.Load()
+ if ffmpreg == nil {
+ return 0, errors.New("wasm not initialized")
+ }
+
+ // Call into ffmpeg.
+ args.Name = "ffmpeg"
+ return wasm.Run(ctx,
+ ffmpreg.run,
+ ffmpreg.mod,
+ args,
+ )
})
}
diff --git a/internal/media/ffmpeg/ffprobe.go b/internal/media/ffmpeg/ffprobe.go
index ccd5072dd..410935d9c 100644
--- a/internal/media/ffmpeg/ffprobe.go
+++ b/internal/media/ffmpeg/ffprobe.go
@@ -21,6 +21,7 @@ package ffmpeg
import (
"context"
+ "errors"
"codeberg.org/gruf/go-ffmpreg/wasm"
)
@@ -35,12 +36,25 @@ var ffprobeRunner runner
// prepares the runner to only allow max given concurrent running instances.
func InitFfprobe(ctx context.Context, max int) error {
ffprobeRunner.Init(max)
- return compileFfprobe(ctx)
+ return initWASM(ctx)
}
// Ffprobe runs the given arguments with an instance of ffprobe.
func Ffprobe(ctx context.Context, args Args) (uint32, error) {
return ffprobeRunner.Run(ctx, func() (uint32, error) {
- return wasm.Run(ctx, runtime, ffprobe, args)
+
+ // Load WASM rt and module.
+ ffmpreg := ffmpreg.Load()
+ if ffmpreg == nil {
+ return 0, errors.New("wasm not initialized")
+ }
+
+ // Call into ffprobe.
+ args.Name = "ffprobe"
+ return wasm.Run(ctx,
+ ffmpreg.run,
+ ffmpreg.mod,
+ args,
+ )
})
}
diff --git a/internal/media/ffmpeg/wasm.go b/internal/media/ffmpeg/wasm.go
index b23809d93..a5612ba14 100644
--- a/internal/media/ffmpeg/wasm.go
+++ b/internal/media/ffmpeg/wasm.go
@@ -22,72 +22,27 @@ package ffmpeg
import (
"context"
"os"
+ "sync/atomic"
+ "unsafe"
- ffmpeglib "codeberg.org/gruf/go-ffmpreg/embed/ffmpeg"
- ffprobelib "codeberg.org/gruf/go-ffmpreg/embed/ffprobe"
+ "codeberg.org/gruf/go-ffmpreg/embed"
"codeberg.org/gruf/go-ffmpreg/wasm"
"github.com/tetratelabs/wazero"
)
-var (
- // shared WASM runtime instance.
- runtime wazero.Runtime
-
- // ffmpeg / ffprobe compiled WASM.
- ffmpeg wazero.CompiledModule
- ffprobe wazero.CompiledModule
-)
-
-// compileFfmpeg ensures the ffmpeg WebAssembly has been
-// pre-compiled into memory. If already compiled is a no-op.
-func compileFfmpeg(ctx context.Context) error {
- if ffmpeg != nil {
- return nil
- }
-
- // Ensure runtime already initialized.
- if err := initRuntime(ctx); err != nil {
- return err
- }
-
- // Compile the ffmpeg WebAssembly module into memory.
- cmod, err := runtime.CompileModule(ctx, ffmpeglib.B)
- if err != nil {
- return err
- }
-
- // Set module.
- ffmpeg = cmod
- return nil
-}
-
-// compileFfprobe ensures the ffprobe WebAssembly has been
-// pre-compiled into memory. If already compiled is a no-op.
-func compileFfprobe(ctx context.Context) error {
- if ffprobe != nil {
- return nil
- }
-
- // Ensure runtime already initialized.
- if err := initRuntime(ctx); err != nil {
- return err
- }
-
- // Compile the ffprobe WebAssembly module into memory.
- cmod, err := runtime.CompileModule(ctx, ffprobelib.B)
- if err != nil {
- return err
- }
-
- // Set module.
- ffprobe = cmod
- return nil
-}
-
-// initRuntime initializes the global wazero.Runtime,
-// if already initialized this function is a no-op.
-func initRuntime(ctx context.Context) (err error) {
- if runtime != nil {
+// ffmpreg is a concurrency-safe pointer
+// to our necessary WebAssembly runtime
+// and compiled ffmpreg module instance.
+var ffmpreg atomic.Pointer[struct {
+ run wazero.Runtime
+ mod wazero.CompiledModule
+}]
+
+// initWASM safely prepares new WebAssembly runtime
+// and compiles ffmpreg module instance, if the global
+// pointer has not been already. else, is a no-op.
+func initWASM(ctx context.Context) error {
+ if ffmpreg.Load() != nil {
return nil
}
@@ -105,7 +60,59 @@ func initRuntime(ctx context.Context) (err error) {
cfg = cfg.WithCompilationCache(cache)
}
+ var (
+ run wazero.Runtime
+ mod wazero.CompiledModule
+ err error
+ set bool
+ )
+
+ defer func() {
+ if err == nil && set {
+ // Drop binary.
+ embed.B = nil
+ return
+ }
+
+ // Close module.
+ if !isNil(mod) {
+ mod.Close(ctx)
+ }
+
+ // Close runtime.
+ if !isNil(run) {
+ run.Close(ctx)
+ }
+ }()
+
// Initialize new runtime from config.
- runtime, err = wasm.NewRuntime(ctx, cfg)
- return
+ run, err = wasm.NewRuntime(ctx, cfg)
+ if err != nil {
+ return err
+ }
+
+ // Compile ffmpreg WebAssembly into memory.
+ mod, err = run.CompileModule(ctx, embed.B)
+ if err != nil {
+ return err
+ }
+
+ // Try set global WASM runtime and module,
+ // or if beaten to it defer will handle close.
+ set = ffmpreg.CompareAndSwap(nil, &struct {
+ run wazero.Runtime
+ mod wazero.CompiledModule
+ }{
+ run: run,
+ mod: mod,
+ })
+
+ return nil
+}
+
+// isNil will safely check if 'v' is nil without
+// dealing with weird Go interface nil bullshit.
+func isNil(i interface{}) bool {
+ type eface struct{ Type, Data unsafe.Pointer }
+ return (*eface)(unsafe.Pointer(&i)).Data == nil
}