Skip to content

Unable to restart camera with aravissrc gstreamer #907

@sean-kiwi

Description

@sean-kiwi

Describe the bug
I need the ability to remove and recreate the arravissrc element of the gstreamer pipeline, so that if my camera has any issues I can restart it without having to restart my entire pipeline.

To Reproduce

  • Create aravissrc element
  • Attempt to destroy and create new aravissrc element
  • Attempt to start new element

Expected behavior
Camera able to restart without crashing gstreamer pipeline

Camera description:
Lucid Pheonix
GigE

Platform description:

  • Aravis version 0.8
  • OS: Linux (NVIDIA Jetpack)
  • Hardware aarch64

Additional context
My main query is about safely destroying the camera object, and if/how to use g_object_unref or gst_object_unref.

// Simple script which will start an aravis pipeline, then restart ONLY the camera
#include <chrono>
#include <condition_variable>
#include <cstdlib>
#include <iostream>
#include <mutex>
#include <string>
#include <thread>

#include <gst/gst.h>


int main(int argc, char *argv[])
{
    gst_init (&argc, &argv);

    GstElement *pipeline = gst_pipeline_new ("aravis_pipeline");
    GstElement *source = gst_element_factory_make ("aravissrc", "source");
    if (!source) {
        std::cerr << "Failed to create the source element." << std::endl;
        return false;
    }

    #define cfg_OffsetY ((1200-1184)/2)
    const char *cam1 = "10.42.0.154";

    g_object_set(G_OBJECT(source),
            "camera-name", cam1,
            "num-arv-buffers", 64,
            "packet-resend", false,
            "packet-size", 9000,
            "auto-packet-size", false,
            NULL);
    
    std::this_thread::sleep_for(std::chrono::seconds(5));


    GstElement *sink = gst_element_factory_make ("fakesink", "fake_sink");

    if (!pipeline || !source || !sink) {
        g_printerr ("Not all elements could be created.\n");
        return -1;
    }

    gst_bin_add_many (GST_BIN (pipeline), source, sink, NULL);

    if (!gst_element_link (source, sink)) {
        g_printerr ("Elements could not be linked.\n");
        gst_object_unref (pipeline);
        return -1;
    }

    GMainLoop *main_loop = g_main_loop_new(NULL, FALSE);
    // CustomData data = {pipeline, main_loop};
    std::cout << "Starting the pipeline." << std::endl;
    gst_element_set_state(pipeline, GST_STATE_PLAYING);

    std::this_thread::sleep_for(std::chrono::seconds(10));

    std::cout << "Restarting the camera source." << std::endl;
    // gst_element_set_state(pipeline, GST_STATE_PAUSED);
    // Restart the camera source

    // Stop camera
    gst_element_set_state(source, GST_STATE_NULL);

    // Wait for data to stop flowing
    std::this_thread::sleep_for(std::chrono::seconds(10));

    std::cout << "Camera source stopped." << std::endl;

    // Remove the source from the pipeline
    gst_element_unlink(source, sink);

    // Remove the source from the pipeline
    gst_bin_remove(GST_BIN(pipeline), source);
    
    // UNREF?
    g_object_unref(source);

    std::this_thread::sleep_for(std::chrono::seconds(10));

    std::cout << "Create a new source." << std::endl;

    // Create a new source
    GstElement *new_source = gst_element_factory_make ("aravissrc", "new_source");
    if (!new_source) {
        std::cerr << "Failed to create the source element." << std::endl;
        return false;
    }

    g_object_set(G_OBJECT(new_source),
        "camera-name", cam1,
        "num-arv-buffers", 64,
        "packet-resend", false,
        "packet-size", 9000,
        "auto-packet-size", false,
        NULL);
    
    std::this_thread::sleep_for(std::chrono::seconds(5));
    std::cout << "Add to pipeline." << std::endl;


    gst_bin_add(GST_BIN(pipeline), new_source);

    std::this_thread::sleep_for(std::chrono::seconds(5));
    std::cout << "Link to pipeline." << std::endl; 
    gst_element_link(new_source, sink);

    std::this_thread::sleep_for(std::chrono::seconds(5));
    std::cout << "sync to pipeline." << std::endl; 

    gst_element_sync_state_with_parent(new_source);

    std::this_thread::sleep_for(std::chrono::seconds(10));


    std::cout << "Starting the pipeline." << std::endl;

    gst_element_set_state(new_source, GST_STATE_PLAYING);


    g_main_loop_run (main_loop);

    /* Free resources */
    g_main_loop_unref (main_loop);
    // gst_object_unref (bus);
    gst_element_set_state (pipeline, GST_STATE_NULL);
    gst_object_unref (pipeline);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    1. bugProblems, incorrect behavior or appearance5. GstreamerIssue in GStreamer plugin

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions