Привет, Хабр! С вами Матвей Мочалов, и сегодня у нас небольшая лабораторная работа. Вспомним, что GPU нужны не только для нейронок и AI — еще они могут ускорять много других полезных задач. А конкретно мы сравним разницу в скорости между работой FFmpeg на процессоре и на видеокарте Nvidia.

В ролях у нас гибридный ноутбук под Linux с мобильной видеокартой RTX 3050Ti и процессором Ryzen 5 5600H. Также в массовке участвует удалённый тестовый сервер с Xeon и заглушкой в PCI слот, которую дядя Дженсен Хуанг решил по доброте сердечной добавить в линейку Quadro.
К слову, ранее мы уже немного работали с FFmpeg, разбираясь с транскодированием и устройством видеоконтейнеров тут.

Подготовка к тесту

Сначала посмотрим, на чём будем проводить тесты.
Начнём с моей личной машины, на которой крутится EndeavourOS(Arch):

Ядро — 6.9.3-arch1-1, 8 гигов DDR4 на частоте 3200Mhz + 8 гигов физического swap и ещё 8 за счёт zram.  CPU — ryzen 5600h 6/12 с теплопакетом 35w (хотя, если верить nvtop, то доходит до 45w) и GPU — RTX 3050ti на 4gb VRAM с теплопакетом 60w.

Версия драйвера  Nvidia — 550.78-7, FFmpeg — 2:6.1.1-7.

Тестовый сервер — AlmaLinux 9.3, ядро 6.6.11-1.el9.x86_64, 16 гигов DDR3 и 2 гига swap.
CPU — Xeon 2630, 6 ядер с отключенным SMT, GPU — Quadro P400.

Версия драйвера Nvidia — 550.54.15,  FFmpeg — свой билд с оптимизациями под CUDA.

Отдельно сделаю ещё акцент на том, что Xeon — это старичок 2012 года, а Quadro — 2017, но, не смотря на возраст, результаты будут весьма неоднозначными.

Теперь скачаем тестовое видео. Пусть это будет детище Blender Foundation — Big Buck Bunny.

```bash
wget https://download.blender.org/demo/movies/BBB/bbb_sunflower_2160p_30fps_normal.mp4.zip
unzip bbb_sunflower_2160p_30fps_normal.mp4.zip
```

Тестирование

Для начала прогоним сравнительный тест на моём ноуте без GPU-ускорения.
Тестировать будем рескейлинг с разрешения 2160p до 1080p.

```bash
ffmpeg -i bbb_sunflower_2160p_30fps_normal.mp4 -vf scale=1920:1080 -c:v mpeg4 -preset medium output_no_acc.mp4
```

И повторим так 5 раз для надёжности, получая вот такие результаты:

Номер теста

Скорость

1

4.09x

2

3.95x

3

4.22x

4

4.17x

5

4.26x

Средний результат — 4.138x.

Однако тест выходит не очень честным, так как, судя по нагрузке на GPU, в nvtop резко растёт потребление питания у iGPU и процент нагрузки на графическое ядро. При этом потребление видеопамяти почти не меняется. Xeon же в тестовом сервере не обладает встроенной графикой вовсе.

Теперь на тестовом сервере:

Номер теста

Скорость

1

3.54x

2

3.52x

3

3.52x

4

3.55х

5

3.54х

В итоге среднее — 3.534x.

Современный Ryzen 5600H на 14.59% оказался быстрее старичка Xeon 2630 — результат, откровенно говоря, не сильно впечатляющий. Между процессорами пропасть почти 10 лет (ряженка вышла в 2021 году). Так ещё к тому же на её стороне была включенная гиперпоточность, хотя что-то мне подсказывает, что в этой операции FFmpeg работал в однопоточном режиме. Кроме того, ей помогала интегрированная графика. Серверный труженик и любитель сборщиков ПК с Алиэкспресс интеграшкой не обладает, ещё и гиперпоточность была задушена.

Впрочем, опустим странности и сомнительный прогресс производительности процессоров для другого поста. Перейдём к тому, что интересно в первую очередь — GPU-ускорению.

CUDA

Начнём снова с моего ноутбука и повторим тесты также по 5 раз.

```bash
ffmpeg -hwaccel cuda -i input.mp4 -vf "scale=1920:1080,format=yuv420p" -c:v mpeg4 -preset medium cuda.mp4
``` 

Номер теста

Скорость

1

4.75х

Как можно заметить, что-то тут не сходится. GPU-ускорение должно быть по определению заметно быстрее в обработке видеоматериала, однако, мы получили результат лишь слегка быстрее, чем у процессора с интегрированной графикой. Как так?
При этом, если посмотреть на мониторинг nvtop, дискретная графика явно была нагружена.

Хорошо, один раз что-то пошло не так, но впереди ещё 4 теста. На всякий случай с помощью инструмента prime-run дополнительно укажем использование непосредственно дискретной графики. 

```bash
prime-run ffmpeg -hwaccel cuda -i input.mp4 -vf "scale=1920:1080,format=yuv420p" -c:v mpeg4 -preset medium cuda.mp4
```

И мы получаем… 4.77?

Номер теста

Скорость

2

4.77х

My honest reaction:

Так, ну хорошо, допустим, что и prime-run недостаточно, хотя nvtop опять же показал, что GPU был загружен. Перейдём к тяжёлой артиллерии и с помощью EnvyControl заставим систему использовать только дискретную графику. Заодно по новой проведём тест процессора, которому iGPU, надеюсь, уже не сможет помочь сжульничать против старичка Xeon. 

```bash
sudo envycontrol -s nvidia --force-comp --coolbits 24
reboot
```

Чудесно, теперь у нас чёрный экран и на Wayland сессии, и на X11.
То FFmpeg удивляет, то теперь EnvyControl, до этого эксперимента работавший стабильно.

Et tu, Brute?

Хорошо, идём в TTY на Ctrl+Alt+F3, вводим логин, пароль и возвращаем всё назад через EnvyControl:

```bash
sudo envycontrol --reset
``

И, Слава Богу, Wayland сессия Кедов снова запустилась, ура!
Только вот по тесту я так и не продвинулся.
Попытаюсь снова переключиться только на дискретку, но и через указание экранного менеджера SDDM: 

```bash
sudo envycontrol -s nvidia --dm sddm 
reboot 
```
* Е[ДАННЫЕ УДАЛЕНЫ]ёт. Возможно…
* Е[ДАННЫЕ УДАЛЕНЫ]ёт. Возможно…

Wayland вновь порадовал чёрным экраном при попытке зайти в систему, в X11же зашёл без проблем, да вот только nvtop показывает, что iGPU продолжает работать вместе с дискреткой.
Ладно, EnvyControl отчего-то не радует на текущий момент. Прибегнем к его страшному старшему кузену — OptimusManager.

Работает он только с Иксами, в отличие от EnvyControl, который ранее нормально работал и под Wayland. Пробуем: 

```bash
optimus-manager --switch nvidia
``

И получаем ошибку с указанием читать логи с букетом других ошибок, от чтения которых понятнее не стало.

Ладно, видимо придётся продолжать тест дальше без переключения в режим Nvidia.

```bash
ERROR: the latest GPU setup attempt failed at Xorg pre-start hook.
Log at /var/log/optimus-manager/switch/switch-20240603T140533.log
Cannot execute command because of previous errors.
```

Продолжаем экзекуцию FFmpeg и меня в попытках понять, почему всё так, как оно есть, а не так, как казалось должно быть. Так и быть, буду дальше использовать prime-run, хотя он, кажется, ничего и не меняет.

```bash
prime-run ffmpeg -hwaccel cuda -i input.mp4 -vf "scale=1920:1080,format=yuv420p" -c:v mpeg4 -preset medium cuda.mp4
```

Номер теста

Скорость

3

4.78х

4

4.79х

5

4.81х

Итого среднее — 4.78x.

Мда, я откровенно говоря ожидал иных результатов. В моём представлении всё должно было ускориться раза в 2 минимум. Также как это происходит в условном DaVinci Resolve, KdenLive и прочих видеоредакторах, где под капотом в бэкенде, скорее всего, также где-то зарыт FFmpeg.

В итоге же разница всего лишь 15.5% относительно Ryzen 5600H. 
Ну что ж, ладно, вернёмся к удалённому серверу и запустим тест там: 

```bash
ffmpeg -hwaccel cuda -i input.mp4 -vf "scale=1920:1080,format=yuv420p" -c:v mpeg4 -preset medium cuda.mp4
```

Начало уже радует: обошлось без сюрпризов, и появилась хоть какая-то закономерность. Затычка для PCI-слота с 2 гигами VRAM оказалась слабее, как процессоров, так и своего более свежего собрата из RTX-линейки. Правда, разница не такая уж и впечатляющая.
У Quadro P400 — в FP32 производительность 0.64 TFLOPS. А у мобильной RTX 3050TI в зависимости от теплопакета должна быть около 8.7 TFLOPS.

Номер теста

Скорость

1

2.99x

2

2.99x

3

2.99x

4

2.99x

5

2.99x

Стабильно, даже подозрительно стабильно — 2.99x.

И при разнице в 13.59 раз по сухой производительности в TFLOPS в FFmpeg мы наблюдаем разницу всего лишь в 1.59 раз.

Различия в работе FFmpeg на CPU и GPU

От практики перейдём теперь к теории, как это всё по идее должно работать.
Обещания теории, что GPU должны быть заметно быстрее, упоминать как-то странно. На примере двух разных систем убедились, что по крайней мере в их случае — это не так.
Судя по тому, как редко кто-то вспоминает про GPU-ускорение в FFmpeg, и когда до этого всё-таки доходит, то в гугле видны другие, такие же несчастные, у которых GPU оказался едва быстрее, либо вовсе медленнее.

Процесс работы на процессоре

При транскодировании на процессоре FFmpeg выполняет следующие действия:

  1. Разделение контейнера на отдельные потоки (аудио, видео).

  2. Декодирование потоков в их сырые форматы.

  3. Применение фильтров к этим потокам (например, масштабирование до 720p для уменьшения размера файла).

  4. Кодирование потоков в указанные форматы.

  5. Мультиплексирование потоков обратно в один файл.

Процесс работы на Видеокарте

NVIDIA Video Codec SDK

Когда мы включаем аппаратное ускорение, некоторые из этих шагов могут выполняться на GPU:

  1. Декодирование потоков происходит на NVDEC (Nvidia Video Decoder).

  2. Фильтрация (например, масштабирование) может выполняться на GPU с использованием CUDA.

  3. Кодирование потоков осуществляется на NVENC (Nvidia Video Encoder).

  4. При этом аудиопотоки всё равно обрабатываются на CPU, так как NVENC/NVDEC предназначены только для видео. 

  5. После декодирования сырые видеокадры отправляются в VRAM для ускоренной фильтрации. 

  6. После фильтрации кадры кодируются и возвращаются в основную память системы для мультиплексирования и завершения процесса.

Закрадывающиеся сомнения

В моих тестах явно есть ошибка…
Может быть со злосчастным видео от Blender Foundation что-то не так — надо бы посмотреть, какой у него вообще кодек.

```bash
ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 bbb_sunflower_2160p_30fps_normal.mp4
```

Используется h264. Так, h264, ну, всё верно, норма для mpeg4 контейн… стоп.
Контейнер у нас .mp4, что и расшифровывается как mpeg4, но кодеки то у нас h264/h265/266, либо софтверный libx264 и т.д.
Так, а у меня? 

*приходит осознание что сам себя поймал в ловушку Джокера*

Чёрт, а я по привычке везде проставил mpeg4, привыкнув считать его синонимичным с контейнером для видео .mp4 в целом.

Хотя, mpeg4 в документации Nvidia за 2023 всё равно указан как также аппаратно ускоряемый, в отличие от приведённой мною выше схемы в разделе "Процесс работы на Видеокарте".
Впрочем, на тормознутости обработки старичка mpeg4, вероятно, сказывается, что он, будучи из 1999 года, сам по себе был менее эффективен в сжатии информации. А также, вероятно, обделён вниманием и со стороны самой Nvidia, так как на его замену есть более эффективные программные и аппаратные кодеки, приходящиеся ему потомками.

Давай по новой

Продолжаем сизифов труд и попробуем теперь прогнать с нормальным кодеком (h265) тесты на ноуте и тестовом сервере.
Заодно в процессе чтения документации я понял, что масштабирование разрешения у меня проходило на CPU, а можно было также задействовать CUDA.

```bash
ffmpeg-cuda -hwaccel cuda -hwaccel_output_format cuda -i bbb_sunflower_2160p_30fps_normal.mp4 -vf "scale_cuda=1920:1080" -c:v hevc_nvenc -preset medium output_cuda.mp4
``
  • GPU:

  1. RTX 3050Ti:

Номер теста

Скорость

1

6.59x

2

6.59x

3

6.57x

4

6.56x

5

6.56x

- Среднее: 6.576x
- Разница h265 vs mpeg 4: +37.5%
- Разница с Ryzen 5600H: +297% 
- Разница с Quadro P400: +245.7%

  1. Quadro P400:

Номер теста

Скорость

1

2.68x

2

2.68x

3

2.67x

4

2.67x

5

2.67x

- Среднее: 2.676x
- Разница h265 vs mpeg 4: -11.7%
- Разница с Ryzen 5600H: +92.5%
- Разница с RTX 3050Ti: -245.7%

  • CPU:

```bash
ffmpeg -i bbb_sunflower_2160p_30fps_normal.mp4 -vf "scale=1920:1080" -c:v libx265 -preset medium output_libx265.mp4
```
  1. Ryzen 5600H:

Номер теста

Скорость

1

1.4x

2

1.37x

3

1.42x

4

1.35x

5

1.41x

- Среднее: 1.39
- Разница h265 vs mpeg 4: -297%
- Разница с Quadro P400: -92.5%
- Разница с RTX 3050Ti: -473%

  1. Xeon 2630:

  • К сожалению, наш билд FFmpeg не имеет поддержки libx265/264, так что Xeon выбывает.

Результаты уже больше похожи на правду. Но и без аномалий не обошлось — Quardo P400 в h265 внезапно показала себя на 11.7% хуже.

Интересно, а как себя относительно ноутбучного железа покажет не престарелое железо разряда мечта сборщика БУ компов “для учёбы”, а что-то помощнее из серверного сегмента? Давайте попробуем?!

Рубрика “Эксперименты”, зашла слишком далеко. Проснитесь, мр. Фримэн.
Рубрика “Эксперименты”, зашла слишком далеко. Проснитесь, мр. Фримэн.

Тестовый сервер 2 — AlmaLinux 9.4, ядро  6.6.31-1.el9.x86_64, 7 гигов DDR4 и 2 гига swap.
CPU — EPYC 7551P, 32 ядра с отключенным Hyper-threading, GPU — RTX A2000.

Версия драйвера Nvidia — 555.42.02, 6 гигов VRAM,  FFmpeg — свой билд с оптимизациями под CUDA.

В FP32 у мобильной RTX 3050Ti и RTX A2000 должен быть примерно одинаковый результат. Разве что видеопамяти у A2000 побольше — 6 гигов против 4.

```bash
ffmpeg-cuda -hwaccel cuda -hwaccel_output_format cuda -i bbb_sunflower_2160p_30fps_normal.mp4 -vf "scale_cuda=1920:1080" -c:v hevc_nvenc -preset medium output_cuda.mp4
``

RTX A2000:

Номер теста

Скорость

1

6.24x

2

6.81x

3

6.8x

4

6.79x

5

6.76x

- Среднее:  6.68x
- Разница RTX 3050Ti: +1.58%
- Разница с Ryzen 5600H: +6.43%
- Разница с Xeon 2630:  +89%
- Разница с Quadro P400: +249%
- Разница с EPYC 7551P: +237%

В итоге получаем схожий результат в пределах погрешности. В этот раз Терафлопсы соотнеслись с реальностью, а вот с EPYC есть загвоздка: AMD AMF на сервере нет, а без него Эпики в аппаратное ускорение не умеют и аналогов libx264/265 не имеют.

Ну что ж, тогда попробуем снова старичка mpeg4.

```bash
ffmpeg -i bbb_sunflower_2160p_30fps_normal.mp4 -vf scale=1920:1080 -c:v mpeg4 -preset medium output_no_acc.mp4
```

EPYC 7551P:

Номер теста

Скорость

1

2.89x

2

2.79x

3

2.83x

4

2.77x

5

2.81x

- Среднее:  2.818x
- Разница RTX 3050Ti: -301%
- Разница с Ryzen 5600H: -89.8%
- Разница с Xeon 2630: -62%
- Разница с Quadro P400: +5.3%
- Разница с A2000: +57%

```bash
ffmpeg-cuda -hwaccel cuda -i bbb_sunflower_2160p_30fps_normal.mp4 -vf "scale=1920:1080,format=yuv420p" -c:v mpeg4 -preset medium output_no_cuda_scale.mp4
```

И на GPU —

RTX A2000: 

Номер теста

Скорость

1

1.76x

2

1.81x

3

1.8x

4

1.79x

5

1.77x

- Среднее:  1.786
- Разница RTX 3050Ti: -267%
- Разница с Ryzen 5600H: -231%
- Разница с Xeon 2630:  -97.8%
- Разница с Quadro P400: -67.4%
- Разница с EPYC 7551P: -57%

AMD, конечно, умеет удивлять, но нередко любит и разочаровывать. Иного результата я ожидал от 32 ядер. Видимо Эпики под работу с мультимедиа контентом совсем не заточены. И смею предположить, подозрительно хороший результат Ryzen5600H связан был с использованием iGPU.
Впрочем, и с Nvidia не обошлось без мистики и странностей — с mpeg4 A2000 справилась куда хуже, чем RTX 3050Ti. По производительности они почти идентичны, так что предположу, что разрыв вызван разными версиями ПО на моём ноутбуке и тестовом сервере.

Теперь в h264

Для полноты эксперимента заодно посмотрим, изменится ли что-то, если сохранить кодек как и у оригинального видео — h264?

```bash
ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i bbb_sunflower_2160p_30fps_normal.mp4 -vf "scale_cuda=1920:1080" -c:v h264_nvenc -preset medium output_cuda.mp4
```
  1. RTX A2000: 

Номер теста

Скорость

1

6.24x

2

6.79x

3

6.81x

4

6.8x

5

6.8x

- Среднее: 6.68x
- Разница c RTX A2000(H265): 0%

  1. Quadro P400:

Номер теста

Скорость

1

2.66x

2

2.66x

3

2.66x

4

2.66x

5

2.66x

- Среднее:  2.66x
- Разница c Quadro P400(H265): -12.4%

  1. RTX 3050Ti:

Номер теста

Скорость

1

6.66x

2

6.66x

3

6.69x

4

6.65x

5

6.66x

