Files
adaptive-video-converter/docs/VIDEO_QUALITY_TESTING.md
2025-12-03 21:55:35 +03:00

19 KiB
Raw Permalink Blame History

Тестирование качества видео и сравнение кодеков

Руководство по анализу качества видео, сравнению кодеков и измерению эффективности сжатия.

📋 Содержание

  1. Метрики качества
  2. Протестированные кодеки
  3. Результаты тестирования
  4. Команды для тестирования
  5. Интерпретация результатов
  6. Рекомендации

Метрики качества

PSNR (Peak Signal-to-Noise Ratio)

Что измеряет: Отношение сигнал/шум в децибелах (dB). Показывает математическое отличие между оригиналом и сжатым видео.

Интерпретация:

  • > 45 dB - Отличное качество (практически неразличимо)
  • 40-45 dB - Очень хорошее качество
  • 35-40 dB - Хорошее качество
  • 30-35 dB - Приемлемое качество
  • < 30 dB - Плохое качество (видимые артефакты)

Формула расчета:

PSNR = 10 × log₁₀(MAX²/MSE)

где MAX - максимальное значение пикселя (255 для 8-bit), MSE - средняя квадратичная ошибка.

SSIM (Structural Similarity Index)

Что измеряет: Структурное сходство изображений. Более точно отражает восприятие человеческим глазом.

Интерпретация:

  • 1.0 - Идентичные изображения (100%)
  • > 0.99 - Отличное качество (99%+ схожести)
  • 0.95-0.99 - Хорошее качество
  • 0.90-0.95 - Приемлемое качество
  • < 0.90 - Заметная потеря качества

Преимущества SSIM:

  • Учитывает яркость, контраст и структуру
  • Лучше коррелирует с субъективной оценкой качества
  • Более устойчива к локальным искажениям

Протестированные кодеки

1. H.264 / AVC

Описание: Широко распространенный кодек, поддерживается всеми устройствами.

Энкодеры:

  • libx264 - CPU энкодер (отличное качество/размер)
  • h264_nvenc - NVIDIA GPU энкодер (быстрее, но менее эффективен)

Параметры качества:

  • CRF: 0-51 (меньше = лучше качество)
  • Рекомендуемый диапазон: 18-28
  • Пресеты: ultrafast, fast, medium, slow, slower, veryslow

2. VP9

Описание: Открытый кодек от Google, часть WebM. На 20-50% эффективнее H.264.

Энкодеры:

  • libvpx-vp9 - CPU энкодер
  • vp9_vaapi - аппаратное ускорение (Intel/AMD)

Параметры качества:

  • CRF: 0-63 (меньше = лучше качество)
  • Рекомендуемый диапазон: 28-35
  • cpu-used: 0-5 (меньше = лучше качество, медленнее)

3. AV1

Описание: Современный кодек, следующее поколение после VP9. На 30-50% эффективнее H.264.

Энкодеры:

  • libsvtav1 - CPU энкодер (быстрый, хорошее качество)
  • libaom-av1 - CPU энкодер (лучшее качество, очень медленный)
  • av1_nvenc - NVIDIA GPU энкодер (быстро, но менее эффективен)
  • av1_amf - AMD GPU энкодер
  • av1_qsv - Intel GPU энкодер

Параметры качества:

  • CRF (libsvtav1): 0-63 (меньше = лучше качество)
  • CQ (av1_nvenc): 0-51 (меньше = лучше качество)
  • Рекомендуемый диапазон: 30-40

Результаты тестирования

Тестовое видео

Параметры:

  • Файл: tenexia.mp4
  • Разрешение: 1920×1080 (Full HD)
  • FPS: 25
  • Длительность: 135 секунд (2:15)
  • Оригинальный размер: 167 MB
  • Оригинальный кодек: H.264 (битрейт ~10 Mbps)

Сводная таблица результатов

Кодек Энкодер Параметр Размер PSNR SSIM Сжатие Скорость
Оригинал - - 167 MB - - 1.0x -
VP9 libvpx-vp9 CRF 32 13 MB 47.42 dB 0.9917 12.8x ~5-10 мин
AV1 libsvtav1 CRF 35 9.5 MB 48.01 dB 0.9921 17.6x ~10-15 мин
AV1 av1_nvenc CQ 32 20 MB N/A N/A 8.3x ~10 сек
AV1 av1_nvenc CQ 40 9.3 MB 47.13 dB 0.9914 18.0x ~10 сек
AV1 av1_nvenc CQ 45 7.1 MB 45.49 dB 0.9899 23.5x ~10 сек
H.264 libx264 CRF 28 9.7 MB 44.85 dB 0.9904 17.2x ~3-5 мин
H.264 h264_nvenc CQ 28 20 MB 47.88 dB 0.9922 8.4x ~10 сек
H.264 h264_nvenc CQ 32 12 MB N/A N/A 14.0x ~10 сек
H.264 h264_nvenc CQ 35 7.9 MB 44.48 dB 0.9891 21.1x ~10 сек

