DataHoarder
883dad8b84
All checks were successful
continuous-integration/drone/push Build is passing
92 lines
1.6 KiB
Go
92 lines
1.6 KiB
Go
package ffmpeg
|
|
|
|
import (
|
|
"fmt"
|
|
"git.gammaspectra.live/S.O.N.G/Ignite/decoder/y4m"
|
|
"git.gammaspectra.live/S.O.N.G/Ignite/frame"
|
|
"git.gammaspectra.live/S.O.N.G/Ignite/utilities"
|
|
"io"
|
|
"os"
|
|
"os/exec"
|
|
"strconv"
|
|
)
|
|
|
|
type Decoder struct {
|
|
cmd *exec.Cmd
|
|
y4m *y4m.Decoder
|
|
}
|
|
|
|
func NewDecoder(r io.Reader, settings map[string]any) (d *Decoder, err error) {
|
|
videoIndex, err := strconv.ParseUint(utilities.GetSettingString(settings, "input-video-index", "0"), 10, 0)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
ffmpegBinary := "ffmpeg"
|
|
if p := os.Getenv("FFMPEG_PATH"); p != "" {
|
|
ffmpegBinary = p
|
|
}
|
|
|
|
cmd := exec.Command(ffmpegBinary,
|
|
//"-v", "quiet",
|
|
"-strict", "experimental",
|
|
"-i", "-",
|
|
"-map_metadata", "-1",
|
|
"-map", fmt.Sprintf("0:v:%d", videoIndex),
|
|
"-f", "yuv4mpegpipe",
|
|
"-strict", "experimental",
|
|
"-",
|
|
)
|
|
cmd.Stdin = r
|
|
|
|
pipeR, pipeW := io.Pipe()
|
|
cmd.Stdout = pipeW
|
|
|
|
cmd.Stderr = os.Stderr
|
|
|
|
err = cmd.Start()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
d = &Decoder{
|
|
cmd: cmd,
|
|
}
|
|
|
|
d.y4m, err = y4m.NewDecoder(pipeR, settings)
|
|
if err != nil {
|
|
d.Close()
|
|
return nil, err
|
|
}
|
|
|
|
return d, nil
|
|
}
|
|
|
|
func (d *Decoder) Decode() (frame.Frame, error) {
|
|
return d.y4m.Decode()
|
|
}
|
|
|
|
func (d *Decoder) DecodeStream() *frame.Stream {
|
|
return d.y4m.DecodeStream()
|
|
}
|
|
|
|
func (d *Decoder) Properties() frame.StreamProperties {
|
|
return d.y4m.Properties()
|
|
}
|
|
|
|
func (d *Decoder) Version() string {
|
|
return d.y4m.Version()
|
|
}
|
|
|
|
func (d *Decoder) Close() {
|
|
if d.y4m != nil {
|
|
d.y4m.Close()
|
|
d.y4m = nil
|
|
}
|
|
if d.cmd != nil {
|
|
d.cmd.Process.Kill()
|
|
d.cmd.Process.Release()
|
|
d.cmd = nil
|
|
}
|
|
}
|