# Тестирование качества видео и сравнение кодеков Руководство по анализу качества видео, сравнению кодеков и измерению эффективности сжатия. ## 📋 Содержание 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 ```bash # Полная информация в 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) ```bash # Базовая конвертация 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 ```bash # Рекомендуемая конфигурация 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 ```bash # Оптимальный баланс качество/размер 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 ```bash 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 ```bash 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) ```bash # Лучшее качество/размер 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 ```bash # Баланс качество/размер 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) ```bash # Базовый расчет 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) ```bash # Базовый расчет 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, лучше всего коррелирует с человеческим восприятием. ```bash # Установка модели 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`: ```bash #!/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/" ``` **Использование:** ```bash 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):** ```bash # Используйте несколько профилей качества # 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 ``` ### Для архивирования ```bash # Используйте AV1 CPU с низким CRF ffmpeg -i input.mp4 \ -c:v libsvtav1 -crf 25 -preset 4 \ -c:a libopus -b:a 192k \ archive.mp4 ``` ### Для быстрой обработки ```bash # Используйте 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. Повторяйте до достижения баланса **Быстрый тест:** ```bash # Извлечь 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 ### Документация - [FFmpeg Encoding Guide](https://trac.ffmpeg.org/wiki/Encode) - [x264 Settings](https://trac.ffmpeg.org/wiki/Encode/H.264) - [VP9 Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/VP9) - [SVT-AV1 Documentation](https://gitlab.com/AOMediaCodec/SVT-AV1) - [NVIDIA Video Codec SDK](https://developer.nvidia.com/video-codec-sdk) ### Научные статьи - "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 сек