Skip to content

Commit

Permalink
lpms: dont call GetCodecInfo for pipe, add pipe transmux test, remove…
Browse files Browse the repository at this point in the history
… excessive logging
  • Loading branch information
cyberj0g committed Jun 28, 2022
1 parent 622b507 commit ef2dba8
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 30 deletions.
Binary file added data/transmux.ts
Binary file not shown.
8 changes: 6 additions & 2 deletions ffmpeg/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1291,15 +1291,19 @@ func TestTranscoder_OutputFPS(t *testing.T) {
}

func TestTranscoderAPI_ClipInvalidConfig(t *testing.T) {
run, dir := setupTest(t)
cmd := `
cp "$1"/../transcoder/test.ts .`
run(cmd)
defer os.RemoveAll(dir)
tc := NewTranscoder()
defer tc.StopTranscoder()
in := &TranscodeOptionsIn{}
in := &TranscodeOptionsIn{Fname: fmt.Sprintf("%s/test.ts", dir)}
out := []TranscodeOptions{{
Oname: "-",
VideoEncoder: ComponentOptions{Name: "drop"},
From: time.Second,
}}

_, err := tc.Transcode(in, out)
if err == nil || err != ErrTranscoderClipConfig {
t.Errorf("Expected '%s', got %v", ErrTranscoderClipConfig, err)
Expand Down
54 changes: 26 additions & 28 deletions ffmpeg/ffmpeg.go
Original file line number Diff line number Diff line change
Expand Up @@ -554,12 +554,10 @@ func (l *CodingSizeLimit) Clamp(p *VideoProfile, format MediaFormatInfo) error {
adjustedHeight.H = clamp(h, l.HeightMin, l.HeightMax)
adjustedHeight.W = format.ScaledWidth(adjustedHeight.H)
if adjustedWidth.Valid(l) {
glog.Infof("[valid] profile %dx%d input=%dx%d accepted %dx%d\n", w, h, format.Width, format.Height, adjustedWidth.W, adjustedWidth.H)
p.Resolution = fmt.Sprintf("%dx%d", adjustedWidth.W, adjustedWidth.H)
return nil
}
if adjustedHeight.Valid(l) {
glog.Infof("[valid] profile %dx%d input=%dx%d accepted %dx%d\n", w, h, format.Width, format.Height, adjustedHeight.W, adjustedHeight.H)
p.Resolution = fmt.Sprintf("%dx%d", adjustedHeight.W, adjustedHeight.H)
return nil
}
Expand Down Expand Up @@ -836,20 +834,6 @@ func destroyCOutputParams(params []C.output_params) {
}

func (t *Transcoder) Transcode(input *TranscodeOptionsIn, ps []TranscodeOptions) (*TranscodeResults, error) {
// here we require input size and aspect ratio
status, format, err := GetCodecInfo(input.Fname)
if err != nil {
return nil, err
}
if status == CodecStatusOk {
// We dont return error in case status != CodecStatusOk because proper error would be returned later in the logic.
// Like 'TranscoderInvalidVideo' or `No such file or directory` would be replaced by error we specify here.
err = ensureEncoderLimits(ps, format)
if err != nil {
return nil, err
}
}

t.mu.Lock()
defer t.mu.Unlock()
if t.stopped || t.handle == nil {
Expand All @@ -858,6 +842,32 @@ func (t *Transcoder) Transcode(input *TranscodeOptionsIn, ps []TranscodeOptions)
if input == nil {
return nil, ErrTranscoderInp
}
// don't read metadata for pipe input, because it can't seek back and av_find_input_format in the decoder will fail
if !strings.HasPrefix(strings.ToLower(input.Fname), "pipe:") {
status, format, err := GetCodecInfo(input.Fname)
if err != nil {
return nil, err
}
if status == CodecStatusOk {
// We don't return error in case status != CodecStatusOk because proper error would be returned later in the logic.
// Like 'TranscoderInvalidVideo' or `No such file or directory` would be replaced by error we specify here.
// here we require input size and aspect ratio
err = ensureEncoderLimits(ps, format)
if err != nil {
return nil, err
}
}
if !t.started {
// NeedsBypass is state where video is present in container & without any frames
videoMissing := status == CodecStatusNeedsBypass || format.Vcodec == ""
if videoMissing {
// Audio-only segment, fail fast right here as we cannot handle them nicely
return nil, ErrTranscoderVid
}
// Stream is either OK or completely broken, let the transcoder handle it
t.started = true
}
}
hw_type, err := accelDeviceType(input.Accel)
if err != nil {
return nil, err
Expand All @@ -877,18 +887,6 @@ func (t *Transcoder) Transcode(input *TranscodeOptionsIn, ps []TranscodeOptions)
if input.Transmuxing {
t.started = true
}
if !t.started {
status, format, _ := GetCodecInfo(input.Fname)
// NeedsBypass is state where video is present in container & vithout any frames
videoMissing := status == CodecStatusNeedsBypass || format.Vcodec == ""
if videoMissing {
// Audio-only segment, fail fast right here as we cannot handle them nicely
return nil, ErrTranscoderVid
}
// Stream is either OK or completely broken, let the transcoder handle it
t.started = true
}

// Output configuration
params, finalizer, err := createCOutputParams(input, ps)
// This prevents C memory leaks
Expand Down
44 changes: 44 additions & 0 deletions ffmpeg/transmuxer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,54 @@ package ffmpeg

import (
"fmt"
"io"
"os"
"testing"
)

func TestTransmuxer_Pipe(t *testing.T) {
run, dir := setupTest(t)

run("cp \"$1\"/../data/transmux.ts .")
ir, iw, err := os.Pipe()
fname := fmt.Sprintf("%s/transmux.ts", dir)
_, err = os.Stat(fname)
if err != nil {
t.Fatal(err)
return
}
var bytesWritten int64
go func(iw *os.File) {
defer iw.Close()
f, _ := os.Open(fname)
b, _ := io.Copy(iw, f)
bytesWritten += b
}(iw)
fpipe := fmt.Sprintf("pipe:%d", ir.Fd())
oname := fmt.Sprintf("%s/test_out.ts", dir)
in := &TranscodeOptionsIn{
Fname: fpipe,
Transmuxing: true,
}
tc := NewTranscoder()
out := []TranscodeOptions{
{
Oname: oname,
VideoEncoder: ComponentOptions{
Name: "copy",
},
AudioEncoder: ComponentOptions{
Name: "copy",
},
Profile: VideoProfile{Format: FormatNone},
},
}
_, err = tc.Transcode(in, out)
if err != nil {
t.Fatal(err)
}
}

func TestTransmuxer_Join(t *testing.T) {
run, dir := setupTest(t)
defer os.RemoveAll(dir)
Expand Down

0 comments on commit ef2dba8

Please sign in to comment.