Pass same type nvds meta before nvv4l2decoder

• Hardware Platform (Jetson / GPU)
GPU/T4
• DeepStream Version
DeepStream-6.0
• NVIDIA GPU Driver Version (valid for GPU only)
NVIDIA-SMI 470.94 Driver Version: 470.94 CUDA Version: 11.4
• Issue Type( questions, new requirements, bugs)
bugs
• How to reproduce the issue ? (This is for bugs. Including which sample app is using, the configuration files content, the command line used and other details for reproducing)
when I put the same type of nvds meta multiple times before nvv4l2decoder and try to probe nvv4l2decoder src. I can only get meta mixed but regularly. For example, I first send an output with many custom meta, but the src probe won’t be triggered. the second will, only get mixed the first custom meta and the second.
here is my pipeline.dot


Before nvv4l2decoder, I used rtph264depay and manually set caps to nal instead of au.
here is my code

#include <gst/gst.h>
#include <string>

#define GST_CUSTOM_META (nvds_get_user_meta_type("GST_CUSTOM_META"))


class CustomMeta
{
public:
    CustomMeta(){}
    CustomMeta(const CustomMeta& meta)
    {
        this->nums = meta.nums;
    }

public:
    int nums;
};

static gpointer custom_copy_meta_func(gpointer data,gpointer user_data)
{
    CustomMeta* src_meta = (CustomMeta*)data;
    CustomMeta* dst_meta = new CustomMeta(*src_meta);

    return dst_meta;
}

static void custom_release_meta_func(gpointer data,gpointer user_data)
{
    CustomMeta* meta = (CustomMeta*)data;
    if(meta)
    {
        delete meta;
    }
}


static gpointer custom_gst_to_nvds_transform_func(gpointer data,gpointer user_data)
{
    NvDsUserMeta* user_meta = (NvDsUserMeta*)data;
    CustomMeta* meta = (CustomMeta*)user_meta->user_meta_data;
    CustomMeta* dst_meta = (CustomMeta*) custom_copy_meta_func(meta,NULL);

    return dst_meta;
}

static void custom_gst_to_nvds_release_func(gpointer data, gpointer user_data)
{
    NvDsUserMeta* user_meta = (NvDsUserMeta*)data;
    CustomMeta* timestamp_meta = (CustomMeta*)user_meta->user_meta_data;
    custom_release_meta_func(timestamp_meta,NULL);
}

int nums = 0;

static void pad_added_handler_F (GstElement *src, GstPad *new_pad, GstPad* sink_pad)
{
//    GstPad* sink_pad = gst_element_get_static_pad(u_data->queue,"sink");

    GstPadLinkReturn ret;

    const gchar *new_pad_type = NULL;

    g_print ("Received new pad '%s' from '%s':\n", GST_PAD_NAME (new_pad), GST_ELEMENT_NAME (src));

    /* If our converter is already linked, we have nothing to do here */
    if (gst_pad_is_linked (sink_pad)) {
        g_print ("We are already linked. Ignoring.\n");
        goto exit;
    }

    ret = gst_pad_link(new_pad,sink_pad);
    if (GST_PAD_LINK_FAILED (ret)) {
        g_print ("Type is '%s' but link failed.\n", new_pad_type);
    } else {
        g_print ("Link succeeded (type '%s').\n", new_pad_type);
    }

    exit:
    gst_object_unref (sink_pad);
    return;
}

static GstPadProbeReturn insert_custom_meta(GstPad*pad, GstPadProbeInfo* info, gpointer user_data)
{
    GstBuffer * buffer = GST_PAD_PROBE_INFO_BUFFER(info);

    buffer = gst_buffer_make_writable(buffer);

    CustomMeta* customMeta = new CustomMeta();

    NvDsMeta* meta = NULL;
    meta = gst_buffer_add_nvds_meta(buffer, custom_meta, NULL, custom_copy_meta_func,
                                    custom_release_meta_func);
    meta->meta_type = GST_CUSTOM_META;
    meta->gst_to_nvds_meta_transform_func = custom_gst_to_nvds_transform_func;
    meta->gst_to_nvds_meta_release_func = custom_gst_to_nvds_release_func;

    customMeta->nums = nums++;

    return GST_PAD_PROBE_OK;
}

static GstPadProbeReturn get_custom_meta(GstPad*pad, GstPadProbeInfo* info, gpointer user_data)
{
    GstBuffer * buffer = GST_PAD_PROBE_INFO_BUFFER(info);

    GstMeta* gst_meta = NULL;
    NvDsMeta * nvds_meta = NULL;
    gpointer state = NULL;

    while(gst_meta = gst_buffer_iterate_meta(buffer,&state))
    {
        nvds_meta = (NvDsMeta*)gst_meta;
        if(nvds_meta->meta_type = GST_CUSTOM_META)
        {
            CustomMeta* meta = (CustomMeta*)nvds_meta->meta_data;
            GST_INFO("timestamp from decoder %ld",meta->nums);
        }

    }

}

