When the h264 bytesStream change the resolution, my pipeline stop working

Hello, everyone. I am facing a problem: when the h264 bytes stream changes the resolution, my pipeline stop working. How can I solve this problem?

// Init Gstreamer basic
    gst_init(nullptr,nullptr);

    // init pipeline element
    pipeline = gst_pipeline_new("pipeline");
    appsrc = gst_element_factory_make("appsrc", "appsrc");
    h264parse = gst_element_factory_make("h264parse", "h264parse");
    decoder = gst_element_factory_make("nvv4l2decoder", "decoder");
    nvvidconv = gst_element_factory_make("nvvidconv", "nvvidconv");
    videoconvert = gst_element_factory_make("videoconvert", "videoconvert");
    appsink = gst_element_factory_make("appsink", "appsink");

    if (!pipeline || !appsrc || !h264parse || !decoder || !nvvidconv || !videoconvert || !appsink) {
        ERROR("Create element fail in Gstreamer!\n");
        return -2;
    }
    // add all element to the pipeline
    gst_bin_add_many(GST_BIN(pipeline), appsrc, h264parse, decoder, nvvidconv, videoconvert, appsink, NULL);
    gst_element_link_many(h264parse, decoder, nvvidconv, NULL);

    // Add Caps in appsrc
    GstCaps *appsrc_caps = gst_caps_new_simple(
                            "video/x-h264",
                            "width", G_TYPE_INT, 1920,
                            "height", G_TYPE_INT, 1080,
                            "framerate", GST_TYPE_FRACTION, 30, 1,
                            "stream-format", G_TYPE_STRING, "byte-stream",
                            NULL);

    //g_object_set(G_OBJECT(appsrc), "caps", appsrc_caps, NULL);
    if (!gst_element_link_filtered(appsrc, h264parse, appsrc_caps)) {
        ERROR("Failed to link appsrc to h264parse with filter.");
        gst_caps_unref(appsrc_caps);
        return -3;
    }
    gst_caps_unref(appsrc_caps);

    // change features in h264parse
    g_object_set(G_OBJECT(h264parse), "config-interval", 1, NULL);

    // add caps between nvvidconv and videoconvert
    GstCaps *nvvidconv_caps = gst_caps_new_simple("video/x-raw",
                                                  "format", G_TYPE_STRING, "BGRx",
                                                  NULL);
    
    if (!gst_element_link_filtered(nvvidconv, videoconvert, nvvidconv_caps)) {
        ERROR("Failed to link nvvidconv to videoconvert with filter.");
        gst_caps_unref(nvvidconv_caps);
        return -3;
    }
    gst_caps_unref(nvvidconv_caps);

    // add caps between videoconvert and appsink
    GstCaps *appsink_caps = gst_caps_new_simple("video/x-raw",
                                                "format", G_TYPE_STRING, "BGR",
                                                NULL);
    if (!gst_element_link_filtered(videoconvert, appsink, appsink_caps)) {
        ERROR("Failed to link videoconvert to appsink with filter.");
        gst_caps_unref(appsink_caps);
        return -4;
    }
    gst_caps_unref(appsink_caps);

    // set appsink festures
    g_object_set(appsink, "emit-signals", TRUE, "sync", FALSE, NULL);
    //g_signal_connect(appsink, "new-sample", G_CALLBACK(on_new_image_static), NULL);
    g_signal_connect(appsink, "new-sample", G_CALLBACK(on_new_image_static), this);
    GstStateChangeReturn ret = gst_element_set_state(pipeline, GST_STATE_PLAYING);
    if (ret == GST_STATE_CHANGE_FAILURE) {
        ERROR("Failed to set pipeline to PLAYING state.");
        return -1; 
    }

Hi,
When the resolution changes, please terminate the current pipeline and re-initialize it. It may not work properly if the resolution changes in runtime.

I cannot control the bytes stream, it will change automatically according to the current bandwidth. So, when everytime it changes, I can only restart the pipeline to fix this problem?

Hi,
When resolution changes, the buffer has to be destroyed and re-allocated. This may not be well considered in the plugins. So we would suggest fix the resolution.

If you would like to give it a try, you may set output of nvvidconv to fixed size and see if it works:

... ! nvvidconv ! video/x-raw,width=1920,height=1080,format=BGRx ! videoconvert ! ...

After I fix the caps( the width and height) between nvvidconv and videoconvert, I can see the video when the source first changes to 960x720. But after it changes to 1920x1080, the video stops again.

Hi,
The default implementation doesn’t handle the use-case. The nvvidconv and nvv4l2decoder are open source, and you may check the code and customize the plugins to handle it.

You can download the source code from release page:

Jetson Linux 36.3 | NVIDIA Developer

ok Thanks…

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.