diff --git a/internal/encoder/encoder.go b/internal/encoder/encoder.go index dabaf08..296d257 100644 --- a/internal/encoder/encoder.go +++ b/internal/encoder/encoder.go @@ -195,16 +195,26 @@ func (e *Encoder) calculateZscaleWidth(path string, originalHeight int) (string, newWidth := width - if sar != "1:1" && sar != "N/A" && sar != "" { - parts := strings.Split(sar, ":") - if len(parts) == 2 { - num, err1 := strconv.Atoi(parts[0]) - den, err2 := strconv.Atoi(parts[1]) - if err1 == nil && err2 == nil && den != 0 { - newWidth = (width * num) / den - fmt.Printf("DEBUG calculated new width: %d (sar=%s)\n", newWidth, sar) - } - } + if sar == "1:1" || sar == "N/A" || sar == "" { + return "", newWidth, nil + } + + parts := strings.Split(sar, ":") + if len(parts) != 2 { + return "", newWidth, nil + } + num, err1 := strconv.Atoi(parts[0]) + den, err2 := strconv.Atoi(parts[1]) + if err1 != nil || err2 != nil || num == 0 || den == 0 { + return "", newWidth, nil + } + + // Round to nearest, then snap down to even (mod-2 widths preferred by AV1/H.264). + newWidth = ((width*num + den/2) / den) &^ 1 + fmt.Printf("DEBUG calculated new width: %d (sar=%s)\n", newWidth, sar) + + if newWidth == width { + return "", newWidth, nil } zscale := fmt.Sprintf("zscale=w=%d:h=%d:filter=spline36", newWidth, height) @@ -270,12 +280,15 @@ func (e *Encoder) encodeVideo(input string, opusFiles []string, job *types.Job, fmt.Printf("DEBUG zscale: %s (newWidth=%d)\n", zscaleStr, newWidth) - vf := zscaleStr + var filters []string if interlaced { - vf = "bwdif=mode=0:par=-1:-1," + vf + filters = append(filters, "bwdif=mode=0:par=-1:-1") + } + if zscaleStr != "" { + filters = append(filters, zscaleStr) } - fmt.Printf("DEBUG final vf: %s\n", vf) + fmt.Printf("DEBUG final vf: %s\n", strings.Join(filters, ",")) args := []string{ "-y", @@ -286,7 +299,9 @@ func (e *Encoder) encodeVideo(input string, opusFiles []string, job *types.Job, args = append(args, "-i", opus) } - args = append(args, "-vf", vf) + if len(filters) > 0 { + args = append(args, "-vf", strings.Join(filters, ",")) + } args = append(args, "-c:v", "libsvtav1") args = append(args, "-crf", strconv.Itoa(job.CRF)) args = append(args, "-preset", strconv.Itoa(job.Preset))