Dump jpeg in deepstream5.0

Hi,guys

In deepstream-app example

I add upload_msg_output function in gie_primary_processing_done_buf_prob

/**
 * Buffer probe function to get the results of primary infer.
 * Here it demonstrates the use by dumping bounding box coordinates in
 * kitti format.
 */
static GstPadProbeReturn
gie_primary_processing_done_buf_prob (GstPad * pad, GstPadProbeInfo * info,
                                      gpointer u_data)
{
    GstBuffer *buf = (GstBuffer *) info->data;
    AppCtx *appCtx = (AppCtx *) u_data;
    NvDsBatchMeta *batch_meta = gst_buffer_get_nvds_batch_meta (buf);
    if (!batch_meta) {
        NVGSTDS_WARN_MSG_V ("Batch meta not found for buffer %p", buf);
        return GST_PAD_PROBE_OK;
    }
    upload_msg_output (appCtx, buf);
    //write_kitti_output (appCtx, batch_meta);

    return GST_PAD_PROBE_OK;
}

and upload_msg_output like this:

static void

upload_msg_output (AppCtx * appCtx, GstBuffer * buf)
{
   NvDsBatchMeta *batch_meta = gst_buffer_get_nvds_batch_meta (buf);

    GstMapInfo in_map_info;
    char* src_data = NULL;

    memset (&in_map_info, 0, sizeof (in_map_info));
    if (!gst_buffer_map (buf, &in_map_info, GST_MAP_READ))
    {
        g_print ("Error: Failed to map gst buffer\n");
        gst_buffer_unmap (buf, &in_map_info);
    }

    NvBufSurface *surface = (NvBufSurface *)in_map_info.data;

    for (NvDsMetaList * l_frame = batch_meta->frame_meta_list; l_frame != NULL; l_frame = l_frame->next)
    {
        printf("total_i_first: %d\n",total_i);
        NvDsFrameMeta *frame_meta = l_frame->data;
        guint stream_id = frame_meta->pad_index;
        box.linkCameraData[stream_id].cameraId = stream_id+1;
        unsigned int dataSize = surface->surfaceList[frame_meta->batch_id].dataSize;

        src_data = (char*) malloc(surface->surfaceList[frame_meta->batch_id].dataSize);
        if(src_data == NULL)
        {
            g_print("Error: failed to malloc src_data \n");
            continue;
        }

        #ifdef PLATFORM_TEGRA
            NvBufSurfaceMap (surface, -1, -1, NVBUF_MAP_READ);
            NvBufSurfacePlaneParams *pParams = &surface->surfaceList[frame_meta->batch_id].planeParams;
            unsigned int offset = 0;
            for(unsigned int num_planes=0; num_planes < pParams->num_planes; num_planes++){
                if(num_planes>0)
                    offset += pParams->height[num_planes-1]*(pParams->bytesPerPix[num_planes-1]*pParams->width[num_planes-1]);
                for (unsigned int h = 0; h < pParams->height[num_planes]; h++) {
                  memcpy((void *)(src_data+offset+h*pParams->bytesPerPix[num_planes]*pParams->width[num_planes]),
                        (void *)((char *)surface->surfaceList[frame_meta->batch_id].mappedAddr.addr[num_planes]+h*pParams->pitch[num_planes]),
                        pParams->bytesPerPix[num_planes]*pParams->width[num_planes]
                        );
                }
            }
            NvBufSurfaceSyncForDevice (surface, -1, -1);
            NvBufSurfaceUnMap (surface, -1, -1);
        #else
            cudaMemcpy((void*)src_data,
                        (void*)surface->surfaceList[frame_meta->batch_id].dataPtr,
                        surface->surfaceList[frame_meta->batch_id].dataSize,
                        cudaMemcpyDeviceToHost);
        #endif

        NvBufSurfaceColorFormat color_format= surface->surfaceList[frame_meta->batch_id].colorFormat;

        if (color_format == NVBUF_COLOR_FORMAT_NV12)
           printf("color_format: NVBUF_COLOR_FORMAT_NV12 \n");
        else if (color_format == NVBUF_COLOR_FORMAT_NV12_ER)
           printf("color_format: NVBUF_COLOR_FORMAT_NV12_ER \n");
        else if (color_format == NVBUF_COLOR_FORMAT_NV12_709)
           printf("color_format: NVBUF_COLOR_FORMAT_NV12_709 \n");
        else if (color_format == NVBUF_COLOR_FORMAT_NV12_709_ER)
           printf("color_format: NVBUF_COLOR_FORMAT_NV12_709_ER \n");
        else
            printf("color_format: NVBUF_COLOR_FORMAT\n");

        gint frame_width = (gint)surface->surfaceList[frame_meta->batch_id].width;
        gint frame_height = (gint)surface->surfaceList[frame_meta->batch_id].height;
        gint frame_step = surface->surfaceList[frame_meta->batch_id].pitch;

        g_print("frame_width =%d\n", frame_width);
        g_print("frame_height=%d\n", frame_height);
        g_print("frame_step=%d\n", frame_step);

        printf("dataSize: %d\n", dataSize);
        img_write(src_data, frame_width, frame_height, frame_step);

        if(src_data != NULL)
        {
            free(src_data);
            src_data = NULL;
        }

    free(box.linkCameraData);
    gst_buffer_unmap(buf, &in_map_info);
}

img_write like this:

void img_write(char *buf, int frame_width, int frame_height, int frame_step)
{
    cv::Mat frame = cv::Mat(frame_height*3/2, frame_width, CV_8UC1, (void*)buf, frame_step);
    cv::Mat out_mat;
    cv::cvtColor(frame, out_mat, cv::COLOR_YUV2BGR_NV12);
    cv::imwrite("savefilename.jpg", out_mat);
}

it output :

color_format: NVBUF_COLOR_FORMAT_NV12_709
frame_width =1920
frame_height=1080
frame_step=2048
dataSize: 3407872

the dump image i wrong ,how can i get right jpeg.

Please refer to this sample of saving NvBufSurface to picture. DeepStream SDK FAQ - Intelligent Video Analytics / DeepStream SDK - NVIDIA Developer Forums

I found a solution : Saving frame with detected object [Jetson Nano, DS4.0.2] - #3 by DaneLLL, it worked

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