IP camera / Raspberry Pi Camera

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());
}
1 Like

Thanks @kashim for the great example!! I’m beginng to see the light in the tunnel :wink:
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());
    }
2 Likes

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.

1 Like

Using this thread to get RPI4 to connect to OF 10.1 on a Mac via gstreamer. I got things working on the Pi side and the sketch compiles on the Mac side but I get no stream coming in. And got this error: