Hello!
I’m setting up a camera pipeline (in a c application) and I have a couple questions.
first,
I often do something wrong (eg. exit the app without properly deallocating the objects) and the camera (nvarguscamerasrc) seems to get stuck, and I get “could not capture” in the logs, even if I use gst-launch-1.0, and only rebooting the Jetson helps.
Is there a way to properly reset the cam? Maybe there’s a process I should kill?
Second,
this is probably more of a gstreamer question, maybe this has something to do with how I work with the camera.
I’m running a server that starts and stops the streaming from the camera. And each of the streaming sessions is supposed to be saved in a separate file.
The problem is, whenever I re-create the filesink, nothing gets written into the new file. (The first stream after initial launch of the pipeline works fine)
Here’s the steps I’m doing to stop and reset the running stream
(from here https://gstreamer.freedesktop.org/documentation/application-development/advanced/pipeline-manipulation.html?gi-language=c#dynamically-changing-the-pipeline)
- block the camera src pad
- in block callback post EOS, pause the cam and remove the blocking pad.
- Exit the main loop by catching EOS in the bus
- pause the pipeline
- unlink, remove and NULL the existing filesink like this:
gst_element_unlink(Pipe.Mp4Mux, Pipe.FileSink);
gst_bin_remove(GST_BIN(Pipe.Pipeline), Pipe.FileSink);
assert(gst_element_set_state(Pipe.FileSink, GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS);
and next time I launch the stream I create a new filesink and add it to the pipe the same way it’s added during initial launch, and set piplene state to PLAYING (Except before that I’m also trying to set the state of new filesink to PAUSED, as gstreamer requires new element to be in the same state as the pipeline, which is in PAUSED state by now)
static int Session = 0;
char Buffer[64];
sprintf(Buffer, "out/session_%d.mp4", Session);
Pipe.FileSink = CreateElement("filesink", "sink");
gst_bin_add(GST_BIN(Pipe.Pipeline), Pipe.FileSink);
g_object_set(G_OBJECT(Pipe.FileSink), "location", Buffer, NULL);
GstState PipeState = GetElementStateBlocking(Pipe.Pipeline);
if (PipeState != GST_STATE_NULL) {
printf("Pipeline state:\n");
PrintElementState(Pipe.Pipeline);
printf("Setting file sink state:\n");
gst_element_set_state(Pipe.FileSink, PipeState);
}
assert(gst_element_link(Pipe.Mp4Mux, Pipe.FileSink));
gst_element_set_state(Pipe.Pipeline, GST_STATE_PLAYING);
g_main_loop_run(Pipe.MainLoop);
But this thing does not run at all. I think the pipeline is running, because I see massive amount of NvDsMeta events in the log. But the new file size is 0.
What I was able to find out so far that the new filesink never reaches “PAUSED” state.
It goes from NULL->READY, then READY->PAUSED returns ASYNC and nothing else happens.
If I do a blocking wait on the state change call, everything just stops.
So the filesink just remains in eternal READY->PAUSED transition. Also the pipe cant switch to playing state because of the unfinished async operation.
Also in the logs I’m getting that filesink was linked successfully to the output Muxer and the caps are ok.
If I leave the new filesink in NULL state, it automatically gets to READY as well, but gets stuck on READY->PLAYING transition.
Tomorrow I’ll try to fire up the remote debugger and see why this async state happens. Maybe I’ll check a more simple pipeline on my dev machine and see if same thing happens.
I’d appreciate any help with this, I’m out of ideas on how to fix that without diving into the source.