Difficulty Linking splitmuxsink Element in C++ Code

Dear Team,

I’ve been working on a task that involves splitting an MP4 file containing both audio and video into segments of 10 seconds each. Initially, I was successful in achieving this through a raw pipeline. However, I’m currently facing challenges while attempting to replicate this behavior in C++ code.

The specific hurdle I encountered involves linking the splitmuxsink element to handle both the audio and video elements within the code. Below, I’ve provided the pipeline command and a snippet of the code I’ve been working on:

Pipeline:

gst-launch-1.0 -ev v4l2src ! video/x-raw ! videoconvert ! queue ! x264enc tune=zerolatency ! queue ! splitmuxsink max-size-time=10000000000 muxer=avimux name=mux location=video%04d.avi autoaudiosrc ! voaacenc ! queue ! mux.audio_0

Code Snippet:


// Compile commend = g++ -o splitmuxsink splitmuxsink.cpp `pkg-config --cflags --libs gstreamer-1.0`

#include <gst/gst.h>

int main(int argc, char *argv[]) {
   
    GstElement *pipeline, *v4l2src, *video_convert, *x264enc, *muxer, *splitmuxsink, *autoaudiosrc, *queue ,*voaacenc;
    GstPad *video_pad, *audio_pad;

    // Initialize GStreamer
    gst_init(&argc, &argv);

    // Create elements
    pipeline = gst_pipeline_new("pipeline");
    v4l2src = gst_element_factory_make("v4l2src", "v4l2src");
    video_convert = gst_element_factory_make("videoconvert", "video_convert");
    x264enc = gst_element_factory_make("x264enc", "x264enc");
    muxer = gst_element_factory_make("avimux", "mux");
    splitmuxsink = gst_element_factory_make("splitmuxsink", "splitmuxsink");
    autoaudiosrc = gst_element_factory_make("autoaudiosrc", "autoaudiosrc");
    voaacenc = gst_element_factory_make("voaacenc", "voaacenc");
    queue = gst_element_factory_make("queue", "enc-queue");


    if (!pipeline || !v4l2src || !video_convert || !x264enc || !muxer || !splitmuxsink || !autoaudiosrc || !voaacenc) {
        g_printerr("One or more elements could not be created. Exiting.\n");
        return -1;
    }

    // Set properties
    g_object_set(splitmuxsink, "max-size-time", G_GUINT64_CONSTANT(10000000000),
                              "muxer", muxer,
                              "name", "mux",
                              "location", "video%04d.avi", NULL);

    // Build the pipeline
    gst_bin_add_many(GST_BIN(pipeline), v4l2src, video_convert, x264enc, splitmuxsink, NULL);

    // Link video elements
    if (!gst_element_link_many(v4l2src, video_convert, x264enc,splitmuxsink, NULL)) {
        g_printerr("Video elements could not be linked.\n");
        gst_object_unref(pipeline);
        return -1;
    }


    gst_bin_add_many(GST_BIN(pipeline),autoaudiosrc,voaacenc,queue, NULL);

    // Link audio elements
    if (!gst_element_link_many(autoaudiosrc,voaacenc,queue,splitmuxsink, NULL)) {
        g_printerr("Audio elements could not be linked.\n");
        gst_object_unref(pipeline);
        return -1;
    }

    // Get pads and link them
    // video_pad = gst_element_get_request_pad(x264enc, "src");
    // audio_pad = gst_element_get_request_pad(voaacenc, "src");
    // gst_pad_link(video_pad, gst_element_get_request_pad(splitmuxsink, "video_%u"));
    // gst_pad_link(audio_pad, gst_element_get_request_pad(splitmuxsink, "audio_%u"));

    // Set the pipeline state to playing
    GstStateChangeReturn ret = gst_element_set_state(pipeline, GST_STATE_PLAYING);
    if (ret == GST_STATE_CHANGE_FAILURE) {
        g_printerr("Unable to set the pipeline to the playing state.\n");
        gst_object_unref(pipeline);
        return -1;
    }

    // Wait until error or EOS
    GstBus *bus = gst_element_get_bus(pipeline);
    GstMessage *msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, (GstMessageType)(GST_MESSAGE_ERROR | GST_MESSAGE_EOS));

    // Free resources
    if (msg != NULL)
        gst_message_unref(msg);
    gst_object_unref(bus);
    gst_element_set_state(pipeline, GST_STATE_NULL);
    gst_object_unref(pipeline);

    return 0;
}

Issue = Audio elements could not be linked.

I kindly request your assistance in resolving this issue. It seems that linking the splitmuxsink element in the C++ code to handle both audio and video is proving to be challenging. Your guidance or any fixes you can provide would be immensely helpful.

Thank you for your attention to this matter.

Best regards,

Sulthan

any update regarding my query?

Hi @Sulthan4,

I believe the error you are getting comes from trying to link an element that has already been linked. That is gst_element_link_many is called twice for the splitmuxsink.

Take a look at gst_element_link_pads, you can use it to link the src pad of your queue to the audio sink pad of the splitmuxsink like so:

gst_element_link_pads(queue, "src", splitmuxsink, "audio_0"); 

By doing that and removing the splitmuxsink from the second call of the gst_element_link_many I believe you should get your expected behaviour.

Regards,

Marco Herrera Valverde
Embedded Software Team Lead
www.ridgerun.com

1 Like

Hi @m-herrera ,

Thanks for your help, its worked now.

Regards.
Sulthan