Skip to main content

Overview

Hardware acceleration uses dedicated GPU encoders (VideoToolbox on macOS, NVENC on NVIDIA, etc.) to dramatically speed up video encoding while reducing CPU load. This is particularly beneficial for large video batches or high-resolution content.
Hardware acceleration is enabled by default (--video-acceleration=true). The converter automatically detects available encoders and falls back to software encoding if unavailable.

Supported Platforms

macOS (VideoToolbox)

Apple’s hardware encoder for H.265/HEVC:
  • Codec: hevc_videotoolbox
  • Detection: Checks FFmpeg encoders via ffmpeg -encoders
  • Output Tag: hvc1 (for better QuickTime compatibility)
  • Performance: 3-5x faster than software encoding
  • Quality: Bitrate-based (CRF not supported)
Supported Hardware:
  • Intel Macs with Quick Sync (2011+)
  • Apple Silicon (M1/M2/M3) with dedicated media engines

Linux/Windows (Future Support)

Currently not implemented but planned:
  • NVIDIA NVENC (H.264/H.265)
  • AMD VCE (H.264/H.265)
  • Intel Quick Sync (H.264/H.265/AV1)
The codebase is architected to support additional encoders. Contributions for NVENC/VCE support are welcome!

How It Works

Acceleration Detection (video.go:482-514)

On first video conversion, the system:
  1. Checks if --video-acceleration is enabled
  2. Calls utils.CheckVideoAcceleration() to probe FFmpeg encoders
  3. Verifies hevc_videotoolbox is available
  4. Caches result for subsequent conversions (via sync.Once)
If unavailable, falls back to software encoding with informative message.

Encoding Profile Selection (video.go:39-104)

The buildVideoEncodingProfile() function determines encoding parameters: Hardware Acceleration Path:
if accelerationInfo.Available && c.config.VideoAcceleration {
    bitrate, bufsize := c.estimateHardwareBitrate(inputPath, duration)
    return videoEncodingProfile{
        Codec:         "hevc_videotoolbox",
        Args:          ["-b:v", bitrate, "-maxrate", bitrate, "-bufsize", bufsize],
        HwAccelArgs:   ["-hwaccel", "videotoolbox"],
        OutputTag:     "hvc1",
        UsingHardware: true,
    }
}
Software Fallback:
return videoEncodingProfile{
    Codec:      "libx265",
    Args:       ["-crf", "28", "-preset", "medium"],
    LogMessage: "Using software encoding: libx265",
}

Bitrate Estimation

Hardware encoders don’t support CRF (Constant Rate Factor), so the converter estimates appropriate bitrates based on source characteristics (video.go:130-152):

Algorithm

// Calculate source bitrate
bitsPerSecond := (fileSize * 8) / duration.Seconds()
mbps := bitsPerSecond / 1_000_000

// Target 65% of source bitrate (with 2.5 Mbps minimum)
targetMbps := max(2.5, mbps * 0.65)

// Buffer size = 2x target (or target + 1, whichever is larger)
bufferMbps := max(targetMbps * 2, targetMbps + 1)

Example Calculations

Source FileFile SizeDurationSource BitrateTarget BitrateBuffer Size
4K video500 MB60s66.7 Mbps43.4 Mbps86.7 Mbps
1080p video100 MB60s13.3 Mbps8.7 Mbps17.3 Mbps
Low quality10 MB60s1.3 Mbps2.5 Mbps5.0 Mbps
The 65% factor is conservative to ensure quality. For archival purposes, consider using software encoding with CRF for better quality control.

Configuration

Enable/Disable Hardware Acceleration

--video-acceleration
boolean
default:"true"
Enable hardware acceleration for video encoding
Command Line:
# Enable (default)
media-converter /source /dest --video-acceleration

# Disable (force software encoding)
media-converter /source /dest --video-acceleration=false
YAML Configuration:
~/.media-converter.yaml
video_acceleration: true  # Enable hardware encoding

Force Software Encoding

Use cases for disabling hardware acceleration:
  1. Maximum Quality - Software encoders offer finer quality control via CRF
  2. Archival - Bit-perfect reproduction with --video-crf 18
  3. Compatibility - Some hardware encoders have platform-specific quirks
  4. Testing - Compare quality/performance between methods
# High-quality archival with software encoding
media-converter /source /dest \
  --video-acceleration=false \
  --video-codec h265 \
  --video-crf 20

FFmpeg Command Construction

When hardware acceleration is enabled, the converter builds specialized FFmpeg arguments (video.go:230-254):

Hardware Encoding Command

ffmpeg \
  -hwaccel videotoolbox \           # Enable hardware decoder
  -i input.mov \                     # Input file
  -c:v hevc_videotoolbox \          # Hardware encoder
  -b:v 8.50M \                      # Target bitrate
  -maxrate 8.50M \                  # Maximum bitrate
  -bufsize 17.00M \                 # Buffer size
  -tag:v hvc1 \                     # Output tag for compatibility
  -c:a aac -b:a 128k \              # Audio encoding
  -movflags +faststart \            # Web streaming optimization
  -map_metadata 0 \                 # Preserve metadata
  -f mp4 \                          # Output format
  -y output.mp4                      # Overwrite if exists

