commit aff2a0fb1dce0d0d66451b1241aa74aa84193484
Author: Nikhil Dasan <n-dasan@ti.com>
Date:   Mon Dec 11 15:55:46 2023 +0530

    Dual cam
    
    Signed-off-by: Nikhil Dasan <n-dasan@ti.com>

diff --git a/apps/basic_demos/app_single_cam/app_single_cam_common.h b/apps/basic_demos/app_single_cam/app_single_cam_common.h
index bad9c78..44573e8 100755
--- a/apps/basic_demos/app_single_cam/app_single_cam_common.h
+++ b/apps/basic_demos/app_single_cam/app_single_cam_common.h
@@ -179,6 +179,20 @@ typedef struct {
 
     app_perf_point_t total_perf;
     char *sensor_name;
+
+    vx_graph graph1;
+    vx_object_array cap_frames1[MAX_NUM_BUF];
+    vx_node capture_node1;
+    tivx_display_params_t display_params1;
+    vx_user_data_object display_param_obj1;
+    vx_image display_image1;
+    vx_node displayNode1;
+    char *sensor_name1;
+    vx_uint8 selectedCam1;/*0-7*/
+    tivx_task task1;
+    uint32_t stop_task_done1;
+    uint32_t stop_task1;
+
 #ifdef x86_64
 	char test_folder_root[APP_MAX_FILE_PATH];
     char dcc_path[APP_MAX_FILE_PATH];
diff --git a/apps/basic_demos/app_single_cam/app_single_cam_main.c b/apps/basic_demos/app_single_cam/app_single_cam_main.c
index 3d44b46..3ccd0e7 100755
--- a/apps/basic_demos/app_single_cam/app_single_cam_main.c
+++ b/apps/basic_demos/app_single_cam/app_single_cam_main.c
@@ -73,7 +73,9 @@
 
 static char availableSensorNames[ISS_SENSORS_MAX_SUPPORTED_SENSOR][ISS_SENSORS_MAX_NAME];
 static vx_uint8 num_sensors_found;
+static char* sensor_list[ISS_SENSORS_MAX_SUPPORTED_SENSOR];
 static IssSensor_CreateParams sensorParams;
+static IssSensor_CreateParams sensorParams1;
 
 #define NUM_CAPT_CHANNELS   (4u)
 
@@ -104,7 +106,6 @@ void add_graph_parameter_by_node_index(vx_graph graph, vx_node node, vx_uint32 n
 vx_status app_init(AppObj *obj)
 {
     vx_status status = VX_SUCCESS;
-    char* sensor_list[ISS_SENSORS_MAX_SUPPORTED_SENSOR];
     vx_uint8 count = 0;
     char ch = 0xFF;
     vx_uint8 selectedSensor = 0xFF;
@@ -165,7 +166,7 @@ vx_status app_init(AppObj *obj)
         obj->selectedCam = 0xFF;
         while(obj->selectedCam == 0xFF)
         {
-            printf("Select camera port index 0-%d : ", ISS_SENSORS_MAX_CHANNEL-1);
+            printf("Select RAW camera port index 0-%d : ", ISS_SENSORS_MAX_CHANNEL-1);
             ch = getchar();
             obj->selectedCam = ch - '0';
 
@@ -183,7 +184,7 @@ vx_status app_init(AppObj *obj)
                     printf("%c : %s \n", count+'a', sensor_list[count]);
                 }
 
-                printf("Select a sensor above or press '0' to autodetect the sensor : ");
+                printf("Select a RAW sensor above or press '0' to autodetect the sensor : ");
                 ch = getchar();
                 if(ch == '0')
                 {
@@ -253,8 +254,8 @@ vx_status app_init(AppObj *obj)
     memset(&obj->display_params, 0, sizeof(tivx_display_params_t));
     obj->display_params.opMode = TIVX_KERNEL_DISPLAY_ZERO_BUFFER_COPY_MODE;
     obj->display_params.pipeId = 2;
-    obj->display_params.outHeight = 1080;
-    obj->display_params.outWidth = 1920;
+    obj->display_params.outHeight = 540;
+    obj->display_params.outWidth = 960;
     obj->display_params.posX = 0;
     obj->display_params.posY = 0;
 
@@ -265,6 +266,76 @@ vx_status app_init(AppObj *obj)
     return status;
 }
 
+vx_status app_init1(AppObj *obj)
+{
+    vx_status status = VX_SUCCESS;
+    vx_uint8 count = 0;
+    char ch = 0xFF;
+    vx_uint8 selectedSensor = 0xFF;
+
+    obj->stop_task1 = 0;
+    obj->stop_task_done1 = 0;
+    obj->selectedCam1 = 0xFF;
+
+    if(obj->is_interactive)
+    {
+        selectedSensor = 0xFF;
+        obj->selectedCam1 = 0xFF;
+        while(obj->selectedCam1 == 0xFF)
+        {
+            printf("Select YUV camera port index 0-%d : ", ISS_SENSORS_MAX_CHANNEL-1);
+            ch = getchar();
+            obj->selectedCam1 = ch - '0';
+
+            if(obj->selectedCam1 >= ISS_SENSORS_MAX_CHANNEL)
+            {
+                printf("Invalid entry %c. Please choose between 0 and %d \n", ch, ISS_SENSORS_MAX_CHANNEL-1);
+                obj->selectedCam1 = 0xFF;
+            }
+
+            while ((obj->selectedCam1 != 0xFF) && (selectedSensor > (num_sensors_found-1)))
+            {
+                printf("%d registered sensor drivers\n", num_sensors_found);
+                for(count=0;count<num_sensors_found;count++)
+                {
+                    printf("%c : %s \n", count+'a', sensor_list[count]);
+                }
+
+                printf("Select a YUV sensor above : ");
+                ch = getchar();
+                selectedSensor = ch - 'a';
+                if(selectedSensor > (num_sensors_found-1))
+                {
+                    printf("Invalid selection %c. Try again \n", ch);
+                }
+            }
+        }
+
+        obj->sensor_name1 = sensor_list[selectedSensor];
+        printf("Sensor selected : %s\n", obj->sensor_name1);
+    }
+    else
+    {
+        selectedSensor = obj->sensor_sel;
+        if(selectedSensor > (num_sensors_found-1))
+        {
+            printf("Invalid sensor selection %d \n", selectedSensor);
+            return VX_FAILURE;
+        }
+    }
+
+    /* Display initialization */
+    memset(&obj->display_params1, 0, sizeof(tivx_display_params_t));
+    obj->display_params1.opMode = TIVX_KERNEL_DISPLAY_ZERO_BUFFER_COPY_MODE;
+    obj->display_params1.pipeId = 0;
+    obj->display_params1.outHeight = 540;
+    obj->display_params1.outWidth = 960;
+    obj->display_params1.posX = 960;
+    obj->display_params1.posY = 0;
+
+    return status;
+}
+
 vx_status app_deinit(AppObj *obj)
 {
     vx_status status = VX_FAILURE;
@@ -723,8 +794,6 @@ Sensor driver does not support metadata yet.
     }
     else
     {
-        obj->display_params.posX = (1920U - obj->display_params.outWidth)/2;
-        obj->display_params.posY = (1080U - obj->display_params.outHeight)/2;
         obj->display_param_obj = vxCreateUserDataObject(obj->context, "tivx_display_params_t", sizeof(tivx_display_params_t), &obj->display_params);
         obj->displayNode = tivxDisplayNode(obj->graph, obj->display_param_obj, obj->display_image);
     }
@@ -822,6 +891,230 @@ Sensor driver does not support metadata yet.
     APP_PRINTF("app_create_graph exiting\n");
     return status;
 }
+/*
+ * Graph,
+ *
+ * input_yuv_img -----> output_display
+ *
+ */
+vx_status app_create_graph1(AppObj *obj)
+{
+    vx_status status = VX_SUCCESS;
+    int32_t sensor_init_status = -1;
+    obj->display_image1 = NULL;
+
+    unsigned int image_width = obj->width_in;
+    unsigned int image_height = obj->height_in;
+
+    vx_user_data_object capture_config;
+    vx_uint8 num_capture_frames = 1;
+    tivx_capture_params_t local_capture_config;
+    uint32_t buf_id;
+    const vx_char capture_user_data_object_name[] = "tivx_capture_params_t";
+    uint32_t sensor_features_enabled = 0;
+    uint32_t sensor_features_supported = 0;
+
+    vx_image capt_yuv_image = NULL;
+
+    uint8_t channel_mask = (1<<obj->selectedCam1);
+
+    vx_uint32 params_list_depth = 1;
+    if(obj->test_mode == 1)
+    {
+        params_list_depth = 2;
+    }
+    vx_graph_parameter_queue_params_t graph_parameters_queue_params_list[params_list_depth];
+
+    printf("Querying %s \n", obj->sensor_name1);
+    memset(&sensorParams1, 0, sizeof(sensorParams1));
+    status = appQueryImageSensor(obj->sensor_name1, &sensorParams1);
+    if(VX_SUCCESS != status)
+    {
+        printf("appQueryImageSensor returned %d\n", status);
+        return status;
+    }
+
+    /*
+    Check for supported sensor features.
+    It is upto the application to decide which features should be enabled.
+    This demo app enables WDR, DCC and 2A if the sensor supports it.
+    */
+    sensor_features_supported = sensorParams1.sensorInfo.features;
+
+    if(ISS_SENSOR_FEATURE_DCC_SUPPORTED == (sensor_features_supported & ISS_SENSOR_FEATURE_DCC_SUPPORTED))
+    {
+        sensor_features_enabled |= ISS_SENSOR_FEATURE_DCC_SUPPORTED;
+        APP_PRINTF("Sensor DCC is enabled \n");
+    }else
+    {
+        APP_PRINTF("Sensor DCC is NOT enabled \n");
+    }
+
+    APP_PRINTF("Sensor width = %d\n", sensorParams1.sensorInfo.raw_params.width);
+    APP_PRINTF("Sensor height = %d\n", sensorParams1.sensorInfo.raw_params.height);
+    APP_PRINTF("Sensor DCC ID = %d\n", sensorParams1.dccId);
+    APP_PRINTF("Sensor Supported Features = 0x%x\n", sensor_features_supported);
+    APP_PRINTF("Sensor Enabled Features = 0x%x\n", sensor_features_enabled);
+    sensor_init_status = appInitImageSensor(obj->sensor_name1, sensor_features_enabled, channel_mask);/*Mask = 1 for camera # 0*/
+    if(0 != sensor_init_status)
+    {
+        /* Not returning failure because application may be waiting for
+            error/test frame */
+        printf("Error initializing sensor %s \n", obj->sensor_name);
+    }
+
+    image_width     = sensorParams1.sensorInfo.raw_params.width;
+    image_height    = sensorParams1.sensorInfo.raw_params.height;
+    obj->cam_dcc_id = sensorParams1.dccId;
+    obj->width_in = image_width;
+    obj->height_in = image_height;
+
+/*
+Assuming same dataformat for all exposures.
+This may not be true for staggered HDR. WIll be handled later
+    for(count = 0;count<raw_params.num_exposures;count++)
+    {
+        memcpy(&(raw_params.format[count]), &(sensorProperties.sensorInfo.dataFormat), sizeof(tivx_raw_image_format_t));
+    }
+*/
+
+/*
+Sensor driver does not support metadata yet.
+*/
+
+    APP_PRINTF("Creating graph 1 \n");
+
+    obj->graph1 = vxCreateGraph(obj->context);
+    if(status == VX_SUCCESS)
+    {
+        status = vxGetStatus((vx_reference) obj->graph1);
+    }
+
+    APP_PRINTF("Initializing params for capture node \n");
+
+    /* Setting to num buf of capture node */
+    obj->num_cap_buf = NUM_BUFS;
+
+    capt_yuv_image = vxCreateImage(
+                            obj->context,
+                            sensorParams1.sensorInfo.raw_params.width,
+                            sensorParams1.sensorInfo.raw_params.height,
+                            VX_DF_IMAGE_UYVY
+                     );
+
+    /* allocate Input and Output refs, multiple refs created to allow pipelining of graph */
+    for(buf_id=0; buf_id<obj->num_cap_buf; buf_id++)
+    {
+        if(status == VX_SUCCESS)
+        {
+            obj->cap_frames1[buf_id] = vxCreateObjectArray(obj->context, (vx_reference)capt_yuv_image, num_capture_frames);
+            status = vxGetStatus((vx_reference) obj->cap_frames1[buf_id]);
+        }
+    }
+
+    /* Config initialization */
+    tivx_capture_params_init(&local_capture_config);
+
+    local_capture_config.timeout = 33;
+    local_capture_config.timeoutInitial = 500;
+
+    local_capture_config.numInst  = 1U;/* Configure both instances */
+    local_capture_config.numCh = 1U;/* Single cam. Only 1 channel enabled */
+    {
+        vx_uint8 ch, id, lane, q;
+        for(id = 0; id < local_capture_config.numInst; id++)
+        {
+            local_capture_config.instId[id]                       = id;
+            local_capture_config.instCfg[id].enableCsiv2p0Support = (uint32_t)vx_true_e;
+            local_capture_config.instCfg[id].numDataLanes         = sensorParams1.sensorInfo.numDataLanes;
+            local_capture_config.instCfg[id].laneBandSpeed        = sensorParams1.sensorInfo.csi_laneBandSpeed;
+
+            for (lane = 0; lane < local_capture_config.instCfg[id].numDataLanes; lane++)
+            {
+                local_capture_config.instCfg[id].dataLanesMap[lane] = lane + 1;
+            }
+            for (q = 0; q < NUM_CAPT_CHANNELS; q++)
+            {
+                ch = (NUM_CAPT_CHANNELS-1)* id + q;
+                local_capture_config.chVcNum[ch]   = q;
+                local_capture_config.chInstMap[ch] = id;
+            }
+        }
+    }
+
+    local_capture_config.chInstMap[0] = obj->selectedCam1/NUM_CAPT_CHANNELS;
+    local_capture_config.chVcNum[0]   = obj->selectedCam1%NUM_CAPT_CHANNELS;
+
+    capture_config = vxCreateUserDataObject(obj->context, capture_user_data_object_name, sizeof(tivx_capture_params_t), &local_capture_config);
+    APP_PRINTF("capture_config = 0x%p \n", capture_config);
+
+    APP_PRINTF("Creating capture node \n");
+    obj->capture_node1 = tivxCaptureNode(obj->graph1, capture_config, obj->cap_frames1[0]);
+    APP_PRINTF("obj->capture_node = 0x%p \n", obj->capture_node1);
+
+    if(status == VX_SUCCESS)
+    {
+        status = vxReleaseUserDataObject(&capture_config);
+    }
+    if(status == VX_SUCCESS)
+    {
+        status = vxSetNodeTarget(obj->capture_node1, VX_TARGET_STRING, TIVX_TARGET_CAPTURE1);
+    }
+
+    obj->capt_yuv_image = (vx_image)vxGetObjectArrayItem(obj->cap_frames1[0], 0);
+    vxReleaseImage(&capt_yuv_image);
+
+    obj->display_param_obj1 = vxCreateUserDataObject(obj->context, "tivx_display_params_t", sizeof(tivx_display_params_t), &obj->display_params1);
+    obj->displayNode1 = tivxDisplayNode(obj->graph1, obj->display_param_obj1, obj->capt_yuv_image);
+
+
+    if(status == VX_SUCCESS)
+    {
+        status = vxSetNodeTarget(obj->displayNode1, VX_TARGET_STRING, TIVX_TARGET_DISPLAY2);
+        APP_PRINTF("Display Set Target done\n");
+    }
+    int graph_parameter_num = 0;
+
+    /* input @ node index 1, becomes graph parameter 0 */
+    add_graph_parameter_by_node_index(obj->graph1, obj->capture_node1, 1);
+
+    /* set graph schedule config such that graph parameter @ index 0 is enqueuable */
+    graph_parameters_queue_params_list[graph_parameter_num].graph_parameter_index = graph_parameter_num;
+    graph_parameters_queue_params_list[graph_parameter_num].refs_list_size = obj->num_cap_buf;
+    graph_parameters_queue_params_list[graph_parameter_num].refs_list = (vx_reference*)&(obj->cap_frames1[0]);
+    graph_parameter_num++;
+
+    if(status == VX_SUCCESS)
+    {
+        status = tivxSetGraphPipelineDepth(obj->graph1, obj->num_cap_buf);
+    }
+
+    /* Schedule mode auto is used, here we dont need to call vxScheduleGraph
+     * Graph gets scheduled automatically as refs are enqueued to it
+     */
+    if(status == VX_SUCCESS)
+    {
+        status = vxSetGraphScheduleConfig(obj->graph1,
+                        VX_GRAPH_SCHEDULE_MODE_QUEUE_AUTO,
+                        params_list_depth,
+                        graph_parameters_queue_params_list
+                        );
+    }
+    APP_PRINTF("vxSetGraphScheduleConfig done\n");
+
+    if(status == VX_SUCCESS)
+    {
+        status = vxVerifyGraph(obj->graph1);
+    }
+
+    if(status == VX_SUCCESS)
+    {
+        status = tivxExportGraphToDot(obj->graph1, ".", "single_cam_graph");
+    }
+
+    APP_PRINTF("app_create_graph 1 exiting\n");
+    return status;
+}
 
 vx_status app_delete_graph(AppObj *obj)
 {
@@ -873,13 +1166,6 @@ vx_status app_delete_graph(AppObj *obj)
       }
     }
 
-    if(NULL != obj->capt_yuv_image)
-    {
-        APP_PRINTF("releasing capt_yuv_image\n");
-        status |= vxReleaseImage(&obj->capt_yuv_image);
-    }
-
-
     if(NULL != obj->y12)
     {
         APP_PRINTF("releasing y12\n");
@@ -1038,6 +1324,50 @@ vx_status app_delete_graph(AppObj *obj)
     return status;
 }
 
+vx_status app_delete_graph1(AppObj *obj)
+{
+    uint32_t buf_id;
+    vx_status status = VX_SUCCESS;
+
+    if(NULL != obj->capture_node1)
+    {
+        APP_PRINTF("releasing capture node\n");
+        status |= vxReleaseNode(&obj->capture_node1);
+    }
+
+    if(NULL != obj->displayNode1)
+    {
+        APP_PRINTF("releasing displayNode\n");
+        status |= vxReleaseNode(&obj->displayNode1);
+    }
+
+    for(buf_id=0; buf_id<obj->num_cap_buf; buf_id++)
+    {
+       if(NULL != obj->cap_frames1[buf_id])
+       {
+        APP_PRINTF("releasing cap_frame # %d\n", buf_id);
+        status |= vxReleaseObjectArray(&(obj->cap_frames1[buf_id]));
+       }
+    }
+
+    if(NULL != obj->capt_yuv_image)
+    {
+        APP_PRINTF("releasing capt_yuv_image\n");
+        status |= vxReleaseImage(&obj->capt_yuv_image);
+    }
+
+    if(NULL != obj->display_param_obj1)
+    {
+        APP_PRINTF("releasing Display Param Data Object\n");
+        status |= vxReleaseUserDataObject(&obj->display_param_obj1);
+    }
+
+    APP_PRINTF("releasing graph\n");
+    status |= vxReleaseGraph(&obj->graph1);
+    APP_PRINTF("releasing graph done\n");
+    return status;
+}
+
 vx_status app_run_graph(AppObj *obj)
 {
     vx_status status = VX_SUCCESS;
@@ -1183,9 +1513,102 @@ static void app_run_task(void *app_var)
     obj->stop_task_done = 1;
 }
 
+vx_status app_run_graph1(AppObj *obj)
+{
+    vx_status status = VX_SUCCESS;
+    vx_uint32 i;
+    vx_uint32 frm_loop_cnt;
+
+    uint32_t buf_id;
+    uint32_t num_refs_capture;
+    vx_object_array out_capture_frames;
+    int graph_parameter_num = 0;
+
+    uint8_t channel_mask = (1<<obj->selectedCam1);
+
+    if(NULL == obj->sensor_name1)
+    {
+        printf("sensor name is NULL \n");
+        return VX_FAILURE;
+    }
+    status = appStartImageSensor(obj->sensor_name1, channel_mask);
+    if(status < 0)
+    {
+        printf("Failed to start sensor %s \n", obj->sensor_name1);
+    }
+
+    graph_parameter_num = 0;
+    for(buf_id=0; buf_id<obj->num_cap_buf; buf_id++)
+    {
+        if(status == VX_SUCCESS)
+        {
+            status = vxGraphParameterEnqueueReadyRef(obj->graph1, 0, (vx_reference*)&(obj->cap_frames1[buf_id]), 1);
+        }
+    }
+
+    /*
+        The application reads and  processes the same image "frm_loop_cnt" times
+        The output may change because on VISS, parameters are updated every frame based on AEWB results
+        AEWB result is avaialble after 1 frame and is applied after 2 frames
+        Therefore, first 2 output images will have wrong colors
+    */
+    frm_loop_cnt = obj->num_frames_to_run;
+    frm_loop_cnt += obj->num_cap_buf;
+
+    if(obj->is_interactive)
+    {
+        /* in interactive mode loop for ever */
+        frm_loop_cnt  = 0xFFFFFFFF;
+    }
+
+    for(i=0; i<frm_loop_cnt; i++)
+    {
+        appPerfPointBegin(&obj->total_perf);
+        if(status == VX_SUCCESS)
+        {
+            status = vxGraphParameterDequeueDoneRef(obj->graph1, graph_parameter_num, (vx_reference*)&out_capture_frames, 1, &num_refs_capture);
+        }
+        APP_PRINTF(" j %d...\n", i);
+        if(status == VX_SUCCESS)
+        {
+            status = vxGraphParameterEnqueueReadyRef(obj->graph1, graph_parameter_num, (vx_reference*)&out_capture_frames, 1);
+        }
+
+        appPerfPointEnd(&obj->total_perf);
+
+        if((obj->stop_task1) || (status != VX_SUCCESS))
+        {
+            break;
+        }
+    }
+
+    if(status == VX_SUCCESS)
+    {
+        status = vxWaitGraph(obj->graph1);
+    }
+
+    if(status == VX_SUCCESS)
+    {
+        status = appStopImageSensor(obj->sensor_name1, channel_mask);
+    }
+    return status;
+}
+
+static void app_run_task1(void *app_var)
+{
+    AppObj *obj = (AppObj *)app_var;
+
+    appPerfStatsCpuLoadResetAll();
+
+    app_run_graph1(obj);
+
+    obj->stop_task_done1 = 1;
+}
+
 static int32_t app_run_task_create(AppObj *obj)
 {
     tivx_task_create_params_t params;
+    tivx_task_create_params_t params1;
     int32_t status;
 
     tivxTaskSetDefaultCreateParams(&params);
@@ -1196,7 +1619,14 @@ static int32_t app_run_task_create(AppObj *obj)
     obj->stop_task = 0;
 
     status = tivxTaskCreate(&obj->task, &params);
+    tivxTaskSetDefaultCreateParams(&params1);
+    params1.task_main = app_run_task1;
+    params1.app_var = obj;
 
+    obj->stop_task_done1 = 0;
+    obj->stop_task1 = 0;
+
+    status = tivxTaskCreate(&obj->task1, &params1);
     return status;
 }
 
@@ -1208,6 +1638,12 @@ static void app_run_task_delete(AppObj *obj)
     }
 
     tivxTaskDelete(&obj->task);
