mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-10-29 07:42:25 -05:00
[feature] support processing of (many) more media types (#3090)
* initial work replacing our media decoding / encoding pipeline with ffprobe + ffmpeg
* specify the video codec to use when generating static image from emoji
* update go-storage library (fixes incompatibility after updating go-iotools)
* maintain image aspect ratio when generating a thumbnail for it
* update readme to show go-ffmpreg
* fix a bunch of media tests, move filesize checking to callers of media manager for more flexibility
* remove extra debug from error message
* fix up incorrect function signatures
* update PutFile to just use regular file copy, as changes are file is on separate partition
* fix remaining tests, remove some unneeded tests now we're working with ffmpeg/ffprobe
* update more tests, add more code comments
* add utilities to generate processed emoji / media outputs
* fix remaining tests
* add test for opus media file, add license header to utility cmds
* limit the number of concurrently available ffmpeg / ffprobe instances
* reduce number of instances
* further reduce number of instances
* fix envparsing test with configuration variables
* update docs and configuration with new media-{local,remote}-max-size variables
This commit is contained in:
parent
5bc567196b
commit
cde2fb6244
376 changed files with 8026 additions and 54091 deletions
181
vendor/codeberg.org/gruf/go-ffmpreg/wasm/instance.go
generated
vendored
Normal file
181
vendor/codeberg.org/gruf/go-ffmpreg/wasm/instance.go
generated
vendored
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
package wasm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"github.com/tetratelabs/wazero"
|
||||
"github.com/tetratelabs/wazero/sys"
|
||||
)
|
||||
|
||||
type Args struct {
|
||||
// Standard FDs.
|
||||
Stdin io.Reader
|
||||
Stdout io.Writer
|
||||
Stderr io.Writer
|
||||
|
||||
// CLI args.
|
||||
Args []string
|
||||
|
||||
// Optional further module configuration function.
|
||||
// (e.g. to mount filesystem dir, set env vars, etc).
|
||||
Config func(wazero.ModuleConfig) wazero.ModuleConfig
|
||||
}
|
||||
|
||||
type Instantiator struct {
|
||||
// Module ...
|
||||
Module string
|
||||
|
||||
// Runtime ...
|
||||
Runtime func(context.Context) wazero.Runtime
|
||||
|
||||
// Config ...
|
||||
Config func() wazero.ModuleConfig
|
||||
|
||||
// Source ...
|
||||
Source []byte
|
||||
}
|
||||
|
||||
func (inst *Instantiator) New(ctx context.Context) (*Instance, error) {
|
||||
switch {
|
||||
case inst.Module == "":
|
||||
panic("missing module name")
|
||||
case inst.Runtime == nil:
|
||||
panic("missing runtime instantiator")
|
||||
case inst.Config == nil:
|
||||
panic("missing module configuration")
|
||||
case len(inst.Source) == 0:
|
||||
panic("missing module source")
|
||||
}
|
||||
|
||||
// Create new host runtime.
|
||||
rt := inst.Runtime(ctx)
|
||||
|
||||
// Compile guest module from WebAssembly source.
|
||||
mod, err := rt.CompileModule(ctx, inst.Source)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Instance{
|
||||
inst: inst,
|
||||
wzrt: rt,
|
||||
cmod: mod,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type InstancePool struct {
|
||||
Instantiator
|
||||
|
||||
pool []*Instance
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
func (p *InstancePool) Get(ctx context.Context) (*Instance, error) {
|
||||
for {
|
||||
// Check for cached.
|
||||
inst := p.Cached()
|
||||
if inst == nil {
|
||||
break
|
||||
}
|
||||
|
||||
// Check if closed.
|
||||
if inst.IsClosed() {
|
||||
continue
|
||||
}
|
||||
|
||||
return inst, nil
|
||||
}
|
||||
|
||||
// Must create new instance.
|
||||
return p.Instantiator.New(ctx)
|
||||
}
|
||||
|
||||
func (p *InstancePool) Put(inst *Instance) {
|
||||
if inst.inst != &p.Instantiator {
|
||||
panic("instance and pool instantiators do not match")
|
||||
}
|
||||
p.lock.Lock()
|
||||
p.pool = append(p.pool, inst)
|
||||
p.lock.Unlock()
|
||||
}
|
||||
|
||||
func (p *InstancePool) Cached() *Instance {
|
||||
var inst *Instance
|
||||
p.lock.Lock()
|
||||
if len(p.pool) > 0 {
|
||||
inst = p.pool[len(p.pool)-1]
|
||||
p.pool = p.pool[:len(p.pool)-1]
|
||||
}
|
||||
p.lock.Unlock()
|
||||
return inst
|
||||
}
|
||||
|
||||
// Instance ...
|
||||
//
|
||||
// NOTE: Instance is NOT concurrency
|
||||
// safe. One at a time please!!
|
||||
type Instance struct {
|
||||
inst *Instantiator
|
||||
wzrt wazero.Runtime
|
||||
cmod wazero.CompiledModule
|
||||
}
|
||||
|
||||
func (inst *Instance) Run(ctx context.Context, args Args) (uint32, error) {
|
||||
if inst.inst == nil {
|
||||
panic("not initialized")
|
||||
}
|
||||
|
||||
// Check instance open.
|
||||
if inst.IsClosed() {
|
||||
return 0, errors.New("instance closed")
|
||||
}
|
||||
|
||||
// Prefix binary name as argv0 to args.
|
||||
cargs := make([]string, len(args.Args)+1)
|
||||
copy(cargs[1:], args.Args)
|
||||
cargs[0] = inst.inst.Module
|
||||
|
||||
// Create base module config.
|
||||
modcfg := inst.inst.Config()
|
||||
modcfg = modcfg.WithName(inst.inst.Module)
|
||||
modcfg = modcfg.WithArgs(cargs...)
|
||||
modcfg = modcfg.WithStdin(args.Stdin)
|
||||
modcfg = modcfg.WithStdout(args.Stdout)
|
||||
modcfg = modcfg.WithStderr(args.Stderr)
|
||||
|
||||
if args.Config != nil {
|
||||
// Pass through config fn.
|
||||
modcfg = args.Config(modcfg)
|
||||
}
|
||||
|
||||
// Instantiate the module from precompiled wasm module data.
|
||||
mod, err := inst.wzrt.InstantiateModule(ctx, inst.cmod, modcfg)
|
||||
|
||||
if mod != nil {
|
||||
// Close module.
|
||||
mod.Close(ctx)
|
||||
}
|
||||
|
||||
// Check for a returned exit code error.
|
||||
if err, ok := err.(*sys.ExitError); ok {
|
||||
return err.ExitCode(), nil
|
||||
}
|
||||
|
||||
return 0, err
|
||||
}
|
||||
|
||||
func (inst *Instance) IsClosed() bool {
|
||||
return (inst.wzrt == nil || inst.cmod == nil)
|
||||
}
|
||||
|
||||
func (inst *Instance) Close(ctx context.Context) error {
|
||||
if inst.IsClosed() {
|
||||
return nil
|
||||
}
|
||||
err1 := inst.cmod.Close(ctx)
|
||||
err2 := inst.wzrt.Close(ctx)
|
||||
return errors.Join(err1, err2)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue