Multiple ofxGstreamer instances from within a vector

#1

Hey all,

I’m working on a large CV system that incorporates over a dozen IP cameras. I’m using ofxGstreamer or more specifically, an instance of ofGstVideoUtils to set the pipeline and load/play the stream. Since I’ve got so many cameras in different rooms I’ve got a “Corridor” wrapper class that handles the stream, the CV, a gui with xml settings, etc.

Corridor.h

class Corridor{

public:
ofGstVideoUtils gst;

(lots of other irrelevant stuff)

};

.cpp,

setup(string IP){    
    
    gst.setPipeline("rtspsrc location=rtsp://admin:admin@" + IP + ":554/cam/realmonitor?channel=1&subtype=1 latency=0 ! queue2 max-size-buffers=2 ! decodebin ! videoconvert", OF_PIXELS_MONO, true, feedWidth, feedHeight);
    gst.startPipeline();
    gst.play();

}

This works really well as long as I’ve got separate, individually declared instances my Corridor class. However, I get a strange error when I try to have multiple instances of my Corridor class inside a vector:

vector<Corridor> corridors;

int numRooms = 2;

for(int i = 0; i < numRooms; i++){
    Corridor c;
    corridors.push_back(c);
}

The error that pops up is:
Call to implicitly-deleted copy constructor of 'Corridor'
that stems from the push_back line.

Any suggestions on how to better initialize my class/ofGstVideoUtils instance so I can use a vector to store all my rooms? Not sure if this is an @arturo/Gstreamer question or just a basic C++ question.

Thanks!

#2

This is because ofxGstVideoUtils contains a mutex or a thread (probably both) and those classes delete their copy constructors. That makes those classes uncopyable and anything that includes them as well. When you push_back something onto a vector you are making a copy of the original but since this classes are notcopyable, the have the copy constructor deleted, the compiler won’t let you.

Since c++11 you can use emplace_back instead of push_back which should avoid any copy but depending on the class it might have it’s move constructor also removed, which i think is the case with ofxGstVideoUtils. In that case the only thing that will work is to use pointers instead fo directly objects in the vector.

Using shared_ptr will make things easier since they’ll auto delete themselves avoiding leaks if you forget to delete before removing from the vector:

vector<shared_ptr<Corridor>> corridors;
int numRooms = 2;

for(int i = 0; i < numRooms; i++){
    auto c = std::make_shared<Corridor>();
    corridors.push_back(c);
}

or even:

vector<shared_ptr<Corridor>> corridors;
int numRooms = 2;

for(int i = 0; i < numRooms; i++){
    corridors.emplace_back(new Corridor);
}
#3

Awesome, that fixed the issue. I figured it was something like that but wasn’t sure of how to get around it. Thanks!

Another quick question: when working with my IP cameras, it seems that sometimes the gstreamer connection will go a little stale. I’ll have to restart my computer or power cycle my router or the camera (sometimes all 3) in order to be able to pull a feed from the camera again. The error is something like:

embedded video playback halted for plugin, module vtdechw0 reported: GStreamer encountered a general resource error

I’m wondering if maybe there’s a way to refresh/reset the gstreamer pipeline in order to get things back to square one again? Any thoughts.

Thanks again, like most people I’ve used many of your addons!

#4

Still encountering this error and hoping to find some new eyes that might know a fix.

Trying to connect to an IP camera’s rtsp feed using gstreamer and getting this error:

[verbose] ofGstUtils: gstreamer inited
[notice ] ofGstUtils: setPipelineWithSink(): gstreamer pipeline: rtspsrc location=rtsp://admin:admin@192.168.187.37:554/cam/realmonitor?channel=1&subtype=1 latency=0 ! queue2 max-size-buffers=2 ! decodebin ! videoconvert ! appsink name=ofappsink enable-last-sample=0 caps="video/x-raw, format=GRAY8, width=640, height=512"
[verbose] ofGstUtils: startPipeline(): attaching callbacks
[verbose] ofGstUtils: gstHandleMessage(): unhandled message from src
[verbose[]v eorfbGossteU] Pipeline is live and tdioless:  ngostt Hnaeneddl ePMReEsRsOaLgLe (wait)i:ng PLAY 
unhandled message from rtspsrc0
[verbose] ofGstUtils: gstHandleMessage(): unhandled message from src
[verbose] ofGstUtils: gstHandleMessage(): unhandled message from rtspsrc0
[verbose] ofGstUtils: gstHandleMessage(): unhandled message from pipeline0
[verbose] ofGstUtils: gstHandleMessage(): unhandled message from rtspsrc0
[verbose] ofGstUtils: gstHandleMessage(): unhandled message from rtspsrc0
[verbose] ofGstUtils: gstHandleMessage(): unhandled message from rtspsrc0
[verbose] ofGstUtils: gstHandleMessage(): unhandled message from rtspsrc0
[verbose] ofGstUtils: gstHandleMessage(): unhandled message from rtspsrc0
[verbose] ofGstUtils: gstHandleMessage(): unhandled message from src
[verbose] ofGstUtils: gstHandleMessage(): unhandled message from rtspsrc0
[verbose] ofGstUtils: gstHandleMessage(): unhandled message from src
[verbose] ofGstUtils: gstHandleMessage(): unhandled message from src
[verbose] ofGstUtils: gstHandleMessage(): unhandled message from src
[verbose] ofGstUtils: gstHandleMessage(): unhandled message from src
[verbose] ofGstUtils: gstHandleMessage(): unhandled message from rtspsrc0
[verbose] ofGstUtils: gstHandleMessage(): unhandled message from src
[verbose] ofGstUtils: gstHandleMessage(): unhandled message from src
[verbose] ofGstUtils: gstHandleMessage(): unhandled message from src
[ error ] ofGstUtils: gstHandleMessage(): embedded video playback halted for plugin, module vtdechw0  reported: GStreamer encountered a general resource error.
[ error ] ofGstUtils: gstHandleMessage(): embedded video playback halted for plugin, module vtdechw0  reported: GStreamer encountered a general resource error.

Once I get this error, restarting my computer and power cycling my cameras and router will fix it. But that’s no longer an option so it’d be nice to know why this is happening.

Edit: Using OF 9.1

#5

Ah not to bring this back from the dead, but did you find a solution? I am running into the same verbose messages, no error but nothing displays.
[UPDATE]
the unhandled messages were harmless, I just mixed up checking to see if the frame was new and updating gstreamer. For anyone who wants an example of an IP camera stream using h.264:

#include "ofApp.h"
#include "ofGstVideoPlayer.h"
size_t feedWidth = 360;
size_t feedHeight = 288;
ofGstVideoUtils gstv;
// These three above can be moved into App.h

//--------------------------------------------------------------
void ofApp::setup(){
    ofSetVerticalSync(true);
    ofSetLogLevel(OF_LOG_VERBOSE); // this is just so you can see messages from GStreamer
    gstv.allocate(feedWidth,feedHeight, OF_PIXELS_RGB);
    gstv.setPipeline("rtspsrc location=rtsp://admin:@192.168.8.192:554/live0.264 latency=0 ! decodebin ! videoconvert ! videoscale", OF_PIXELS_RGB, true, feedWidth, feedHeight);
    gstv.startPipeline();
    gstv.play();

    img.allocate(feedWidth,feedHeight
                 , OF_IMAGE_COLOR);
    
}

//--------------------------------------------------------------
void ofApp::update(){
    gstv.update();
    if(gstv.isFrameNew()){
        img.setFromPixels(gstv.getPixels());
    }
}

//--------------------------------------------------------------
void ofApp::draw(){
	img.draw(0,0);
}

1 Like