int main() {


    std::string uri = "rtsp://172.21.30.204:554/rtp/34020000001320001008/34020000001320001008/SIMPLE";

    GstElement * pipeline = gst_pipeline_new("test-pipeline");
    GstElement * source = gst_element_factory_make("urisourcebin","source");
    GstElement * sink = gst_element_factory_make("fakesink","sink");
    GstElement * depay = gst_element_factory_make("rtph264depay","depay-0");
    GstElement * capsfilter = gst_element_factory_make("capsfilter","filter-0");
    GstElement * nvstreammux = gst_element_factory_make("nvstreammux","mux");
    GstElement * parser = gst_element_factory_make("h264parse","parse");
    GstElement * decoder = gst_element_factory_make("nvv4l2decoder","decoder");

    gst_bin_add_many(GST_BIN(pipeline),source,sink,depay,capsfilter,parser,nvstreammux,decoder,NULL);

    gst_element_link_many(depay, capsfilter, parser, decoder,NULL);

    GstPad* depay_src_pad = gst_element_get_static_pad(depay,"src");
    GstPad* depay_sink_pad = gst_element_get_static_pad(depay,"sink");
    GstPad* decoder_src_pad = gst_element_get_static_pad(decoder,"src");
    GstPad* mux_sink_pad = gst_element_get_request_pad(nvstreammux,"sink_0");
    GstPad* mux_src_pad = gst_element_get_static_pad(nvstreammux,"src");
    gst_pad_link(decoder_src_pad,mux_sink_pad);
    gst_element_link(nvstreammux,sink);

    g_signal_connect(source,"pad-added",G_CALLBACK(pad_added_handler_F),depay_sink_pad);
    g_object_set(source,"uri",uri.c_str(),NULL);

    g_object_set(nvstreammux,"width",1920,"height",1080,"batch-size",1,NULL);

    GstCaps *caps = gst_caps_new_simple ("video/x-h264",
                                         "stream-format", G_TYPE_STRING, "byte-stream",
                                         "alignment", G_TYPE_STRING, "nal",
                                         NULL);
    g_object_set(capsfilter,"caps",caps,NULL);



    gst_pad_add_probe(depay_src_pad,GST_PAD_PROBE_TYPE_BUFFER,GstPadProbeCallback(insert_custom_meta),NULL,NULL);
    gst_pad_add_probe(decoder_src_pad,GST_PAD_PROBE_TYPE_BUFFER,GstPadProbeCallback(get_custom_meta),NULL,NULL);

    gst_object_unref(depay_src_pad);
    gst_object_unref(depay_sink_pad);
    gst_object_unref(decoder_src_pad);
    gst_object_unref(mux_sink_pad);
    gst_object_unref(mux_src_pad);


    gst_element_set_state(pipeline,GST_STATE_PLAYING);


    GMainLoop *mainLoop;
    mainLoop = g_main_loop_new(NULL,FALSE);
    g_main_loop_run(mainLoop);

    gst_element_set_state(pipeline,GST_STATE_NULL);

    gst_object_unref(pipeline);

    return 0;

}

• Requirement details( This is for new requirement. Including the module name-for which plugin or for which sample application, the function description)

Sorry for the late response, our team will do the investigation and provide suggestions soon. Thanks

Can you explain what does this mean?

the first buffer downstream to nvv4l2decoder won’t triggered the src probe on nvv4l2decoder.

The compressed data is not packed frame by frame in GstBuffer. What you see is correct. You may try to add “insert_custom_meta” to h264parse src pad if you are sure the h264 stream is one frame one slice.

Now I know that my GstBuffer passed a nalu one time because I add capsfilter with nalu between rtph265 and h264parse. Now I’d like to know if I save many buffers after nvv4l2decoder without push downstream and the saved buffer attach the maximum of num-extra-surface, nvv4l2decoder will drop the buffer later arrived?

No. nvv4l2decoder will decode every NAL it received. It can only drop output frame by setting “skip-frames” property. Gst-nvvideo4linux2 — DeepStream 6.0.1 Release documentation

But when I didn’t unref the buffer of surface either push it downstream to streammux, it reach the maximum of num-extra-surface. will it kept waiting or it’s receive the buffer from upstream but didn’t decode it immediately until I push or unref the buffer.

No, it will be decoded immediately.

but where to save? there is no more room for the decoder result

If you don’t push the data to downstream, the pipeline will stop.

Is there any way to raise the maximum of num-extra-surface larger than 24 ?

No.

thx.

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