Fixed ffmpeg stdin not closing, io.Seeker and io.EOF errors
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
DataHoarder 2023-11-07 09:24:01 +01:00
parent 230d505377
commit 8c6e604f26
Signed by: DataHoarder
SSH key fingerprint: SHA256:OLTRf6Fl87G52SiR7sWLGNzlJt4WOX+tfI2yxo0z7xk
5 changed files with 40 additions and 17 deletions

View file

@ -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)

View file

@ -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
}

View file

@ -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

View file

@ -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
}
}

View file

@ -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)
}