Победители по категориям

🥇 Лучшее качество: AV1 CPU (CRF 35) - PSNR 48.01 dB, SSIM 0.9921

🥇 Лучшее сжатие при сохранении качества: AV1 GPU (CQ 40) - 9.3 MB, PSNR 47.13 dB

🥇 Максимальное сжатие: AV1 GPU (CQ 45) - 7.1 MB, PSNR 45.49 dB (всё ещё отличное)

Лучший баланс скорость/качество: AV1 GPU (CQ 40) - быстро + малый размер + хорошее качество


Команды для тестирования

1. Анализ исходного видео

Получить метаданные с помощью ffprobe

# Полная информация в JSON формате
ffprobe -v error -show_format -show_streams -print_format json input.mp4

# Краткая информация о видео
ffprobe -v error -select_streams v:0 -show_entries stream=codec_name,width,height,r_frame_rate,bit_rate -of default=noprint_wrappers=1 input.mp4

# Информация об аудио
ffprobe -v error -select_streams a:0 -show_entries stream=codec_name,sample_rate,bit_rate,channels -of default=noprint_wrappers=1 input.mp4

# Размер файла и битрейт
ffprobe -v error -show_entries format=size,duration,bit_rate -of default=noprint_wrappers=1:nokey=1 input.mp4

2. Конвертация видео

VP9 (CPU)

# Базовая конвертация
ffmpeg -i input.mp4 \
  -c:v libvpx-vp9 \
  -crf 32 \
  -b:v 0 \
  -row-mt 1 \
  -cpu-used 2 \
  -c:a libopus \
  -b:a 128k \
  output_vp9.webm

# Параметры:
# -crf 32        - качество (18-40, меньше = лучше)
# -b:v 0         - режим постоянного качества
# -row-mt 1      - многопоточность
# -cpu-used 2    - скорость кодирования (0-5)

AV1 (CPU) - libsvtav1

# Рекомендуемая конфигурация
ffmpeg -i input.mp4 \
  -c:v libsvtav1 \
  -crf 35 \
  -preset 6 \
  -svtav1-params tune=0 \
  -c:a libopus \
  -b:a 128k \
  output_av1_cpu.mp4

# Параметры:
# -crf 35        - качество (0-63, меньше = лучше)
# -preset 6      - скорость (0-13, 6 = средняя)
# -svtav1-params tune=0 - оптимизация под PSNR

AV1 (GPU) - NVIDIA

# Оптимальный баланс качество/размер
ffmpeg -i input.mp4 \
  -c:v av1_nvenc \
  -preset p7 \
  -cq 40 \
  -b:v 0 \
  -c:a libopus \
  -b:a 128k \
  output_av1_gpu.mp4

# Параметры:
# -preset p7     - качество пресета (p1-p7, p7 = лучшее)
# -cq 40         - constant quality (0-51, меньше = лучше)
# -b:v 0         - без ограничения битрейта

# Максимальное сжатие (хорошее качество)
ffmpeg -i input.mp4 -c:v av1_nvenc -preset p7 -cq 45 -b:v 0 -c:a libopus -b:a 128k output_av1_small.mp4

AV1 (GPU) - AMD

ffmpeg -i input.mp4 \
  -c:v av1_amf \
  -quality quality \
  -qp_i 40 -qp_p 40 \
  -c:a libopus \
  -b:a 128k \
  output_av1_amd.mp4

AV1 (GPU) - Intel

ffmpeg -i input.mp4 \
  -c:v av1_qsv \
  -preset veryslow \
  -global_quality 40 \
  -c:a libopus \
  -b:a 128k \
  output_av1_intel.mp4

H.264 (CPU)

# Лучшее качество/размер
ffmpeg -i input.mp4 \
  -c:v libx264 \
  -crf 28 \
  -preset slow \
  -c:a aac \
  -b:a 128k \
  output_h264_cpu.mp4

# Параметры:
# -crf 28        - качество (18-28, меньше = лучше)
# -preset slow   - компромисс скорость/качество
#                  (ultrafast, fast, medium, slow, slower, veryslow)

H.264 (GPU) - NVIDIA

# Баланс качество/размер
ffmpeg -i input.mp4 \
  -c:v h264_nvenc \
  -preset p7 \
  -cq 33 \
  -b:v 0 \
  -c:a aac \
  -b:a 128k \
  output_h264_gpu.mp4

