TDA4VEN-Q1: LDC output image has issues.

Part Number: TDA4VEN-Q1

Tool/software:

Hello:

I encountered some issues while using the LDC kernel on the entry J722s SDK11 platform. The specific details are as follows: I used the capture output (1280*960) with 4 channels as input for LDC. When using the native code with #define LDC_TABLE_WIDTH (1920) and #define LDC_TABLE_HEIGHT (1080), three of the image channels exhibited a blurred section in the middle, while one channel remained normal. However, when using #define LDC_TABLE_WIDTH (1280) and #define LDC_TABLE_HEIGHT (1960), all four output images appeared blurry. Below, I will attach screenshots of the output images for both configurations. The following code snippet shows a simple initialization I performed for LDC:

c
static void set_ldc_default_params(AppObj *obj, LDCObj *ldcObj)
{
        ldcObj->info_Input.width = 1280; //INPUT_CAMERA_WIDTH;
        ldcObj->info_Input.height = 960; //INPUT_CAMERA_HEIGHT;
        ldcObj->info_Input.dataFormat = VX_DF_IMAGE_UYVY;

        ldcObj->info_output.width = 1280; //INPUT_CAMERA_WIDTH;
        ldcObj->info_output.height = 960; //INPUT_CAMERA_HEIGHT;
        ldcObj->info_output.dataFormat = VX_DF_IMAGE_NV12;
}

Below, I will provide the code for app_ldc.c and app_ldc.h. Could you help identify which configurations might be causing this issue?

app_ldc.h
/*
 *
 * Copyright (c) 2020 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.
 *
 */
#ifndef _APP_LDC_MODULE
#define _APP_LDC_MODULE

#include "app_common.h"

/**
 * \defgroup group_vision_apps_modules_ldc LDC Node Module
 *
 * \brief This section contains module APIs for the TIOVX LDC node tivxVpacLdcNode
 *
 * \ingroup group_vision_apps_modules
 *
 * @{
 */

// #include "app_modules.h"
// #include "app_sensor_module.h"
//#include <TI/hwa_vpac_ldc.h>
#include "app_common.h"

/** \brief Default LDC table width.  Can be modified as needed for use case
 *
 */
#define LDC_TABLE_WIDTH     (1920)

/** \brief Default LDC table width.  Can be modified as needed for use case
 *
 */
#define LDC_TABLE_HEIGHT    (1080)

/** \brief Default LDC downscale factor.  Can be modified as needed for use case
 *
 */
#define LDC_DS_FACTOR       (2)

/** \brief Default LDC block width.  Can be modified as needed for use case
 *
 */
#define LDC_BLOCK_WIDTH     (64)

/** \brief Default LDC block height.  Can be modified as needed for use case
 *
 */
#define LDC_BLOCK_HEIGHT    (32)

/** \brief Default LDC pixel padding.  Can be modified as needed for use case
 *
 */
#define LDC_PIXEL_PAD       (1)

#define APP_MODULES_MAX_OBJ_NAME_SIZE    (512)

/** \brief LDC Module Data Structure
 *
 * Contains the data objects required to use tivxVpacLdcNode
 *
 */
typedef struct {
  
     ImgObjInfo info_Input;

     ImgObjInfo info_output;

     vx_object_array arr_Input[MAX_NUM_BUFS];

      vx_image img_Input[MAX_NUM_BUFS];
      vx_image img_Output[MAX_NUM_BUFS];

    /*! LDC node object */
    vx_node node;

    /*! LDC mesh image */
    vx_image mesh_img;

    /*! LDC node params structure to initialize config object */
    tivx_vpac_ldc_params_t params;

    /*! User data object for config parameter, used as node parameter of LDC node */
    vx_user_data_object config;

    /*! LDC mesh params structure to initialize mesh config object */
    tivx_vpac_ldc_mesh_params_t   mesh_params;

    /*! User data object for mesh config, used as node parameter of LDC node */
    vx_user_data_object mesh_config;

    /*! LDC region params structure to initialize region params config object */
    tivx_vpac_ldc_region_params_t region_params;

    /*! User data object for region config, used as node parameter of LDC node */
    vx_user_data_object region_config;

    /*! User data object for DCC config parameter, used as node parameter of LDC node */
    vx_user_data_object dcc_config;

    /*! LDC table width, set to \ref LDC_TABLE_WIDTH  */
    vx_uint32 table_width;

    /*! LDC table height, set to \ref LDC_TABLE_HEIGHT  */
    vx_uint32 table_height;

    /*! LDC downscale factor, set to \ref LDC_DS_FACTOR  */
    vx_uint32 ds_factor;

    /*! Output object array of LDC node  */
    //vx_object_array output_arr;
    vx_object_array output_arr[MAX_NUM_BUFS];

    /*! Flag to enable writing LDC output  */
    vx_int32 en_out_ldc_write;

    /*! Node used to write LDC output */
    vx_node write_node;

    /*! File path used to write LDC node output */
    vx_array file_path;

    /*! File path prefix used to write LDC node output */
    vx_array file_prefix;

    /*! User data object containing write cmd parameters */
    vx_user_data_object write_cmd;

    /*! Output file path for LDC node output */
    vx_char output_file_path[TIVX_FILEIO_FILE_PATH_LENGTH];

    /*! Name of LDC module */
    vx_char objName[APP_MODULES_MAX_OBJ_NAME_SIZE];

    vx_char name_NodeObj[APP_MAX_FILE_PATH];
    vx_char name_Target[APP_MAX_FILE_PATH];

    vx_int32 graph_parameter_index;//图参数索引
}LDCObj;

#ifdef __cplusplus
extern "C" {
#endif

/** \brief LDC module init helper function
 *
 * This LDC init helper function will create all the data objects required to create the LDC
 * node
 *
 * \param [in]  context    OpenVX context which must be created using \ref vxCreateContext
 * \param [out] ldcObj     LDC Module object which gets populated with LDC node data objects
 * \param [in]  sensorObj  Sensor Module object used to initialize LDC data object parameters;
 *                         must be initialized prior to passing to this function
 * \param [in]  objName    String of the name of this object
 *
 * \param [in]  num_cameras_enabled  Number of cameras enabled
 *
 */
vx_status app_init_ldc(vx_context context, LDCObj *ldcObj , uint32_t num_cameras_enabled);

/** \brief LDC module deinit helper function
 *
 * This LDC deinit helper function will release all the data objects created during the \ref app_init_ldc call
 *
 * \param [in,out] ldcObj  LDC Module object which contains LDC node data objects which are released in this function
 *
 */
void app_deinit_ldc(LDCObj *ldcObj);

/** \brief LDC module delete helper function
 *
 * This LDC delete helper function will delete the LDC node and write node that is created during the \ref app_create_graph_ldc call
 *
 * \param [in,out] ldcObj  LDC Module object which contains LDC node objects which are released in this function
 *
 */
void app_delete_ldc(LDCObj *ldcObj);

/** \brief LDC module create helper function
 *
 * This LDC create helper function will create the node using all the data objects created during the \ref app_init_ldc call.
 * Internally calls \ref app_create_graph_ldc_write_output if en_out_ldc_write is set
 *
 * \param [in]     graph      OpenVX graph that has been created using \ref vxCreateGraph and where the LDC node is created
 * \param [in,out] ldcObj     LDC Module object which contains LDC node and write node which are created in this function
 * \param [in]     input_arr  Input object array to LDC node.  Must be created separately using \ref vxCreateObjectArray
 * \param [in]     target     The name of the target (ASCII string) on which the node executes.
 *
 */
vx_status app_create_graph_ldc(vx_graph graph, LDCObj *ldcObj, vx_object_array input_arr, const char *target);

/** \brief LDC module write output helper function
 *
 * This LDC create helper function will create the node for writing the LDC output
 *
 * \param [in]     graph   OpenVX graph
 * \param [in,out] ldcObj  LDC Module object which contains LDC node and write node which are created in this function
 *
 */
//vx_status app_create_graph_ldc_write_output(vx_graph graph, LDCObj *ldcObj);

void add_graph_parameter_by_num(vx_graph graph, vx_node node);

/** \brief LDC module write output helper function
 *
 * This LDC create helper function will create the node for writing the LDC output
 *
 * \param [in] ldcObj        LDC Module object which contains the write node used in this function
 * \param [in] start_frame   Starting frame to write
 * \param [in] num_frames    Total number of frames to write
 * \param [in] num_skip      Number of capture frames to skip writing
 *
 */
//vx_status app_send_cmd_ldc_write_node(LDCObj *ldcObj, vx_uint32 start_frame, vx_uint32 num_frames, vx_uint32 num_skip);
#ifdef __cplusplus
}
#endif

/* @} */

#endif


app_ldc.c
/*
 *
 * Copyright (c) 2020 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 "app_ldc_module.h"
#include "ldc_lut_1920x1080.h"
#include "app_pics_io_module.h"

static uint8_t  g_ldc_lut[] = LDC_LUT_1920_1080;
#if 0
static vx_status configure_dcc_params(vx_context context, LDCObj *ldcObj, SensorObj *sensorObj)
{
    vx_status status = VX_SUCCESS;

    if(sensorObj->sensor_dcc_enabled)
    {
        int32_t dcc_buff_size;
        uint8_t * dcc_buf;
        vx_map_id dcc_buf_map_id;

        dcc_buff_size = appIssGetDCCSizeLDC(sensorObj->sensor_name, sensorObj->sensor_wdr_enabled);

        if (dcc_buff_size > 0)
        {
            ldcObj->dcc_config = vxCreateUserDataObject(context, "dcc_ldc", dcc_buff_size, NULL );
            status = vxGetStatus((vx_reference)ldcObj->dcc_config);

            if(status == VX_SUCCESS)
            {
                vxSetReferenceName((vx_reference)ldcObj->dcc_config, "ldc_node_dcc_config");

                vxMapUserDataObject(
                        ldcObj->dcc_config, 0,
                        dcc_buff_size,
                        &dcc_buf_map_id,
                        (void **)&dcc_buf,
                        VX_WRITE_ONLY,
                        VX_MEMORY_TYPE_HOST, 0);

                status = appIssGetDCCBuffLDC(sensorObj->sensor_name, sensorObj->sensor_wdr_enabled,  dcc_buf, dcc_buff_size);
                if(status != VX_SUCCESS)
                {
                    printf("[LDC-MODULE] Error getting DCC buffer \n");
                }
                vxUnmapUserDataObject(ldcObj->dcc_config, dcc_buf_map_id);
            }
            else
            {
                printf("[LDC-MODULE] Unable to create DCC config object! \n");
            }
        }
    }
    else
    {
        ldcObj->dcc_config = NULL;
    }

    return status;
}
#endif
static vx_status configure_mesh_params(vx_context context, LDCObj *ldcObj)
{
    vx_status status = VX_SUCCESS;

    vx_uint32 table_width_ds, table_height_ds;
    vx_imagepatch_addressing_t image_addr;
    vx_rectangle_t rect;

    table_width_ds = (((ldcObj->table_width / (1 << ldcObj->ds_factor)) + 1u) + 15u) & (~15u);
    table_height_ds = ((ldcObj->table_height / (1 << ldcObj->ds_factor)) + 1u);

    /* Mesh Image */
    ldcObj->mesh_img = vxCreateImage(context, table_width_ds, table_height_ds, VX_DF_IMAGE_U32);
    status = vxGetStatus((vx_reference)ldcObj->mesh_img);

    if(status == VX_SUCCESS)
    {
        vxSetReferenceName((vx_reference)ldcObj->mesh_img, "ldc_node_mesh_img");

        /* Copy Mesh table */
        rect.start_x = 0;
        rect.start_y = 0;
        rect.end_x = table_width_ds;
        rect.end_y = table_height_ds;

        image_addr.dim_x = table_width_ds;
        image_addr.dim_y = table_height_ds;
        image_addr.stride_x = 4u;
        image_addr.stride_y = table_width_ds * 4u;

        status = vxCopyImagePatch(ldcObj->mesh_img,
                                &rect, 0,
                                &image_addr,
                                g_ldc_lut,
                                VX_WRITE_ONLY,
                                VX_MEMORY_TYPE_HOST);
        if (status == VX_SUCCESS)
        {
            /* Mesh Parameters */
            memset(&ldcObj->mesh_params, 0, sizeof(tivx_vpac_ldc_mesh_params_t));

            tivx_vpac_ldc_mesh_params_init(&ldcObj->mesh_params);

            ldcObj->mesh_params.mesh_frame_width  = ldcObj->table_width;
            ldcObj->mesh_params.mesh_frame_height = ldcObj->table_height;
            ldcObj->mesh_params.subsample_factor  = ldcObj->ds_factor;

            ldcObj->mesh_config = vxCreateUserDataObject(context, "tivx_vpac_ldc_mesh_params_t", sizeof(tivx_vpac_ldc_mesh_params_t), NULL);
            status = vxGetStatus((vx_reference)ldcObj->mesh_config);

            if(status == VX_SUCCESS)
            {
                vxSetReferenceName((vx_reference)ldcObj->mesh_config, "ldc_node_mesh_config");

                status = vxCopyUserDataObject(ldcObj->mesh_config, 0,
                                    sizeof(tivx_vpac_ldc_mesh_params_t),
                                    &ldcObj->mesh_params,
                                    VX_WRITE_ONLY,
                                    VX_MEMORY_TYPE_HOST);
                if(status != VX_SUCCESS)
                {
                    printf("[LDC-MODULE] Unable to copy mesh params into buffer! \n");
                }
            }
            else
            {
                printf("[LDC-MODULE] Unable to create mesh config object! \n");
            }
        }
        else
        {
            printf("[LDC-MODULE] Unable to copy mesh image! \n");
        }
    }
    else
    {
        printf("[LDC-MODULE] Unable to create mesh image! \n");
    }

    return status;
}

static vx_status configure_region_params(vx_context context, LDCObj *ldcObj)
{
    vx_status status = VX_SUCCESS;

    /* Block Size parameters */
    ldcObj->region_params.out_block_width  = LDC_BLOCK_WIDTH;
    ldcObj->region_params.out_block_height = LDC_BLOCK_HEIGHT;
    ldcObj->region_params.pixel_pad        = LDC_PIXEL_PAD;
    ldcObj->region_params.enable        = 1;

    ldcObj->region_config = vxCreateUserDataObject(context, "tivx_vpac_ldc_region_params_t", sizeof(tivx_vpac_ldc_region_params_t),  NULL);
    status = vxGetStatus((vx_reference)ldcObj->region_config);

    if(status == VX_SUCCESS)
    {
        vxSetReferenceName((vx_reference)ldcObj->region_config, "ldc_node_region_config");

        status = vxCopyUserDataObject(ldcObj->region_config, 0,
                            sizeof(tivx_vpac_ldc_region_params_t),
                            &ldcObj->region_params,
                            VX_WRITE_ONLY,
                            VX_MEMORY_TYPE_HOST);
        if(status != VX_SUCCESS)
        {
            printf("[LDC-MODULE] Unable to copy ldc region params to buffer! \n");
        }
    }
    else
    {
        printf("[LDC-MODULE] Unable to create region config object! \n");
    }

    return status;
}

