Skip to content

Disallow invalid samplerates #801

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions src/log.nim
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ type BarType* = enum

type PackedInt* = distinct int64

proc pack*(flag: bool, number: int64): PackedInt =
func pack*(flag: bool, number: int64): PackedInt =
let maskedNumber = number and 0x7FFFFFFFFFFFFFFF'i64
let flagBit = if flag: 0x8000000000000000'i64 else: 0'i64
PackedInt(flagBit or maskedNumber)

proc getFlag*(packed: PackedInt): bool =
func getFlag*(packed: PackedInt): bool =
int64(packed) < 0

proc getNumber*(packed: PackedInt): int64 =
func getNumber*(packed: PackedInt): int64 =
let raw = int64(packed) and 0x7FFFFFFFFFFFFFFF'i64
if (raw and 0x4000000000000000'i64) != 0:
raw or 0x8000000000000000'i64
Expand Down Expand Up @@ -116,7 +116,6 @@ proc closeTempDir*() =
if tempDir != "":
try:
removeDir(tempDir)
debug "Removed Temp Directory."
except OSError:
discard

Expand All @@ -136,7 +135,7 @@ proc error*(msg: string) {.noreturn.} =
type StringInterner* = object
strings*: Table[string, ptr string]

proc newStringInterner*(): StringInterner =
func newStringInterner*(): StringInterner =
result.strings = initTable[string, ptr string]()

proc intern*(interner: var StringInterner, s: string): ptr string =
Expand Down
36 changes: 28 additions & 8 deletions src/render/format.nim
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,36 @@ type Priority = object
frame: ptr AVFrame
stream: ptr AVStream

proc initPriority(index: float64, frame: ptr AVFrame, stream: ptr AVStream): Priority =
func initPriority(index: float64, frame: ptr AVFrame, stream: ptr AVStream): Priority =
result.index = index
result.frame = frame
result.stream = stream

proc `<`(a, b: Priority): bool = a.index < b.index
func `<`(a, b: Priority): bool = a.index < b.index


proc checkAudioEncoder(encoder: ptr AVCodec, rate: cint) =
if encoder.sample_fmts == nil:
error &"{encoder.name}: No known audio formats avail."

var allowed: seq[cint]

if encoder.supported_samplerates != nil:
var i: cint = 0
let samplerates = cast[ptr UncheckedArray[cint]](encoder.supported_samplerates)
while samplerates[i] != 0:
allowed.add samplerates[i]
inc i
else:
if encoder.id == 86018: # aac_at
allowed = @[48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000]
else:
debug "audio encoder claims to support every samplerate"
return

if rate notin allowed:
let allowedStr = allowed.join(" ")
error &"samplerate '{rate}' not allowed for {encoder.name}.\nAllowed: {allowedStr}"

proc makeMedia*(args: mainArgs, tl: v3, outputPath: string, rules: Rules, bar: Bar) =
var options: Table[string, string]
Expand Down Expand Up @@ -68,9 +92,7 @@ proc makeMedia*(args: mainArgs, tl: v3, outputPath: string, rules: Rules, bar: B
var (aOutStream, aEncCtx) = output.addStream(args.audioCodec, rate = rate,
layout = tl.layout, metadata = {"language": "und"}.toTable)
let encoder = aEncCtx.codec
if encoder.sample_fmts == nil:
error &"{encoder.name}: No known audio formats avail."

checkAudioEncoder(encoder, tl.sr)
aEncCtx.open()

# Update stream parameters after opening encoder for formats like AAC in MKV
Expand Down Expand Up @@ -98,9 +120,7 @@ proc makeMedia*(args: mainArgs, tl: v3, outputPath: string, rules: Rules, bar: B
var (aOutStream, aEncCtx) = output.addStream(args.audioCodec, rate = rate,
layout = tl.layout, metadata = {"language": tl.a[i].lang}.toTable)
let encoder = aEncCtx.codec
if encoder.sample_fmts == nil:
error &"{encoder.name}: No known audio formats avail."

checkAudioEncoder(encoder, tl.sr)
aEncCtx.open()

# Update stream parameters after opening encoder for formats like AAC in MKV
Expand Down
6 changes: 3 additions & 3 deletions src/util/rules.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@ import std/strformat
import ../ffmpeg
import ../log

proc defaultVideoCodec*(self: ptr AVOutputFormat): string =
func defaultVideoCodec*(self: ptr AVOutputFormat): string =
let codecId = self.video_codec
if codecId != AV_CODEC_ID_NONE:
let codecName = avcodec_get_name(codecId)
if codecName != nil:
return $codecName
return "none"

proc defaultAudioCodec*(self: ptr AVOutputFormat): string =
func defaultAudioCodec*(self: ptr AVOutputFormat): string =
let codecId = self.audio_codec
if codecId != AV_CODEC_ID_NONE:
let codecName = avcodec_get_name(codecId)
if codecName != nil:
return $codecName
return "none"

proc defaultSubtitleCodec*(self: ptr AVOutputFormat): string =
func defaultSubtitleCodec*(self: ptr AVOutputFormat): string =
let codecId = self.subtitle_codec
if codecId != AV_CODEC_ID_NONE:
let codecName = avcodec_get_name(codecId)
Expand Down