Dynamically adjusting crop to input resolution

Information:
• Hardware Platform (Jetson / GPU) Jetson Nano
• DeepStream Version 6.01
• Issue Type( questions, new requirements, bugs) question

Hi, I have the following DeepStream pipeline I’m running on Jetson Nano:
uridecodebin → nvvideoconvert (crop) → nvstreammux → nvinfer → nvtracker → nvdsanalytics → etc…

My issue is, the resolution from input source can change on the go. While all other elements seem to adjust to resolution change just fine (nvstreammux converts everything to fixed model resolution anyways), nvvideoconvert (crop) element receives absolute crop coordinates from a file and produces the wrong crop as the result. I want to dynamically change this pipeline element to adjust to source resolution.

My questions are:

  1. How does one detect resolution change? Is there any event or signal emitted when that happens? Or should I use some factory element, like GstDiscoverer, or write my own custom element?

  2. What would be the best way to adjust nvvideoconvert (crop) element on the fly? Should I g_signal_connect callback to a signal or listen to event?

  3. Would it be sufficient to g_object_set “src-crop” property and should I flush the element after that? Or should I unlink this element from the pipeline entirely and link in a new one?

It would be of great help if you have any links or examples of similar issues.

Thanks in advance.

1.You can add probe function to the plugin to check the video resolution.
2. Nvvideoconvert does not support dynamic config setting.

1 Like

Thanks for your response. I’ve tested this out and decided to update, in case anyone else faces the same issue.

I followed official Gstreamer docs to make a probe and ended up with the following code:

// Registering probe
GstPad *source_srcpad = gst_element_get_static_pad (source_bin, "src");
gst_pad_add_probe(  source_srcpad, 
                        GST_PAD_PROBE_TYPE_BUFFER, 
                        (GstPadProbeCallback)test_probe, 
                        (gpointer)nvvidconv_crop, 
                        NULL);
// Probe callback
GstPadProbeReturn CounterPipeline::test_probe(GstPad *pad, GstPadProbeInfo *info, gpointer user_data)
{
    /**
     * Callback for source pad buffer probe.
    */
    GstCaps *current_caps = gst_pad_get_current_caps(pad);
    GstStructure *caps_structure = gst_caps_get_structure(current_caps, 0);
    gint height, width;
    GstElement *nvvidconv_crop = (GstElement *)user_data;

    if (gst_structure_get_int(caps_structure, "width", &width) && gst_structure_get_int(caps_structure, "height", &height))
    {
        if (width != 1920 || height != 1080) 
        {
            g_print("Resolution changed from %dx%d to %dx%d\n", 1920, 1080, width, height);
            std::string scr_crop = "100:100:200:200";
            g_object_set(G_OBJECT(nvvidconv_crop), "src-crop", scr_crop.c_str(), NULL);
        }
    }

Probing resolution worked as expected. Surprisingly, dynamically setting nvvideoconvert’s property worked as well!

Hope it helps someone in the future.

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

Glad to hear that and thanks for your confirmation.