camera capture pipeline questions (jetson nano)

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)

  1. block the camera src pad
  2. in block callback post EOS, pause the cam and remove the blocking pad.
  3. Exit the main loop by catching EOS in the bus
  4. pause the pipeline
  5. 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.

Hi,
Pleas check this sample and see if it helps your usecase. If you still hit issues, please share a test sample so that we can reproduce it.

For more information, do you use r32.2.1? What is your camera( brand, model ID )?

Yes, I have l4t 32.2.1.

I just built a pipeline that reads from file and writes to file, and it also stalls when I run it for the second time, so it’s not the camera. I’ll have to check with the debugger, because I have no idea how to deduce the solution just from the docs.

And about the camera not being able to capture:
The sample you provided doesn’t really help. It’s just a capture program that works.
I have no trouble with capturing. The problem is when I stop the capture program without waiting for EOS, or destroying the allocating objects - then the cam gets stuck.

I’ll make a sample later this week, but it’s just a simple webcam capture pipeline that I interrupt with ctrl+c

edit:
camera is IMX219-160 https://www.waveshare.com/wiki/IMX219-160_Camera

I tried a simple test case with cam->fakesink and it does not seem to freeze,
I’ll have to try with a more elaborate piplene. It’s not that important, I’m more worried about my second issue, but I’ll try to make a repro case later this week.