Hi,
I had a question about LDC node processing. I used the method mentioned in the attached related link to generate my hardware version of the mesh LUT for specifically IMX623 cameras. I made sure to use the correct spec file too corresponding to IMX623.
I am attaching here the input image used, MATLAB generated mesh LUT ( mesh.txt ) and the respective DCC tool generated hardware version of mesh LUT ( IMX623_mesh_lut.txt ).
2100.mesh.txt IMX623_mesh_lut.txt Input_image.zip
I used this generated IMX623_mesh_LUT as the LUT for the LDC node. Below is a LDC node that we have written for use in our own application. When I run this on the EVM, I have a segmentation fault at
(line 40) status = vxCopyImagePatch(mesh_img, &rect, 0, &image_addr,ldc_lut, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST);
void NodeGraphProcessing::lDCprocessing(vx_context context) { vx_status status = VX_SUCCESS; vx_image ldc_in_image = getInputImage(); GraphBaseInfo graphBaseInfo = {getGraph(), getContext()}; GraphNodeGenerator mGraphNodeGenerator(graphBaseInfo); GraphNodeCommon *GraphCommonNode = new GraphNodeCommon(); vx_image mesh_img = NULL; vx_rectangle_t rect; vx_image ldc_out = NULL; uint32_t table_width, table_height; vx_imagepatch_addressing_t image_addr; vx_user_data_object mesh_params_obj; tivx_vpac_ldc_mesh_params_t mesh_params; tivx_vpac_ldc_region_params_t region_params; vx_user_data_object region_params_obj; tivx_vpac_ldc_params_t ldc_params; vx_user_data_object ldc_param_obj; vx_node node_ldc; table_width = (((1936 / (1 << 2)) + 1u) + 15u) & (~15u); table_height = ((1552 / (1 << 2)) + 1u); /* Mesh Image */ mesh_img = vxCreateImage(context, table_width, table_height, VX_DF_IMAGE_U32); /* Copy Mesh table */ rect.start_x = 0; rect.start_y = 0; rect.end_x = table_width; rect.end_y = table_height; image_addr.dim_x = table_width; image_addr.dim_y = table_height; image_addr.stride_x = 4u; image_addr.stride_y = table_width * 4u; if (status == VX_SUCCESS) { status = vxCopyImagePatch(mesh_img, &rect, 0, &image_addr, ldc_lut, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST); } if (VX_SUCCESS != status) { printf("Copy Image Failed\n"); } ldc_out = vxCreateImage(context, 1936, 1552, (vx_df_image)VX_DF_IMAGE_NV12); /* Mesh Parameters */ mesh_params_obj = vxCreateUserDataObject(context, "tivx_vpac_ldc_mesh_params_t", sizeof(tivx_vpac_ldc_mesh_params_t), NULL); memset(&mesh_params, 0, sizeof(tivx_vpac_ldc_mesh_params_t)); tivx_vpac_ldc_mesh_params_init(&mesh_params); mesh_params.mesh_frame_width = 1936; mesh_params.mesh_frame_height = 1552; mesh_params.subsample_factor = 4; if (status == VX_SUCCESS) { status = vxCopyUserDataObject(mesh_params_obj, 0, sizeof(tivx_vpac_ldc_mesh_params_t), &mesh_params, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST); } /* Block Size parameters */ region_params_obj = vxCreateUserDataObject(context, "tivx_vpac_ldc_region_params_t", sizeof(tivx_vpac_ldc_region_params_t), NULL); region_params.enable = 1; region_params.out_block_width = 64; region_params.out_block_height = 32; region_params.pixel_pad = 1; if (status == VX_SUCCESS) { status = vxCopyUserDataObject(region_params_obj, 0, sizeof(tivx_vpac_ldc_region_params_t), ®ion_params, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST); } /* LDC Configuration */ tivx_vpac_ldc_params_init(&ldc_params); ldc_params.luma_interpolation_type = 1; ldc_param_obj = vxCreateUserDataObject(context, "tivx_vpac_ldc_params_t", sizeof(tivx_vpac_ldc_params_t), NULL); if (status == VX_SUCCESS) { status = vxCopyUserDataObject(ldc_param_obj, 0, sizeof(tivx_vpac_ldc_params_t), &ldc_params, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST); } vx_graph graph = getGraph(); // change mesh_image to NULL and check node_ldc = tivxVpacLdcNode(graph, ldc_param_obj, NULL, region_params_obj, mesh_params_obj, mesh_img, NULL, ldc_in_image, ldc_out, NULL); GraphCommonNode->setNode(node_ldc); if (status == VX_SUCCESS) { status = vxSetNodeTarget(node_ldc, VX_TARGET_STRING, TIVX_TARGET_VPAC_LDC1); } else { printf("app_create_ldc returned error \n"); } setOutputImage(ldc_out); vx_uint32 outWidth, outHeight; vx_size outSize, inSize; vxQueryImage(ldc_out, VX_IMAGE_SIZE, &outSize, sizeof(vx_size)); vxQueryImage(ldc_out, VX_IMAGE_WIDTH, &outWidth, sizeof(vx_uint32)); vxQueryImage(ldc_in_image, VX_IMAGE_SIZE, &inSize, sizeof(vx_size)); vxQueryImage(ldc_out, VX_IMAGE_HEIGHT, &outHeight, sizeof(vx_uint32)); printf("Output image width: %d\n", outWidth); printf("Output image height: %d\n", outHeight); printf("Input image size: %ld bytes\n", inSize); printf("Output image size: %ld bytes\n", outSize); }
I am not entirely sure why this could be failing here. Is there a fault in the way the LUT is generated or am I missing something here ? Could you please suggest on any changes or test trials I could I try to debug this?
Thank you
-Prathiksha