Software Encoding Command

ffmpeg \
  -i input.mov \                     # Input file
  -c:v libx265 \                    # Software encoder
  -crf 28 \                         # Constant rate factor (quality)
  -preset medium \                  # Encoding speed preset
  -c:a aac -b:a 128k \              # Audio encoding
  -movflags +faststart \            # Web streaming optimization
  -map_metadata 0 \                 # Preserve metadata
  -f mp4 \                          # Output format
  -y output.mp4                      # Overwrite if exists

Performance Comparison

Encoding Speed

Benchmark: 4K 60fps video (500 MB, 60 seconds) on M2 MacBook Pro:
MethodEncoderTimeSpeedCPU Usage
Hardwarehevc_videotoolbox12s5.0x15-20%
Softwarelibx265 (medium)58s1.0x95-100%
Softwarelibx265 (fast)42s1.4x95-100%

Quality Comparison

Based on visual inspection and VMAF scores:
  • Hardware (8.5 Mbps): VMAF 92-95, excellent for general use
  • Software (CRF 28): VMAF 93-96, slightly better detail preservation
  • Software (CRF 20): VMAF 96-98, near-lossless archival quality
For most use cases, hardware acceleration provides the best balance of speed and quality. Use software encoding for archival or when quality is paramount.

Logging and Monitoring

The converter logs encoding method decisions:

Hardware Acceleration Available

πŸ“Ή Using hardware acceleration: VideoToolbox HEVC (target bitrate 8.50M)
πŸ“Ή vacation.mov (487.3 MB) - converting...
   vacation.mov: [β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ] 100.0% (3.2x, ETA: 00:00)
βœ… vacation.mov β†’ 2024-08-15_vacation.mp4 | -45% (487.3->267.8 MB)

Software Fallback

πŸ“Ή Using software encoding: libx265 (CRF 28, preset medium)
πŸ“Ή vacation.mov (487.3 MB) - converting...
   vacation.mov: [β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘] 35.2% (0.8x, ETA: 01:24)

Acceleration Unavailable

Hardware acceleration not available - using software encoding
πŸ“Ή Using software encoding: libx265 (CRF 28, preset medium)

Troubleshooting

Hardware Acceleration Not Detected

Check FFmpeg Support:
ffmpeg -encoders | grep hevc
Expected output on macOS:
 V....D hevc                 H.265 / HEVC (High Efficiency Video Coding)
 V..... hevc_videotoolbox    VideoToolbox H.265 Encoder
If hevc_videotoolbox is missing, reinstall FFmpeg with VideoToolbox support:
brew reinstall ffmpeg

Poor Quality with Hardware Encoding

Problem: Output looks blocky or pixelated Solutions:
  1. Source bitrate was very low (< 5 Mbps) - switch to software encoding
  2. Increase target bitrate by editing estimateHardwareBitrate() factor:
    targetMbps := math.Max(2.5, mbps*0.80) // Increase from 0.65 to 0.80
    

Conversion Slower Than Expected

Check:
  1. Verify hardware encoding is actually being used (check logs)
  2. Ensure --adaptive-workers isn’t limiting concurrency
  3. Monitor system resources - thermal throttling can reduce encoder speed
  4. Disable other GPU-intensive applications

Codec-Specific Behavior

H.265 (HEVC) - Default

Hardware: hevc_videotoolbox (macOS only) Software: libx265 with CRF 28 Use Case: Best balance of compatibility and compression
media-converter /source /dest --video-codec h265

H.264 (AVC)

Hardware: Not implemented (always uses software) Software: libx264 with CRF 23 Use Case: Maximum compatibility with older devices
media-converter /source /dest --video-codec h264
H.264 hardware encoding is not implemented. The --video-codec h264 flag always uses software encoding regardless of --video-acceleration setting.

AV1

Hardware: Not implemented (always uses software) Software: libaom-av1 with CRF 35 Use Case: Maximum compression for archival/streaming
media-converter /source /dest --video-codec av1
AV1 encoding is extremely slow (5-10x slower than H.265 software encoding). Only recommended for final archival encodes where file size is critical.

Future Enhancements

Planned hardware acceleration support:
  • NVIDIA NVENC (Linux/Windows) - H.264/H.265/AV1
  • Intel Quick Sync (Cross-platform) - H.264/H.265/AV1
  • AMD VCE (Linux/Windows) - H.264/H.265
  • Apple VideoToolbox AV1 (macOS 14+)
Contributions welcome! See internal/converter/video.go for implementation patterns.

Adaptive Workers

Dynamic concurrency management for video conversions

Performance Tuning

Optimize conversion speed and resource usage

Build docs developers (and LLMs) love