LINUX.ORG.RU

Нарезка видеопотока на кадры с GPU ускорением в realtime

 , ,


0

1

Всем привет!

Есть проблема задействования GPU при нарезке видеопотоков на кадры.
Сейчас используется OpenCV, но без GPU ест много CPU. Собрать с CUDA10 не получилось, вырезали поддержку.

ffmpeg дает большую задержку при формировании потока кадров.

Кто-то использовал иные решения? Есть варианты?



Последнее исправление: job_maker (всего исправлений: 1)

Есть проблема задействования GPU при нарезке видеопотоков на кадры

что такое «нарезка видеопотоков на кадры» ? Для обработки видео в реалтайме традиционно gstreamer все нормальные люди используют.

anonymous
()

в общем-то, используя VAAPI можно кодировать/декодировать быстрее реалтайма

Harald ★★★★★
()

ffmpeg дает большую задержку при формировании потока кадров

Вы его из консоли запускаете?

RazrFalcon ★★★★★
()

Сейчас используется OpenCV, но без GPU ест много CPU. Собрать с CUDA10 не получилось, вырезали поддержку.

Кто вырезал, чего вырезали? И куда смотрят зоозащитники! В моем зверинце все на месте:

Linux 5.1.12-gentoo

dev-util/nvidia-cuda-toolkit
     Installed versions:  10.1.168-r1

x11-drivers/nvidia-drivers
     Installed versions:  430.26-r1

media-libs/opencv
     Installed versions:  4.1.0 (... cuda vaapi ...)

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

Deleted
()
Последнее исправление: Deleted (всего исправлений: 3)
Ответ на: комментарий от Harald

Сначала декодирование, а потом «выхватывание» потока кадров, в виде jpeg.

job_maker
() автор топика
Ответ на: комментарий от job_maker

Так выдирайте кодом, прямо сырой кадр. Каждый раз запускать ffmpeg и генерировать jpeg естественно медленно.

RazrFalcon ★★★★★
()
Ответ на: комментарий от job_maker

А почему тогда собрать OpenCV с CUDA не удается ?

Для карточек Titan Xp, те же 1080 только памяти заметно больше, вроде бы собирается и даже работает OpenCV.

Есть сценарий проблемы с OpenCV + CUDA по части сборки ?

Deleted
()
Последнее исправление: Deleted (всего исправлений: 2)
Ответ на: комментарий от Deleted

Да, пожалуйста:

cmake -D CMAKE_BUILD_TYPE=RELEASE -D  [br]
CMAKE_INSTALL_PREFIX=/usr/local -D WITH_CUDA=ON -D [br]
CMAKE_C_COMPILER=gcc-4.8 -DCMAKE_CXX_COMPILER=g++-4.8 -D [br]
ENABLE_FAST_MATH=1 -D CUDA_FAST_MATH=1 -D WITH_CUBLAS=1 -D [br]
INSTALL_PYTHON_EXAMPLES=ON -D [br]
OPENCV_EXTRA_MODULES_PATH=/root/opencv_contrib/modules -D [br]
CUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda-10.1 -D [br]
OPENCV_ENABLE_NON_FREE=ON .. [br]

Успешно генерируется, а при сборке через make -j8, прилетают кучи ошибок

make[1]: *** [modules/cudaarithm/CMakeFiles/opencv_cudaarithm.dir/all] Error 2 [br]
Makefile:162: recipe for target 'all' failed [br]
make: *** [all] Error 2 [br]

job_maker
() автор топика
Ответ на: комментарий от job_maker

а host-система какая ?

почему gcc 4.8 а не 8.3.0 ?

какую версию собираете opencv ? чем не походит 4.1.0 ?

уточните какой версии cuda 10.1 ? проблем с последней 10.1.168 нет никаких.

тикет здесь уже разместили ? https://github.com/opencv/opencv

Deleted
()

OpenCV умеет работать с GStreamer. Кормишь ему пайп вроде

filesrc location=test.mkv ! matroskademux ! vaapih264dec ! videoconvert ! appsink
в VideoCapture и радуешься.

klokik
()
Последнее исправление: klokik (всего исправлений: 1)
Ответ на: комментарий от job_maker

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

Deleted
()
Ответ на: комментарий от Deleted

Спасибо вам огромное за правильные наводящие вопросы!
Все собралось и даже нашли виновника проблем))) это старая версия opencv собранная через conda.
В итоге: gcc 8.30, cuda 10.1 -> opencv 4.1 - собрано!
Будем тестить декодинг видеопотоков, в том числе и через GStreamer.

job_maker
() автор топика
Ответ на: комментарий от job_maker

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

Deleted
()
Ответ на: комментарий от job_maker

AFAIK, gstreamer не зависит от OpenCV.

Gstreamer-у и CUDA не нужна, точнее отдельные компоненты наверно могут ее использовать, но тебя оно это не касается. Тут только кормить видеопоток бинарному nvdec и забирать готовые кадры для обработки OpenCV, для декодирования видеопотока и нарезки на кадры CUDA (явно) не используется, потому можешь использовать OpenCV собраный без нее.

klokik
()
Ответ на: комментарий от klokik

А можно какой-то пример «кормить видеопоток бинарному nvdec и забирать готовые кадры для обработки OpenCV»?
В части «кормить видеопоток бинарному nvdec»? Похоже что-то неизвестное нам)

