Перейти к содержимому
Compvision.ru
mult1plexer

VideoCapture аппаратное декодирование

Recommended Posts

Здравствуйте. Столкнулся с проблемой получения кадра с веб камеры и видео. Как оказалось opencv использует программное декодирование видео потока. В результате чего не могу получить 60fps и убрать нагрузку с процессора. Через проигрыватель, который идет с K-Lite Codec Pack все воспроизводится так как надо. Кто нибудь решал такую проблему или может есть другой способ получать кадры с видео?

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А что вы собираетесь делать с полученной cv::Мат картинкой?  Многие алгоритмы вообще онлайн не работают на обычном железе.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Сам думал сделать, но руки не доходят. Вопрос важный и по делу. Так как h.264 может аппратно декодироваться. Но и для остальных кодеков аппаратные возможности лучше испоьзовать на 100 процентов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
3 часа назад, fotomer сказал:

А что вы собираетесь делать с полученной cv::Мат картинкой?  Многие алгоритмы вообще онлайн не работают на обычном железе.

что значит не работают онлайн? не понял этот тезис

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Попробуй принудительно изменить backend у capture: CAP_FFMPEG, CAP_DSHOW или CAP_VFW. Они выбираются по очереди, какой первый подойдёт. Возможно, что у тебя первый в списке как раз не аппаратный.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
8 часов назад, Nuzhny сказал:

Попробуй принудительно изменить backend у capture: CAP_FFMPEG, CAP_DSHOW или CAP_VFW. Они выбираются по очереди, какой первый подойдёт. Возможно, что у тебя первый в списке как раз не аппаратный.

это я первым делом сделал. как я понял у меня через directshow идет, с gstreamer не удалось запустить завершается 0xc000007ошибкой

8 часов назад, Pechkin80 сказал:

Для линукса по идеи нужен GStreamer. Интересная статья по теме:

https://blog.zhaw.ch/high-performance/2017/10/24/boost-your-gstreamer-pipeline-with-the-gpu-plugin/

я пока под windows запускаю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Можно у Capture посмотреть свойство CAP_PROP_BACKEND.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
15 часов назад, Nuzhny сказал:

Можно у Capture посмотреть свойство CAP_PROP_BACKEND.

что это даст? камера работает только с DSHOW в opencv, в VLC тоже самое только через DSHOW

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
51 минуту назад, mult1plexer сказал:

что это даст? камера работает только с DSHOW в opencv, в VLC тоже самое только через DSHOW

А что за камера ? Камера работает по протоколу обычно и не привязана к кодеку. Если только совсем какойто ширпотреб.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Веб-камеры используются не по протоколу, а через драйвер. Может оказаться, для неё есть DirectShow драйвер и всё. Но тут ещё вопрос, используется ли DirectShow или сейчас всё  реализовано через MSMF. Всё  - это dshow и vfw.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
20 часов назад, Pechkin80 сказал:

А что за камера ? Камера работает по протоколу обычно и не привязана к кодеку. Если только совсем какойто ширпотреб.

китайские нонейм модули без опознавательных знаков

13 часа назад, Nuzhny сказал:

Веб-камеры используются не по протоколу, а через драйвер. Может оказаться, для неё есть DirectShow драйвер и всё. Но тут ещё вопрос, используется ли DirectShow или сейчас всё  реализовано через MSMF. Всё  - это dshow и vfw.

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

так в этом и суть, что MPC-HC от k-lite  захватывает нормально не через DirectShow. Значит как минимум это можно как то поменять. В opencv проблема даже в FHD сделать захват, FPS падает до 7-10. А по дефолту открывает в 640х480

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Для аппаратного декодирования h.264/h.265/mpeg4/MJPEG можно взять библиотеки из проекта ffmpeg. Там есть реализаций кодеков с использованием SDK от  NVIDIA, AMD и INTEL, также есть варианты для мобильных устройств. В ffmpeg есть свой модуль для работы с камерами. OpenCV версий 3 и 4 можно собрать с поддержкой ffmpeg для декодирования.

Применяя аппаратный декодер и OpenCV модули с поддержкой NVIDIA Cuda и/или OpenCL, есть возможность построить алгоритмы без копирования декодированного потока в хост память.  DirectX и OpenGL поверхности в памяти  GPU могут являться источником для  OpenCl/Cuda матриц в OpenCV не покидая GPU.

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

ffmpeg тут ничего нового не придумал, а просто предоставляет обёртку над DirectShow.

Я уже давно этой темы не касался, надеюсь, что не навру.

