Hi ALL
I was write frame or obj to jpg file in deepstream test5 app use nvds_obj_enc_process. But obj_meta and surface only true when batch_size=1, while set batch_size=2 i see obj_meta and surface not mapping.
I had try with create new idx_surface from surface and with source mp4 file but it not solve the problem.
Under this is my code, please help me. thanks
static void
bbox_generated_probe_after_analytics (AppCtx * appCtx, GstBuffer * buf,
NvDsBatchMeta * batch_meta, guint index)
{
/**my int**/
GstMapInfo inmap = GST_MAP_INFO_INIT;
if (!gst_buffer_map(buf, &inmap, GST_MAP_READ)) {
g_print ("input buffer mapinfo failed\n");
return;
}
// NvBufSurface *ip_surf = (NvBufSurface *) inmap.data;
NvBufSurface *ip_surf = NULL, idx_surface;
ip_surf = (NvBufSurface *) inmap.data;
// NvBufSurface *idx_surface = (NvBufSurface *) g_malloc0 (sizeof (NvBufSurface));
gst_buffer_unmap(buf, &inmap);
///Read path folder save image
gchar *folderPath;
NvDsImageSave nvds_imgsave = appCtx->config.image_save_config;
if (nvds_imgsave.enable){
if (nvds_imgsave.output_folder_path){
folderPath = g_strdup(nvds_imgsave.output_folder_path);
}
}
/**end int**/
NvDsObjectMeta *obj_meta = NULL;
GstClockTime buffer_pts = 0;
guint32 stream_id = 0;
for (NvDsMetaList * l_frame = batch_meta->frame_meta_list; l_frame != NULL;
l_frame = l_frame->next) {
NvDsFrameMeta *frame_meta = l_frame->data;
stream_id = frame_meta->source_id;
GstClockTime buf_ntp_time = 0;
if (playback_utc == FALSE) {
/** Calculate the buffer-NTP-time
* derived from this stream's RTCP Sender Report here:
*/
StreamSourceInfo *src_stream = &testAppCtx->streams[stream_id];
buf_ntp_time = frame_meta->ntp_timestamp;
if (buf_ntp_time < src_stream->last_ntp_time) {
NVGSTDS_WARN_MSG_V ("Source %d: NTP timestamps are backward in time."
" Current: %lu previous: %lu", stream_id, buf_ntp_time,
src_stream->last_ntp_time);
}
src_stream->last_ntp_time = buf_ntp_time;
}
GList *l;
for (l = frame_meta->obj_meta_list; l != NULL; l = l->next) {
/*check
/* Now using above information we need to form a text that should
* be displayed on top of the bounding box, so lets form it here. */
obj_meta = (NvDsObjectMeta *) (l->data);
if(parse_nvdsanalytics_meta_data(obj_meta))///if object_meta in analytic region filter will save image and sent message to kafka
{
/**MY CUSTOM CODE**/
/// Creat surface index
idx_surface = *ip_surf;
idx_surface.surfaceList = &(ip_surf->surfaceList[frame_meta->source_id]);
idx_surface.numFilled = idx_surface.batchSize = 1;
///Creat path image
gchar *daytimes;
time_t t = time (NULL);
struct tm *tm = localtime (&t);
daytimes = g_strjoin("_",g_strjoin("", g_strdup_printf("%i", tm->tm_year + 1900),g_strdup_printf("%02i", tm->tm_mon + 1), g_strdup_printf("%02i", tm->tm_mday), NULL),
g_strjoin("",g_strdup_printf("%02i", tm->tm_hour), g_strdup_printf("%02i", tm->tm_min), g_strdup_printf("%02i", tm->tm_sec),NULL), NULL);
gchar *image_save_path = g_strjoin("", folderPath, "/camera", g_strdup_printf("%i",frame_meta->source_id), "_", g_strdup_printf("%04i",frame_meta->frame_num),"_", daytimes, ".jpg", NULL);
// g_print("%s\n", image_save_path);
g_print("batch ID:%d source ID:%d\n", frame_meta->batch_id, frame_meta->source_id);
if (nvds_imgsave.save_image_full_frame){
NvDsObjectMeta *dummy_obj_meta = (NvDsObjectMeta *) g_malloc0 (sizeof (NvDsObjectMeta));
dummy_obj_meta->rect_params.width = idx_surface.surfaceList[0].width;
dummy_obj_meta->rect_params.height = idx_surface.surfaceList[0].height;
dummy_obj_meta->rect_params.top = 0;
dummy_obj_meta->rect_params.left = 0;
save_image(image_save_path, &idx_surface, dummy_obj_meta, frame_meta, 0 , appCtx->obj_ctx_handle);
}
else{
if(nvds_imgsave.save_image_cropped_object){
save_image(image_save_path, &idx_surface, obj_meta, frame_meta, 0, appCtx->obj_ctx_handle);
}
}
/**END**/
/**
* Enable only if this callback is after tiler
* NOTE: Scaling back code-commented
* now that bbox_generated_probe_after_analytics() is post analytics
* (say pgie, tracker or sgie)
* and before tiler, no plugin shall scale metadata and will be
* corresponding to the nvstreammux resolution
*/
float scaleW = 0;
float scaleH = 0;
/* Frequency of messages to be send will be based on use case.
* Here message is being sent for first object every 30 frames.
*/
buffer_pts = frame_meta->buf_pts;
if (!appCtx->config.streammux_config.pipeline_width
|| !appCtx->config.streammux_config.pipeline_height) {
g_print ("invalid pipeline params\n");
return;
}
LOGD ("stream %d==%d [%d X %d]\n", frame_meta->source_id,
frame_meta->pad_index, frame_meta->source_frame_width,
frame_meta->source_frame_height);
scaleW =
(float) frame_meta->source_frame_width /
appCtx->config.streammux_config.pipeline_width;
scaleH =
(float) frame_meta->source_frame_height /
appCtx->config.streammux_config.pipeline_height;
if (playback_utc == FALSE) {
/** Use the buffer-NTP-time derived from this stream's RTCP Sender
* Report here:
*/
buffer_pts = buf_ntp_time;
}
/** Generate NvDsEventMsgMeta for every object */
NvDsEventMsgMeta *msg_meta =
(NvDsEventMsgMeta *) g_malloc0 (sizeof (NvDsEventMsgMeta));
generate_event_msg_meta (msg_meta, obj_meta->class_id, FALSE,
/**< useTs NOTE: Pass FALSE for files without base-timestamp in URI */
buffer_pts,
appCtx->config.multi_source_config[stream_id].uri, image_save_path, daytimes, stream_id,
appCtx->config.multi_source_config[stream_id].camera_id,
obj_meta, scaleW, scaleH, frame_meta);
testAppCtx->streams[stream_id].meta_number++;
NvDsUserMeta *user_event_meta =
nvds_acquire_user_meta_from_pool (batch_meta);
if (user_event_meta) {
/*
* Since generated event metadata has custom objects for
* Vehicle / Person which are allocated dynamically, we are
* setting copy and free function to handle those fields when
* metadata copy happens between two components.
*/
user_event_meta->user_meta_data = (void *) msg_meta;
user_event_meta->base_meta.batch_meta = batch_meta;
user_event_meta->base_meta.meta_type = NVDS_EVENT_MSG_META;
user_event_meta->base_meta.copy_func =
(NvDsMetaCopyFunc) meta_copy_func;
user_event_meta->base_meta.release_func =
(NvDsMetaReleaseFunc) meta_free_func;
nvds_add_user_meta_to_frame (frame_meta, user_event_meta);
} else {
g_print ("Error in attaching event meta to buffer\n");
}
}
}
testAppCtx->streams[stream_id].frameCount++;
}
}
bool save_image(gchar *path,
NvBufSurface *ip_surf, NvDsObjectMeta *obj_meta,
NvDsFrameMeta *frame_meta, gint obj_counter, gpointer obj_ctx_handle) {
NvDsObjEncUsrArgs userData = {0};
if (strlen(path) >= sizeof(userData.fileNameImg)) {
g_print ("Path save image out of size\n");
return false;
}
userData.saveImg = TRUE;
userData.attachUsrMeta = FALSE;
g_stpcpy(userData.fileNameImg,path);
userData.fileNameImg[strlen(path)] = '\0';
userData.objNum = obj_counter++;
nvds_obj_enc_process(obj_ctx_handle, &userData, ip_surf, obj_meta, frame_meta);
nvds_obj_enc_finish (obj_ctx_handle);
return true;
}
**• Hardware Platform Jetson **
• DeepStream Version 5.0
• JetPack Version 4.4
• TensorRT Version 7.1