static vx_status configure_ldc_params(vx_context context, LDCObj *ldcObj)
{
    vx_status status = VX_SUCCESS;
    vx_uint32 dccId = 0;
    /* LDC Configuration */
    tivx_vpac_ldc_params_init(&ldcObj->params);
    ldcObj->params.luma_interpolation_type = 1;
    ldcObj->params.dcc_camera_id = dccId;

    ldcObj->config = vxCreateUserDataObject(context, "tivx_vpac_ldc_params_t", sizeof(tivx_vpac_ldc_params_t), NULL);
    status = vxGetStatus((vx_reference)ldcObj->config);

    if(status == VX_SUCCESS)
    {
        vxSetReferenceName((vx_reference)ldcObj->config, "ldc_node_config");

        status = vxCopyUserDataObject(ldcObj->config, 0,
                            sizeof(tivx_vpac_ldc_params_t),
                            &ldcObj->params,
                            VX_WRITE_ONLY,
                            VX_MEMORY_TYPE_HOST);
        // if(status != VX_SUCCESS)
        // {
        //     printf("[LDC-MODULE] Unable to copy ldc config params into buffer! \n");
        // }
    }
    // else
    // {
    //     printf("[LDC-MODULE] Unable to create ldc params object! \n");
    // }

    return status;
}

