fix: correct interlace detection and reap idet child
The previous detector substring-matched "TFF"/"BFF" against idet's own label text, so it returned true on every source, and `cmd.Start()` was never paired with `Wait()`, leaving a zombie ffmpeg per file. Run idet bounded with `-frames:v 400 -an -sn -f null -` so it completes, use CombinedOutput so the child is reaped, and parse the "Multi frame detection" summary line — interlaced only when TFF+BFF > Progressive.
This commit is contained in:
@@ -6,12 +6,15 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"videnc-vibe/pkg/types"
|
"videnc-vibe/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var idetSummaryRegex = regexp.MustCompile(`Multi frame detection:\s+TFF:\s*(\d+)\s+BFF:\s*(\d+)\s+Progressive:\s*(\d+)\s+Undetermined:\s*(\d+)`)
|
||||||
|
|
||||||
type Encoder struct {
|
type Encoder struct {
|
||||||
ffmpegPath string
|
ffmpegPath string
|
||||||
ffprobePath string
|
ffprobePath string
|
||||||
@@ -122,20 +125,43 @@ func (e *Encoder) GetMediaInfo(path string) (width, height int, interlaced bool,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = exec.Command(e.ffmpegPath, "-i", path, "-hide_banner", "-vf", "idet")
|
cmd = exec.Command(e.ffmpegPath,
|
||||||
stderr, _ := cmd.StderrPipe()
|
"-hide_banner",
|
||||||
cmd.Start()
|
"-nostats",
|
||||||
buf := make([]byte, 16384)
|
"-i", path,
|
||||||
n, _ := stderr.Read(buf)
|
"-vf", "idet",
|
||||||
stderr.Close()
|
"-frames:v", "400",
|
||||||
outputStr := string(buf[:n])
|
"-an", "-sn",
|
||||||
interlaced = strings.Contains(outputStr, "TFF") || strings.Contains(outputStr, "BFF")
|
"-f", "null", "-",
|
||||||
|
)
|
||||||
|
idetOut, _ := cmd.CombinedOutput()
|
||||||
|
interlaced = detectInterlaced(string(idetOut))
|
||||||
|
|
||||||
fmt.Printf("DEBUG interlaced: %v\n", interlaced)
|
fmt.Printf("DEBUG interlaced: %v\n", interlaced)
|
||||||
|
|
||||||
return width, height, interlaced, nil
|
return width, height, interlaced, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// detectInterlaced parses ffmpeg idet's "Multi frame detection" summary line
|
||||||
|
// and returns true when TFF+BFF clearly outnumber Progressive frames among
|
||||||
|
// the decided frames. Undetermined frames are ignored. If the summary line
|
||||||
|
// is missing, returns false (default to progressive).
|
||||||
|
func detectInterlaced(idetOutput string) bool {
|
||||||
|
m := idetSummaryRegex.FindStringSubmatch(idetOutput)
|
||||||
|
if m == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
tff, _ := strconv.Atoi(m[1])
|
||||||
|
bff, _ := strconv.Atoi(m[2])
|
||||||
|
prog, _ := strconv.Atoi(m[3])
|
||||||
|
interlaced := tff + bff
|
||||||
|
decided := interlaced + prog
|
||||||
|
if decided == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return interlaced > prog
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Encoder) calculateZscaleWidth(path string, originalHeight int) (string, int, error) {
|
func (e *Encoder) calculateZscaleWidth(path string, originalHeight int) (string, int, error) {
|
||||||
cmd := exec.Command(e.ffprobePath, "-v", "error", "-select_streams", "v:0", "-show_entries", "stream=width,height,sample_aspect_ratio", "-print_format", "json", path)
|
cmd := exec.Command(e.ffprobePath, "-v", "error", "-select_streams", "v:0", "-show_entries", "stream=width,height,sample_aspect_ratio", "-print_format", "json", path)
|
||||||
output, err := cmd.CombinedOutput()
|
output, err := cmd.CombinedOutput()
|
||||||
|
|||||||
Reference in New Issue
Block a user