Hey Guys, I know this is a very noob question but I’m a little stuck.
I have Raspberry Pi camera on the network and I would like to stream video from this device so I can process it using openCV. I’ve tried turing Pi camera into IPcamera and using ofxIpVideoGrabber but this addon doesn’t compile with new OF 0.9.3 on linux 64bit.
https://github.com/bakercp/ofxIpVideoGrabber/issues/24
Then I’ve tried to stream the video over TCP on some port and wanted to consume this stream from OF but then I don’t know how to take advantage of this classes ofVideoGrabber or ofVideoPlayer with my custom stream and I don’t want to reinvent the wheel.
I’m sure this have been done millions of times before me, are there any examples out there for TCP + ofVideoGrabber or IPcamera + ofVideoGrabber ??
perhaps it can be convenient to use gstreamer for raspberrypi
Example Server with module picam:
raspivid -t 999999 -w 800 -h 600 -fps 25 -hf -b 2000000 -o - | gst-launch-1.0 -v fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! tcpserversink host=192.168.0.100 port=5000
and use ofGstVideoUtils for client
Example Client with openframeworks:
#include "ofMain.h"
class RTSP : public ofBaseApp
{
public:
ofGstVideoUtils gst;
ofTexture tex;
ofPixels pix;
int w,h,x,y;
void setup() {
w=800,h=600;
x=0,y=0;
gst.setPipeline("tcpclientsrc host=192.168.0.100 port=5000 ! gdpdepay ! rtph264depay ! avdec_h264 ! videoconvert",OF_PIXELS_RGB,true,w,h);
gst.startPipeline();
tex.allocate(w,h,GL_RGB);
pix.allocate(w,h,OF_PIXELS_RGB);
gst.play();
}
void update() {
gst.update();
if(gst.isFrameNew()) {
pix.setFromExternalPixels( gst.getPixels() ,w,h,GL_RGB);
tex.loadData(pix);
}
}
void draw() {
tex.draw(x,y,w,h);
}
};
int main( ){
ofSetupOpenGL(1024,768, OF_WINDOW);
ofRunApp( new RTSP());
}
Thanks @kashim for the great example!! I’m beginng to see the light in the tunnel
When I run this example I get
[notice ] ofGstUtils: setPipelineWithSink(): gstreamer pipeline: tcpclientsrc host=192.168.1.122 port=5000 ! gdpdepay ! rtph264depay ! avdec_h264 ! videoconvert ! appsink name=ofappsink caps="video/x-raw, format=RGB, width=800, height=600"
[warning] ofGstVideoUtils: update(): ofGstVideoUtils not loaded
[ error ] ofGLUtils: ofGetGlFormatAndType(): internal format not recognized, returning GL_RGBA
It seem to be related to this line
pix.setFromExternalPixels(gst.getPixels(),w,h, GL_RGB);
If I substitue GL_RGB for OF_PIXELS_RGB (I know it’s wrong ) the example runs with some freaky pixel action going on. What else can I try to debug this ?
I’m on Linux 64bit, OF 0.9.3
Server is giving me quite a lot of weird output but it seem to be OK
raspivid -t 0 -w 800 -h 600 -fps 25 -hf -b 2000000 -o - | gst-launch-1.0 -v fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! tcpserversink host=192.168.1.122 port=5000
Setting pipeline to PAUSED ...
/GstPipeline:pipeline0/GstTCPServerSink:tcpserversink0: current-port = 5000
Pipeline is PREROLLING ...
/GstPipeline:pipeline0/GstH264Parse:h264parse0.GstPad:src: caps = "video/x-h264\,\ width\=\(int\)800\,\ height\=\(int\)600\,\ framerate\=\(fraction\)0/1\,\ parsed\=\(boolean\)true\,\ stream-format\=\(string\)avc\,\ alignment\=\(string\)au\,\ level\=\(string\)4\,\ profile\=\(string\)high\,\ codec_data\=\(buffer\)01640028ffe1000f27640028ac2b406409bf2c03c489a801000528ee025cb0"
/GstPipeline:pipeline0/GstRtpH264Pay:rtph264pay0.GstPad:src: caps = "application/x-rtp\,\ media\=\(string\)video\,\ clock-rate\=\(int\)90000\,\ encoding-name\=\(string\)H264\,\ sprop-parameter-sets\=\(string\)\"J2QAKKwrQGQJvywDxImo\\\,KO4CXLA\\\=\"\,\ payload\=\(int\)96\,\ ssrc\=\(uint\)4214831023\,\ timestamp-offset\=\(uint\)2862397318\,\ seqnum-offset\=\(uint\)6718"
/GstPipeline:pipeline0/GstGDPPay:gdppay0.GstPad:sink: caps = "application/x-rtp\,\ media\=\(string\)video\,\ clock-rate\=\(int\)90000\,\ encoding-name\=\(string\)H264\,\ sprop-parameter-sets\=\(string\)\"J2QAKKwrQGQJvywDxImo\\\,KO4CXLA\\\=\"\,\ payload\=\(int\)96\,\ ssrc\=\(uint\)4214831023\,\ timestamp-offset\=\(uint\)2862397318\,\ seqnum-offset\=\(uint\)6718"
/GstPipeline:pipeline0/GstRtpH264Pay:rtph264pay0.GstPad:sink: caps = "video/x-h264\,\ width\=\(int\)800\,\ height\=\(int\)600\,\ framerate\=\(fraction\)0/1\,\ parsed\=\(boolean\)true\,\ stream-format\=\(string\)avc\,\ alignment\=\(string\)au\,\ level\=\(string\)4\,\ profile\=\(string\)high\,\ codec_data\=\(buffer\)01640028ffe1000f27640028ac2b406409bf2c03c489a801000528ee025cb0"
/GstPipeline:pipeline0/GstRtpH264Pay:rtph264pay0: timestamp = 2862397318
/GstPipeline:pipeline0/GstRtpH264Pay:rtph264pay0: seqnum = 6718
/GstPipeline:pipeline0/GstGDPPay:gdppay0.GstPad:src: caps = "application/x-gdp\,\ streamheader\=\(buffer\)\<\ 01000100284e000000a7ffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000304900004773744576656e7453747265616d53746172742c2073747265616d2d69643d28737472696e6729636532613539613633343335353435643231366438646433626636363464393062383230643265313432623939393161343330326163333866383339373133662c20666c6167733d2847737453747265616d466c616773294753545f53545245414d5f464c41475f4e4f4e452c2067726f75702d69643d2875696e7429303b00\,\ 010001000002000000ff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000055d000006170706c69636174696f6e2f782d7274702c206d656469613d28737472696e6729766964656f2c20636c6f636b2d726174653d28696e742939303030302c20656e636f64696e672d6e616d653d28737472696e6729483236342c207370726f702d706172616d657465722d736574733d28737472696e6729224a3251414b4b77725147514a7679774478496d6f5c2c4b4f3443584c415c3d222c207061796c6f61643d28696e742939362c20737372633d2875696e7429343231343833313032332c2074696d657374616d702d6f66667365743d2875696e7429323836323339373331382c207365716e756d2d6f66667365743d2875696e74293637313800\,\ 01000100464e00000155ffffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000005d6700004773744576656e745365676d656e742c207365676d656e743d284773745365676d656e7429224773745365676d656e742c20666c6167733d284773745365676d656e74466c616773294753545f5345474d454e545f464c41475f4e4f4e452c20726174653d28646f75626c6529312c206170706c6965642d726174653d28646f75626c6529312c20666f726d61743d28477374466f726d6174294753545f464f524d41545f54494d452c20626173653d286775696e74363429302c206f66667365743d286775696e74363429302c2073746172743d286775696e74363429302c2073746f703d286775696e7436342931383434363734343037333730393535313631352c2074696d653d286775696e74363429302c20706f736974696f6e3d286775696e74363429302c206475726174696f6e3d286775696e7436342931383434363734343037333730393535313631353b223b00\,\ 01000100505e00000051ffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000ca6300004773745461674c6973742d73747265616d2c207461676c6973743d287461676c69737429227461676c6973745c2c5c20766964656f2d636f6465635c3d5c28737472696e675c29482e3236345c3b223b00\ \>"
/GstPipeline:pipeline0/GstTCPServerSink:tcpserversink0.GstPad:sink: caps = "application/x-gdp\,\ streamheader\=\(buffer\)\<\ 01000100284e000000a7ffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000304900004773744576656e7453747265616d53746172742c2073747265616d2d69643d28737472696e6729636532613539613633343335353435643231366438646433626636363464393062383230643265313432623939393161343330326163333866383339373133662c20666c6167733d2847737453747265616d466c616773294753545f53545245414d5f464c41475f4e4f4e452c2067726f75702d69643d2875696e7429303b00\,\ 010001000002000000ff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000055d000006170706c69636174696f6e2f782d7274702c206d656469613d28737472696e6729766964656f2c20636c6f636b2d726174653d28696e742939303030302c20656e636f64696e672d6e616d653d28737472696e6729483236342c207370726f702d706172616d657465722d736574733d28737472696e6729224a3251414b4b77725147514a7679774478496d6f5c2c4b4f3443584c415c3d222c207061796c6f61643d28696e742939362c20737372633d2875696e7429343231343833313032332c2074696d657374616d702d6f66667365743d2875696e7429323836323339373331382c207365716e756d2d6f66667365743d2875696e74293637313800\,\ 01000100464e00000155ffffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000005d6700004773744576656e745365676d656e742c207365676d656e743d284773745365676d656e7429224773745365676d656e742c20666c6167733d284773745365676d656e74466c616773294753545f5345474d454e545f464c41475f4e4f4e452c20726174653d28646f75626c6529312c206170706c6965642d726174653d28646f75626c6529312c20666f726d61743d28477374466f726d6174294753545f464f524d41545f54494d452c20626173653d286775696e74363429302c206f66667365743d286775696e74363429302c2073746172743d286775696e74363429302c2073746f703d286775696e7436342931383434363734343037333730393535313631352c2074696d653d286775696e74363429302c20706f736974696f6e3d286775696e74363429302c206475726174696f6e3d286775696e7436342931383434363734343037333730393535313631353b223b00\,\ 01000100505e00000051ffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000ca6300004773745461674c6973742d73747265616d2c207461676c6973743d287461676c69737429227461676c6973745c2c5c20766964656f2d636f6465635c3d5c28737472696e675c29482e3236345c3b223b00\ \>"
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
sorry I made a cut and paste of unnecessary code.
for debug client side use gst-launch, this:
gst-launch-1.0 -v tcpclientsrc host=192.168.1.122 port=5000 ! gdpdepay ! rtph264depay ! avdec_h264 ! videoconvert ! autovideosink sync=false
Use code without “ofPixels pix;” this not necessary, populated texture with getPixels method of ofGstVideoUtils:
#define PORT_GST 5000
class RTSP : public ofBaseApp
{
public:
ofGstVideoUtils gst;
ofTexture tex;
int w,h,x,y;
string ip;
void setup() {
w=800,h=600;
x=0,y=0;
ip="192.168.1.122";
gst.setPipeline("tcpclientsrc host="+ip+" port="+ofToString(PORT_GST)+" ! gdpdepay ! rtph264depay ! avdec_h264 ! videoconvert", OF_PIXELS_RGB, true, w, h);
gst.startPipeline();
tex.allocate(w,h,GL_RGB);
gst.play();
}
void update() {
gst.update();
if(gst.isFrameNew()) {
tex.loadData(gst.getPixels());
}
}
void draw() {
tex.draw(x,y,w,h);
}
};
int main( ){
ofSetupOpenGL(1024,768, OF_WINDOW);
ofRunApp( new RTSP());
}
Thank for your help @kashim!! It didn’t work with of93 ( gstreamer was crashing ) but as I’ve upgraded to of94 it works just fine. Super useful.