static vx_status create_ldc_outputs(vx_context context, LDCObj *ldcObj, uint32_t num_cameras_enabled)
{
    vx_status status = VX_SUCCESS;

    /* LDC Output image in NV12 format */ 
    vx_image output_img = vxCreateImage(context, ldcObj->table_width, ldcObj->table_height, VX_DF_IMAGE_NV12);
    //vx_image output_img = vxCreateImage(context, ldcObj->info_output.width,  ldcObj->info_output.height, VX_DF_IMAGE_NV12);
    status = vxGetStatus((vx_reference)output_img);
    if(status == VX_SUCCESS)
    {
         for (vx_uint32 buf_id = 0; buf_id < MAX_NUM_BUFS && buf_id < num_cameras_enabled; buf_id++)
         {
            printf("----------------create_ldc_outputs---------------\n");
            printf("------num_cameras_enabled = %d-----\n",num_cameras_enabled);
            ldcObj->output_arr[buf_id] = vxCreateObjectArray(context, (vx_reference)output_img, num_cameras_enabled);
            
        // ldcObj->output_arr = vxCreateObjectArray(context, (vx_reference)output_img, num_cameras_enabled);
            //vxReleaseImage(&output_img);

            if (vxGetStatus((vx_reference)ldcObj->output_arr[buf_id]) != VX_SUCCESS)
            {
                printf("ldcObj->output_arr[buf_id] creat failed\n");
                return VX_FAILURE;
            }
            else{
                     printf("----------------create_ldc_img_Output---------------\n");
                ldcObj->img_Output[buf_id] = (vx_image)vxGetObjectArrayItem( ldcObj->output_arr[buf_id],0);
                if(vxGetStatus((vx_reference)ldcObj->img_Output[buf_id]) != VX_SUCCESS)
                {
                     printf("ldcObj->img_Output[buf_id] creat failed\n");
                     status = VX_FAILURE;
                }
            }
        }
        // if(status = VX_SUCCESS)
        // {
        //     printf("[LDC-MODULE] Unable to create output image array! \n");
        // }
        // else
        // {
        //     vxSetReferenceName((vx_reference)ldcObj->output_arr, "ldc_node_output_arr");
        // }
    }
    vxReleaseImage(&output_img);
    // else
    // {
    //     printf("[LDC-MODULE] Unable to create output image! \n");
    // }

    // if(ldcObj->en_out_ldc_write == 0)
    // {
    //     char file_path[TIVX_FILEIO_FILE_PATH_LENGTH];
    //     char file_prefix[TIVX_FILEIO_FILE_PREFIX_LENGTH];

    //     strcpy(file_path, ldcObj->output_file_path);
    //     ldcObj->file_path   = vxCreateArray(context, VX_TYPE_UINT8, TIVX_FILEIO_FILE_PATH_LENGTH);
    //     status = vxGetStatus((vx_reference)ldcObj->file_path);
    //     if(status == VX_SUCCESS)
    //     {
    //         vxSetReferenceName((vx_reference)ldcObj->file_path, "ldc_write_node_file_path");

    //         vxAddArrayItems(ldcObj->file_path, TIVX_FILEIO_FILE_PATH_LENGTH, &file_path[0], 1);
    //     }
    //     else
    //     {
    //         printf("[LDC-MODULE] Unable to create file path object for writing outputs! \n");
    //     }

    //     strcpy(file_prefix, "ldc_output");
    //     ldcObj->file_prefix = vxCreateArray(context, VX_TYPE_UINT8, TIVX_FILEIO_FILE_PREFIX_LENGTH);
    //     status = vxGetStatus((vx_reference)ldcObj->file_prefix);
    //     if(status == VX_SUCCESS)
    //     {
    //         vxSetReferenceName((vx_reference)ldcObj->file_prefix, "ldc_write_node_file_prefix");

    //         vxAddArrayItems(ldcObj->file_prefix, TIVX_FILEIO_FILE_PREFIX_LENGTH, &file_prefix[0], 1);
    //     }
    //     else
    //     {
    //         printf("[LDC-MODULE] Unable to create file prefix object for writing outputs! \n");
    //     }

    //     ldcObj->write_cmd = vxCreateUserDataObject(context, "tivxFileIOWriteCmd", sizeof(tivxFileIOWriteCmd), NULL);
    //     status = vxGetStatus((vx_reference)ldcObj->write_cmd);
    //     if(status != VX_SUCCESS)
    //     {
    //         printf("[LDC-MODULE] Unable to create file write cmd object! \n");
    //     }
    //     else
    //     {
    //         vxSetReferenceName((vx_reference)ldcObj->write_cmd, "ldc_write_node_write_cmd");
    //     }
    // }
    // else
    // {
    //     ldcObj->file_path   = NULL;
    //     ldcObj->file_prefix = NULL;
    //     ldcObj->write_node  = NULL;
    //     ldcObj->write_cmd   = NULL;
    // }

    return status;
}
vx_status app_init_ldc(vx_context context, LDCObj *ldcObj , uint32_t num_cameras_enabled)
{
    vx_status status = VX_SUCCESS;

    ldcObj->table_width  = LDC_TABLE_WIDTH;
    ldcObj->table_height = LDC_TABLE_HEIGHT;
    ldcObj->ds_factor    = LDC_DS_FACTOR;

    // ldcObj->info_Input.width = 1280;
    // ldcObj->info_Input.height = 960;
    // ldcObj->info_Input.dataFormat = VX_DF_IMAGE_NV12;

    // ldcObj->info_Output1.width = 1280;
    // ldcObj->info_Output1.height = 960;
    // ldcObj->info_Output1.dataFormat = VX_DF_IMAGE_NV12;


    // strcpy(ldcObj->name_NodeObj, "LDCNode");
    // strcpy(ldcObj->name_Target, TIVX_TARGET_VPAC_LDC1);

    //status = configure_dcc_params(context, ldcObj, sensorObj);

    if(status == VX_SUCCESS)
    {
        status = configure_mesh_params(context, ldcObj);
    }

    if(status == VX_SUCCESS)
    {
        status = configure_region_params(context, ldcObj);
    }

    if(status == VX_SUCCESS)
    {
        status = configure_ldc_params(context, ldcObj);
    }

    if(status == VX_SUCCESS)
    {
        status = create_ldc_outputs(context, ldcObj, num_cameras_enabled);
    }

    vx_image input_img = vxCreateImage(context, ldcObj->info_Input.width, ldcObj->info_Input.height, ldcObj->info_Input.dataFormat);
    vx_int32 i = 0;

    for (i=0; i<MAX_NUM_BUFS; i++)
    {
        ldcObj->arr_Input[i] = vxCreateObjectArray(context, (vx_reference)input_img, num_cameras_enabled);
        ldcObj->img_Input[i] = (vx_image)vxGetObjectArrayItem(ldcObj->arr_Input[i], 0);
        APP_ASSERT_VALID_REF(ldcObj->img_Input[i]);
    }

    vx_image output_img = vxCreateImage(context, ldcObj->info_output.width, ldcObj->info_output.height, ldcObj->info_output.dataFormat);

    vxReleaseImage(&output_img);

    vxReleaseImage(&input_img);

    return (status);
}

