Files
tdarr-plugs/agent_notes/analysis.md
Tdarr Plugin Developer aa71eb96d7 Initial commit: Tdarr plugin stack
Plugins:
- misc_fixes v2.8: Pre-processing, container remux, stream conforming
- stream_organizer v4.8: English priority, subtitle extraction, SRT conversion
- combined_audio_standardizer v1.13: AAC/Opus encoding, downmix creation
- av1_svt_converter v2.22: AV1 video encoding via SVT-AV1

Structure:
- Local/ - Plugin .js files (mount in Tdarr)
- agent_notes/ - Development documentation
- Latest-Reports/ - Error logs for analysis
2025-12-15 11:33:36 -08:00

4.7 KiB

SVT-AV1 Plugin Bitrate Feature Analysis

Current State

Existing Bitrate Control

The plugin currently implements bitrate control via the maxrate_cap dropdown input:

  • Type: Dropdown with 11 preset values
  • Options: 0 (unlimited), 2000, 3000, 4000, 5000, 6000, 8000, 10000, 12000, 15000, 20000 kbps
  • Default: 0* (unlimited)
  • Implementation: Lines 531-540 in the plugin
  • Behavior: When set to non-zero, applies -maxrate and -bufsize (2x maxrate) to FFmpeg command

Current Logic Flow

graph TD
    A[Start] --> B{maxrate_cap != 0?}
    B -->|Yes| C[Apply maxrate + bufsize<br/>Buffer = 2.0x maxrate]
    B -->|No| D[Uncapped CRF<br/>No bitrate limit]
    C --> E[Build FFmpeg Command]
    D --> E

Requirements from Agent Notes

From implementation_plan.md:

  1. Custom Maxrate: Allow users to manually type a specific kbps value (not limited to dropdown presets)
  2. Source-Relative Bitrate: Allow setting bitrate cap relative to source file bitrate
    • Options: match_source, 75%_source, 50%_source, 33%_source, 25%_source
  3. Logic Precedence:
    • If strategy ≠ static → Calculate from source
    • Else if custom_maxrate > 0 → Use custom value
    • Else → Use maxrate_cap dropdown

Design Decisions

Input Design

1. Custom Maxrate Input

  • Type: Text input (string)
  • Default: Empty string ''
  • Validation: Parse as integer, check > 0, handle NaN gracefully
  • Position: After maxrate_cap dropdown

2. Target Bitrate Strategy Dropdown

  • Type: Dropdown
  • Options: 6 choices
    • static* - Use custom_maxrate or maxrate_cap (default)
    • match_source - Match source bitrate (100%)
    • 75%_source - 75% of source
    • 50%_source - 50% of source
    • 33%_source - 33% of source
    • 25%_source - 25% of source
  • Position: After custom_maxrate input

Bitrate Detection Strategy

graph TD
    A[Start] --> B[Check videoStream.bit_rate]
    B -->|Available| C[Use video stream bitrate]
    B -->|Missing| D[Check format.bit_rate]
    D -->|Available| E[Use overall file bitrate]
    D -->|Missing| F[sourceBitrateKbps = null<br/>Log warning]
    C --> G[Convert bps to kbps]
    E --> G
    G --> H[sourceBitrateKbps ready]
    F --> I[Fall back to static mode]

Key Details:

  • Primary source: file.ffProbeData.streams[videoStreamIndex].bit_rate (bps)
  • Fallback: file.ffProbeData.format.bit_rate (bps)
  • Conversion: Divide by 1000 to get kbps
  • Graceful failure: If neither available, log warning and use static mode

Logic Precedence Implementation

// Priority 1: target_bitrate_strategy (highest)
if (strategy !== 'static' && sourceBitrateKbps) {
  calculatedMaxrate = Math.round(sourceBitrateKbps * multiplier);
}

// Priority 2: custom_maxrate (middle)
if (!calculatedMaxrate && custom_maxrate !== '' && parseInt(custom_maxrate) > 0) {
  calculatedMaxrate = parseInt(custom_maxrate);
}

// Priority 3: maxrate_cap dropdown (lowest, existing)
if (!calculatedMaxrate && maxrate_cap !== '0') {
  calculatedMaxrate = parseInt(maxrate_cap);
}

// Priority 4: No limit (default)
if (!calculatedMaxrate) {
  // Uncapped CRF mode (existing behavior)
}

Info Logging Strategy

Add clear logs to help users understand which bitrate method was used:

  • Strategy mode: "Using target bitrate strategy '50%_source': Source bitrate 10000k → Maxrate 5000k"
  • Custom mode: "Using custom maxrate: 7500k"
  • Dropdown mode: "Using maxrate cap from dropdown: 5000k"
  • Fallback warning: "Warning: target_bitrate_strategy selected but source bitrate unavailable. Falling back to static mode."

Edge Cases to Handle

  1. Invalid custom_maxrate input

    • Non-numeric strings → Ignore, fall through to dropdown
    • Negative numbers → Ignore, fall through to dropdown
    • Zero → Treat as empty, fall through to dropdown
  2. Missing source bitrate with strategy selected

    • Log warning message
    • Fall back to custom_maxrate or maxrate_cap
    • Don't error/crash the plugin
  3. All inputs empty/zero

    • Default to uncapped CRF mode (existing behavior)
    • No maxrate applied
  4. Conflicting inputs

    • User sets both strategy and custom_maxrate
    • Strategy takes precedence (as designed)
    • Log which one was used

Compatibility Considerations

  • Backward compatible: Existing configurations continue to work
  • Default behavior: target_bitrate_strategy = 'static' and custom_maxrate = '' → Original behavior
  • No breaking changes: All new inputs have safe defaults
  • FFmpeg compatibility: Uses existing -maxrate and -bufsize flags (no new FFmpeg requirements)