+    while(obj->stop_task_done1==0)
+    {
+         tivxTaskWaitMsecs(100);
+    }
+
+    tivxTaskDelete(&obj->task1);
 }
 
 static char menu[] = {
@@ -1244,6 +1680,7 @@ static vx_status app_run_graph_interactive(AppObj *obj)
     FILE *fp;
     app_perf_point_t *perf_arr[1];
     uint8_t channel_mask = (1<<obj->selectedCam);
+    uint8_t channel_mask1 = (1<<obj->selectedCam1);
 
     status = app_run_task_create(obj);
     if(status!=0)
@@ -1304,6 +1741,7 @@ static vx_status app_run_graph_interactive(AppObj *obj)
 
                 case 'x':
                     obj->stop_task = 1;
+                    obj->stop_task1 = 1;
                     done = 1;
                     break;
 
@@ -1318,6 +1756,7 @@ static vx_status app_run_graph_interactive(AppObj *obj)
     if(status == VX_SUCCESS)
     {
         status = appStopImageSensor(obj->sensor_name, channel_mask);
+        status |= appStopImageSensor(obj->sensor_name1, channel_mask1);
     }
     return status;
 }
@@ -1625,12 +2064,14 @@ int app_single_cam_main(int argc, char* argv[])
     if(VX_SUCCESS == status)
     {
         status = app_init(obj);
+        status |= app_init1(obj);
         if(VX_SUCCESS == status)
         {
             APP_PRINTF("app_init done\n");
             /* Not checking status because application may be waiting for
                 error/test frame */
             app_create_graph(obj);
+            app_create_graph1(obj);
             if(VX_SUCCESS == status)
             {
                 APP_PRINTF("app_create_graph done\n");
@@ -1646,6 +2087,7 @@ int app_single_cam_main(int argc, char* argv[])
                 {
                     APP_PRINTF("app_run_graph done\n");
                     status = app_delete_graph(obj);
+                    status |= app_delete_graph1(obj);
                     if(VX_SUCCESS == status)
                     {
                         APP_PRINTF("app_delete_graph done\n");
@@ -1679,6 +2121,7 @@ int app_single_cam_main(int argc, char* argv[])
             printf("Error : app_deinit returned 0x%x \n", status);
         }
         appDeInitImageSensor(obj->sensor_name);
+        appDeInitImageSensor(obj->sensor_name1);
     }
     else
     {