Веб камеры в Windows работают через DirectShow драйвер (или WMF) и тут ничего не попишешь. Я очень сомневаюсь, что у них есть что-то своё. Соответственно, при отображении видео используется DXVA - аппаратное декодирование с выводом видео на экран. При этом кадры даже не поступают в оперативную память, а отправляются сразу на аппаратный декодер, встроенный в процессор или видеокарту. Это даже не CUDA или OpenCL, а отдельные специализированные чипы внутри процессора или видеокарты: Intel Quick Sync Video, Nvidia NVENC или AMD Video Coding Engine. Ffmpeg, например, умеет декодировать сетевое видео или файлы и на CUDA - cuvid. Но это уже будет грузить видеокарту, в отличие от полностью аппаратного Nvidia NVENC. Как всё это применить к вебкамерам я, к сожалению, не в курсе.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Полностью справедливо для камер только с DirectShow/WMF драйвером. Некоторые имеют еще собственный драйвер и SDK, особенно с вариантами для Windows и Linux. Часто, такие камеры выдают полное разрешение и частоту кадров только в сжатом видео потоке ( Mjpeg/h.264) – видел китайcкую камеру 5Mp/60Hz/h.264 120Mbit поток, подключённую по USB2… Такие случаи как раз для аппаратного декодирования. В SDK Intel Quick Sync Video, Nvidia NVENC есть примеры копирования декодированного кадра в OpenCL/Cuda память.   

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
3 часа назад, Nuzhny сказал:

ffmpeg тут ничего нового не придумал, а просто предоставляет обёртку над DirectShow.

Я уже давно этой темы не касался, надеюсь, что не навру.

Веб камеры в Windows работают через DirectShow драйвер (или WMF) и тут ничего не попишешь. Я очень сомневаюсь, что у них есть что-то своё. Соответственно, при отображении видео используется DXVA - аппаратное декодирование с выводом видео на экран. При этом кадры даже не поступают в оперативную память, а отправляются сразу на аппаратный декодер, встроенный в процессор или видеокарту. Это даже не CUDA или OpenCL, а отдельные специализированные чипы внутри процессора или видеокарты: Intel Quick Sync Video, Nvidia NVENC или AMD Video Coding Engine. Ffmpeg, например, умеет декодировать сетевое видео или файлы и на CUDA - cuvid. Но это уже будет грузить видеокарту, в отличие от полностью аппаратного Nvidia NVENC. Как всё это применить к вебкамерам я, к сожалению, не в курсе.

Примение CUDA ИМХО сомнительное дело впринцепи. Если CUDA используется для задач обработки изображений, то использование CUDA ещё и для декодирования будет приводить к частостому сбросу всего кеша GPU и снижению производительности. Я вот тоже слышал что для этого специальный чип внутри процессора или карты есть + SSE/MMX, но как убедиться что FFMPRG или GSTREAMER всё сделал поуму для декодирования ?

Я может залез не в свою тему, но как там  обстоят дело с подключением камеры за 3 бакса ИМХО не самое главное. Но в любом профессиональном решении с нормальной IP камерой этот впрос не может быть обойдён стороной.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

С ip камерами  как раз всё проще. Их можно пачкой на CUDA декодировать, а потом обрабатывать изображения, не выгружая декодированные кадры из видеопамяти. Можно отдавать их, например в TensorFlow.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
1 час назад, Nuzhny сказал:

С ip камерами  как раз всё проще. Их можно пачкой на CUDA декодировать, а потом обрабатывать изображения, не выгружая декодированные кадры из видеопамяти. Можно отдавать их, например в TensorFlow.

Хм, можно попдробнее.... Это такой интерфейс есть чтоб получать данные уже загруженные в GPU , но декодированные? Для декодирования и обработки изображений разные библиотеки используются. Я не знаком с TensorFlow, но я пологаю. что могут потребоваться какието предварительные действия, до применения TensorFlow которых нет в TensorFlow. Очень подозрительно просто что TensorFlow представляется волшебной палочкой. Всё универсальное не всегда самоелучшее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Получать можно в том же ffmpeg:

1. Если не собран, то собрать ffmpeg с поддержкой cuvid. Проверка: ./ffmpeg -hwaccels

2. При создании AVCodec вызвать avcodec_find_decoder_by_name("h264_cuvid") или avcodec_find_decoder_by_name("mjpeg_cuvid").

3. Перед вызовом avcodec_decode_video2 устанавливать decCtx->pix_fmt = AV_PIX_FMT_CUDA

4. Тут уже нам возвращают указатель на видеопамять в AVFrame, можно копировать её к себе и обрабатывать:

4.1. Учитываем, что в данном случае у нас кадр не YUV420, а NV12: cudaMemcpy(data, picture->data[0], height * picture->linesize[0], cudaMemcpyDefault)

4.2.  Хочется RGB? Вызываем nppiNV12ToBGR_709HDTV_8u_P2C3R

4.3. Хочется засунуть в OpenCV? Вот: cv::cuda::GpuMat* gpuFrame = new cv::cuda::GpuMat(height, width, CV_8UC1, picture->data[0], picture->linesize[0])

Выгрузить из GPU memory и сохранить? Вот: cv::Mat frame; gpuFrame->download(frame);

4.4. Хочется отобразить кадр без копирования в ОЗУ? Создаём OpenGL окно: cv::namedWindow("wnd name", cv::WINDOW_OPENGL)

 

Это про декодирование на CUDA и обработку кадра средствами OpenCV без копирования в системную память.