- Среднее:  6.66x
- Разница c RTX 3050Ti(H265): +1.27%

```bash
ffmpeg -i bbb_sunflower_2160p_30fps_normal.mp4 -vf "scale=1920:1080" -c:v libx264 -preset medium output_cpu.mp4
```
  1. Ryzen 5600H:

Номер теста

Скорость

1

2.49x

2

2.48x

3

2.47

4

2.46

5

2.48

- Среднее:  2.476x
- Разница c Ryzen5600H(H265): +78.12%

Результаты, с одной стороны, закономерные, а с другой — снова удивляющие. RTX A2000 не показала вообще изменений между H264 и H265, у RTX 3050Ti в пределах погрешности, Quadro P400 внезапно показала себя заметно хуже с H264, а Ryzen 5600H наоборот — намного лучше справился с H264.

Итоговая таблица

Было

Тестовая конфигурация

Изначальный кодек

Конечный кодек

Среднее

Ryzen 5600H

h264

mpeg4

4.138x

RTX 3050Ti

h264

mpeg4

4.78x

Xeon 2630

h264

mpeg4

3.534x

Quadro P400

h264

mpeg4

2.99x

EPYC 7551P

h264

mpeg4

2.818x

RTX A2000

h264

mpeg4

1.786x

Стало (H265)

Тестовая конфигурация

Изначальный кодек

Конечный кодек

Среднее

RTX A2000

h264

h265

6.68x

RTX 3050Ti

h264

h265

6.576x

Quadro P400

h264

h265

2.676x

Ryzen 5600H

h264

h265

1.39x

Стало (H264)

Тестовая конфигурация

Изначальный кодек

Конечный кодек

Среднее

RTX A2000

h264

h264

6.68x

RTX 3050Ti

h264

h264

6.66x

Quadro P400

h264

h264

2.66x

Ryzen 5600H

h264

h264

2.476x

Выводы

Я знаю, что ничего не знаю. (с) Возможно, Сократ, но и это — не точно.

Скелетор Я же вернусь в следующей серии, где, возможно, снова затронем FFmpeg с транскодированием. Либо с уже новой, менее болезненной к разбору темой.
Спасибо за прочтение, с нетерпением жду ваших комментариев!

