Управляем чем угодно откуда угодно

gstreamer API + самописный софт

Обсуждение линуксовой части и софта на борту виртурилки

gstreamer API + самописный софт

Сообщение andrewion » 19 ноя 2013, 17:19

Всем доброго дня!

С чего это я?

Решил в не конкурса попросить виртурилку за проделанную работу :D Шутка!

Хочу предложить сообществу свой вклад в развитие проекта.
Сами понимаете, что принимать видеопоток gstreamer'ом во встроенное в его систему рендеринга - довольно тупо для некоторых задач, если ничего нельзя поделать с его буфером видеокадров (кадры).
Особенно это актуально, если нужно что-то с этими кадрами делать, например:
  • Пусть кадры через OpenCV, чтобы распознавать образы на видео
  • Делать из кадров текстуры для OpenGL объектов :)
  • Или просто выводить кадры в собственном окне вашего приложения (например через HDC)

Да что угодно можно делать с этими кадрами, если к ним есть доступ.

Так уж получилось, что мне нужно обрабатывать видео поток с gtreamer'а в собственном приложении, прогоняя его кадры через OpenCV, что бы в них можно было что-то распознать (например себя :) ).
Как ни строй pipeline для приёма видеопотока с в2р на gtreamer, OpenCV ничего адекватного не получает из этого видеопотока. Поэтому было решено поковыряться в API gstreamer'а.
Отдельное спасибо ребятам за исходники из этой ветки форума http://forum.virt2real.ru/viewtopic.php?f=38&t=13343&start=30 - натолкнули на ряд хороших идей. А далее я уже сам допиливал захват вдеобуфера gstreamer'а + ряд приятных мелочей.

Начнём по порядку.

Исходники

Сами исходники реализованы на C++.
Скачать их можно отсюда:
gst.zip
(7.15 КБ) Скачиваний: 306


Свой проект я делаю на C++ в Microsoft Visual Studio Ultimate 2012 версии 11 на базе классов MFC+ATL.
В проекте я использую OpenCV, поэтому примеры ниже будут для него.

Для того, чтобы исходники адекватно компилились, необходимо следующее:
  • Установить себе на комп gtreamer и привязать проект к нему. Нас интересует в первую очередь следующее:
    • Указать пути к папка с заголовочными файлами (т.е. *.h) gtreamer:
      • c:\gstreamer\1.0\x86_64\include\gstreamer-1.0\
      • c:\gstreamer\1.0\x86_64\include\glib-2.0\
      • c:\gstreamer\1.0\x86_64\lib\glib-2.0\include\
      • c:\gstreamer\1.0\x86_64\include\gstreamer-1.0\gst\app\
    • Указать путь к папке со статичными библиотеками (т.е. *.lib) gtreamer:
      • c:\gstreamer\1.0\x86_64\lib\
    • Указать список необходимы статичных библиотек:
      • gstreamer-1.0.lib
      • glib-2.0.lib
      • gobject-2.0.lib
      • gstapp-1.0.lib
      • gstriff-1.0.lib
      • gstpbutils-1.0.lib
      • gstbase-1.0.lib
  • Установить себе на комп OpenCV и привязать проект к нему. Нас интересует в первую очередь следующее:
    • Указать пути к папка с заголовочными файлами (т.е. *.h) OpenCV:
      • c:\Program Files (x86)\OpenCV-2.4.6.0\build\include\opencv
      • c:\Program Files (x86)\OpenCV-2.4.6.0\build\include\
    • Указать путь к папке со статичными библиотеками (т.е. *.lib) OpenCV:
      • c:\Program Files (x86)\OpenCV-2.4.6.0\build\x64\vc11\lib
    • Указать список необходимы статичных библиотек:
      • opencv_calib3d246.lib
      • opencv_contrib246.lib
      • opencv_core246.lib
      • opencv_features2d246.lib
      • opencv_flann246.lib
      • opencv_gpu246.lib
      • opencv_haartraining_engine.lib
      • opencv_highgui246.lib
      • opencv_imgproc246.lib
      • opencv_legacy246.lib
      • opencv_ml246.lib
      • opencv_nonfree246.lib
      • opencv_objdetect246.lib
      • opencv_photo246.lib
      • opencv_stitching246.lib
      • opencv_ts246.lib
      • opencv_video246.lib
      • opencv_videostab246.lib
  • Подключить заголовочный файл в собственное приложение: GstOpenCV.h

На в2р запускаем строчку:
Код: Выделить всё
gst-launch v4l2src always-copy=FALSE ! video/x-raw-yuv,format=\(fourcc\)NV12,width=640,height=480 ! dmaiaccel ! dmaienc_mpeg4 encodingpreset=2 targetbitrate=2000000 ratecontrol=2 intraframeinterval=1 ! queue ! rtpmp4vpay ! udpsink port=3000 host=IP_КОМПА


Где-то объявляем эти переменные:
Код: Выделить всё
CWinThread *pGstThread;
CGstOpenCV *pCGstVideo;

pGstThread - указатель на объект, отвечающий за работу с потоком в котором у нас будет вертеться видеопоток gtreamer'а.
pCGstVideo - указатель на объект, отвечающий за работу с gtreamer API с добавками для OpenCV.

Инициализация класса и выделение его в отдельный поток приложения:
Код: Выделить всё
pCGstVideo = new CGstOpenCV("udpsrc port=3000 caps=\" application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)MP4V-ES, profile-level-id=(string)5, config=(string)000001b005000001b50ecf00000100000001200086e00024e26003ec1bd6664ba98514043c1463, payload=(int)96, ssrc=(uint)591258361, clock-base=(uint)2524003075, seqnum-base=(uint)599\" ! rtpmp4vdepay ! queue ! avdec_mpeg4 ! videoscale", "c:\\gstreamer\\1.0\\x86_64\\");

pGstThread = new CWinThread(*GstVideoInit, (CGstOpenCV*)pCGstVideo);
pGstThread->CreateThread();

CGstOpenCV - сам класс, при инициализации конструктора, содержит два параметра:
  • pipelineString_ - pipeline для gtreamer'а, по которому будем принимать видео поток
  • gstreamerPath_ - путь, где находится сам gtreamer на компе. Это нужно для того, чтобы он мог найти и подрубить необходимые для его работы плагины. Кстати, этот путь можно найти в реестре винды.

После того как запустили gtreamer в отдельный поток приложения, теперь можно брать кадры из видеопотока:
Код: Выделить всё
...
IplImage* pFrame = pCGstVideo->getFrame();
...


Вот и всё. :D
А что деть с этим кадром под OpenCV, вы и сами знаете.

В завершение

Пример выше, подразумевает, что gtreamer нужен в приложении для использования в OpenCV, однако оговорюсь, что предлагаемое мною решения, куда больше возможностей.
Если посмотреть на исходник класса CGstOpenCV, то там вы найдёте реализацию метода getFrame():
Код: Выделить всё
// Возвращает указатель на кадр
IplImage *CGstOpenCV::getFrame ()
{
   if (!frame)
   {
      gint width = getWidth();
      gint height = getHeight();
      gint channels = getChannels();

      if (!width || !height || !channels)
      {
         setInfoMessage("Не возможно инициализировать кадр для OpenCV из видеопотока");
         return NULL;
      }

      frame = cvCreateImageHeader(cvSize(width, height), IPL_DEPTH_8U, channels);
   }

   frame->imageData = (char*)getFrameBuffer();

   return frame;
}


Т.е. по сути для доступа к буферу кадра видеопотока, необходимо использовать метод getFrameBuffer() из базового класса CGstVideo, а далее это буфер можно пускать под свои нужды.

Всем удачи! :D
Аватара пользователя
andrewion
 
Сообщения: 150
Зарегистрирован: 03 сен 2013, 21:46

Re: gstreamer API + самописный софт

Сообщение dmitry.ulitin » 19 ноя 2013, 22:47

andrewion писал(а):На в2р запускаем строчку:
Код: Выделить всё
gst-launch v4l2src always-copy=FALSE ! video/x-raw-yuv,format=\(fourcc\)NV12,width=640,height=480 ! dmaiaccel ! dmaienc_mpeg4 encodingpreset=2 targetbitrate=2000000 ratecontrol=2 intraframeinterval=1 ! queue ! rtpmp4vpay ! udpsink port=3000 host=IP_КОМПА



Вот ведь обидно - это строчка у меня на в2р не запускается - точнее падает секунд через 5:
Код: Выделить всё
.....
Setting pipeline to PLAYING ...
New clock: GstSystemClock
ERROR: from element /GstPipeline:pipeline0/dmaienc_mpeg4:dmaienc_mpeg40: GStreamer encountered a general stream error.
Additional debug info:
../../src/src/gsttidmaienc.c(1143): encode_buffer_get_free (): /GstPipeline:pipeline0/dmaienc_mpeg4:dmaienc_mpeg40:
Not enough space free on the output buffer
Execution ended after 12465222335 ns.
Setting pipeline to PAUSED ...

(gst-launch-0.10:1505): GStreamer-CRITICAL **: gst_mini_object_unref: assertion `GST_IS_MINI_OBJECT (mini_object)' failed
Setting pipeline to READY ...
Setting pipeline to NULL ...
Freeing pipeline ...
gst-launch-0.10: Buffer.c:257: Buffer_getUserPtr: Assertion `hBuf' failed.
./stream-mpg.sh: line 7:  1505 Aborted


ЧЯДН?
Может кто ещё проверить?
dmitry.ulitin
 
Сообщения: 14
Зарегистрирован: 09 сен 2013, 23:35

Re: gstreamer API + самописный софт

Сообщение andrewion » 19 ноя 2013, 23:09

dmitry.ulitin писал(а):
andrewion писал(а):На в2р запускаем строчку:
Код: Выделить всё
gst-launch v4l2src always-copy=FALSE ! video/x-raw-yuv,format=\(fourcc\)NV12,width=640,height=480 ! dmaiaccel ! dmaienc_mpeg4 encodingpreset=2 targetbitrate=2000000 ratecontrol=2 intraframeinterval=1 ! queue ! rtpmp4vpay ! udpsink port=3000 host=IP_КОМПА



Вот ведь обидно - это строчка у меня на в2р не запускается - точнее падает секунд через 5:
Код: Выделить всё
.....
Setting pipeline to PLAYING ...
New clock: GstSystemClock
ERROR: from element /GstPipeline:pipeline0/dmaienc_mpeg4:dmaienc_mpeg40: GStreamer encountered a general stream error.
Additional debug info:
../../src/src/gsttidmaienc.c(1143): encode_buffer_get_free (): /GstPipeline:pipeline0/dmaienc_mpeg4:dmaienc_mpeg40:
Not enough space free on the output buffer
Execution ended after 12465222335 ns.
Setting pipeline to PAUSED ...

(gst-launch-0.10:1505): GStreamer-CRITICAL **: gst_mini_object_unref: assertion `GST_IS_MINI_OBJECT (mini_object)' failed
Setting pipeline to READY ...
Setting pipeline to NULL ...
Freeing pipeline ...
gst-launch-0.10: Buffer.c:257: Buffer_getUserPtr: Assertion `hBuf' failed.
./stream-mpg.sh: line 7:  1505 Aborted


ЧЯДН?
Может кто ещё проверить?


А у вас последняя прошифка стоит? И в2р является ethernet-устройством с IP 192.168.3.128? Если так, то комп должен являться с IP 192.168.3.1.

UPD:
Кстати, у меня та же фигня иногда бывает с ошибкой "gst-launch-0.10: Buffer.c:257: Buffer_getUserPtr: Assertion `hBuf' failed. ". Помогает либо очередной перезапуск, либо перезагрузка в2р.
Аватара пользователя
andrewion
 
Сообщения: 150
Зарегистрирован: 03 сен 2013, 21:46

Re: gstreamer API + самописный софт

Сообщение CHERTS » 11 фев 2014, 10:19

Эээээ мммм я правильно понял, что Вы захватываете видео gstreamer с в2р и отправляете его на ком, а на компе его принимаете и отдаете OpenCV ?
Если так, то тогда вопрос, зачем? Более интересен вариант захвата и обработки видео тем же OpenCV на самой виртурилке, без применения компа или мощнасти виртурилки это не позволяют?
CHERTS
 
Сообщения: 20
Зарегистрирован: 30 сен 2013, 12:01

Re: gstreamer API + самописный софт

Сообщение phoenix367 » 11 фев 2014, 18:01

andrewion писал(а):
dmitry.ulitin писал(а):
andrewion писал(а):
UPD:
Кстати, у меня та же фигня иногда бывает с ошибкой "gst-launch-0.10: Buffer.c:257: Buffer_getUserPtr: Assertion `hBuf' failed. ". Помогает либо очередной перезапуск, либо перезагрузка в2р.


А это у вас именно с новой прошивкой или всегда такое было? Сейчас планирую портировать ПО своего робота на новую прошивку и думаю подождать еще пока ядро и прочее стабилизируют или уже можно.
phoenix367
 
Сообщения: 193
Зарегистрирован: 09 сен 2013, 00:19

Re: gstreamer API + самописный софт

Сообщение sanya555 » 03 мар 2014, 13:57

Добрый день. Пытаюсь скомпилить проект, но при создании экземпляра класа pCGstVideo возникает ошибка. Если вам не сложно не могли бы вы мне помочь с этим, буду очень благодарен.
Код ошибки.
Error 102 error LNK2019: unresolved external symbol _cvCreateImageHeader referenced in function "public: struct _IplImage * __thiscall CGstOpenCV::getFrame(void)" (?getFrame@CGstOpenCV@@QAEPAU_IplImage@@XZ) E:\desctop\visual studio\c++ mfc\first_test\gstreamer_api\gstreamer_api\GstOpenCV.obj gstreamer_api
sanya555
 
Сообщения: 74
Зарегистрирован: 10 фев 2014, 13:20

Re: gstreamer API + самописный софт

Сообщение sanya555 » 03 мар 2014, 19:08

Возможно глупый вопрос, но возможна ли причина моей проблемы в том, что я собираю проект на VS 2013? Очень прошу помощи, так как для программиста нету большего наказания как застой)
sanya555
 
Сообщения: 74
Зарегистрирован: 10 фев 2014, 13:20

Re: gstreamer API + самописный софт

Сообщение phoenix367 » 03 мар 2014, 19:31

sanya555 писал(а):Возможно глупый вопрос, но возможна ли причина моей проблемы в том, что я собираю проект на VS 2013? Очень прошу помощи, так как для программиста нету большего наказания как застой)


Ну вам же линкер английским по белому говорит, что не может найти символ cvCreateImageHeader. Подключите библиотеку opencv_imgproc (хотя точно не помню, смотрите документацию где определена функция, может opencv_core)
phoenix367
 
Сообщения: 193
Зарегистрирован: 09 сен 2013, 00:19

Re: gstreamer API + самописный софт

Сообщение sanya555 » 03 мар 2014, 20:03

Путь к библиотекам прописал. Дело в том что ранее не приходилось работать с студией. Библиотеки подключал по примеру как тут-http://social.msdn.microsoft.com/Forums/ru-RU/a4839e68-e6c4-4b8f-b09c-94e954c4e4d6/-opengl-microsoft-visual-studio-2012?forum=vsru
Сами исходники добавлял напрямую через #include в основной программе.
sanya555
 
Сообщения: 74
Зарегистрирован: 10 фев 2014, 13:20

Re: gstreamer API + самописный софт

Сообщение phoenix367 » 03 мар 2014, 22:44

sanya555 писал(а):Путь к библиотекам прописал. Дело в том что ранее не приходилось работать с студией. Библиотеки подключал по примеру как тут-http://social.msdn.microsoft.com/Forums/ru-RU/a4839e68-e6c4-4b8f-b09c-94e954c4e4d6/-opengl-microsoft-visual-studio-2012?forum=vsru
Сами исходники добавлял напрямую через #include в основной программе.


Здесь сложно сказать, что у вас не так. Проверьте еще раз правильность всех путей к opencv, а также названия подключаемых библиотек, поскольку MSVC не выдаст предупреждений, если не может найти библиотеку при линковке.
phoenix367
 
Сообщения: 193
Зарегистрирован: 09 сен 2013, 00:19

След.

Вернуться в Софт на виртурилке - SDK, Linux, Github, программирование (C/C++ и др.)

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

cron