mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
[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
This commit is contained in:
@ -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
|
||||
// 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
|
||||
}]
|
||||
|
||||
// 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 {
|
||||
// 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
|
||||
}
|
||||
|
Reference in New Issue
Block a user