Комментарии (28)


  1. friend001002
    10.07.2024 13:58
    +2

    хотя что-то мне подсказывает, что в этой операции FFmpeg работал в однопоточном режиме

    kdenlive мне говорит, что многопоточный рендер может вызвать артефакты изображения. Не хочется рисковать.


    1. cdnnow_writer
      10.07.2024 13:58

      Исходя из моего общения с друзьями операторами и монтажёрами, многие не хотят рисковать и с GPU-рендерингом, доверяя только обработке проекта на процессоре.


  1. mpa4b
    10.07.2024 13:58
    +1

    libx265 (не знаю как другие) любит работать на CPU во много потоков, правда ни один она при этом почему-то не занимает на 100% на длительное время. Следовательно, надо запускать несколько инстансов ffmpeg для получения реальной картины, да ещё и подбирать это кол-во для демонстрации реального выигрыша на конкретном CPU.


    1. cdnnow_writer
      10.07.2024 13:58

      Спасибо за совет, в следующий раз когда буду более подробно и под другим углом проводить тесты + скорее всего с другим железом, учту это.


  1. basilbasilbasil
    10.07.2024 13:58
    +4

    что-то мне подсказывает что выше скорости аппаратного кодера не прыгнешь
    я бы сначала отпрофилировал каждый этап и замерил скорости


    1. cdnnow_writer
      10.07.2024 13:58

      Ну вот, для mpeg4, внезапно, как оказалось может.
      Не удивлюсь уже, если за пределами mpeg4 vs h264 и при других задачах, помимо просто рескейла/смены битрейта ещё какие-то сюрпризы вскроются.


  1. Grand_piano
    10.07.2024 13:58
    +3

    Эммм, прошу прощения, а вы уверены что попадали в поддерживаемые картами профили энкодеров? Тут бы в документацию поглубже нырнуть, как мне кажется.


    1. cdnnow_writer
      10.07.2024 13:58

      После проведения этого эксперимента, я уже ни в чём не уверен, но исходя из моего перечитывания SDK Nvidia и спецификаций использованных нами карточек, в профили мы попадали.


      1. Grand_piano
        10.07.2024 13:58

        Прям с битрейтами, левелами, профилями, частотой кадров?


  1. ivankudryavtsev
    10.07.2024 13:58
    +2

    NVENC/NVDEC + рескейл легко дают 500-1000 fps на вашей задаче. Просто инструмент не тот. Возьмите Gstreamer из поставки DeepStream и убедитесь сами. Тесты, конечно, тестируют софт, но вводят в заблуждение относительно железа.

    Еще я бы хотел отметить, что скейл на cpu и два трансфера RGB туда сюда через pci-e уменьшают производительность радикально. В нормальном варианте скейл тоже должен быть в gpu (deepstream).


    1. Barabashkad
      10.07.2024 13:58

      вроде не должно быть переноса RGB туда сюда
      так как указан для декодера -hwaccel_output_format_cuda
      используеться scale_cuda а потом опять h264_nvenc


      1. ivankudryavtsev
        10.07.2024 13:58

        Ну может тогда не 2, а все 4 трансфера….


        1. Barabashkad
          10.07.2024 13:58

          может тогда не RGB a NV12. это в 1.5 раза меньше данных :-)


          1. ivankudryavtsev
            10.07.2024 13:58

            Ну может и nv12, это надо ffmpeg смотреть.


    1. cdnnow_writer
      10.07.2024 13:58

      Спасибо что напомнили про Gstreamer, в данном случае хотелось конкретно на примере ffmpeg поэкспериментировать, так как с ним привыкли работать.
      FFmpeg ещё на удивление ведёт себя в лучшую сторону когда работаешь с его модулями по отдельности через код на плюсах, а не в консоли. Пока что правда непонятно, почему так.


  1. ToSHiC
    10.07.2024 13:58
    +1

    Вам пы попробовать указывать nvenc/nvdec явно в качестве кодека, и nvscale в качестве скейлера - при такой комбинации, и отключении кодирования звука, потребление cpu должно быть совсем небольшим.


    1. kalina87
      10.07.2024 13:58
      +1

      Да, автор явно перепутал аппаратные кодеки нвидиа с полусофтовой кудой


      1. cdnnow_writer
        10.07.2024 13:58

        В первых 2/3 напутал, я про это и сам отписался. Хотя по идее mpeg4 тоже аппаратно поддерживается, но вот фильтр на рескейл определённо грузил только процессор.

        ffmpeg-cuda -hwaccel cuda -hwaccel_output_format cuda -i bbb_sunflower_2160p_30fps_normal.mp4 -vf "scale_cuda=1920:1080" -c:v hevc_nvenc -preset medium output_cuda.mp4
        

        Тут уж и кодек указан аппаратный, и фильтр на рескейл аппаратный, мониторинг показывал что GPU был загружен, а CPU почти простаивал. Или же этого тоже недостаточно и ещё что-то нужно было указывать в параметрах команды для большего аппаратного ускорения?


        1. ToSHiC
          10.07.2024 13:58

          Вот так уже существенно лучше, правда в статье этого не было )
          Надо ещё проверить, что кадры не передаются каждый раз из видеокарты в основную память и обратно. Например, это можно посмотреть в дебаг логах ffmpeg, там надо смотреть на pixel format в разных стадиях пайплайна обработки.


    1. cdnnow_writer
      10.07.2024 13:58

      После того как я заметил что mpeg4 напутал с h264/h265 я же вроде бы так и сделал, да и мониторинг у меня отражал что CPU почти не грузился(в статью правда это уже не вошло).

      ffmpeg-cuda -hwaccel cuda -hwaccel_output_format cuda -i bbb_sunflower_2160p_30fps_normal.mp4 -vf "scale_cuda=1920:1080" -c:v hevc_nvenc -preset medium output_cuda.mp4
      


  1. PbIXTOP
    10.07.2024 13:58

    Показ разницы в процентах в таких тестах просто неприемлем для нормального восприятия.

    Например -300% - это как? а фраза "выполнение в 4 раза дольше" выглядит более понятно.

    И оперировать следовало не ускорением, а понятием время исполнения.


    1. cdnnow_writer
      10.07.2024 13:58

      Спасибо за замечание, в следующем посте по этой теме или аналогичными, буду писать словами развёрнуто, а не только процентами.


  1. melodictsk
    10.07.2024 13:58
    +2

    В topaz video ai то же странности с этим ffmpeg, иногда 15 ФПС, иногда 60. Недозагрузка ГПУ и цпу. Надо поэкспериментировать, может быть реально перед обработкой в топазе быстрее будет перегнать в х265, а потом уже запускать обработку.


    1. cdnnow_writer
      10.07.2024 13:58

      С ffmpeg у меня странности ещё продолжились дальше, когда я решил его использовать не из под консоли, а по документации подключая его модули в программе на плюсах. Разницы в производительности я от этого не ожидал, но она снова откуда-то взялась.

      Ну а ещё в исходниках ffmpeg убивает околонулевое количество комментариев.


  1. jidckii
    10.07.2024 13:58
    +3

    Ты ffmpeg не правильно запускаешь, у тебя везде используется фильтр и кодек для CPU.

    Для GPU другие аргументы и зависят от того, что за GPU.

    Рекомендую почитать https://trac.ffmpeg.org/wiki/HWAccelIntro


    1. basilbasilbasil
      10.07.2024 13:58

      cdnnowВ общем, М̶и̶х̶а̶и̶л̶, Матвей, несмотря не первый неудачный опыт, будет логично провести вторую попытку с верными вводными, мы верим - у вас получится!


      1. cdnnow_writer
        10.07.2024 13:58

        Спасибо, буду стараться.)
        Хотя в завершающей 1/3 от статьи, вроде наконец-то тестировал уже всё как надо.
        Но в комментариях появилось много интересных предложений для нового тестирования, так что продолжению скорее всего точно быть. Плюс интересно ещё поэкспериментировать с FFmpeg не в консоли, а с подключением его отдельных библиотек в коде, под конкретные задачи.

        И по стилю, скорее всего дальше будет также. Не хочется вырезать неудачные дубли и трудности, так как примеров того когда всё идёт как надо достаточно. А когда всё пошло не по плану, обычно отбраковывается и свет никогда не видит, хотя интересного и полезного, там порой не меньше.


    1. cdnnow_writer
      10.07.2024 13:58

      Читал во время написания поста, перечитал опять и честно говоря так и не понял, где именно везде у меня кодек для CPU.

      ffmpeg-cuda -hwaccel cuda -hwaccel_output_format cuda -i bbb_sunflower_2160p_30fps_normal.mp4 -vf "scale_cuda=1920:1080" -c:v hevc_nvenc -preset medium output_cuda.mp4
      

      Кодек - hevc_nvenc использует GPU.

      NVENC can be used for H.264 and HEVC encoding. FFmpeg supports NVENC through the h264_nvenc and hevc_nvenc encoders. In order to enable it in FFmpeg you need:

      Фильтр - scale_cuda - использует GPU.

      An example using scale_cuda and encoding in hardware, scale_cuda is available if compiled with ffnvcodec and --enable-cuda-llvm (default is on, requires nvidia llvm to be present at runtime):

      Да и мониторинг через nvtop и htop, указывает на загрузку GPU, а не CPU.