job_maker
() автор топика
Ответ на: комментарий от job_maker
gst-launch-1.0 filesrc location=~/big_buck_bunny.mov ! qtdemux ! h264parse ! vaapidecode ! vaapisink [br]
WARNING: erroneous pipeline: no element "vaapidecode"

Вот такая штука всплыла.
Ставили стандартные пакеты из репозитория Ubuntu 18.04.
gstreamer1.0-vaapi 1.14

job_maker
() автор топика
Ответ на: комментарий от job_maker

vaapidecode есть на 16.04, в 18.04 может называться vaapih264dec, например, в зависимости от кодека. И gstreamer1.0-vaapi должен быть установлен.

Но у тебя на нвидия которая напрямую vaapi не поддерживает, зато у них есть vdpau и nvdec. Ну или использовать враппер с vdpau на vaapi и оверрайдить белый список с «GST_VAAPI_ALL_DRIVERS=1».

Посмотри что у тебя есть «gst-inspect-1.0 vdpau» и «gst-inspect-1.0 nvdec» и подставь в свой пайплайн. Второго скорее нету, ибо для него надо gst-plugins-bad с кудой пересобирать. А первый должен быть.

klokik
()
Ответ на: комментарий от anonymous

традиционно gstreamer

Лучше держаться подальше от этого говна.

ox55ff ★★★★★
()
Ответ на: комментарий от job_maker

no element «vaapidecode»

У gstreamer есть блэклист. Плагин может туда попасть. Проверять через gst-inspect-1.0 -b. Но когда я занимался декодированием видео плагин назывался vaapih264dec.

ox55ff ★★★★★
()
Ответ на: комментарий от ox55ff

Делать надо на NVIDIA VIDEO CODEC SDK

делаем, собираем ffmpeg.
Только один вопрос: как кадры питоном с ffmpeg?)) Собственно потому и был gstreamer через CPU.

У gstreamer есть блэклист. Плагин может туда попасть. Проверять через gst-inspect-1.0 -b. Но когда я занимался декодированием видео плагин назывался vaapih264dec.

Блеклист пуст, vaapih264dec не увидели, но может уже и не надо, если поймем как кадры с ffmpeg забирать?)) Нам поток декодированный с него нужен, по 10 кадров/с с 1 камеры. И каждый кадр забирать питоном.

job_maker
() автор топика
Ответ на: комментарий от job_maker

Сразу добавлю, что хотелось бы не сохранять кадры куда-то в jpg, а потом читать. А именно декодировать поток видео в поток картинок.
Потом питоном забирать именно поток. Чтоб не требовалось много места на HDD.
Надеюсь нормально объяснил)

job_maker
() автор топика
Ответ на: комментарий от job_maker

Не знаю как это в питоне, но на чистом libav тебе нужно получить контекст кодека через AVCodecContext* avcodec_alloc_context3(const AVCodec *codec) . Он хочет id кодека, который можно получить по имени через функцию AVCodec* avcodec_find_decoder_by_name(const char *name). Список доступных кодеков можно посмотреть так:

AVCodec* currentCodec = av_codec_next(nullptr);
while (currentCodec != nullptr)
{
    qDebug() << currentCodec->name;
    currentCodec = av_codec_next(currentCodec);
}
Например у меня есть такие:
h264_cuvid
hevc_cuvid
mjpeg_cuvid
mpeg1_cuvid
mpeg2_cuvid
mpeg4_cuvid
vc1_cuvid
vp8_cuvid
vp9_cuvid
cuvid - это как раз аппаратный кодек nvidia.

ox55ff ★★★★★
()
Ответ на: комментарий от job_maker

Подозрительно как-то, что там за камера такая, что проц с 10 кадрами в секунду не справляется? Ну или может не захват кадров тормозит а питоновский код которым картинка обрабатывается?

klokik
()
Ответ на: комментарий от klokik

да, тормозит питоновский код, но и камер там было 7. Нагрузка 8 ядерного CPU была 52%.
Сейчас пересобрали ffmpeg с GPU.
Только странно что нагрузка на CPU все равно есть. Но файл распаковал из 50 мб в 15 Гб очень шустро, наверняка быстрее чем 30 кадров в секунду))

Переписали код OpenCV на прием видеопотока с ffmpeg.
Осталось тестировать)

job_maker
() автор топика
Ответ на: комментарий от klokik

а вот это интересно)
надо попробовать. хотя уже и так пошло. поток идет, картинки режутся))

job_maker
() автор топика
Ответ на: комментарий от klokik

ffmpeg всё равно использует CPU под 100%. Какие бы настройки я там не пробовал. В итоге, есть подозрение, что декодирование у нас действительно на GPU, а вот дальше ffmpeg по умолчанию пытается кодировать и это происходит на CPU.
При этом процесс на GPU появляется, нагрузка на GPU есть.

process1 = (
    ffmpeg
    .input("rtmp://127.0.0.1:5935/live/201801150259", hwaccel="nvdec")
    .output('pipe:', format='rawvideo', pix_fmt='rgb24')
    .run_async(pipe_stdout=True)
)

while True:

    in_bytes = process1.stdout.read(width * height * 3)
    if not in_bytes: continue
    in_frame = (np.frombuffer(in_bytes, np.uint8).reshape([height, width, 3]))

job_maker
() автор топика
Ответ на: комментарий от job_maker

нашел ответ. Надо использовать cuvid и для декодирования и для кодирования. Тогда оба процесса будут идти на GPU.

job_maker
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.