void app_deinit_ldc(LDCObj *ldcObj)
{
    vxReleaseUserDataObject(&ldcObj->config);
    vxReleaseUserDataObject(&ldcObj->region_config);
    vxReleaseUserDataObject(&ldcObj->mesh_config);

    vxReleaseImage(&ldcObj->mesh_img);
    vxReleaseObjectArray(&ldcObj->output_arr);

    if(ldcObj->dcc_config != NULL)
    {
        vxReleaseUserDataObject(&ldcObj->dcc_config);
    }
    // if(ldcObj->en_out_ldc_write == 0)
    // {
    //     vxReleaseArray(&ldcObj->file_path);
    //     vxReleaseArray(&ldcObj->file_prefix);
    //     vxReleaseUserDataObject(&ldcObj->write_cmd);
    // }
}

void app_delete_ldc(LDCObj *ldcObj)
{
    if(ldcObj->node != NULL)
    {
        vxReleaseNode(&ldcObj->node);
    }
    if(ldcObj->write_node != NULL)
    {
        vxReleaseNode(&ldcObj->write_node);
    }
}

vx_status app_create_graph_ldc(vx_graph graph, LDCObj *ldcObj, vx_object_array input_arr, const char *target)
{
    vx_status status = VX_SUCCESS;

    if (ldcObj->dcc_config != NULL)
    {
        printf("-----------------dcc_config-----------------\n");
        vx_image input_img = (vx_image)vxGetObjectArrayItem(input_arr, 0);
        vx_image output_img = (vx_image)vxGetObjectArrayItem(ldcObj->output_arr[0], 0);

        ldcObj->node = tivxVpacLdcNode(graph, ldcObj->config, NULL,
                                       NULL, NULL,
                                       NULL, ldcObj->dcc_config, input_img,
                                       output_img, NULL);

        vxReleaseImage(&input_img);
        vxReleaseImage(&output_img);

        status = vxGetStatus((vx_reference)ldcObj->node);
        if(status == VX_SUCCESS)
        {
            vxSetReferenceName((vx_reference)ldcObj->node, "ldc_node");
            vxSetNodeTarget(ldcObj->node, VX_TARGET_STRING, target);

            // vx_bool replicate[] = { vx_false_e, vx_false_e, vx_false_e, vx_false_e, vx_false_e, vx_false_e, vx_true_e, vx_true_e, vx_false_e};
            // vxReplicateNode(graph, ldcObj->node, replicate, 9);
        }
        // else
        // {
        //     printf("[LDC-MODULE] Unable to create LDC node with DCC config! \n");
        // }

    }
    else
    {
         printf("-----------------tivxVpacLdcNode-----------------\n");
        vx_image input_img = (vx_image)vxGetObjectArrayItem(input_arr, 0);
        vx_image output_img = (vx_image)vxGetObjectArrayItem(ldcObj->output_arr[0], 0);

        ldcObj->node = tivxVpacLdcNode(graph, ldcObj->config, NULL,
                                    ldcObj->region_config, ldcObj->mesh_config,
                                    ldcObj->mesh_img, NULL, input_img,
                                    output_img, NULL);

        vxReleaseImage(&input_img);
        vxReleaseImage(&output_img);

        status = vxGetStatus((vx_reference)ldcObj->node);

        if(status == VX_SUCCESS)
        {
            vxSetReferenceName((vx_reference)ldcObj->node, "ldc_node");
            vxSetNodeTarget(ldcObj->node, VX_TARGET_STRING, TIVX_TARGET_VPAC_LDC1);

            vx_bool replicate[] = { vx_false_e, vx_false_e, vx_false_e, vx_false_e, vx_false_e, vx_false_e, vx_true_e, vx_true_e, vx_false_e};
            vxReplicateNode(graph, ldcObj->node, replicate, 9);
        }
        // else
        // {
        //     printf("[LDC-MODULE] Unable to create LDC node without DCC config! \n");
        // }
    }

    // if(ldcObj->en_out_ldc_write == 0)
    // {
    //     status = app_create_graph_ldc_write_output(graph, ldcObj);
    // }

    return status;
}

 void add_graph_parameter_by_num(vx_graph graph, vx_node node)
{
    //if (m_ConvertArmv8Obj.node != NULL)
   // {
        vx_parameter parameter = vxGetParameterByIndex(node, 7);//只有第3个参数支持添加到graph;第一个是config添加图参数没有意义。
        vxAddParameterToGraph(graph, parameter);
        vxReleaseParameter(&parameter);
   // }
}

