How to crop frame use VIC?

Right now i am working on FPDLink camera. My camera is 1280 719 and they are in sync mode. If I connected four cameras, the frames size will be 5120719. So any way can crop them to four 1280*719 frames easily?

And any way can transfer yuv422 to rgb without using cuda? Like VIC or something?


  1. you may use NvVideoConverter to set the cropping rectangle for the converter.
    please download L4T Multimedia API, you may also check Multimedia API Sample Applications for demonstrations.

  2. please refer to sample application, 07_video_convert for color format conversion.

I am try to use NvBufferTransform to transfer yuv422 to yuv420. And i refer tegra_multimedia_api/samples/12_camera_v4l2_cuda/camera_v4l2_cuda.cpp.But when i view the yuv420 file,the picture looks missing some plane. Can you help me ?

NvBufferMemSyncForDevice(ctx->g_buff[v4l2_buf.index].dmabuff_fd, 0,
                                     (void **)&ctx->g_buff[v4l2_buf.index].start);

            // Convert the camera buffer from YUV422 to YUV420P
            if (-1 == NvBufferTransform(ctx->g_buff[v4l2_buf.index].dmabuff_fd, ctx->render_dmabuf_fd,
                ERROR_RETURN("Failed to convert the buffer");


            NvBufferMemMap(ctx->render_dmabuf_fd, 0, NvBufferMem_Write, &psrc_data);
            NvBufferMemSyncForCpu(ctx->render_dmabuf_fd, 0, &psrc_data);
            yuv420_ofstream->write((char *)psrc_data, 719 * 1280 * 3 / 2);

If you use r32.2.1, please call dump_dmabuf()

If using yuv420,so i need call dump_dmabuf three times for three planes? And if use NvBufferMemSuncForCpu need sync for three planes too?

Yes, you need to call NvBufferMemMap(), NvBufferMemSyncForCpu(), NvBufferMemUnMap() for each plane. For V4L2_PIX_FMT_YUV420M, there are three separate planes( Y, U, V planes ).

Right now i can transfer yuv422 -> yuv420 -> jpeg.But i still can not crop the frames.
I found two ways to crop frames, one is NvBufferTransform, and i can not understand how to config

 * Holds parameters for buffer transform functions.
typedef struct _NvBufferTransformParams
  /** flag to indicate which of the transform parameters are valid. */
  uint32_t transform_flag;
  /** flip method. */
  NvBufferTransform_Flip transform_flip;
  /** transform filter. */
  NvBufferTransform_Filter transform_filter;
  /** source rectangle coordinates for crop opeartion. */
  NvBufferRect src_rect;
  /** destination rectangle coordinates for crop opeartion. */
  NvBufferRect dst_rect;
  /** NvBufferSession to be used for transform. If NULL, the default session
   * is used. */
  NvBufferSession session;

transform_filter = NVBUFFER_TRANSFORM_CROP_DST looks can not work.

Anther way is

ctx.jpegenc->setCropRect(ctx.crop_left, ctx.crop_top,
                             ctx.crop_width, ctx.crop_height);

and in this way , i change ctx.crop_width and ctx.crop_height’s value, jpeg will output green frames. Any way can crop frames?

Please refer to below patch for 12_camera_v4l2_cuda:

@@ -308,7 +308,7 @@ display_initialize(context_t * ctx)
     // Create EGL renderer
     ctx->renderer = NvEglRenderer::createEglRenderer("renderer0",
-            ctx->cam_w, ctx->cam_h, 0, 0);
+            320, 240, 0, 0);
     if (!ctx->renderer)
         ERROR_RETURN("Failed to create EGL renderer");
@@ -507,6 +507,8 @@ prepare_buffers(context_t * ctx)
+    input_params.width = 320;
+    input_params.height = 240;
     input_params.colorFormat = get_nvbuff_color_fmt(V4L2_PIX_FMT_YUV420M);
     input_params.nvbuf_tag = NvBufferTag_NONE;
     // Create Render buffer
@@ -577,6 +579,7 @@ start_capture(context_t * ctx)
     struct sigaction sig_action;
     struct pollfd fds[1];
     NvBufferTransformParams transParams;
+    NvBufferRect src_rect;
     // Ensure a clean shutdown if user types <ctrl+c>
     sig_action.sa_handler = signal_handle;
@@ -589,8 +592,13 @@ start_capture(context_t * ctx)
     // Init the NvBufferTransformParams
     memset(&transParams, 0, sizeof(transParams));
-    transParams.transform_flag = NVBUFFER_TRANSFORM_FILTER;
     transParams.transform_filter = NvBufferTransform_Filter_Smart;
+ = 100;
+    src_rect.left = 100;
+    src_rect.width = 320;
+    src_rect.height = 240;
+    transParams.src_rect = src_rect;
     // Enable render profiling information

It crops (top,left,width,height)=(100,100,320,240) from original frames.

Hi,Danel,thanks, thats can help me. Sorry i have another question. Can jpeg encodec generate gray scale image?
I tried change JCS_YCbCr to JCS_GRAYSCALE, its return error. Any help?

if (ctx->jpegenc->encodeFromFd(buffer->planes[0].fd, JCS_YCbCr, &out_buf,
                                       out_buf_size, ctx->quality) < 0)
            cerr << "Error while encoding from fd" << endl;
            ctx->got_error = true;

We support V4L2_PIX_FMT_YUV420M and V4L2_PIX_FMT_NV12M in jpeg encoding. Please check 05_jpeg_encode sample. Thanks.

OK,i though jpeg encoder support transfer to gray image.Do we have some sample about only get y for yuv420 input to jpeg encoder?

Hi, DaneLLL
I tried to save the frame which after crop to yuv420_I420 format. but when i preview the frame looks missing some infomation.BTW, i use the dump_dmabuf for three planes.

I have checked the frame, the U looks have V’s infomation. The green bar at the bottom is form V. If only show Y and U looks good.But the yuv420m sould be three plane ,right?

Please check if you run the code of dumping YUV like

dump_dmabuf(ctx->render_dmabuf_fd, 0, outputfile);
dump_dmabuf(ctx->render_dmabuf_fd, 1, outputfile);
dump_dmabuf(ctx->render_dmabuf_fd, 2, outputfile);

And check the file size. For 320x240, the size is 320x240x1.5

And try other resolution such as 320x180, 640x480, 640x360.

Thanks DaneLLL. You are right. I forgot the pitch of the UV planes.