Про TensorFlow: тут надо использовать С++ API, на Питончике такой возможности нет. Добавили такую возможность недавно в версии 1.12: вот обсуждение.

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
1 час назад, Nuzhny сказал:

Получать можно в том же ffmpeg:

1. Если не собран, то собрать ffmpeg с поддержкой cuvid. Проверка: ./ffmpeg -hwaccels

2. При создании AVCodec вызвать avcodec_find_decoder_by_name("h264_cuvid") или avcodec_find_decoder_by_name("mjpeg_cuvid").

3. Перед вызовом avcodec_decode_video2 устанавливать decCtx->pix_fmt = AV_PIX_FMT_CUDA

4. Тут уже нам возвращают указатель на видеопамять в AVFrame, можно копировать её к себе и обрабатывать:

4.1. Учитываем, что в данном случае у нас кадр не YUV420, а NV12: cudaMemcpy(data, picture->data[0], height * picture->linesize[0], cudaMemcpyDefault)

4.2.  Хочется RGB? Вызываем nppiNV12ToBGR_709HDTV_8u_P2C3R

4.3. Хочется засунуть в OpenCV? Вот: cv::cuda::GpuMat* gpuFrame = new cv::cuda::GpuMat(height, width, CV_8UC1, picture->data[0], picture->linesize[0])

Выгрузить из GPU memory и сохранить? Вот: cv::Mat frame; gpuFrame->download(frame);

4.4. Хочется отобразить кадр без копирования в ОЗУ? Создаём OpenGL окно: cv::namedWindow("wnd name", cv::WINDOW_OPENGL)

 

Это про декодирование на CUDA и обработку кадра средствами OpenCV без копирования в системную память.

Про TensorFlow: тут надо использовать С++ API, на Питончике такой возможности нет. Добавили такую возможность недавно в версии 1.12: вот обсуждение.

Спасибо, интересно будет поробовать. Тогда получаеться VideoCapture class из OpenCV не используем ? Он ведь вроде как сам работает с FFMPEG ?

И управление видеопотоком тоже надо будет через FFMPEG реализовывать. Или сам VideoCapture OpenCV прпатчить для более эффективной работы ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

С другой стороны есть cudacodec из opencv_contrib, который, вроде, делает как раз необходимое. Но я его не проверял, ничего не могу сказать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

NuzhnyБольшое спасибо за ваши ответы. Но у меня так бывает что к теме я возвращаюсь через несколько месяцев.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
В 05.02.2019 at 00:32, ppop21285 сказал:

Для аппаратного декодирования h.264/h.265/mpeg4/MJPEG можно взять библиотеки из проекта ffmpeg. Там есть реализаций кодеков с использованием SDK от  NVIDIA, AMD и INTEL, также есть варианты для мобильных устройств. В ffmpeg есть свой модуль для работы с камерами. OpenCV версий 3 и 4 можно собрать с поддержкой ffmpeg для декодирования.

 

Применяя аппаратный декодер и OpenCV модули с поддержкой NVIDIA Cuda и/или OpenCL, есть возможность построить алгоритмы без копирования декодированного потока в хост память.  DirectX и OpenGL поверхности в памяти  GPU могут являться источником для  OpenCl/Cuda матриц в OpenCV не покидая GPU.

 

 

В 05.02.2019 at 12:21, Nuzhny сказал:

С ip камерами  как раз всё проще. Их можно пачкой на CUDA декодировать, а потом обрабатывать изображения, не выгружая декодированные кадры из видеопамяти. Можно отдавать их, например в TensorFlow.

 из gpu есть Mali T860 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
В 29.01.2019 at 09:25, Nuzhny сказал:

Попробуй принудительно изменить backend у capture: CAP_FFMPEG, CAP_DSHOW или CAP_VFW. Они выбираются по очереди, какой первый подойдёт. Возможно, что у тебя первый в списке как раз не аппаратный.

У меня процессор Intel Pentium n3710 с графическим ядром INTEL HD GRAPHICS. Если верить данной таблице https://www.wikizero.com/en/Intel_Graphics_Technologyто данное графическое ядро позволяет декодировать 2k 30 кадров в секунду. 

Открываю файл 1080p, кодек h264  с принудительно заданным backend ffmpeg:
cv::VideoCapture  cam( "2.mp4", cv::CAP_FFMPEG);
Загрузка процессора от 25 до 60%.
Открываю данный файл, используя Microsoft Media Foundation:
cv::VideoCapture  cam( "2.mp4", cv::CAP_MSMF);
Загрузка процессора от 10 до 25%. Почему так происходит?! Насколько я читал ffmpeg использует аппаратное декодирование.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

ffmpeg сам по себе может что-то и не уметь, если его специально не собрали с поддержкой этого аппаратного ускорения. Хотя логично было бы его включать для интеловских процессоров. Если у тебя есть просто собранный отдельно ffmpeg (или скачанный), то можешь посмотреть, что он умеет и повыбирать разные кодеки из командной строки.

Например, команда "ffmpeg -hwaccels" выведен список доступных аппаратных кодеков.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×