// vx_status app_create_graph_ldc_write_output(vx_graph graph, LDCObj *ldcObj)
// {
//     vx_status status = VX_SUCCESS;

//     vx_image output_img = (vx_image)vxGetObjectArrayItem(ldcObj->output_arr, 0);
//     ldcObj->write_node = tivxWriteImageNode(graph, output_img, ldcObj->file_path, ldcObj->file_prefix);
//     vxReleaseImage(&output_img);

//     status = vxGetStatus((vx_reference)ldcObj->write_node);
//     if(status == VX_SUCCESS)
//     {
//         vxSetReferenceName((vx_reference)ldcObj->write_node, "ldc_write_node");
//         vxSetNodeTarget(ldcObj->write_node, VX_TARGET_STRING, TIVX_TARGET_MPU_0);

//         vx_bool replicate[] = { vx_true_e, vx_false_e, vx_false_e};
//         vxReplicateNode(graph, ldcObj->write_node, replicate, 3);
//     }
//     else
//     {
//         printf("[LDC-MODULE] Unable to create node to write LDC output! \n");
//     }

//     return (status);
// }

// vx_status app_send_cmd_ldc_write_node(LDCObj *ldcObj, vx_uint32 start_frame, vx_uint32 num_frames, vx_uint32 num_skip)
// {
//     vx_status status = VX_SUCCESS;

//     tivxFileIOWriteCmd write_cmd;

//     write_cmd.start_frame = start_frame;
//     write_cmd.num_frames = num_frames;
//     write_cmd.num_skip = num_skip;

//     status = vxCopyUserDataObject(ldcObj->write_cmd, 0, sizeof(tivxFileIOWriteCmd),\
//                   &write_cmd, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST);

//     if(status == VX_SUCCESS)
//     {
//         vx_reference refs[2];

//         refs[0] = (vx_reference)ldcObj->write_cmd;

//         status = tivxNodeSendCommand(ldcObj->write_node, TIVX_CONTROL_CMD_SEND_TO_ALL_REPLICATED_NODES,
//                                  TIVX_FILEIO_CMD_SET_FILE_WRITE,
//                                  refs, 1u);

//         if(VX_SUCCESS != status)
//         {
//             printf("LDC Node send command failed!\n");
//         }

//         APP_PRINTF("LDC node send command success!\n");
//     }

//     return (status);
// }