This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PROCESSOR-SDK-DRA8X-TDA4X: Draw 2D Lines Flickering

Part Number: PROCESSOR-SDK-DRA8X-TDA4X

I am attempting to overlay some vertical lines over my mosaic output images, however my lines would flicker if simply drawn during my run graph. In attempt to fix this I Dequeued my mosaic output, drew my lines and Enqueued it back. This resulted in a solid line, however the line is behind my mosaic output image.

For reference I am using the following functions for initializing a then drawing my lines.

static vx_status app_create_draw(AppObj *obj)
{
vx_status status = VX_SUCCESS;
Draw2D_BufInfo sBufInfo;
vx_imagepatch_addressing_t image_addr;
vx_rectangle_t rect;
vx_map_id map_id;
uint8_t *data_ptr[2];
int i, j, image_size;

Draw2D_create(&obj->pHndl);
sBufInfo.bufWidth = DISPLAY_WIDTH;
sBufInfo.bufHeight = DISPLAY_HEIGHT;
sBufInfo.bufPitch[0] = DISPLAY_WIDTH;
sBufInfo.bufPitch[1] = DISPLAY_WIDTH;
sBufInfo.dataFormat = DRAW2D_DF_YUV420SP_UV;
sBufInfo.transperentColor = 0;
sBufInfo.transperentColorFormat = DRAW2D_DF_YUV420SP_UV;

for (j = 0; j < APP_BUFFER_Q_DEPTH; j++)
{
for (i = 0; i < 2; i++)
{
rect.start_x = 0;
rect.start_y = 0;
rect.end_x = DISPLAY_WIDTH;
rect.end_y = DISPLAY_HEIGHT;

status |= vxMapImagePatch(obj->imgMosaicObj.output_image[j],
&rect,
i,
&map_id,
&image_addr,
(void*)&data_ptr[i],
VX_READ_AND_WRITE,
VX_MEMORY_TYPE_HOST,
VX_NOGAP_X
);

if (0 == i)
{
image_size = DISPLAY_WIDTH * DISPLAY_HEIGHT;
memset(data_ptr[i], 0, image_size);
}
else
{
image_size = DISPLAY_WIDTH * (DISPLAY_HEIGHT / 2);
memset(data_ptr[i], 128, image_size);
}

vxUnmapImagePatch(obj->imgMosaicObj.output_image[j], map_id);
}
}

sBufInfo.bufAddr[0] = data_ptr[0];
sBufInfo.bufAddr[1] = data_ptr[1];

status |= Draw2D_setBufInfo(obj->pHndl, &sBufInfo);

return status;
}

static vx_status app_draw_bounding_box(AppObj *obj, vx_image image)
{
vx_status status = VX_SUCCESS;
Draw2D_LinePrm sLinePrm;
vx_imagepatch_addressing_t image_addr;
vx_rectangle_t rect;
vx_map_id map_id;
uint8_t *data_ptr[3];
int i;

for (i = 0; i < 2; i++)
{
rect.start_x = 0;
rect.start_y = 0;
rect.end_x = DISPLAY_WIDTH;
rect.end_y = DISPLAY_HEIGHT;

status |= vxMapImagePatch(image,
&rect,
i,
&map_id,
&image_addr,
(void*)&data_ptr[i],
VX_READ_ONLY,
VX_MEMORY_TYPE_HOST,
VX_NOGAP_X
);

vxUnmapImagePatch(image, map_id);
}

Draw2D_updateBufAddr(obj->pHndl, data_ptr);

// sLinePrm.lineColor = 0x00807F; //black
sLinePrm.lineColor = 0x4C54FF; //red

sLinePrm.lineSize = 10;
sLinePrm.lineColorFormat = DRAW2D_DF_YUV420SP_UV;

status |= Draw2D_drawLine(obj->pHndl,
DISPLAY_WIDTH/4.8+160,
0,
DISPLAY_WIDTH/4.8+160,
DISPLAY_HEIGHT,
&sLinePrm);

status |= Draw2D_drawLine(obj->pHndl,
3*DISPLAY_WIDTH/4.8+160,
0,
3*DISPLAY_WIDTH/4.8+160,
DISPLAY_HEIGHT,
&sLinePrm);

return status;
}

static vx_status app_run_graph_for_one_frame_pipeline(AppObj *obj, vx_int32 frame_id)
{
vx_status status = VX_SUCCESS;

appPerfPointBegin(&obj->total_perf);
ImgMosaicObj *imgMosaicObj = &obj->imgMosaicObj;
CaptureObj *captureObj = &obj->captureObj;

if(obj->pipeline < 0)
{
/* Enqueue outpus */

if (obj->en_out_img_write == 1)
{
vxGraphParameterEnqueueReadyRef(obj->graph, imgMosaicObj->graph_parameter_index, (vx_reference*)&imgMosaicObj->output_image[obj->enqueueCnt], 1);
}

/* Enqueue inputs during pipeup dont execute */
vxGraphParameterEnqueueReadyRef(obj->graph, captureObj->graph_parameter_index, (vx_reference*)&obj->captureObj.raw_image_arr[obj->enqueueCnt], 1);

#ifdef BORDERS
vxGraphParameterEnqueueReadyRef(obj->graph, imgMosaicObj->graph_parameter_index, (vx_reference*)&imgMosaicObj->output_image[obj->enqueueCnt], 1);
#endif

obj->enqueueCnt++;
obj->enqueueCnt = (obj->enqueueCnt >= APP_BUFFER_Q_DEPTH)? 0 : obj->enqueueCnt;
obj->pipeline++;

}

if(obj->pipeline == 0)
{
if (obj->en_out_img_write == 1)
{
vxGraphParameterEnqueueReadyRef(obj->graph, imgMosaicObj->graph_parameter_index, (vx_reference*)&imgMosaicObj->output_image[obj->enqueueCnt], 1);
}
/* Execute 1st frame */
vxGraphParameterEnqueueReadyRef(obj->graph, captureObj->graph_parameter_index, (vx_reference*)&obj->captureObj.raw_image_arr[obj->enqueueCnt], 1);

#ifdef BORDERS
vxGraphParameterEnqueueReadyRef(obj->graph, imgMosaicObj->graph_parameter_index, (vx_reference*)&imgMosaicObj->output_image[obj->enqueueCnt], 1);
#endif

obj->enqueueCnt++;
obj->enqueueCnt = (obj->enqueueCnt >= APP_BUFFER_Q_DEPTH)? 0 : obj->enqueueCnt;
obj->pipeline++;
#ifdef BORDERS
//// /* Get output reference, waits until a frame is available */
//// /* Dequeue output */
// vxGraphParameterDequeueDoneRef(obj->graph, imgMosaicObj->graph_parameter_index, (vx_reference*)&mosaic_output_image, 1, &num_refs);

// /* Drawing bounding box */
// status = app_draw_bounding_box(obj, imgMosaicObj->output_image[obj->enqueueCnt]);
// // /* Enqueue output */
// vxGraphParameterEnqueueReadyRef(obj->graph, imgMosaicObj->graph_parameter_index, (vx_reference*)&mosaic_output_image, 1);
#endif
}

if(obj->pipeline > 0)
{
vx_image capture_input_image;
vx_image mosaic_output_image;
vx_image display_image;
uint32_t num_refs;

/* Dequeue input */
vxGraphParameterDequeueDoneRef(obj->graph, captureObj->graph_parameter_index, (vx_reference*)&capture_input_image, 1, &num_refs);

if(obj->en_out_img_write == 1)
{
vx_char output_file_name[APP_MAX_FILE_PATH];

/* Dequeue output */
vxGraphParameterDequeueDoneRef(obj->graph, imgMosaicObj->graph_parameter_index, (vx_reference*)&mosaic_output_image, 1, &num_refs);


appPerfPointBegin(&obj->fileio_perf);

snprintf(output_file_name, APP_MAX_FILE_PATH, "%s/mosaic_output_%010d_%dx%d.yuv", obj->output_file_path, (frame_id - APP_BUFFER_Q_DEPTH), imgMosaicObj->out_width, imgMosaicObj->out_height);
writeMosaicOutput(output_file_name, mosaic_output_image);

appPerfPointEnd(&obj->fileio_perf);

/* Enqueue output */
vxGraphParameterEnqueueReadyRef(obj->graph, imgMosaicObj->graph_parameter_index, (vx_reference*)&mosaic_output_image, 1);
}


#ifdef BORDERS
//// /* Get output reference, waits until a frame is available */
//// /* Dequeue output */
vxGraphParameterDequeueDoneRef(obj->graph, imgMosaicObj->graph_parameter_index, (vx_reference*)&mosaic_output_image, 1, &num_refs);

// /* Drawing bounding box */
status = app_draw_bounding_box(obj, imgMosaicObj->output_image[obj->enqueueCnt]);
// // /* Enqueue output */
vxGraphParameterEnqueueReadyRef(obj->graph, imgMosaicObj->graph_parameter_index, (vx_reference*)&mosaic_output_image, 1);
#endif
/* Enqueue input - start execution */
vxGraphParameterEnqueueReadyRef(obj->graph, captureObj->graph_parameter_index, (vx_reference*)&capture_input_image, 1);

obj->enqueueCnt++;
obj->dequeueCnt++;

obj->enqueueCnt = (obj->enqueueCnt >= APP_BUFFER_Q_DEPTH)? 0 : obj->enqueueCnt;
obj->dequeueCnt = (obj->dequeueCnt >= APP_BUFFER_Q_DEPTH)? 0 : obj->dequeueCnt;

}

appPerfPointEnd(&obj->total_perf);

return status;
}

  • Hi Jeff,

    Is the mosaic output directly connected to display? In this case, DQ will return the buffer only after it is displayed.. 

    If you want to put/draw lines on mosaic output, i would suggest to update mosaic node, so along with mosaicing, it should also add lines in the output buffer.

    Rgds,

    Brijesh 

  • Hi Brijesh,

    After further looking into the mosaic node, I noticed an "enable_overlay" parameter. 

    I went into the vx_img_mosaic_draw_overlay_avp2.c file and modified it to simply draw my vertical lines, however this still results in my lines being in the background of the output.

    Is there any way to bring the lines to the foreground of the image so that they are on top of my mosaic output?

    Thanks,

    Jeff

  • Hi Jeff, 

    That's correct way. You could update the mosaic node and use Draw2D library on the mosaic output buffer to draw lines. 

    So you enabled flag this flag and drawn lines on the output buffer, and isn't the lines visible? Do you have any other graphics on top of the mosaic from difference video pipeline? Can you try disabling it?

    Regards,

    Brijesh

  • Hi Brijesh,

    The lines are visible, but they are only visible in the background.

    I do not have any other nodes affecting the mosaic output in the video pipeline.

    I attached a clip of what my output looks like.

    The red lines should run the length of the image, but for some reason they are put behind the mosaic windows.

    Thanks,

    Jeff

  • Hi Jeff,

    One thing that i noted in mosaic node is, enable_overlay condition is checked under clear_count condition check, it means buffer will get updated only for some initial 2 to 3 frames, but after that lines will not be drawn. So can you please move your line drawing logic out of clear_count if block?

    Regards,

    Brijesh

  • Thanks Brijesh, 

    Fixed my issues moving the drawing logic to an area that is run more than three times. Should have been obvious, but I suppose hindsight is 20/20.

    Thanks again,

    Jeff