From 8c6e604f26c6340f9270f63cf6ab234797c45cfc Mon Sep 17 00:00:00 2001 From: WeebDataHoarder <57538841+WeebDataHoarder@users.noreply.github.com> Date: Tue, 7 Nov 2023 09:24:01 +0100 Subject: [PATCH] Fixed ffmpeg stdin not closing, io.Seeker and io.EOF errors --- cli/encode-libaom/encode-libaom.go | 3 ++- decoder/ffmpeg/ffmpeg.go | 27 ++++++++++++++++++++------- decoder/libdav1d/libdav1d.go | 2 +- decoder/y4m/y4m.go | 24 ++++++++++++++++-------- encoder/libx264/libx264.go | 1 + 5 files changed, 40 insertions(+), 17 deletions(-) diff --git a/cli/encode-libaom/encode-libaom.go b/cli/encode-libaom/encode-libaom.go index 9580814..cad5769 100644 --- a/cli/encode-libaom/encode-libaom.go +++ b/cli/encode-libaom/encode-libaom.go @@ -4,6 +4,7 @@ package main import ( "encoding/csv" + "errors" "flag" "fmt" "git.gammaspectra.live/S.O.N.G/Ignite/encoder/libaom" @@ -91,7 +92,7 @@ func main() { for { record, err := c.Read() if err != nil { - if err == io.EOF { + if errors.Is(err, io.EOF) { break } panic(err) diff --git a/decoder/ffmpeg/ffmpeg.go b/decoder/ffmpeg/ffmpeg.go index 7f7e12a..f07fbd8 100644 --- a/decoder/ffmpeg/ffmpeg.go +++ b/decoder/ffmpeg/ffmpeg.go @@ -29,23 +29,31 @@ func NewDecoder(r io.Reader, settings map[string]any) (d *Decoder, err error) { cmd := exec.Command(ffmpegBinary, //"-v", "quiet", + "-probesize", "8192", "-strict", "experimental", - "-i", "-", + "-i", "pipe:", "-map_metadata", "-1", "-map", fmt.Sprintf("0:v:%d", videoIndex), "-f", "yuv4mpegpipe", "-strict", "experimental", - "-", + "pipe:", ) - cmd.Stdin = r - pipeR, pipeW := io.Pipe() - cmd.Stdout = pipeW + cmdIn, err := cmd.StdinPipe() + if err != nil { + return nil, err + } + + cmdOut, err := cmd.StdoutPipe() + if err != nil { + return nil, err + } cmd.Stderr = os.Stderr err = cmd.Start() if err != nil { + defer cmd.Process.Release() return nil, err } @@ -53,9 +61,14 @@ func NewDecoder(r io.Reader, settings map[string]any) (d *Decoder, err error) { cmd: cmd, } - d.y4m, err = y4m.NewDecoder(pipeR, settings) + go func() { + defer cmdIn.Close() + _, _ = io.Copy(cmdIn, r) + }() + + d.y4m, err = y4m.NewDecoder(cmdOut, settings) if err != nil { - d.Close() + defer d.Close() return nil, err } diff --git a/decoder/libdav1d/libdav1d.go b/decoder/libdav1d/libdav1d.go index 98124b1..b3aa368 100644 --- a/decoder/libdav1d/libdav1d.go +++ b/decoder/libdav1d/libdav1d.go @@ -125,7 +125,7 @@ func (d *Decoder) decodeFrame() C.int { if d.data.sz == 0 { if err := d.readIvf(); err != nil { - if err == io.EOF { + if errors.Is(err, io.EOF) { //try flush? if res = d.flushPicture(); res != -ErrEAGAIN { return res diff --git a/decoder/y4m/y4m.go b/decoder/y4m/y4m.go index fc20f48..9989989 100644 --- a/decoder/y4m/y4m.go +++ b/decoder/y4m/y4m.go @@ -15,6 +15,7 @@ import ( type Decoder struct { r io.Reader + seeker io.ReadSeeker frameSeekTable []int64 parameters map[Parameter][]string @@ -60,6 +61,13 @@ func NewDecoder(reader io.Reader, settings map[string]any) (*Decoder, error) { } var err error + if seeker, ok := s.r.(io.ReadSeeker); ok { + //test seeker + if _, err = seeker.Seek(0, io.SeekCurrent); err == nil { + s.seeker = seeker + } + } + if err = s.readHeader(); err != nil { return nil, err } @@ -130,9 +138,9 @@ func (s *Decoder) SeekToFrame(frameNumber int) (err error) { return nil } - if seeker, ok := s.r.(io.Seeker); ok { + if s.seeker != nil { if frameNumber >= 0 && len(s.frameSeekTable) > frameNumber && s.frameSeekTable[frameNumber] != 0 { - if _, err = seeker.Seek(s.frameSeekTable[frameNumber], io.SeekStart); err != nil { + if _, err = s.seeker.Seek(s.frameSeekTable[frameNumber], io.SeekStart); err != nil { return err } @@ -143,7 +151,7 @@ func (s *Decoder) SeekToFrame(frameNumber int) (err error) { //attempt blind seek from last decoded frame framesToSeekFromLast := frameNumber + 1 - len(s.frameSeekTable) - if _, err = seeker.Seek(s.frameSeekTable[len(s.frameSeekTable)-1]+int64(5+1+s.frameSize)*int64(framesToSeekFromLast), io.SeekStart); err != nil { + if _, err = s.seeker.Seek(s.frameSeekTable[len(s.frameSeekTable)-1]+int64(5+1+s.frameSize)*int64(framesToSeekFromLast), io.SeekStart); err != nil { return err } @@ -152,7 +160,7 @@ func (s *Decoder) SeekToFrame(frameNumber int) (err error) { return nil } else if frameNumber >= 0 && s.frameStartOffset != 0 { //attempt full blind seek from start - if _, err = seeker.Seek(s.frameStartOffset+int64(5+1+s.frameSize)*int64(frameNumber), io.SeekStart); err != nil { + if _, err = s.seeker.Seek(s.frameStartOffset+int64(5+1+s.frameSize)*int64(frameNumber), io.SeekStart); err != nil { return err } @@ -194,8 +202,8 @@ func (s *Decoder) GetFrameSeekTable() []int64 { func (s *Decoder) GetFrame() (parameters map[Parameter][]string, frameObject frame.Frame, err error) { var index int64 - if seeker, ok := s.r.(io.Seeker); ok { - if index, err = seeker.Seek(0, io.SeekCurrent); err != nil { + if s.seeker != nil { + if index, err = s.seeker.Seek(0, io.SeekCurrent); err != nil { return nil, nil, err } } @@ -377,8 +385,8 @@ func (s *Decoder) parseParameters() (err error) { s.frameSize, err = s.properties.ColorSpace.FrameSize(s.properties.Width, s.properties.Height) - if seeker, ok := s.r.(io.Seeker); ok { - if index, err := seeker.Seek(0, io.SeekCurrent); err == nil { + if s.seeker != nil { + if index, err := s.seeker.Seek(0, io.SeekCurrent); err == nil { s.frameStartOffset = index } } diff --git a/encoder/libx264/libx264.go b/encoder/libx264/libx264.go index 6481a78..d56f122 100644 --- a/encoder/libx264/libx264.go +++ b/encoder/libx264/libx264.go @@ -231,6 +231,7 @@ func (e *Encoder) Encode(f frame.Frame) error { copy(unsafe.Slice((*byte)(e.pictureIn.img.plane[2]), len(cr)), cr) e.pictureIn.i_pts = C.int64_t(f.PTS()) + //TODO: read flags for statistic tracking return e.encoderEncode(e.pictureIn) }