Continuing the discussion from Issue with smart record If we record through h265 stream:
**• Hardware Platform -----> 4060
**• DeepStream Version ------> 7.1
**• TensorRT Version ---------> 8.6.2.1
**• NVIDIA GPU Driver Version --------> 560.35.05
I tried by implementing transcode functionality in the populate_rtspsrc_bin_video in opt/nvidia/deepstream/deepstream-7.1/sources/gst-plugins/gst-nvurisrcbin/gstdsnvurisrcbin.cpp. Below is my modified code of populate_rtspsrc_bin_video().
populate_rtspsrc_bin_video (GstDsNvUriSrcBin * bin, GstPad * pad,
const char *encoding_name)
{
GstCapsUPtr caps = NULL;
GstCapsFeatures *feature = NULL;
if (bin->video_elem_populated) {
GstPadUPtr sinkpad = gst_element_get_static_pad (bin->depay, "sink");
return gst_pad_link (pad, sinkpad) == GST_PAD_LINK_OK;
}
if (!bin->depay) {
if (!g_strcmp0 (encoding_name, "H264")) {
bin->depay = gst_element_factory_make ("rtph264depay", "depay");
bin->parser = gst_element_factory_make ("h264parse", "parser");
} else if (!g_strcmp0 (encoding_name, "H265")) {
bin->depay = gst_element_factory_make ("rtph265depay", "depay");
bin->parser = gst_element_factory_make ("h265parse", "parser");
bin->caps_filter_h265 = gst_element_factory_make("capsfilter", "caps_filter_h265");
GstCaps *h265_caps = gst_caps_new_simple("video/x-h265", "alignment", G_TYPE_STRING, "au", NULL);
g_object_set(G_OBJECT(bin->caps_filter_h265), "caps", h265_caps, NULL);
gst_caps_unref(h265_caps);
bin->decoder = gst_element_factory_make("nvv4l2decoder", "h265_decoder");
bin->transcode_queue = gst_element_factory_make("queue", "transcode_queue");
bin->h264_encoder = gst_element_factory_make("nvv4l2h264enc", "h264_encoder");
bin->caps_filter_h264 = gst_element_factory_make("capsfilter", "caps_filter_h264");
GstCaps *h264_caps = gst_caps_new_simple("video/x-h264", "alignment", G_TYPE_STRING, "au", NULL);
g_object_set(G_OBJECT(bin->caps_filter_h264), "caps", h264_caps, NULL);
gst_caps_unref(h264_caps);
bin->h264_parser = gst_element_factory_make("h264parse", "h264_parser");
} else if (!g_strcmp0 (encoding_name, "MP4V-ES")) {
bin->depay = gst_element_factory_make ("rtpmp4vdepay", "depay");
bin->parser = gst_element_factory_make ("mpeg4videoparse", "parser");
} else {
GST_ELEMENT_ERROR (bin, STREAM, FAILED, ("%s not supported",
encoding_name), (NULL));
return FALSE;
}
if (!bin->depay) {
GST_ELEMENT_ERROR (bin, STREAM, FAILED, ("Failed to create 'depay'"),
(NULL));
return FALSE;
}
if (!g_strcmp0 (encoding_name, "H265")) {
gst_bin_add_many (GST_BIN (bin), bin->depay, bin->parser,
bin->caps_filter_h265, bin->decoder, bin->transcode_queue,
bin->h264_encoder, bin->caps_filter_h264, bin->h264_parser, NULL);
NVGSTDS_LINK_ELEMENT (bin->depay, bin->parser, FALSE);
NVGSTDS_LINK_ELEMENT (bin->parser, bin->caps_filter_h265, FALSE);
NVGSTDS_LINK_ELEMENT (bin->caps_filter_h265, bin->decoder, FALSE);
NVGSTDS_LINK_ELEMENT (bin->decoder, bin->transcode_queue, FALSE);
NVGSTDS_LINK_ELEMENT (bin->transcode_queue, bin->h264_encoder, FALSE);
NVGSTDS_LINK_ELEMENT (bin->h264_encoder, bin->caps_filter_h264, FALSE);
NVGSTDS_LINK_ELEMENT (bin->caps_filter_h264, bin->h264_parser, FALSE);
} else {
gst_bin_add_many (GST_BIN (bin), bin->depay, bin->parser, NULL);
NVGSTDS_LINK_ELEMENT (bin->depay, bin->parser, FALSE);
}
if (!gst_element_sync_state_with_parent (bin->depay) ||
!gst_element_sync_state_with_parent (bin->parser) ||
(!g_strcmp0 (encoding_name, "H265") &&
(!gst_element_sync_state_with_parent (bin->caps_filter_h265) ||
!gst_element_sync_state_with_parent (bin->decoder) ||
!gst_element_sync_state_with_parent (bin->transcode_queue) ||
!gst_element_sync_state_with_parent (bin->h264_encoder) ||
!gst_element_sync_state_with_parent (bin->caps_filter_h264) ||
!gst_element_sync_state_with_parent (bin->h264_parser)))) {
GST_ELEMENT_ERROR (bin, STREAM, FAILED, ("Failed to sync state"), (NULL));
return FALSE;
}
}
GstPadUPtr sinkpad = gst_element_get_static_pad (bin->depay, "sink");
if (gst_pad_link (pad, sinkpad) != GST_PAD_LINK_OK) {
return FALSE;
}
bin->tee_rtsp_pre_decode =
gst_element_factory_make ("tee", "tee_rtsp_pre_decode");
if (!bin->tee_rtsp_pre_decode) {
GST_ELEMENT_ERROR (bin, RESOURCE, FAILED,
("Failed to create 'tee_rtsp'"), (NULL));
return FALSE;
}
bin->tee_rtsp_post_decode =
gst_element_factory_make ("tee", "tee_rtsp_post_decode");
if (!bin->tee_rtsp_post_decode) {
GST_ELEMENT_ERROR (bin, RESOURCE, FAILED,
("Failed to create 'tee_rtsp'"), (NULL));
return FALSE;
}
bin->dec_que = gst_element_factory_make ("queue", "dec_que");
if (!bin->dec_que) {
GST_ELEMENT_ERROR (bin, RESOURCE, FAILED,
("Failed to create 'queue'"), (NULL));
return FALSE;
}
if (bin->config->rtsp_reconnect_interval_sec > 0) {
NVGSTDS_ELEM_ADD_PROBE (bin,
bin->depay, "src", rtspsrc_monitor_probe_func,
GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, bin);
}
bin->decodebin = gst_element_factory_make ("decodebin", "decodebin");
if (!bin->decodebin) {
GST_ELEMENT_ERROR (bin, STREAM, FAILED,
("Failed to create 'decodebin'"), (NULL));
return FALSE;
}
g_signal_connect (G_OBJECT (bin->decodebin), "child-added",
G_CALLBACK (decodebin_child_added), bin);
bin->cap_filter = gst_element_factory_make ("queue", "queue");
if (!bin->cap_filter) {
GST_ELEMENT_ERROR (bin, STREAM, FAILED,
("Failed to create 'queue'"), (NULL));
return FALSE;
}
g_signal_connect (G_OBJECT (bin->decodebin), "pad-added",
G_CALLBACK (cb_newpad2), bin);
bin->nvvidconv = gst_element_factory_make ("nvvideoconvert", "nvvidconv");
g_object_set (G_OBJECT (bin->nvvidconv), "disable-passthrough", bin->config->disable_passthrough, NULL);
g_object_set (G_OBJECT (bin->nvvidconv), "gpu-id", bin->config->gpu_id, NULL);
if (!bin->nvvidconv) {
GST_ELEMENT_ERROR (bin, STREAM, FAILED,
("Could not create element 'nvvidconv_elem'"), (NULL));
return FALSE;
}
caps = gst_caps_new_empty_simple ("video/x-raw");
feature = gst_caps_features_new ("memory:NVMM", NULL);
gst_caps_set_features (caps, 0, feature);
bin->cap_filter1 =
gst_element_factory_make ("capsfilter", "src_cap_filter_nvvidconv");
if (!bin->cap_filter1) {
GST_ELEMENT_ERROR (bin, STREAM, FAILED,
("Could not create 'queue'"), (NULL));
return FALSE;
}
g_object_set (G_OBJECT (bin->cap_filter1), "caps", caps.get (), NULL);
gst_bin_add_many (GST_BIN (bin),
bin->tee_rtsp_pre_decode, bin->dec_que,
bin->tee_rtsp_post_decode, bin->decodebin,
bin->cap_filter, bin->nvvidconv, bin->cap_filter1, NULL);
if (!gst_element_sync_state_with_parent (bin->tee_rtsp_pre_decode) ||
!gst_element_sync_state_with_parent (bin->dec_que) ||
!gst_element_sync_state_with_parent (bin->tee_rtsp_post_decode) ||
!gst_element_sync_state_with_parent (bin->decodebin) ||
!gst_element_sync_state_with_parent (bin->cap_filter) ||
!gst_element_sync_state_with_parent (bin->nvvidconv) ||
!gst_element_sync_state_with_parent (bin->cap_filter1)) {
GST_ELEMENT_ERROR (bin, STREAM, FAILED,
("Failed to sync child states"), (NULL));
return FALSE;
}
// If H265 input, link H264 parser to tee
if (!g_strcmp0 (encoding_name, "H265"))
NVGSTDS_LINK_ELEMENT (bin->h264_parser, bin->tee_rtsp_pre_decode, FALSE);
else
NVGSTDS_LINK_ELEMENT (bin->parser, bin->tee_rtsp_pre_decode, FALSE);
link_element_to_tee_src_pad (bin->tee_rtsp_pre_decode, bin->dec_que);
NVGSTDS_LINK_ELEMENT (bin->dec_que, bin->decodebin, FALSE);
if (bin->recordCtx && (bin->config->smart_rec_mode == 0 || bin->config->smart_rec_mode == 1))
link_element_to_tee_src_pad (bin->tee_rtsp_pre_decode,
bin->recordCtx->recordbin);
link_element_to_tee_src_pad (bin->tee_rtsp_post_decode, bin->cap_filter);
NVGSTDS_LINK_ELEMENT (bin->cap_filter, bin->nvvidconv, FALSE);
NVGSTDS_LINK_ELEMENT (bin->nvvidconv, bin->cap_filter1, FALSE);
GstPadUPtr target_pad = gst_element_get_static_pad (bin->cap_filter1, "src");
GstPad *src_pad = gst_ghost_pad_new_from_template ("vsrc_0", target_pad,
gst_static_pad_template_get (&gst_nvurisrc_bin_vsrc_template));
gst_pad_add_probe (src_pad, GST_PAD_PROBE_TYPE_QUERY_BOTH,
src_pad_query_probe, bin, NULL);
gst_pad_set_active (src_pad, TRUE);
gst_element_add_pad (GST_ELEMENT (bin), src_pad);
bin->video_elem_populated = TRUE;
return TRUE;
}
once I downloaded and checked my recorded videos which consists of green blocks on the frames. I have attached a frame below. please check the above modified code and please let us know why is it happening and what is the fix for this?
- I dont find the code for NvDsSRStart, NvDsSRStop in smart record. Is it open source or not?
Thank you @fanzh
