Hi Processors Team:
I am using psdkra_j7presi_00_08 to run ldc on EMULATION_MODE.
When input and output image format is VX_DF_IMAGE_U8, ldc can run correctly.
input is 256*128 U8 luma pic,output is 256*128 U8 luma pic,subsample_factor = 0,so the mesh size is 256*128.
When I change input and output image format to VX_DF_IMAGE_UYVY,ldc can not run correctly.
input is 256*128 UYVY pic,output is 256*128 UYVY pic,and the mesh is the same .
"Segmentation fault (core dumped)" is printed in terminal when I run ldc.
Below is my graph and some config and I have upload my source code .
Q1 Whether psdkra_j7presi_00_08 can support UYVY and NV12 format in ldc on EMULATION_MODE.
Q2 How to config ldc node to process UYVY pic, is there something wrong in my code?
Thanks.
/*
* Graph,
* ldc_config
* |
* v
* input_img -> LDC -----> ldc_img
* ldc_region ---^
* ldc_mesh ---^
*
*/
obj->ldc_params.luma_interpolation_type = 1; //BILINEAR
obj->ldc_region_params.out_block_width = 1;
obj->ldc_region_params.out_block_height = 1;
obj->ldc_region_params.pixel_pad = 0;
obj->ldc_params.mesh.frame_width = 256;
obj->ldc_params.mesh.frame_height = 128;
obj->ldc_params.mesh.subsample_factor = 0;
/* * * Copyright (c) 2017 Texas Instruments Incorporated * * All rights reserved not granted herein. * * Limited License. * * Texas Instruments Incorporated grants a world-wide, royalty-free, non-exclusive * license under copyrights and patents it now or hereafter owns or controls to make, * have made, use, import, offer to sell and sell ("Utilize") this software subject to the * terms herein. With respect to the foregoing patent license, such license is granted * solely to the extent that any such patent is necessary to Utilize the software alone. * The patent license shall not apply to any combinations which include this software, * other than combinations with devices manufactured by or for TI ("TI Devices"). * No hardware patent is licensed hereunder. * * Redistributions must preserve existing copyright notices and reproduce this license * (including the above copyright notice and the disclaimer and (if applicable) source * code license limitations below) in the documentation and/or other materials provided * with the distribution * * Redistribution and use in binary form, without modification, are permitted provided * that the following conditions are met: * * * No reverse engineering, decompilation, or disassembly of this software is * permitted with respect to any software provided in binary form. * * * any redistribution and use are licensed by TI for use only with TI Devices. * * * Nothing shall obligate TI to provide you with source code for the software * licensed and provided to you in object code. * * If software source code is provided to you, modification and redistribution of the * source code are permitted provided that the following conditions are met: * * * any redistribution and use of the source code, including any resulting derivative * works, are licensed by TI for use only with TI Devices. * * * any redistribution and use of any object code compiled from the source code * and any resulting derivative works, are licensed by TI for use only with TI Devices. * * Neither the name of Texas Instruments Incorporated nor the names of its suppliers * * may be used to endorse or promote products derived from this software without * specific prior written permission. * * DISCLAIMER. * * THIS SOFTWARE IS PROVIDED BY TI AND TI'S LICENSORS "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL TI AND TI'S LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include <TI/tivx.h> #include <TI/j7.h> #include <tivx_utils_file_rd_wr.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <assert.h> #include <sys/stat.h> #define APP_MAX_FILE_PATH (256u) #define APP_ASSERT(x) assert((x)) #define APP_ASSERT_VALID_REF(ref) (APP_ASSERT(vxGetStatus((vx_reference)(ref))==VX_SUCCESS)); typedef struct { /* config options */ char input_file_path[APP_MAX_FILE_PATH]; char output_file_path[APP_MAX_FILE_PATH]; char input_file_prefix[APP_MAX_FILE_PATH]; char output_file_prefix[APP_MAX_FILE_PATH]; char input_mesh_file[APP_MAX_FILE_PATH]; uint32_t start_fileno; uint32_t end_fileno; uint32_t width; uint32_t height; uint32_t width_out; uint32_t height_out; char input_file[APP_MAX_FILE_PATH]; char output_file[APP_MAX_FILE_PATH]; /* OpenVX references */ vx_context context; vx_graph graph; vx_node node_ldc; vx_image input_img; vx_image ldc_img; vx_image ldc_mesh; // vx_matrix affine_matrix; // int16_t matrix[6]; vx_user_data_object ldc_config; tivx_vpac_ldc_params_t ldc_params; vx_user_data_object ldc_region; tivx_vpac_ldc_region_params_t ldc_region_params; } AppObj; AppObj gAppObj; static void app_parse_cmd_line_args(AppObj *obj, int argc, char *argv[]); static void app_init(AppObj *obj); static void app_deinit(AppObj *obj); static vx_status app_create_graph(AppObj *obj); static vx_status app_run_graph(AppObj *obj); static void app_delete_graph(AppObj *obj); static vx_status app_load_vximage_mesh_from_text_file(char *filename, vx_image image); int main(int argc, char* argv[]) { AppObj *obj = &gAppObj; app_parse_cmd_line_args(obj, argc, argv); app_init(obj); app_create_graph(obj); app_run_graph(obj); app_delete_graph(obj); app_deinit(obj); return 0; } static void app_init(AppObj *obj) { tivxInit(); obj->context = vxCreateContext(); APP_ASSERT_VALID_REF(obj->context); tivxHwaLoadKernels(obj->context); } static void app_deinit(AppObj *obj) { tivxHwaUnLoadKernels(obj->context); vxReleaseContext(&obj->context); tivxDeInit(); } /* * Graph, * ldc_config * | * v * input_img -> LDC -----> ldc_img * ldc_region ---^ * ldc_mesh ---^ * */ static vx_status app_create_graph(AppObj *obj) { vx_status status = VX_SUCCESS; char mesh_file_name[APP_MAX_FILE_PATH]; obj->graph = vxCreateGraph(obj->context); APP_ASSERT_VALID_REF(obj->graph); /* In/Out Images */ obj->input_img = vxCreateImage(obj->context, obj->width, obj->height, VX_DF_IMAGE_UYVY); //VX_DF_IMAGE_U8 VX_DF_IMAGE_UYVY APP_ASSERT_VALID_REF(obj->input_img); vxSetReferenceName((vx_reference)obj->input_img, "InputImageUYVY"); obj->ldc_img = vxCreateImage(obj->context, obj->width_out, obj->height_out, VX_DF_IMAGE_UYVY); //VX_DF_IMAGE_U8 VX_DF_IMAGE_UYVY APP_ASSERT_VALID_REF(obj->ldc_img); vxSetReferenceName((vx_reference)obj->ldc_img, "OutputImageUYVY"); /* Config, and region params */ memset(&obj->ldc_params, 0, sizeof(tivx_vpac_ldc_params_t)); obj->ldc_config = vxCreateUserDataObject(obj->context, "tivx_vpac_ldc_params_t", sizeof(tivx_vpac_ldc_params_t), NULL); APP_ASSERT_VALID_REF(obj->ldc_config); vxSetReferenceName((vx_reference)obj->ldc_config, "LDC_Configuration"); memset(&obj->ldc_region_params, 0, sizeof(tivx_vpac_ldc_region_params_t)); obj->ldc_region = vxCreateUserDataObject(obj->context, "tivx_vpac_ldc_region_params_t", sizeof(tivx_vpac_ldc_region_params_t), NULL); APP_ASSERT_VALID_REF(obj->ldc_region); vxSetReferenceName((vx_reference)obj->ldc_region, "LDC_Region"); obj->ldc_params.luma_interpolation_type = 1; //BILINEAR obj->ldc_region_params.out_block_width = 1; obj->ldc_region_params.out_block_height = 1; obj->ldc_region_params.pixel_pad = 0; status = vxCopyUserDataObject(obj->ldc_region, 0, sizeof(tivx_vpac_ldc_region_params_t), &obj->ldc_region_params, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST); APP_ASSERT(status==VX_SUCCESS); /* Mesh Table */ obj->ldc_params.mesh.frame_width = 256; obj->ldc_params.mesh.frame_height = 128; obj->ldc_params.mesh.subsample_factor = 0; obj->ldc_mesh = vxCreateImage(obj->context, obj->ldc_params.mesh.frame_width/(1<<obj->ldc_params.mesh.subsample_factor)/*+1*/, obj->ldc_params.mesh.frame_height/(1<<obj->ldc_params.mesh.subsample_factor)/*+1*/, VX_DF_IMAGE_U32); APP_ASSERT_VALID_REF(obj->ldc_mesh); vxSetReferenceName((vx_reference)obj->ldc_mesh, "LDC_Mesh"); snprintf(mesh_file_name, APP_MAX_FILE_PATH, "%s", obj->input_mesh_file); app_load_vximage_mesh_from_text_file(mesh_file_name, obj->ldc_mesh); /* Affine Matrix */ // obj->affine_matrix = vxCreateMatrix(obj->context, VX_TYPE_INT16, 2, 3); // APP_ASSERT_VALID_REF(obj->affine_matrix); // vxSetReferenceName((vx_reference)obj->affine_matrix, "LDC_AffineMatrix"); /* obj->matrix[0] = 4096; obj->matrix[1] = 0; obj->matrix[4] = 0; //256 obj->matrix[2] = 0; obj->matrix[3] = 4096; obj->matrix[5] = 0; //320 status = vxCopyMatrix(obj->affine_matrix, obj->matrix, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST); APP_ASSERT(status==VX_SUCCESS); */ /* This data structure must be added after the entire structure is configured (including mesh portion) */ status = vxCopyUserDataObject(obj->ldc_config, 0, sizeof(tivx_vpac_ldc_params_t), &obj->ldc_params, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST); APP_ASSERT(status==VX_SUCCESS); obj->node_ldc = tivxVpacLdcNode(obj->graph, obj->ldc_config, obj->ldc_region, obj->ldc_mesh, NULL,//obj->affine_matrix, NULL, NULL, NULL, obj->input_img, NULL, obj->ldc_img, NULL, NULL, NULL, NULL); APP_ASSERT_VALID_REF(obj->node_ldc); status = vxSetNodeTarget(obj->node_ldc, VX_TARGET_STRING, TIVX_TARGET_VPAC_LDC1); APP_ASSERT(status==VX_SUCCESS); vxSetReferenceName((vx_reference)obj->node_ldc, "LDC_Processing"); status = vxVerifyGraph(obj->graph); APP_ASSERT(status==VX_SUCCESS); status = tivxExportGraphToDot(obj->graph,".", "vx_app_ldc"); APP_ASSERT(status==VX_SUCCESS); return status; } static void app_delete_graph(AppObj *obj) { vxReleaseNode(&obj->node_ldc); vxReleaseGraph(&obj->graph); vxReleaseImage(&obj->input_img); vxReleaseImage(&obj->ldc_img); vxReleaseImage(&obj->ldc_mesh); vxReleaseUserDataObject(&obj->ldc_config); // vxReleaseMatrix(&obj->affine_matrix); vxReleaseUserDataObject(&obj->ldc_region); } static vx_status app_run_graph(AppObj *obj) { uint32_t curFileNum; vx_status status = VX_SUCCESS; printf("enter app_run_graph ...\n"); char * data_read_buffer = NULL; data_read_buffer = malloc(1280*800*2); /* create output directory is not already existing */ mkdir(obj->output_file_path, S_IRWXU | S_IRWXG | S_IRWXO); printf("Loading [%s] ...\n", obj->input_file); // tivx_utils_load_vximage_from_pngfile(obj->input_img, input_file_name, vx_true_e); tivx_utils_load_vximage_from_dat(obj->input_img, obj->input_file,data_read_buffer,0); //printf(" %d of %d: Running graph ...\n", curFileNum, obj->end_fileno); status = vxScheduleGraph(obj->graph); APP_ASSERT(status==VX_SUCCESS); status = vxWaitGraph(obj->graph); APP_ASSERT(status==VX_SUCCESS); // printf(" %d of %d: Saving [%s] ...\n", curFileNum, obj->end_fileno, output_file_name_img); // tivx_utils_save_vximage_to_pngfile(output_file_name_img, obj->ldc_img); // printf(" %d of %d: Done !!!\n", curFileNum, obj->end_fileno); printf(" Saving [%s] ...\n", obj->output_file); tivx_utils_save_vximage_to_dat(obj->output_file, obj->ldc_img); free(data_read_buffer); return status; } #if 0 static vx_status app_run_graph(AppObj *obj) { char input_file_name[APP_MAX_FILE_PATH]; char output_file_name_img[APP_MAX_FILE_PATH]; uint32_t curFileNum; vx_status status = VX_SUCCESS; /* create output directory is not already existing */ mkdir(obj->output_file_path, S_IRWXU | S_IRWXG | S_IRWXO); for(curFileNum = obj->start_fileno; curFileNum <= obj->end_fileno; curFileNum++) { snprintf(input_file_name, APP_MAX_FILE_PATH, "%s/%s%05d.png", obj->input_file_path, obj->input_file_prefix, curFileNum ); snprintf(output_file_name_img, APP_MAX_FILE_PATH, "%s/%s_ldc_%05d.png", obj->output_file_path, obj->output_file_prefix, curFileNum ); printf(" %d of %d: Loading [%s] ...\n", curFileNum, obj->end_fileno, input_file_name); tivx_utils_load_vximage_from_pngfile(obj->input_img, input_file_name, vx_true_e); printf(" %d of %d: Running graph ...\n", curFileNum, obj->end_fileno); status = vxScheduleGraph(obj->graph); APP_ASSERT(status==VX_SUCCESS); status = vxWaitGraph(obj->graph); APP_ASSERT(status==VX_SUCCESS); printf(" %d of %d: Saving [%s] ...\n", curFileNum, obj->end_fileno, output_file_name_img); tivx_utils_save_vximage_to_pngfile(output_file_name_img, obj->ldc_img); printf(" %d of %d: Done !!!\n", curFileNum, obj->end_fileno); } return status; } #endif static vx_status app_load_vximage_mesh_from_text_file(char *filename, vx_image image) { vx_uint32 width, height; vx_imagepatch_addressing_t image_addr; vx_rectangle_t rect; vx_map_id map_id; vx_df_image df; void *data_ptr; vx_status status; status = vxGetStatus((vx_reference)image); if(status==VX_SUCCESS) { vxQueryImage(image, VX_IMAGE_WIDTH, &width, sizeof(vx_uint32)); vxQueryImage(image, VX_IMAGE_HEIGHT, &height, sizeof(vx_uint32)); vxQueryImage(image, VX_IMAGE_FORMAT, &df, sizeof(vx_df_image)); rect.start_x = 0; rect.start_y = 0; rect.end_x = width; rect.end_y = height; status = vxMapImagePatch(image, &rect, 0, &map_id, &image_addr, &data_ptr, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST, VX_NOGAP_X ); printf("dim_x %d dim_y %d stride_y %d\n",image_addr.dim_x,image_addr.dim_y, image_addr.stride_y); #if 0 int x,y; for(y=0; y < image_addr.dim_y; y++) { uint32_t *data = (uint32_t*)data_ptr + (image_addr.stride_y/4)*y; for(x=0; x < image_addr.dim_x; x++) { data[x] = 0; } } #else if(status==VX_SUCCESS) { FILE *fp = fopen(filename,"r"); if(fp!=NULL) { size_t ret; int x,y; int xoffset,yoffset; int deltax,deltay; for(y=0; y < image_addr.dim_y; y++) { uint32_t *data = (uint32_t*)data_ptr + (image_addr.stride_y/4)*y; for(x=0; x < image_addr.dim_x; x++) { ret = fscanf(fp, "%d %d", &xoffset, &yoffset); if(ret!=2) { printf("# ERROR: Unable to read data from file [%s]\n", filename); } deltax = xoffset*2-x*8; deltay = yoffset*2-y*8; data[x] = (deltay<<16)|(deltax&0xffff); /* if(y==26) { printf("y=26 x=%d xof=%d yof=%d dx=%d dy=%d dx=%x dy=%x data[x]=%x \n", x,xoffset,yoffset, deltax,deltay, deltax,deltay,data[x]); }*/ } } fclose(fp); } else { printf("# ERROR: Unable to open file for reading [%s]\n", filename); status = VX_FAILURE; } vxUnmapImagePatch(image, map_id); } #endif } return status; } static void app_show_usage(int argc, char* argv[]) { printf("\n"); printf(" LDC HWA Demo - (c) Texas Instruments 2018\n"); printf(" ========================================================\n"); printf("\n"); printf(" Usage,\n"); printf(" %s --cfg <config file>\n", argv[0]); printf("\n"); } static void app_set_cfg_default(AppObj *obj) { snprintf(obj->input_file_path,APP_MAX_FILE_PATH, "/home/kedarc/code/j7_cmodels/database/sequence0001/camera002/data"); snprintf(obj->output_file_path,APP_MAX_FILE_PATH, "./ldc_out"); snprintf(obj->input_file_prefix,APP_MAX_FILE_PATH, "00000"); snprintf(obj->output_file_prefix,APP_MAX_FILE_PATH, "00000"); obj->start_fileno = 74; obj->end_fileno = 84; obj->width = 1280; obj->height = 720; obj->width_out = 1280; obj->height_out = 720; } static void app_parse_cfg_file(AppObj *obj, char *cfg_file_name) { FILE *fp = fopen(cfg_file_name, "r"); char line_str[1024]; char *token; if(fp==NULL) { printf("# ERROR: Unable to open config file [%s]\n", cfg_file_name); exit(0); } else { printf("# open config file [%s]\n", cfg_file_name); } while(fgets(line_str, sizeof(line_str), fp)!=NULL) { char s[]=" \t"; if (strchr(line_str, '#')) { continue; } /* get the first token */ token = strtok(line_str, s); if(strcmp(token, "input_file_path")==0) { token = strtok(NULL, s); token[strlen(token)-1]=0; strcpy(obj->input_file_path, token); printf("# input_file_path [%s]\n", obj->input_file_path); } else if(strcmp(token, "output_file_path")==0) { token = strtok(NULL, s); token[strlen(token)-1]=0; strcpy(obj->output_file_path, token); printf("# output_file_path [%s]\n", obj->output_file_path); } else if(strcmp(token, "input_file_prefix")==0) { token = strtok(NULL, s); token[strlen(token)-1]=0; strcpy(obj->input_file_prefix, token); } else if(strcmp(token, "output_file_prefix")==0) { token = strtok(NULL, s); token[strlen(token)-1]=0; strcpy(obj->output_file_prefix, token); } else if(strcmp(token, "input_mesh_file")==0) { token = strtok(NULL, s); token[strlen(token)-1]=0; strcpy(obj->input_mesh_file, token); } else if(strcmp(token, "start_seq")==0) { token = strtok(NULL, s); obj->start_fileno = atoi(token); } else if(strcmp(token, "end_seq")==0) { token = strtok(NULL, s); obj->end_fileno = atoi(token); } else if(strcmp(token, "width_in")==0) { token = strtok(NULL, s); obj->width = atoi(token); } else if(strcmp(token, "height_in")==0) { token = strtok(NULL, s); obj->height = atoi(token); } else if(strcmp(token, "width_out")==0) { token = strtok(NULL, s); obj->width_out = atoi(token); } else if(strcmp(token, "height_out")==0) { token = strtok(NULL, s); obj->height_out = atoi(token); } else if(strcmp(token, "input_file")==0) { token = strtok(NULL, s); token[strlen(token)-1]=0; strcpy(obj->input_file, token); } else if(strcmp(token, "output_file")==0) { token = strtok(NULL, s); token[strlen(token)-1]=0; strcpy(obj->output_file, token); } } fclose(fp); if(obj->width<128) obj->width = 128; if(obj->height<128) obj->height = 128; if(obj->width_out<128) obj->width_out = 128; if(obj->height_out<128) obj->height_out = 128; if(obj->end_fileno < obj->start_fileno) obj->end_fileno = obj->start_fileno; } static void app_parse_cmd_line_args(AppObj *obj, int argc, char *argv[]) { int i; app_set_cfg_default(obj); if(argc==1) { app_show_usage(argc, argv); exit(0); } for(i=0; i<argc; i++) { if(strcmp(argv[i], "--cfg")==0) { i++; if(i>=argc) { app_show_usage(argc, argv); } app_parse_cfg_file(obj, argv[i]); break; } else if(strcmp(argv[i], "--help")==0) { app_show_usage(argc, argv); exit(0); } } }