# Параметры:
# -preset p7     - качество (p1-p7)
# -cq 33         - constant quality (0-51)

3. Измерение качества

PSNR (Peak Signal-to-Noise Ratio)

# Базовый расчет PSNR
ffmpeg -i encoded.mp4 -i original.mp4 \
  -lavfi "[0:v][1:v]psnr" \
  -f null - 2>&1 | grep "PSNR"

# С сохранением детальной статистики в файл
ffmpeg -i encoded.mp4 -i original.mp4 \
  -lavfi "[0:v][1:v]psnr=stats_file=psnr_stats.log" \
  -f null -

# Просмотр статистики
head -5 psnr_stats.log && echo "..." && tail -5 psnr_stats.log

Формат вывода:

PSNR y:46.02 u:53.92 v:53.54 average:47.42 min:41.20 max:52.27
  • y - яркость (luminance)
  • u, v - цветовые каналы (chrominance)
  • average - средний PSNR
  • min, max - минимальный и максимальный PSNR по кадрам

SSIM (Structural Similarity Index)

# Базовый расчет SSIM
ffmpeg -i encoded.mp4 -i original.mp4 \
  -lavfi "[0:v][1:v]ssim" \
  -f null - 2>&1 | grep "SSIM"

# С сохранением детальной статистики
ffmpeg -i encoded.mp4 -i original.mp4 \
  -lavfi "[0:v][1:v]ssim=stats_file=ssim_stats.log" \
  -f null -

# Просмотр статистики
head -5 ssim_stats.log && echo "..." && tail -5 ssim_stats.log

Формат вывода:

SSIM Y:0.9887 (19.46 dB) U:0.9979 (26.70 dB) V:0.9979 (26.75 dB) All:0.9917 (20.83 dB)
  • Значения 0.0-1.0 (1.0 = идентичные изображения)
  • dB - SSIM в децибелах (для удобства сравнения)

VMAF (Video Multimethod Assessment Fusion)

VMAF - современная метрика от Netflix, лучше всего коррелирует с человеческим восприятием.

# Установка модели VMAF (один раз)
# Скачать модель с https://github.com/Netflix/vmaf/tree/master/model

# Расчет VMAF
ffmpeg -i encoded.mp4 -i original.mp4 \
  -lavfi "[0:v][1:v]libvmaf=model_path=/path/to/vmaf_v0.6.1.json:log_path=vmaf.json" \
  -f null -

# Интерпретация VMAF:
# 90-100 - Отличное качество
# 75-90  - Хорошее качество
# 50-75  - Приемлемое качество
# < 50   - Плохое качество

4. Полный скрипт для тестирования

Создайте файл test_codec.sh:

#!/bin/bash

# Использование: ./test_codec.sh input.mp4 encoded.mp4 output_dir

INPUT="$1"
ENCODED="$2"
OUTPUT_DIR="${3:-.}"

mkdir -p "$OUTPUT_DIR"

echo "=== Анализ размеров файлов ==="
echo "Оригинал:"
ls -lh "$INPUT" | awk '{print $5, $9}'
echo "Сжатый:"
ls -lh "$ENCODED" | awk '{print $5, $9}'
echo ""

# Рассчет сжатия
ORIG_SIZE=$(stat -f%z "$INPUT" 2>/dev/null || stat -c%s "$INPUT")
ENC_SIZE=$(stat -f%z "$ENCODED" 2>/dev/null || stat -c%s "$ENCODED")
RATIO=$(echo "scale=2; $ORIG_SIZE / $ENC_SIZE" | bc)
echo "Сжатие: ${RATIO}x"
echo ""

echo "=== Метаданные закодированного видео ==="
ffprobe -v error -show_format -show_streams -print_format json "$ENCODED" | \
  grep -E "(codec_name|width|height|bit_rate|size)" | head -10
echo ""

echo "=== Расчет PSNR ==="
ffmpeg -i "$ENCODED" -i "$INPUT" \
  -lavfi "[0:v][1:v]psnr=stats_file=$OUTPUT_DIR/psnr_stats.log" \
  -f null - 2>&1 | grep "PSNR"
echo ""

echo "=== Расчет SSIM ==="
ffmpeg -i "$ENCODED" -i "$INPUT" \
  -lavfi "[0:v][1:v]ssim=stats_file=$OUTPUT_DIR/ssim_stats.log" \
  -f null - 2>&1 | grep "SSIM"
echo ""

echo "Детальная статистика сохранена в $OUTPUT_DIR/"

Использование:

chmod +x test_codec.sh
./test_codec.sh original.mp4 encoded.mp4 ./test_results

Интерпретация результатов

Матрица принятия решений

Сценарий Рекомендуемый кодек Параметры Ожидаемый результат
Максимальное качество AV1 CPU CRF 30-35 Лучшее качество, малый размер
Быстрое кодирование AV1 GPU CQ 38-42 Быстро, хорошее качество
Совместимость H.264 CPU CRF 23-28 Работает везде
Веб-стриминг VP9 CRF 30-35 Хороший баланс
Архивирование AV1 CPU CRF 25-30 Лучшее качество

Соответствие метрик и визуального качества

PSNR SSIM Визуальная оценка
> 45 dB > 0.99 Практически неотличимо от оригинала
40-45 dB 0.98-0.99 Отличное качество, артефакты незаметны
35-40 dB 0.95-0.98 Хорошее качество, артефакты видны при внимательном просмотре
30-35 dB 0.90-0.95 Приемлемое качество, видимые артефакты
< 30 dB < 0.90 Плохое качество, явные артефакты

Факторы, влияющие на результаты

  1. Контент видео:

    • Статичные сцены сжимаются лучше
    • Быстрое движение требует больше битрейта
    • Детализированные текстуры сложнее сжать
    • Темные сцены могут показывать бандинг
  2. Разрешение:

    • Высокие разрешения требуют более высокого битрейта
    • При одинаковом CRF, 4K будет весить больше чем 1080p
  3. Частота кадров:

    • 60 FPS требует ~1.5-2x больше битрейта чем 30 FPS
    • Высокий FPS важнее для игрового контента
  4. Цветовое пространство:

    • HDR (10-bit) требует ~20-30% больше битрейта
    • Широкий цветовой охват увеличивает размер

Рекомендации

Для продакшена

Adaptive Streaming (DASH/HLS):

# Используйте несколько профилей качества
# 360p, 480p, 720p, 1080p, 1440p, 2160p

# Dual codec для максимальной совместимости:
# - AV1 для современных браузеров
# - H.264 для старых устройств (iOS < 14)

# Пример: avc уже реализует это
avc input.mp4 output/ -c dual -f both -r 360,720,1080

Для архивирования

# Используйте AV1 CPU с низким CRF
ffmpeg -i input.mp4 \
  -c:v libsvtav1 -crf 25 -preset 4 \
  -c:a libopus -b:a 192k \
  archive.mp4

Для быстрой обработки

# Используйте GPU кодирование
ffmpeg -i input.mp4 \
  -c:v av1_nvenc -preset p7 -cq 35 \
  -c:a aac -b:a 128k \
  quick_encode.mp4

Подбор оптимального CRF/CQ

Метод бинарного поиска:

  1. Начните с среднего значения (CRF 28 для H.264, 32 для VP9, 35 для AV1)
  2. Закодируйте короткий фрагмент (30-60 сек)
  3. Проверьте качество (PSNR > 45, SSIM > 0.99 для отличного качества)
  4. Если качество избыточное - увеличьте CRF на 2-3
  5. Если качество недостаточное - уменьшите CRF на 2-3
  6. Повторяйте до достижения баланса

Быстрый тест:

# Извлечь 60 секунд с 30-й секунды
ffmpeg -ss 30 -i input.mp4 -t 60 -c copy sample.mp4

# Протестировать разные CRF
for crf in 30 32 35 38 40; do
  ffmpeg -i sample.mp4 -c:v libsvtav1 -crf $crf -preset 8 -c:a copy test_crf${crf}.mp4
  
  # Измерить качество
  ffmpeg -i test_crf${crf}.mp4 -i sample.mp4 -lavfi "[0:v][1:v]psnr" -f null - 2>&1 | grep "PSNR"
  
  # Размер файла
  ls -lh test_crf${crf}.mp4
done

Дополнительные ресурсы

Инструменты

  • FFmpeg - https://ffmpeg.org/
  • ffprobe - анализ медиа файлов
  • MediaInfo - GUI инструмент для анализа
  • Handbrake - GUI для кодирования
  • ab-av1 - инструмент для подбора оптимальных параметров AV1

Документация

Научные статьи

  • "The Netflix Tech Blog: Per-Title Encode Optimization"
  • "VMAF: The Journey Continues" - Netflix
  • "AV1 Performance vs x265 and libvpx" - Facebook Engineering

Changelog

2025-11-12 - Создан документ на основе реальных тестов

  • Протестированы кодеки: VP9, AV1 (CPU/GPU), H.264 (CPU/GPU)
  • Добавлены все команды для тестирования
  • Добавлены результаты сравнения на видео 1920×1080, 135 сек