I am trying to attach a custom type metadata to gstreamer buffer on nvdecoder_src_pad, exactly like in example “sources/apps/sample_apps/deepstream-gst-metadata-test/deepstream_gst_metadata.c”. For this, I have slightly modified to make the code work like bellow::
typedef struct _NvDecoderMeta
{
cv::Mat frame;
guint frame_type;
guint frame_num;
gboolean dec_err;
} NvDecoderMeta;
I have modified the nvinfer and nvdecoder src_pad_buffer_probe like this::
static GstPadProbeReturn
nvinfer_src_pad_buffer_probe (GstPad * pad, GstPadProbeInfo * info,
gpointer u_data)
{
GstBuffer *buf = (GstBuffer *) info->data;
NvDsMetaList * l_frame = NULL;
NvDsUserMeta *user_meta = NULL;
NvDecoderMeta * decoder_meta = NULL;
NvDsMetaList * l_user_meta = NULL;
NvDsBatchMeta *batch_meta = gst_buffer_get_nvds_batch_meta (buf);
for (l_frame = batch_meta->frame_meta_list; l_frame != NULL;
l_frame = l_frame->next) {
NvDsFrameMeta *frame_meta = (NvDsFrameMeta *) (l_frame->data);
for (l_user_meta = frame_meta->frame_user_meta_list; l_user_meta != NULL;
l_user_meta = l_user_meta->next) {
user_meta = (NvDsUserMeta *) (l_user_meta->data);
// if(user_meta->base_meta.meta_type == NVDS_DECODER_GST_META_EXAMPLE)
// {
decoder_meta = (NvDecoderMeta *)user_meta->user_meta_data;
g_print("Dec Meta retrieved as NVDS USER METADTA For Frame_Num = %d \n",
decoder_meta->frame_num);
g_print("frame type = %d, frame_num = %d decode_error_status = %d\n\n",
decoder_meta->frame_type, decoder_meta->frame_num,
decoder_meta->dec_err);
cv::Mat received = decoder_meta->frame;
cv::imwrite(patH, received);
received.release();
//}
}
}
return GST_PAD_PROBE_OK;
}
static GstPadProbeReturn
nvdecoder_src_pad_buffer_probe (GstPad * pad, GstPadProbeInfo * info,
gpointer u_data)
{
GstBuffer *buf = (GstBuffer *) info->data;
NvDsMeta *meta = NULL;
NvDecoderMeta *decoder_meta = (NvDecoderMeta *)g_malloc0(sizeof(NvDecoderMeta));
if(decoder_meta == NULL)
{
return GST_FLOW_ERROR;
}
/* Add dummy metadata */
decoder_meta->frame = cv::imread("image.jpg"); // Set custom metadata
decoder_meta->frame_type = (frame_number % 3);
decoder_meta->frame_num = frame_number++;
decoder_meta->dec_err = ((frame_number % 4) / 3);
/* Attach decoder metadata to gst buffer using gst_buffer_add_nvds_meta() */
meta = gst_buffer_add_nvds_meta (buf, decoder_meta, NULL,
decoder_meta_copy_func, decoder_meta_release_func);
/* Set metadata type */ // Commented on Purpose
// meta->meta_type = (GstNvDsMetaType)NVDS_DECODER_GST_META_EXAMPLE;
/* Set transform function to transform decoder metadata from Gst meta to
* nvds meta */
meta->gst_to_nvds_meta_transform_func = decoder_gst_to_nvds_meta_transform_func;
/* Set release function to release the transformed nvds metadata */
meta->gst_to_nvds_meta_release_func = decoder_gst_nvds_meta_release_func;
g_print("GST Dec Meta attached with gst decoder output buffer for Frame_Num = %d\n",
decoder_meta->frame_num);
g_print("frame type = %d, frame_num = %d kitty = %c decode_error_status = %d\n\n",
decoder_meta->frame_type, decoder_meta->frame_num, decoder_meta->kitty,
decoder_meta->dec_err);
return GST_PAD_PROBE_OK;
}
The rest of the code remains same exactly like the example sources/apps/sample_apps/deepstream-gst-metadata-test
The code compiles and runs as expected for first few frames, and then crashes due to memory. It even receives the cv::Mat frame on nvinfer_src_pad_buffer_probe because I see it writes the frame in the directory. But I wonder why this crashes because if I define a new ‘gchar’ type metadata instead of cv:;Mat, the program runs fine. From the DS4.0 Plugin manual, I see the line “If gst meta is not attached with gst_buffer_add_nvds_meta (), it is not transformed into DeepStream metadata. It is still available in the Gst Buffer though.” But when I comment out the line
meta = gst_buffer_add_nvds_meta (buf, decoder_meta, NULL,
decoder_meta_copy_func, decoder_meta_release_func);
,the program crashes at the beginning.
Is it not possible to define custom metadata or am I missing something?