add: add interlaced detection and bwdif deinterlacing

This commit is contained in:
Esa Kataja
2026-04-04 18:08:25 +03:00
parent 9356d45074
commit 53adafbc40
2 changed files with 18 additions and 10 deletions
+2 -2
View File
@@ -82,7 +82,7 @@ func processFile(inputPath string, cfg *types.Config, enc *encoder.Encoder, meta
filename := filepath.Base(inputPath) filename := filepath.Base(inputPath)
isSeries, imdbID, tvmazeID, season, episode := metadata.ParseFilename(filename) isSeries, imdbID, tvmazeID, season, episode := metadata.ParseFilename(filename)
width, height, err := enc.GetMediaInfo(inputPath) width, height, interlaced, err := enc.GetMediaInfo(inputPath)
if err != nil { if err != nil {
log.ErrorFile(inputPath, "Getting media info", err.Error()) log.ErrorFile(inputPath, "Getting media info", err.Error())
mover.MoveToFailed(inputPath, cfg.Paths.Failed) mover.MoveToFailed(inputPath, cfg.Paths.Failed)
@@ -128,7 +128,7 @@ func processFile(inputPath string, cfg *types.Config, enc *encoder.Encoder, meta
DeleteOrigin: deleteOrigin, DeleteOrigin: deleteOrigin,
} }
if err := enc.Transcode(inputPath, job, meta); err != nil { if err := enc.Transcode(inputPath, job, meta, interlaced); err != nil {
log.ErrorFile(inputPath, "Transcoding", err.Error()) log.ErrorFile(inputPath, "Transcoding", err.Error())
mover.MoveToFailed(inputPath, cfg.Paths.Failed) mover.MoveToFailed(inputPath, cfg.Paths.Failed)
outputPath := filepath.Join(filepath.Dir(inputPath), "output.mkv") outputPath := filepath.Join(filepath.Dir(inputPath), "output.mkv")
+16 -8
View File
@@ -33,21 +33,24 @@ func (e *Encoder) CheckDeps() error {
return nil return nil
} }
func (e *Encoder) GetMediaInfo(path string) (width, height int, err error) { func (e *Encoder) GetMediaInfo(path string) (width, height int, interlaced bool, err error) {
cmd := exec.Command(e.ffmpegPath, "-i", path, "-hide_banner") cmd := exec.Command(e.ffmpegPath, "-i", path, "-hide_banner", "-vf", "idet")
output, _ := cmd.StderrPipe() output, _ := cmd.StderrPipe()
cmd.Start() cmd.Start()
buf := make([]byte, 8192) buf := make([]byte, 16384)
n, _ := output.Read(buf) n, _ := output.Read(buf)
output.Close() output.Close()
var w, h int var w, h int
fmt.Sscanf(string(buf[:n]), "%dx%d", &w, &h) fmt.Sscanf(string(buf[:n]), "%dx%d", &w, &h)
return w, h, nil
interlaced = strings.Contains(string(buf[:n]), "TFF") || strings.Contains(string(buf[:n]), "BFF")
return w, h, interlaced, nil
} }
func (e *Encoder) Transcode(input string, job *types.Job, metadata *types.Metadata) error { func (e *Encoder) Transcode(input string, job *types.Job, metadata *types.Metadata, interlaced bool) error {
dir := filepath.Dir(input) dir := filepath.Dir(input)
audioWavs, err := e.extractAudio(input, dir) audioWavs, err := e.extractAudio(input, dir)
if err != nil { if err != nil {
@@ -61,7 +64,7 @@ func (e *Encoder) Transcode(input string, job *types.Job, metadata *types.Metada
} }
defer e.cleanupOpus(opusFiles) defer e.cleanupOpus(opusFiles)
if err := e.encodeVideo(input, opusFiles, job, metadata); err != nil { if err := e.encodeVideo(input, opusFiles, job, metadata, interlaced); err != nil {
return fmt.Errorf("encoding video: %w", err) return fmt.Errorf("encoding video: %w", err)
} }
@@ -93,12 +96,17 @@ func (e *Encoder) encodeOpus(wavs []string, dir string) ([]string, error) {
return opusFiles, nil return opusFiles, nil
} }
func (e *Encoder) encodeVideo(input string, opusFiles []string, job *types.Job, metadata *types.Metadata) error { func (e *Encoder) encodeVideo(input string, opusFiles []string, job *types.Job, metadata *types.Metadata, interlaced bool) error {
dir := filepath.Dir(input) dir := filepath.Dir(input)
outFile := filepath.Join(dir, "output.mkv") outFile := filepath.Join(dir, "output.mkv")
svtParams := fmt.Sprintf("film-grain=10:film-grain-denoise=1:scd=1:qm-min=4:qm-max=15:preset=%d", job.Preset) svtParams := fmt.Sprintf("film-grain=10:film-grain-denoise=1:scd=1:qm-min=4:qm-max=15:preset=%d", job.Preset)
vf := "zscale=filter=spline36:mode=16:9"
if interlaced {
vf = "bwdif=mode=0:par=-1:-1," + vf
}
args := []string{ args := []string{
"-y", "-y",
"-i", input, "-i", input,
@@ -106,7 +114,7 @@ func (e *Encoder) encodeVideo(input string, opusFiles []string, job *types.Job,
"-crf", strconv.Itoa(job.CRF), "-crf", strconv.Itoa(job.CRF),
"-svtav1-params", svtParams, "-svtav1-params", svtParams,
"-pix_fmt", "yuv420p10le", "-pix_fmt", "yuv420p10le",
"-vf", "zscale=filter=spline36:mode=16:9", "-vf", vf,
"-c:a", "copy", "-c:a", "copy",
"-c:s", "copy", "-c:s", "copy",
} }