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.

TDA4VM: Support 5 cameras

Part Number: TDA4VM

Hi,

We have four ISX019 cameras connected on CSIRX 0 and one IMX390 camera connected on CSIRX 1 link B. We want to get all five cameras running and showing up on display. ISX019 has resolution of 1280x960 and IMX390 has resolution of 640x480. Because of the different resolutions, my understanding is that I can not use single capture node. I developed the graph with two capture nodes and essentially two instances of each OpenVX node. I also have two display nodes, one with pipe id 0 and another with pipe id 2. I scaled and positioned the images such that both should appear on the display (IMX390 and one of the four cameras from ISX019).

The problem is that the app gets blocked at first call to vxGraphParameterDequeueDoneRef. Please check the attached code and let me know if my approach is correct or there's a better way to do it.

Thanks,

Vibhorvisteon_app_five_cam.zip

  • Here's the CSIRX register status after running the app.

    CSI_RX_IF_VBUS2APB_INFO_IRQS
    /dev/mem opened.
    Memory mapped at address 0xffff879d0000.
    Read at address 0x04504020 (0xffff879d4020): 0x00000000

    CSI_RX_IF_VBUS2APB_ERROR_IRQS
    /dev/mem opened.
    Memory mapped at address 0xffffa8830000.
    Read at address 0x04504028 (0xffffa8834028): 0x00000000

    CSI_RX_IF_VBUS2APB_DPHY_STATUS
    /dev/mem opened.
    Memory mapped at address 0xffff9e460000.
    Read at address 0x04504048 (0xffff9e464048): 0x00333306

    CSI_RX_IF_VBUS2APB_DPHY_LANE_CONTROL
    /dev/mem opened.
    Memory mapped at address 0xffffa59c0000.
    Read at address 0x04504040 (0xffffa59c4040): 0x0001F01F

    CSI_RX_IF_VBUS2APB_DPHY_ERR_STATUS_IRQ
    /dev/mem opened.
    Memory mapped at address 0xffff96a80000.
    Read at address 0x0450404C (0xffff96a8404c): 0x00000000

    CSI_RX_IF_VBUS2APB_DPHY_ERR_IRQ_MASK_CFG
    /dev/mem opened.
    Memory mapped at address 0xffff80410000.
    Read at address 0x04504050 (0xffff80414050): 0x00000000

    CSI_RX_IF_VBUS2APB_ERROR_DEBUG
    /dev/mem opened.
    Memory mapped at address 0xffffb3840000.
    Read at address 0x04504074 (0xffffb3844074): 0x00000000

    CSI_RX_IF_VBUS2APB_STREAM0_CTRL
    /dev/mem opened.
    Memory mapped at address 0xffff80540000.
    Read at address 0x04504100 (0xffff80544100): 0x00000000

    CSI_RX_IF_VBUS2APB_STREAM0_STATUS
    /dev/mem opened.
    Memory mapped at address 0xffff98ec0000.
    Read at address 0x04504104 (0xffff98ec4104): 0x00000100

    CSI_RX_IF_VBUS2APB_STREAM1_CTRL
    /dev/mem opened.
    Memory mapped at address 0xffffb7490000.
    Read at address 0x04504200 (0xffffb7494200): 0x00000000

    CSI_RX_IF_VBUS2APB_STREAM1_STATUS
    /dev/mem opened.
    Memory mapped at address 0xffffaa610000.
    Read at address 0x04504204 (0xffffaa614204): 0x00000100

    CSI_RX_IF_VBUS2APB_STREAM2_CTRL
    /dev/mem opened.
    Memory mapped at address 0xffff876e0000.
    Read at address 0x04504300 (0xffff876e4300): 0x00000000

    CSI_RX_IF_VBUS2APB_STREAM2_STATUS
    /dev/mem opened.
    Memory mapped at address 0xffff87620000.
    Read at address 0x04504304 (0xffff87624304): 0x00000100

    CSI_RX_IF_VBUS2APB_STREAM3_CTRL
    /dev/mem opened.
    Memory mapped at address 0xffffa7530000.
    Read at address 0x04504300 (0xffffa7534300): 0x00000000

    CSI_RX_IF_VBUS2APB_STREAM3_STATUS
    /dev/mem opened.
    Memory mapped at address 0xffffb15a0000.
    Read at address 0x04504304 (0xffffb15a4304): 0x00000100

  • Hi Vibhor,

    Does both of the nodes individually run fine? Could you please first check if you are able to capture from both the instances independently? 

    Meanwhile, i will check the registers.

    Regards,

    Brijesh

  • Hi Brijesh,

    Attaching updated code. With this code we are able to run individual instances independently but when both are enabled then the display remains blank and deque is blocked. I also tried creating two separate graphs `vx_graph   graph[2];` but that did not help, got the same result.

    Regards,

    Vibhor
    visteon_app_five_cam_threads.zip

  • Hi Vibhor,

    I have reviewed your code, it looks fine to me. 

    This remind me that there was a bug in SDK6.2, which does not allow to run two CSI instances independently.  I think the hang that you are seeing, could be due this issue.  This issue is not fixed in SDK7.0 also. 

    I am looking into this issue and will share the fix as soon as possible.

    Rgds,

    Brijesh 

  • Hi Vibhor,

    Can you apply attached patch on tiovx folder and try 5 camera usecase? 

    TIOVX_Capture_Dual_Inst_Fix.zip

    Regards,

    Brijesh

  • Hi Brijesh,

    I think the patch based on some other release, can you provide the patch for 6.2 release ?

  • Hi Mahipal,

    I generated this patch on top of SDK6.2 release. I checked it again, it gets applied cleanly on SDK6.2 release. 

    Wondering, do you have any changes on top of SDK6.2 in capture node? Can you please check?

    Regards,

    Brijesh

  • Hi Brijesh,

    The patch did not work for me. Please see attached app source code and modified vx_capture_target.c file. I have two variants of vx_capture_target.c file, one with the earlier change you had suggested for configuring virtual channel in multi-cam app and another variant without the previous virtual channel change.

    Even with single capture node (sensor0_enabled set to 0 in app.cfg), I wanted to test with capture instance 1 but got following error because instId = 1 and numOfInstUsed = 1.

     

    App Create Graph Done!

    [MCU2_1] 59.277657 s: VX_ZONE_ERROR:[tivxCaptureSetCreateParams:412] CAPTURE: ERROR: Wrong Instance ID provided: 0 !!!
    1.068578 s: VX_ZONE_ERROR:[ownContextSendCmd:553] Command ack message returned failure cmd_status: -1
    1.068585 s: VX_ZONE_ERROR:[ownNodeKernelInit:486] Target kernel, TIVX_CMD_NODE_CREATE failed
    1.068672 s: VX_ZONE_ERROR:[ownGraphNodeKernelInit:583] kernel init for node 0, kernel com.ti.capture ... failed !!!
    1.068682 s: VX_ZONE_ERROR:[vxVerifyGraph:2010] Node kernel init failed
    1.068686 s: VX_ZONE_ERROR:[vxVerifyGraph:2064] Graph verify failed
    Graph 1 verify failed -1


    I modified the condition like this `if (instId > prms->numOfInstUsed)` but now I'm running into following error during graph run.


    [MCU2_1] 55.190546 s:
    [MCU2_1] 55.190597 s: IssSensor_Start status 0
    [MCU2_1] 55.190623 s: ImageSensor_RemoteServiceHandler: IM_SENSOR_CMD_STREAM_ON status 0x0
    [MCU2_1] 55.191011 s: src/fvid2_drvMgr.c @ Line 1193:
    [MCU2_1] 55.191046 s: Number of frames is zero!!
    [MCU2_1] 55.191076 s: src/csirx_drv.c @ Line 410:
    [MCU2_1] 55.191097 s: Check frame list error
    [MCU2_1] 55.191131 s: VX_ZONE_ERROR:[tivxCaptureEnqueueFrameToDriver:286] CAPTURE: ERROR: Frame could not be queued for frame 0 !!!
    [MCU2_1] 55.191184 s: VX_ZONE_ERROR:[tivxCaptureProcess:574] CAPTURE: ERROR: Enqueue Frame to Driver failed !!!
    [MCU2_1] 55.191234 s: VX_ZONE_ERROR:[tivxTargetKernelExecute:372] tivxTargetKernelExecute: Kernel process function for [com.ti.capture] returned error code: -1
    [MCU2_1] 55.191435 s: src/fvid2_drvMgr.c @ Line 1193:
    [MCU2_1] 55.191466 s: Number of frames is zero!!
    [MCU2_1] 55.191493 s: src/csirx_drv.c @ Line 410:
    [MCU2_1] 55.191513 s: Check frame list error
    [MCU2_1] 55.191587 s: VX_ZONE_ERROR:[tivxCaptureEnqueueFrameToDriver:286] CAPTURE: ERROR: Frame could not be queued for frame 0 !!!
    [MCU2_1] 55.191644 s: VX_ZONE_ERROR:[tivxCaptureProcess:574] CAPTURE: ERROR: Enqueue Frame to Driver failed !!!
    [MCU2_1] 55.191692 s: VX_ZONE_ERROR:[tivxTargetKernelExecute:372] tivxTargetKernelExecute: Kernel process function for [com.ti.capture] returned error code: -1
    [MCU2_1] 55.197174 s: src/fvid2_drvMgr.c @ Line 1193:
    [MCU2_1] 55.197209 s: Number of frames is zero!!

     

    So, two questions.

     

    1. Is there any other change I can try?
    2. We no longer need the use-case of setting virtual channel in multi-cam app, can I remove the changes made for vcMapToChIdx?

    Thanks,
    Vibhor

    visteon_app_five_cam_threads_generic.zip

    /*
     *
     * Copyright (c) 2018 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 "VX/vx.h"
    #include "TI/tivx_event.h"
    #include "tivx_hwa_kernels.h"
    #include "tivx_kernel_capture.h"
    #include "TI/tivx_target_kernel.h"
    #include "tivx_kernels_target_utils.h"
    #include "tivx_hwa_capture_priv.h"
    
    #include <TI/tivx_queue.h>
    #include <ti/drv/fvid2/fvid2.h>
    #include <ti/drv/csirx/csirx.h>
    
    #define CAPTURE_FRAME_DROP_LEN                          (4096U*4U)
    
    #define CAPTURE_INST_ID_INVALID                         (0xFFFFU)
    
    typedef struct tivxCaptureParams_t tivxCaptureParams;
    
    typedef struct
    {
        uint32_t instId;
        /**< Csirx Drv Instance ID. */
        uint8_t numCh;
        /**< Number of channels processed on given CSIRX DRV instance. */
        uint32_t chVcMap[TIVX_CAPTURE_MAX_CH];
        /**< Virtual ID for channels for current capture instance. */
        uint32_t vcMapToChIdx[TIVX_CAPTURE_MAX_CH];
        /**< Mapping of VC Map to Channel Index */
        Fvid2_Handle drvHandle;
        /**< FVID2 capture driver handle. */
        Csirx_CreateParams createPrms;
        /**< Csirx create time parameters */
        Csirx_CreateStatus createStatus;
        /**< Csirx create time status */
        Fvid2_CbParams drvCbPrms;
        /**< Capture callback params */
        uint8_t raw_capture;
        /**< flag indicating raw capture */
        Csirx_InstStatus captStatus;
        /**< CSIRX Capture status. */
        Csirx_DPhyCfg dphyCfg;
        /**< CSIRX DPHY configuration. */
        tivxCaptureParams *captParams;
        /**< Reference to capture node parameters. */
    } tivxCaptureInstParams;
    
    struct tivxCaptureParams_t
    {
        tivxCaptureInstParams instParams[TIVX_CAPTURE_MAX_INST];
        /* Capture Instance parameters */
        uint32_t numOfInstUsed;
        /**< Number of CSIRX DRV instances used in current TIOVX Node. */
        uint8_t numCh;
        /**< Number of channels processed on given capture node instance. */
        tivx_obj_desc_t *img_obj_desc[TIVX_CAPTURE_MAX_CH];
        /* Captured Images */
        uint8_t steady_state_started;
        /**< Flag indicating whether or not steady state has begun. */
        tivx_event  frame_available;
        /**< Following Queues i.e. freeFvid2FrameQ, pendingFrameQ, fvid2_free_q_mem,
         *   fvid2Frames, and pending_frame_free_q_mem are for given instance of the
         *   Node. If Node instance contains more than 1 instances of the CSIRX DRV
         *   instances, then first 'n' channels are for first instance of the driver
         *   then n channels for next driver and so on... */
        /**< Event indicating when a frame is available. */
        tivx_queue freeFvid2FrameQ[TIVX_CAPTURE_MAX_CH];
        /**< Internal FVID2 queue */
        tivx_queue pendingFrameQ[TIVX_CAPTURE_MAX_CH];
        /**< Internal pending frame queue */
        uintptr_t fvid2_free_q_mem[TIVX_CAPTURE_MAX_CH][TIVX_CAPTURE_MAX_NUM_BUFS];
        /**< FVID2 queue mem */
        Fvid2_Frame fvid2Frames[TIVX_CAPTURE_MAX_CH][TIVX_CAPTURE_MAX_NUM_BUFS];
        /**< FVID2 frame structs */
        uintptr_t pending_frame_free_q_mem[TIVX_CAPTURE_MAX_CH][TIVX_CAPTURE_MAX_NUM_BUFS];
        /**< pending frame queue mem */
    };
    
    static tivx_target_kernel vx_capture_target_kernel1 = NULL;
    static tivx_target_kernel vx_capture_target_kernel2 = NULL;
    
    static vx_status captDrvCallback(Fvid2_Handle handle, void *appData, void *reserved);
    static uint32_t tivxCaptureExtractInCsiDataType(uint32_t format);
    static uint32_t tivxCaptureExtractCcsFormat(uint32_t format);
    static uint32_t tivxCaptureExtractDataFormat(uint32_t format);
    static vx_status tivxCaptureEnqueueFrameToDriver(
           tivx_obj_desc_object_array_t *output_desc,
           tivxCaptureParams *prms);
    static vx_status tivxCaptureSetCreateParams(
           tivxCaptureParams *prms,
           const tivx_obj_desc_user_data_object_t *obj_desc);
    static vx_status VX_CALLBACK tivxCaptureProcess(
           tivx_target_kernel_instance kernel,
           tivx_obj_desc_t *obj_desc[],
           uint16_t num_params, void *priv_arg);
    static vx_status VX_CALLBACK tivxCaptureCreate(
           tivx_target_kernel_instance kernel,
           tivx_obj_desc_t *obj_desc[],
           uint16_t num_params, void *priv_arg);
    static vx_status VX_CALLBACK tivxCaptureDelete(
           tivx_target_kernel_instance kernel,
           tivx_obj_desc_t *obj_desc[],
           uint16_t num_params, void *priv_arg);
    static vx_status VX_CALLBACK tivxCaptureControl(
           tivx_target_kernel_instance kernel,
           uint32_t node_cmd_id, tivx_obj_desc_t *obj_desc[],
           uint16_t num_params, void *priv_arg);
    static vx_status tivxCaptureGetStatistics(tivxCaptureParams *prms,
        tivx_obj_desc_user_data_object_t *usr_data_obj);
    static void tivxCaptureCopyStatistics(tivxCaptureParams *prms,
        tivx_capture_statistics_t *capt_status_prms);
    static void tivxCaptureGetChannelIndices(const tivxCaptureParams *prms,
                                             uint32_t instId,
                                             uint32_t *startChIdx,
                                             uint32_t *endChIdx);
    static uint32_t tivxCaptureGetNodeChannelNum(const tivxCaptureParams *prms,
                                                 uint32_t instId,
                                                 uint32_t chId);
    static uint32_t tivxCaptureGetDrvInstIndex(const tivxCaptureParams *prms,
                                               uint32_t instId);
    static uint32_t tivxCaptureMapInstId(uint32_t instId);
    static void tivxCapturePrintStatus(tivxCaptureInstParams *prms);
    
    /**
     *******************************************************************************
     *
     * \brief Callback function from driver to application
     *
     * Callback function gets called from Driver to application on reception of
     * a frame
     *
     * \param  handle       [IN] Driver handle for which callback has come.
     * \param  appData      [IN] Application specific data which is registered
     *                           during the callback registration.
     * \param  reserved     [IN] Reserved.
     *
     * \return  SYSTEM_LINK_STATUS_SOK on success
     *
     *******************************************************************************
     */
    static vx_status captDrvCallback(Fvid2_Handle handle, void *appData, void *reserved)
    {
        tivxCaptureParams *prms = (tivxCaptureParams*)appData;
    
        tivxEventPost(prms->frame_available);
    
        return (vx_status)VX_SUCCESS;
    }
    
    static vx_status tivxCaptureEnqueueFrameToDriver(
           tivx_obj_desc_object_array_t *output_desc,
           tivxCaptureParams *prms)
    {
        vx_status status = (vx_status)VX_SUCCESS;
        int32_t fvid2_status = FVID2_SOK;
        void *output_image_target_ptr;
        uint64_t captured_frame;
        uint32_t chId = 0U;
        static Fvid2_FrameList frmList;
        Fvid2_Frame *fvid2Frame;
        uint32_t startChIdx, endChIdx, instIdx, vcId;
        tivxCaptureInstParams *instParams;
    
        tivxGetObjDescList(output_desc->obj_desc_id, (tivx_obj_desc_t **)prms->img_obj_desc,
                           prms->numCh);
    
        /* Prepare and queue frame-list for each instance */
        for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
        {
            instParams = &prms->instParams[instIdx];
            tivxCaptureGetChannelIndices(prms, instIdx, &startChIdx, &endChIdx);
            frmList.numFrames = instParams->numCh;
            for (chId = startChIdx ; chId < endChIdx ; chId++)
            {
                if ((uint32_t)TIVX_OBJ_DESC_RAW_IMAGE == prms->img_obj_desc[0]->type)
                {
                    tivx_obj_desc_raw_image_t *raw_image;
    
                    raw_image = (tivx_obj_desc_raw_image_t *)prms->img_obj_desc[chId];
    
                    /* Question: is the fact that we are just using mem_ptr[0] and not remaining planes correct? */
                    output_image_target_ptr = tivxMemShared2TargetPtr(&raw_image->mem_ptr[0]);
    
    
                    captured_frame = ((uintptr_t)output_image_target_ptr +
                        (uint64_t)tivxComputePatchOffset(0, 0, &raw_image->imagepatch_addr[0U]));
                }
                else
                {
                    tivx_obj_desc_image_t *image;
                    image = (tivx_obj_desc_image_t *)prms->img_obj_desc[chId];
    
                    /* Question: is the fact that we are just using mem_ptr[0] and not remaining exposures correct? */
                    output_image_target_ptr = tivxMemShared2TargetPtr(&image->mem_ptr[0]);
    
                    captured_frame = ((uintptr_t)output_image_target_ptr +
                        (uint64_t)tivxComputePatchOffset(0, 0, &image->imagepatch_addr[0U]));
                }
    
                tivxQueueGet(&prms->freeFvid2FrameQ[chId], (uintptr_t*)&fvid2Frame, TIVX_EVENT_TIMEOUT_NO_WAIT);
    
                if (NULL != fvid2Frame)
                {
                    vcId = instParams->chVcMap[(chId - startChIdx)];
                    /* Put into frame list as it is for same driver instance */
                    frmList.frames[(chId - startChIdx)]           = fvid2Frame;
                    frmList.frames[(chId - startChIdx)]->chNum    =
                        instParams->vcMapToChIdx[vcId];
                    frmList.frames[(chId - startChIdx)]->addr[0U] = captured_frame;
                    frmList.frames[(chId - startChIdx)]->appData  = output_desc;
                }
                else
                {
                    VX_PRINT(VX_ZONE_ERROR, " CAPTURE: Could not retrieve buffer from buffer queue!!!\n");
                }
            }
    
            /* All the frames from frame-list */
            fvid2_status = Fvid2_queue(instParams->drvHandle, &frmList, 0);
            if (FVID2_SOK != fvid2_status)
            {
                status = (vx_status)VX_FAILURE;
                VX_PRINT(VX_ZONE_ERROR, " CAPTURE: ERROR: Frame could not be queued for frame %d !!!\n", chId);
                break;
            }
        }
    
        return status;
    }
    
    static uint32_t tivxCaptureExtractInCsiDataType(uint32_t format)
    {
        uint32_t inCsiDataType;
    
        switch (format)
        {
            case (vx_df_image)VX_DF_IMAGE_RGB:
                inCsiDataType = FVID2_CSI2_DF_RGB888;
                break;
            case (vx_df_image)VX_DF_IMAGE_RGBX:
                inCsiDataType = FVID2_CSI2_DF_RGB888;
                break;
            case (vx_df_image)VX_DF_IMAGE_U16:
            case (uint32_t)TIVX_RAW_IMAGE_P12_BIT:
                inCsiDataType = FVID2_CSI2_DF_RAW12;
                break;
            case (vx_df_image)VX_DF_IMAGE_UYVY:
            case (vx_df_image)VX_DF_IMAGE_YUYV:
                inCsiDataType = FVID2_CSI2_DF_YUV422_8B;
                break;
            default:
                inCsiDataType = 0xFFFFFFFFu;
                break;
        }
    
        return inCsiDataType;
    }
    
    static uint32_t tivxCaptureExtractCcsFormat(uint32_t format)
    {
        uint32_t ccsFormat = FVID2_CCSF_BITS12_PACKED;
    
        switch (format)
        {
            case (uint32_t)TIVX_RAW_IMAGE_P12_BIT:
                ccsFormat = FVID2_CCSF_BITS12_PACKED;
                break;
            case (vx_enum)TIVX_RAW_IMAGE_16_BIT:
            case (vx_df_image)VX_DF_IMAGE_U16:
            case (vx_df_image)VX_DF_IMAGE_UYVY:
            case (vx_df_image)VX_DF_IMAGE_YUYV:
                ccsFormat = FVID2_CCSF_BITS12_UNPACKED16;
                break;
            default:
                ccsFormat = FVID2_CCSF_MAX;
                break;
        }
    
        return ccsFormat;
    }
    
    static uint32_t tivxCaptureMapInstId(uint32_t instId)
    {
        uint32_t drvInstId = 0xFFFF;
        switch (instId)
        {
            case 0:
                drvInstId = CSIRX_INSTANCE_ID_0;
                break;
            case 1:
                drvInstId = CSIRX_INSTANCE_ID_1;
                break;
            default:
                /* do nothing */
                break;
        }
    
        return (drvInstId);
    }
    
    /* TODO: Complete this case statement */
    static uint32_t tivxCaptureExtractDataFormat(uint32_t format)
    {
        uint32_t dataFormat = FVID2_DF_BGRX32_8888;
    
        return dataFormat;
    }
    
    static vx_status tivxCaptureSetCreateParams(
           tivxCaptureParams *prms,
           const tivx_obj_desc_user_data_object_t *obj_desc)
    {
        vx_status status = (vx_status)VX_SUCCESS;
        uint32_t loopCnt = 0U, i, format, width, height, planes, stride[TIVX_IMAGE_MAX_PLANES];
        void *capture_config_target_ptr;
        tivx_capture_params_t *params;
        uint32_t chIdx, instId = 0U, instIdx;
        Csirx_CreateParams *createParams;
    
        capture_config_target_ptr = tivxMemShared2TargetPtr(&obj_desc->mem_ptr);
    
        tivxMemBufferMap(capture_config_target_ptr, obj_desc->mem_size,
            (vx_enum)VX_MEMORY_TYPE_HOST, (vx_enum)VX_READ_ONLY);
    
        params = (tivx_capture_params_t *)capture_config_target_ptr;
    
        /* Scan through all the instances provided in the Node instance and prepare CSIRX DRV instance data/cfg */
        for (instIdx = 0U ; instIdx < params->numInst ; instIdx++)
        {
            /* set instance to be used for capture */
            prms->instParams[instIdx].instId = tivxCaptureMapInstId(params->instId[instIdx]);
            prms->numOfInstUsed++;
        }
        /* Scan through all the channels provided in the Node instance and prepare CSIRX DRV instance data/cfg */
        for (chIdx = 0U ; chIdx < params->numCh ; chIdx++)
        {
            instId = tivxCaptureGetDrvInstIndex(prms, params->chInstMap[chIdx]);
            if (instId > prms->numOfInstUsed)
            {
                status = (vx_status)VX_FAILURE;
                VX_PRINT(VX_ZONE_ERROR, " CAPTURE: ERROR: Wrong Instance ID provided: %d !!!\n", params->chInstMap[chIdx]);
                break;
            }
            else
            {
                prms->instParams[instId].vcMapToChIdx[params->chVcNum[chIdx]] = chIdx;
                prms->instParams[instId].chVcMap[prms->instParams[instId].numCh] =
                                                            params->chVcNum[chIdx];
                prms->instParams[instId].numCh++;
            }
        }
    
        if (status == (vx_status)VX_SUCCESS)
        {
            if ((vx_enum)TIVX_OBJ_DESC_RAW_IMAGE == (vx_enum)prms->img_obj_desc[0]->type)
            {
                tivx_obj_desc_raw_image_t *raw_image;
                raw_image = (tivx_obj_desc_raw_image_t *)prms->img_obj_desc[0];
                format = raw_image->params.format[0].pixel_container; /* TODO: Question: what should be done when this is different per exposure */
                width = raw_image->params.width;
                height = raw_image->params.height + (raw_image->params.meta_height_before + raw_image->params.meta_height_after);
                planes = raw_image->params.num_exposures;
                for (i = 0; i < planes; i++)
                {
                    stride[i] = (uint32_t)raw_image->imagepatch_addr[i].stride_y;
                }
                prms->instParams[instId].raw_capture = 1U;
            }
            else
            {
                tivx_obj_desc_image_t *image;
                image = (tivx_obj_desc_image_t *)prms->img_obj_desc[0];
                format = image->format;
                width = image->imagepatch_addr[0].dim_x;
                height = image->imagepatch_addr[0].dim_y;
                planes = image->planes;
                for (i = 0; i < planes; i++)
                {
                    stride[i] = (uint32_t)image->imagepatch_addr[i].stride_y;
                }
                prms->instParams[instId].raw_capture = 0U;
            }
    
            /* Do following for each CSIRX DRV instance in the current Node */
            for (instIdx = 0U ; instIdx < params->numInst ; instIdx++)
            {
                prms->instParams[instIdx].captParams = prms;
                /* set instance configuration parameters */
                createParams = &prms->instParams[instIdx].createPrms;
                Csirx_createParamsInit(createParams);
                /* Set CSIRX D-PHY configuration parameters */
                Csirx_initDPhyCfg(&prms->instParams[instIdx].dphyCfg);
                prms->instParams[instIdx].dphyCfg.inst               = params->instId[instIdx];
    
                /* set module configuration parameters */
                createParams->instCfg.enableCsiv2p0Support = params->instCfg[instIdx].enableCsiv2p0Support;
                createParams->instCfg.enableErrbypass = (uint32_t)FALSE;
                createParams->instCfg.numDataLanes = params->instCfg[instIdx].numDataLanes;
                for (loopCnt = 0U ;
                     loopCnt < createParams->instCfg.numDataLanes ;
                     loopCnt++)
                {
                    createParams->instCfg.dataLanesMap[loopCnt] = params->instCfg[instIdx].dataLanesMap[loopCnt];
                }
    
                createParams->numCh = prms->instParams[instIdx].numCh;
                for (loopCnt = 0U ; loopCnt < createParams->numCh ; loopCnt++)
                {
                    createParams->chCfg[loopCnt].chId = loopCnt;
                    createParams->chCfg[loopCnt].chType = CSIRX_CH_TYPE_CAPT;
                    createParams->chCfg[loopCnt].vcNum = prms->instParams[instIdx].chVcMap[loopCnt];
    
                    if ((uint32_t)TIVX_OBJ_DESC_RAW_IMAGE == prms->img_obj_desc[0]->type)
                    {
                        createParams->chCfg[loopCnt].inCsiDataType =
                            FVID2_CSI2_DF_RAW12;
                    }
                    else
                    {
                        createParams->chCfg[loopCnt].inCsiDataType =
                            tivxCaptureExtractInCsiDataType(format);
                    }
                    createParams->chCfg[loopCnt].outFmt.width =
                        width;
                    createParams->chCfg[loopCnt].outFmt.height =
                        height;
                    for (i = 0; i < planes; i ++)
                    {
                        createParams->chCfg[loopCnt].outFmt.pitch[i] =
                            stride[i];
                    }
    
                    createParams->chCfg[loopCnt].outFmt.dataFormat =
                        tivxCaptureExtractDataFormat(format);
                    createParams->chCfg[loopCnt].outFmt.ccsFormat =
                        tivxCaptureExtractCcsFormat(format);
                }
                /* set frame drop buffer parameters */
                createParams->frameDropBufLen = CAPTURE_FRAME_DROP_LEN;
                createParams->frameDropBuf = (uint64_t)tivxMemAlloc(createParams->frameDropBufLen, (int32_t)TIVX_MEM_EXTERNAL);
            }
        }
    
        tivxMemBufferUnmap(capture_config_target_ptr,
           obj_desc->mem_size, (vx_enum)VX_MEMORY_TYPE_HOST,
           (vx_enum)VX_READ_ONLY);
    
        return status;
    }
    
    static vx_status VX_CALLBACK tivxCaptureProcess(
           tivx_target_kernel_instance kernel,
           tivx_obj_desc_t *obj_desc[],
           uint16_t num_params, void *priv_arg)
    {
        vx_status status = (vx_status)VX_SUCCESS;
        int32_t fvid2_status = FVID2_SOK;
        tivxCaptureParams *prms = NULL;
        tivx_obj_desc_object_array_t *output_desc;
        static Fvid2_FrameList frmList;
        vx_uint32 size, frmIdx = 0U, chId = 0U;
        vx_enum state;
        Fvid2_Frame *fvid2Frame;
        tivx_obj_desc_object_array_t *desc;
        uint32_t instIdx;
        tivxCaptureInstParams *instParams;
    
        if ( (num_params != TIVX_KERNEL_CAPTURE_MAX_PARAMS)
            || (NULL == obj_desc[TIVX_KERNEL_CAPTURE_INPUT_ARR_IDX])
            || (NULL == obj_desc[TIVX_KERNEL_CAPTURE_OUTPUT_IDX])
        )
        {
            status = (vx_status)VX_FAILURE;
        }
    
        if((vx_status)VX_SUCCESS == status)
        {
            output_desc = (tivx_obj_desc_object_array_t *)obj_desc[TIVX_KERNEL_CAPTURE_OUTPUT_IDX];
    
            status = tivxGetTargetKernelInstanceContext(kernel,
                (void **)&prms, &size);
    
            if (((vx_status)VX_SUCCESS != status) || (NULL == prms) ||
                (sizeof(tivxCaptureParams) != size))
            {
                status = (vx_status)VX_FAILURE;
            }
            else
            {
                status = tivxGetTargetKernelInstanceState(kernel, &state);
            }
        }
    
        if((vx_status)VX_SUCCESS == status)
        {
            /* Steady state: receives a buffer and returns a buffer */
            if ((vx_enum)VX_NODE_STATE_STEADY == state)
            {
                /* Providing buffers to capture source */
                status = tivxCaptureEnqueueFrameToDriver(output_desc, prms);
    
                if ((vx_status)VX_SUCCESS != status)
                {
                    status = (vx_status)VX_FAILURE;
                    VX_PRINT(VX_ZONE_ERROR, " CAPTURE: ERROR: Enqueue Frame to Driver failed !!!\n");
                }
    
                /* Starts FVID2 on initial frame */
                if ((vx_status)VX_SUCCESS == status)
                {
                    if (0U == prms->steady_state_started)
                    {
                        /* start all driver instances in the node */
                        for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
                        {
                            fvid2_status = Fvid2_start(prms->instParams[instIdx].drvHandle, NULL);
                            if (FVID2_SOK != fvid2_status)
                            {
                                status = (vx_status)VX_FAILURE;
                                VX_PRINT(VX_ZONE_ERROR, " CAPTURE: ERROR: Could not start FVID2 !!!\n");
                                break;
                            }
                        }
    
                        if (status == (vx_status)VX_SUCCESS)
                        {
                            prms->steady_state_started = 1;
                        }
                    }
                }
    
                /* Pends until a frame is available then dequeue frames from capture driver */
                if ((vx_status)VX_SUCCESS == status)
                {
                    tivx_obj_desc_t *tmp_desc[TIVX_CAPTURE_MAX_CH] = {NULL};
    
                    uint32_t is_all_ch_frame_available = 0;
    
                    for(chId = 0U ; chId < prms->numCh ; chId++)
                    {
                        tmp_desc[chId] = NULL;
                    }
    
                    while(is_all_ch_frame_available == 0U)
                    {
                        is_all_ch_frame_available = 1;
                        for(chId = 0U ; chId < prms->numCh ; chId++)
                        {
                            tivxQueuePeek(&prms->pendingFrameQ[chId], (uintptr_t*)&tmp_desc[chId]);
                            if(NULL==tmp_desc[chId])
                            {
                                is_all_ch_frame_available = 0;
                            }
                        }
    
                        if(is_all_ch_frame_available == 0U)
                        {
                            tivxEventWait(prms->frame_available, TIVX_EVENT_TIMEOUT_WAIT_FOREVER);
    
                            for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
                            {
                                instParams = &prms->instParams[instIdx];
                                fvid2_status = Fvid2_dequeue(instParams->drvHandle,
                                                             &frmList,
                                                             0,
                                                             FVID2_TIMEOUT_NONE);
    
                                if(FVID2_SOK == fvid2_status)
                                {
                                    for(frmIdx=0; frmIdx < frmList.numFrames; frmIdx++)
                                    {
                                        fvid2Frame = frmList.frames[frmIdx];
                                        chId = tivxCaptureGetNodeChannelNum(
                                                            prms,
                                                            instIdx,
                                                            fvid2Frame->chNum);
                                        desc = (tivx_obj_desc_object_array_t *)fvid2Frame->appData;
    
                                        tivxQueuePut(&prms->freeFvid2FrameQ[chId], (uintptr_t)fvid2Frame, TIVX_EVENT_TIMEOUT_NO_WAIT);
                                        tivxQueuePut(&prms->pendingFrameQ[chId], (uintptr_t)desc, TIVX_EVENT_TIMEOUT_NO_WAIT);
                                    }
                                }
                                else if (fvid2_status == FVID2_ENO_MORE_BUFFERS)
                                {
                                    /* continue: move onto next driver instance
                                      within node as current driver instance did
                                      not generate this CB */
                                }
                                else
                                {
                                    /* TIOVX-687: Note: disabling for now until investigated further */
                                    if (FVID2_EAGAIN != fvid2_status)
                                    {
                                        status = (vx_status)VX_FAILURE;
                                        VX_PRINT(VX_ZONE_ERROR,
                                            " CAPTURE: ERROR: FVID2 Dequeue failed !!!\n");
                                    }
                                }
                            }
                        }
                    }
    
                    for(chId = 0U ; chId < prms->numCh ; chId++)
                    {
                        tivxQueueGet(&prms->pendingFrameQ[chId], (uintptr_t*)&tmp_desc[chId], TIVX_EVENT_TIMEOUT_NO_WAIT);
                    }
                    /* all values in tmp_desc[] should be same */
                    obj_desc[TIVX_KERNEL_CAPTURE_OUTPUT_IDX] = (tivx_obj_desc_t *)tmp_desc[0];
                }
            }
            /* Pipe-up state: only receives a buffer; does not return a buffer */
            else
            {
                status = tivxCaptureEnqueueFrameToDriver(output_desc, prms);
            }
        }
    
        return status;
    }
    
    static vx_status VX_CALLBACK tivxCaptureCreate(
           tivx_target_kernel_instance kernel,
           tivx_obj_desc_t *obj_desc[],
           uint16_t num_params, void *priv_arg)
    {
        vx_status status = (vx_status)VX_SUCCESS;
        int32_t fvid2_status = FVID2_SOK;
        tivx_obj_desc_user_data_object_t *input_obj_desc;
        tivx_obj_desc_object_array_t *output_desc;
        tivxCaptureParams *prms = NULL;
        uint32_t chId, bufId, instIdx;
        tivxCaptureInstParams *instParams;
    
        if ( (num_params != TIVX_KERNEL_CAPTURE_MAX_PARAMS)
            || (NULL == obj_desc[TIVX_KERNEL_CAPTURE_INPUT_ARR_IDX])
            || (NULL == obj_desc[TIVX_KERNEL_CAPTURE_OUTPUT_IDX])
        )
        {
            status = (vx_status)VX_FAILURE;
        }
        else
        {
            input_obj_desc = (tivx_obj_desc_user_data_object_t *)obj_desc[TIVX_KERNEL_CAPTURE_INPUT_ARR_IDX];
            output_desc = (tivx_obj_desc_object_array_t *)obj_desc[TIVX_KERNEL_CAPTURE_OUTPUT_IDX];
    
            prms = tivxMemAlloc(sizeof(tivxCaptureParams), (vx_enum)TIVX_MEM_EXTERNAL);
    
            if (NULL != prms)
            {
                memset(prms, 0, sizeof(tivxCaptureParams));
            }
            else
            {
                VX_PRINT(VX_ZONE_ERROR, " CAPTURE: ERROR: Could allocate memory !!!\n");
                status = (vx_status)VX_ERROR_NO_MEMORY;
            }
    
            if ((vx_status)VX_SUCCESS == status)
            {
                /* Initialize steady_state_started to 0 */
                prms->steady_state_started = 0;
                /* Initialize raw capture to 0 */
                for (instIdx = 0U ; instIdx < TIVX_CAPTURE_MAX_INST ; instIdx++)
                {
                    prms->instParams[instIdx].raw_capture = 0;
                }
    
                /* Set number of channels to number of items in object array */
                prms->numCh = (uint8_t)output_desc->num_items;
    
                if (prms->numCh > TIVX_CAPTURE_MAX_CH)
                {
                    status = (vx_status)VX_ERROR_INVALID_PARAMETERS;
                    VX_PRINT(VX_ZONE_ERROR, "Object descriptor number of channels exceeds max value allowed by capture!!!\r\n");
                }
            }
    
            /* Setting CSIRX capture parameters */
            if ((vx_status)VX_SUCCESS == status)
            {
                tivxGetObjDescList(output_desc->obj_desc_id, (tivx_obj_desc_t **)prms->img_obj_desc,
                               prms->numCh);
    
                status = tivxCaptureSetCreateParams(prms, input_obj_desc);
            }
    
            /* Creating frame available event */
            if ((vx_status)VX_SUCCESS == status)
            {
                status = tivxEventCreate(&prms->frame_available);
    
                if ((vx_status)VX_SUCCESS != status)
                {
                    VX_PRINT(VX_ZONE_ERROR, "Event creation failed in capture!!!\r\n");
                }
            }
    
            /* Creating FVID2 handle */
            if ((vx_status)VX_SUCCESS == status)
            {
                for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
                {
                    instParams = &prms->instParams[instIdx];
                    Fvid2CbParams_init(&instParams->drvCbPrms);
    
                    instParams->drvCbPrms.cbFxn   = (Fvid2_CbFxn) &captDrvCallback;
                    instParams->drvCbPrms.appData = prms;
    
                    instParams->drvHandle = Fvid2_create(CSIRX_CAPT_DRV_ID,
                                                         instParams->instId,
                                                         &instParams->createPrms,
                                                         &instParams->createStatus,
                                                         &instParams->drvCbPrms);
    
                    if ((NULL == instParams->drvHandle) ||
                        (instParams->createStatus.retVal != FVID2_SOK))
                    {
                        VX_PRINT(VX_ZONE_ERROR, ": Capture Create Failed!!!\r\n");
                        status = (vx_status)VX_FAILURE;
                    }
                    else
                    {
                        /* Set CSIRX D-PHY configuration parameters */
                        Csirx_initDPhyCfg(&instParams->dphyCfg);
                        instParams->dphyCfg.inst = instParams->instId;
                        fvid2_status = Fvid2_control(
                            instParams->drvHandle, IOCTL_CSIRX_SET_DPHY_CONFIG,
                            &instParams->dphyCfg, NULL);
                        if (FVID2_SOK != fvid2_status)
                        {
                            status = (vx_status)VX_FAILURE;
                            VX_PRINT(VX_ZONE_ERROR, ": Failed to set PHY Parameters!!!\r\n");
                        }
                    }
                }
            }
    
            /* Creating FVID2 frame Q */
            if ((vx_status)VX_SUCCESS == status)
            {
                for(chId = 0u ; chId < prms->numCh ; chId++)
                {
                    status = tivxQueueCreate(&prms->freeFvid2FrameQ[chId], TIVX_CAPTURE_MAX_NUM_BUFS, prms->fvid2_free_q_mem[chId], 0);
    
                    if ((vx_status)VX_SUCCESS != status)
                    {
                        VX_PRINT(VX_ZONE_ERROR, ": Capture queue create failed!!!\r\n");
                        break;
                    }
    
                    for(bufId = 0u ; bufId < (TIVX_CAPTURE_MAX_NUM_BUFS) ; bufId++)
                    {
                        tivxQueuePut(&prms->freeFvid2FrameQ[chId], (uintptr_t)&prms->fvid2Frames[chId][bufId], TIVX_EVENT_TIMEOUT_NO_WAIT);
                    }
                }
            }
    
            /* Creating pending frame Q */
            if ((vx_status)VX_SUCCESS == status)
            {
                for(chId = 0U ; chId < prms->numCh ; chId++)
                {
                    status = tivxQueueCreate(&prms->pendingFrameQ[chId], TIVX_CAPTURE_MAX_NUM_BUFS, prms->pending_frame_free_q_mem[chId], 0);
    
                    if ((vx_status)VX_SUCCESS != status)
                    {
                        VX_PRINT(VX_ZONE_ERROR, ": Capture create failed!!!\r\n");
                        break;
                    }
                }
            }
    
            if ((vx_status)VX_SUCCESS == status)
            {
                tivxSetTargetKernelInstanceContext(kernel, prms, sizeof(tivxCaptureParams));
            }
            else if (NULL != prms)
            {
                for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
                {
                    instParams = &prms->instParams[instIdx];
                    if (NULL != instParams->drvHandle)
                    {
                        Fvid2_delete(instParams->drvHandle, NULL);
                        instParams->drvHandle = NULL;
                    }
                }
    
                if (NULL != prms->frame_available)
                {
                    tivxEventDelete(&prms->frame_available);
                }
    
                tivxMemFree(prms, sizeof(tivxCaptureParams), (vx_enum)TIVX_MEM_EXTERNAL);
            }
            else
            {
                /* do nothing */
            }
        }
    
        return status;
    }
    
    static void tivxCapturePrintStatus(tivxCaptureInstParams *prms)
    {
        int32_t fvid2_status;
        uint32_t cnt;
    
        if (NULL != prms)
        {
            fvid2_status = Fvid2_control(prms->drvHandle,
                                    IOCTL_CSIRX_GET_INST_STATUS,
                                    &prms->captStatus,
                                    NULL);
            tivx_set_debug_zone((vx_enum)VX_ZONE_INFO);
            if (FVID2_SOK == fvid2_status)
            {
                VX_PRINT(VX_ZONE_INFO,
                    "\n\r==========================================================\r\n");
                VX_PRINT(VX_ZONE_INFO,
                          ": Capture Status: Instance|%d\r\n", prms->instId);
                VX_PRINT(VX_ZONE_INFO,
                          "==========================================================\r\n");
                VX_PRINT(VX_ZONE_INFO,
                          ": FIFO Overflow Count: %d\r\n",
                          prms->captStatus.overflowCount);
                VX_PRINT(VX_ZONE_INFO,
                          ": Spurious UDMA interrupt count: %d\r\n",
                          prms->captStatus.spuriousUdmaIntrCount);
    
                VX_PRINT(VX_ZONE_INFO,
                    "  [Channel No] | Frame Queue Count |"
                    " Frame De-queue Count | Frame Drop Count |\n");
                for(cnt = 0U ; cnt < prms->numCh ; cnt ++)
                {
                    VX_PRINT(VX_ZONE_INFO,
                          "\t\t%d|\t\t%d|\t\t%d|\t\t%d|\n",
                          cnt,
                          prms->captStatus.queueCount[cnt],
                          prms->captStatus.dequeueCount[cnt],
                          prms->captStatus.dropCount[cnt]);
                }
            }
            else
            {
                VX_PRINT(VX_ZONE_ERROR, " CAPTURE: ERROR: FVID2 Control failed !!!\n");
            }
            tivx_clr_debug_zone((vx_enum)VX_ZONE_INFO);
        }
    }
    
    static vx_status VX_CALLBACK tivxCaptureDelete(
           tivx_target_kernel_instance kernel,
           tivx_obj_desc_t *obj_desc[],
           uint16_t num_params, void *priv_arg)
    {
        vx_status status = (vx_status)VX_SUCCESS;
        int32_t fvid2_status = FVID2_SOK;
        tivxCaptureParams *prms = NULL;
        static Fvid2_FrameList frmList;
        uint32_t size, chId, instIdx;
        tivxCaptureInstParams *instParams;
    
        if ( (num_params != TIVX_KERNEL_CAPTURE_MAX_PARAMS)
            || (NULL == obj_desc[TIVX_KERNEL_CAPTURE_INPUT_ARR_IDX])
            || (NULL == obj_desc[TIVX_KERNEL_CAPTURE_OUTPUT_IDX])
        )
        {
            status = (vx_status)VX_FAILURE;
        }
        else
        {
            status = tivxGetTargetKernelInstanceContext(kernel, (void **)&prms, &size);
    
            if ((vx_status)VX_SUCCESS != status)
            {
                VX_PRINT(VX_ZONE_ERROR, " CAPTURE: ERROR: Could not obtain kernel instance context !!!\n");
            }
    
            if(NULL == prms)
            {
                VX_PRINT(VX_ZONE_ERROR, "Kernel instance context is NULL!!!\n");
                status = (vx_status)VX_FAILURE;
            }
    
            if ((vx_status)VX_SUCCESS == status)
            {
                for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
                {
                    instParams = &prms->instParams[instIdx];
                    /* Stopping FVID2 Capture */
                    if ((vx_status)VX_SUCCESS == status)
                    {
                        fvid2_status = Fvid2_stop(instParams->drvHandle, NULL);
    
                        if (FVID2_SOK != fvid2_status)
                        {
                            status = (vx_status)VX_FAILURE;
                            VX_PRINT(VX_ZONE_ERROR, " CAPTURE: ERROR: FVID2 Capture not stopped !!!\n");
                        }
                    }
    
                    /* Dequeue all the request from the driver */
                    if ((vx_status)VX_SUCCESS == status)
                    {
                        Fvid2FrameList_init(&frmList);
                        do
                        {
                            fvid2_status = Fvid2_dequeue(
                                instParams->drvHandle,
                                &frmList,
                                0,
                                FVID2_TIMEOUT_NONE);
                        } while (FVID2_SOK == fvid2_status);
    
                        if (FVID2_ENO_MORE_BUFFERS != fvid2_status)
                        {
                            VX_PRINT(VX_ZONE_ERROR, " CAPTURE: ERROR: FVID2 Capture Dequeue Failed !!!\n");
                            status = (vx_status)VX_FAILURE;
                        }
                    }
    
                    if ((vx_status)VX_SUCCESS == status)
                    {
                        tivxCapturePrintStatus(instParams);
                    }
    
                    /* Deleting FVID2 handle */
                    if ((vx_status)VX_SUCCESS == status)
                    {
                        fvid2_status = Fvid2_delete(instParams->drvHandle, NULL);
    
                        if (FVID2_SOK != fvid2_status)
                        {
                            status = (vx_status)VX_FAILURE;
                            VX_PRINT(VX_ZONE_ERROR, " CAPTURE: ERROR: FVID2 Delete Failed !!!\n");
                        }
                    }
    
                    /* Free-ing kernel instance params */
                    if ( (vx_status)VX_SUCCESS == status)
                    {
                        instParams->drvHandle = NULL;
    
                        if (sizeof(tivxCaptureParams) == size)
                        {
                            tivxMemFree(prms, sizeof(tivxCaptureParams), (vx_status)TIVX_MEM_EXTERNAL);
                        }
                    }
                }
            }
    
            /* Deleting FVID2 frame Q */
            if ((vx_status)VX_SUCCESS == status)
            {
                for(chId = 0U; chId < prms->numCh ; chId++)
                {
                    tivxQueueDelete(&prms->freeFvid2FrameQ[chId]);
                }
            }
    
            /* Deleting pending frame Q */
            if ((vx_status)VX_SUCCESS == status)
            {
                for(chId= 0U ; chId < prms->numCh ; chId++)
                {
                    tivxQueueDelete(&prms->pendingFrameQ[chId]);
                }
            }
    
            /* Deleting event */
            if ((vx_status)VX_SUCCESS == status)
            {
                tivxEventDelete(&prms->frame_available);
            }
        }
    
        return status;
    }
    
    static void tivxCaptureCopyStatistics(tivxCaptureParams *prms,
        tivx_capture_statistics_t *capt_status_prms)
    {
        uint32_t i, instIdx, strmIdx;
        tivxCaptureInstParams *instParams;
    
        for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
        {
            instParams = &prms->instParams[instIdx];
            for (i = 0U ; i < instParams->numCh ; i++)
            {
                capt_status_prms->queueCount[instIdx][i]     = instParams->captStatus.queueCount[i];
                capt_status_prms->dequeueCount[instIdx][i]   = instParams->captStatus.dequeueCount[i];
                capt_status_prms->dropCount[instIdx][i]      = instParams->captStatus.dropCount[i];
            }
            capt_status_prms->overflowCount[instIdx]         = instParams->captStatus.overflowCount;
            capt_status_prms->spuriousUdmaIntrCount[instIdx] = instParams->captStatus.spuriousUdmaIntrCount;
            capt_status_prms->frontFIFOOvflCount[instIdx]    = instParams->captStatus.frontFIFOOvflCount;
            capt_status_prms->crcCount[instIdx]              = instParams->captStatus.crcCount;
            capt_status_prms->eccCount[instIdx]              = instParams->captStatus.eccCount;
            capt_status_prms->correctedEccCount[instIdx]     = instParams->captStatus.correctedEccCount;
            capt_status_prms->dataIdErrorCount[instIdx]      = instParams->captStatus.dataIdErrorCount;
            capt_status_prms->invalidAccessCount[instIdx]    = instParams->captStatus.invalidAccessCount;
            capt_status_prms->invalidSpCount[instIdx]        = instParams->captStatus.invalidSpCount;
            for (strmIdx = 0U ; strmIdx < TIVX_CAPTURE_MAX_STRM ; strmIdx++)
            {
                capt_status_prms->strmFIFOOvflCount[instIdx][strmIdx] =
                                instParams->captStatus.strmFIFOOvflCount[strmIdx];
            }
        }
    }
    
    static vx_status tivxCaptureGetStatistics(tivxCaptureParams *prms,
        tivx_obj_desc_user_data_object_t *usr_data_obj)
    {
        vx_status                             status = (vx_status)VX_SUCCESS;
        tivx_capture_statistics_t                 *capt_status_prms = NULL;
        void                                  *target_ptr;
    
        if (NULL != usr_data_obj)
        {
            target_ptr = tivxMemShared2TargetPtr(&usr_data_obj->mem_ptr);
    
            tivxMemBufferMap(target_ptr, usr_data_obj->mem_size,
                (vx_enum)VX_MEMORY_TYPE_HOST, (vx_enum)VX_WRITE_ONLY);
    
            if (sizeof(tivx_capture_statistics_t) ==
                    usr_data_obj->mem_size)
            {
                capt_status_prms = (tivx_capture_statistics_t *)target_ptr;
    
                tivxCaptureCopyStatistics(prms, capt_status_prms);
            }
            else
            {
                VX_PRINT(VX_ZONE_ERROR,
                    "tivxCaptureGetStatistics: Invalid Size \n");
                status = (vx_status)VX_ERROR_INVALID_PARAMETERS;
            }
    
            tivxMemBufferUnmap(target_ptr, usr_data_obj->mem_size,
                (vx_enum)VX_MEMORY_TYPE_HOST, (vx_enum)VX_WRITE_ONLY);
        }
        else
        {
            VX_PRINT(VX_ZONE_ERROR,
                "tivxCaptureGetStatistics: User Data Object is NULL \n");
            status = (vx_status)VX_ERROR_INVALID_PARAMETERS;
        }
    
        return (status);
    }
    
    static vx_status VX_CALLBACK tivxCaptureControl(
           tivx_target_kernel_instance kernel,
           uint32_t node_cmd_id, tivx_obj_desc_t *obj_desc[],
           uint16_t num_params, void *priv_arg)
    {
        vx_status status = (vx_status)VX_SUCCESS;
        int32_t fvid2_status = FVID2_SOK;
        uint32_t             size, instIdx;
        tivxCaptureParams *prms = NULL;
        tivxCaptureInstParams *instParams;
    
        status = tivxGetTargetKernelInstanceContext(kernel, (void **)&prms, &size);
    
        if ((vx_status)VX_SUCCESS != status)
        {
            VX_PRINT(VX_ZONE_ERROR,
                "tivxCaptureControl: Failed to Get Target Kernel Instance Context\n");
        }
        else if ((NULL == prms) ||
            (sizeof(tivxCaptureParams) != size))
        {
            VX_PRINT(VX_ZONE_ERROR,
                "tivxCaptureControl: Invalid Object Size\n");
            status = (vx_status)VX_FAILURE;
        }
        else
        {
            /* do nothing */
        }
    
        if ((vx_status)VX_SUCCESS == status)
        {
            switch (node_cmd_id)
            {
                case TIVX_CAPTURE_PRINT_STATISTICS:
                {
                    for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
                    {
                        instParams = &prms->instParams[instIdx];
                        tivxCapturePrintStatus(instParams);
                    }
                    break;
                }
                case TIVX_CAPTURE_GET_STATISTICS:
                {
                    if (NULL != obj_desc[0])
                    {
                        for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
                        {
                            instParams = &prms->instParams[instIdx];
                            fvid2_status = Fvid2_control(instParams->drvHandle,
                                                    IOCTL_CSIRX_GET_INST_STATUS,
                                                    &instParams->captStatus,
                                                    NULL);
                            if (FVID2_SOK != fvid2_status)
                            {
                                VX_PRINT(VX_ZONE_ERROR,
                                    "tivxCaptureControl: Get status returned failure\n");
                                status = (vx_status)VX_FAILURE;
                                break;
                            }
                        }
                        if ((vx_status)VX_SUCCESS == status)
                        {
                            status = tivxCaptureGetStatistics(prms,
                                (tivx_obj_desc_user_data_object_t *)obj_desc[0U]);
                            if ((vx_status)VX_SUCCESS != status)
                            {
                                VX_PRINT(VX_ZONE_ERROR,
                                    "tivxCaptureControl: Get status failed\n");
                                status = (vx_status)VX_FAILURE;
                            }
    
                        }
                    }
                    else
                    {
                        VX_PRINT(VX_ZONE_ERROR,
                            "tivxCaptureControl: User data object was NULL\n");
                        status = (vx_status)VX_FAILURE;
                    }
                    break;
                }
                default:
                {
                    VX_PRINT(VX_ZONE_ERROR,
                        "tivxCaptureControl: Invalid Command Id\n");
                    status = (vx_status)VX_FAILURE;
                    break;
                }
            }
        }
        return status;
    }
    
    void tivxAddTargetKernelCapture(void)
    {
        char target_name[TIVX_TARGET_MAX_NAME];
        vx_enum self_cpu;
    
        self_cpu = tivxGetSelfCpuId();
    
        if((self_cpu == (vx_enum)TIVX_CPU_ID_IPU1_0) || (self_cpu == (vx_enum)TIVX_CPU_ID_IPU1_1))
        {
            strncpy(target_name, TIVX_TARGET_CAPTURE1, TIVX_TARGET_MAX_NAME);
    
            vx_capture_target_kernel1 = tivxAddTargetKernelByName(
                                TIVX_KERNEL_CAPTURE_NAME,
                                target_name,
                                tivxCaptureProcess,
                                tivxCaptureCreate,
                                tivxCaptureDelete,
                                tivxCaptureControl,
                                NULL);
    
            strncpy(target_name, TIVX_TARGET_CAPTURE2, TIVX_TARGET_MAX_NAME);
    
            vx_capture_target_kernel2 = tivxAddTargetKernelByName(
                                TIVX_KERNEL_CAPTURE_NAME,
                                target_name,
                                tivxCaptureProcess,
                                tivxCaptureCreate,
                                tivxCaptureDelete,
                                tivxCaptureControl,
                                NULL);
        }
    }
    
    void tivxRemoveTargetKernelCapture(void)
    {
        vx_status status = (vx_status)VX_SUCCESS;
    
        status = tivxRemoveTargetKernel(vx_capture_target_kernel1);
        if(status == (vx_status)VX_SUCCESS)
        {
            vx_capture_target_kernel1 = NULL;
        }
        status = tivxRemoveTargetKernel(vx_capture_target_kernel2);
        if(status == (vx_status)VX_SUCCESS)
        {
            vx_capture_target_kernel2 = NULL;
        }
    }
    
    static void tivxCaptureGetChannelIndices(const tivxCaptureParams *prms,
                                             uint32_t instId,
                                             uint32_t *startChIdx,
                                             uint32_t *endChIdx)
    {
        uint32_t instIdx;
    
        *startChIdx = 0U;
        *endChIdx   = 0U;
        for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
        {
            /* get start channel ID here */
            if (instIdx == instId)
            {
                break;
            }
            else
            {
                *startChIdx += prms->instParams[instIdx].numCh;
            }
        }
        /* Get last channel ID here */
        if (instIdx < prms->numOfInstUsed)
        {
            *endChIdx = *startChIdx + prms->instParams[instIdx].numCh;
        }
    }
    
    static uint32_t tivxCaptureGetNodeChannelNum(const tivxCaptureParams *prms,
                                                 uint32_t instId,
                                                 uint32_t chId)
    {
        uint32_t instIdx, chIdx = 0U;
    
        /* Get addition of all the channels processed on all previous driver instances */
        for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
        {
            if (instIdx == instId)
            {
                break;
            }
            else
            {
                chIdx += prms->instParams[instIdx].numCh;
            }
        }
        chIdx += chId;
    
        return (chIdx);
    }
    
    static uint32_t tivxCaptureGetDrvInstIndex(const tivxCaptureParams *prms,
                                               uint32_t instId)
    {
        uint32_t instIdx, instVal;
    
        instVal = tivxCaptureMapInstId(instId);
        for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
        {
            if (prms->instParams[instIdx].instId == instVal)
            {
                /* Found out the index for required instance */
                break;
            }
        }
    
        return instIdx;
    }
    
    /*
     *
     * Copyright (c) 2018 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 "VX/vx.h"
    #include "TI/tivx_event.h"
    #include "tivx_hwa_kernels.h"
    #include "tivx_kernel_capture.h"
    #include "TI/tivx_target_kernel.h"
    #include "tivx_kernels_target_utils.h"
    #include "tivx_hwa_capture_priv.h"
    
    #include <TI/tivx_queue.h>
    #include <ti/drv/fvid2/fvid2.h>
    #include <ti/drv/csirx/csirx.h>
    
    #define CAPTURE_FRAME_DROP_LEN                          (4096U*4U)
    
    #define CAPTURE_INST_ID_INVALID                         (0xFFFFU)
    
    typedef struct tivxCaptureParams_t tivxCaptureParams;
    
    typedef struct
    {
        uint32_t instId;
        /**< Csirx Drv Instance ID. */
        uint8_t numCh;
        /**< Number of channels processed on given CSIRX DRV instance. */
        uint32_t chVcMap[TIVX_CAPTURE_MAX_CH];
        /**< Virtual ID for channels for current capture instance. */
        Fvid2_Handle drvHandle;
        /**< FVID2 capture driver handle. */
        Csirx_CreateParams createPrms;
        /**< Csirx create time parameters */
        Csirx_CreateStatus createStatus;
        /**< Csirx create time status */
        Fvid2_CbParams drvCbPrms;
        /**< Capture callback params */
        uint8_t raw_capture;
        /**< flag indicating raw capture */
        Csirx_InstStatus captStatus;
        /**< CSIRX Capture status. */
        Csirx_DPhyCfg dphyCfg;
        /**< CSIRX DPHY configuration. */
        tivxCaptureParams *captParams;
        /**< Reference to capture node parameters. */
    } tivxCaptureInstParams;
    
    struct tivxCaptureParams_t
    {
        tivxCaptureInstParams instParams[TIVX_CAPTURE_MAX_INST];
        /* Capture Instance parameters */
        uint32_t numOfInstUsed;
        /**< Number of CSIRX DRV instances used in current TIOVX Node. */
        uint8_t numCh;
        /**< Number of channels processed on given capture node instance. */
        tivx_obj_desc_t *img_obj_desc[TIVX_CAPTURE_MAX_CH];
        /* Captured Images */
        uint8_t steady_state_started;
        /**< Flag indicating whether or not steady state has begun. */
        tivx_event  frame_available;
        /**< Following Queues i.e. freeFvid2FrameQ, pendingFrameQ, fvid2_free_q_mem,
         *   fvid2Frames, and pending_frame_free_q_mem are for given instance of the
         *   Node. If Node instance contains more than 1 instances of the CSIRX DRV
         *   instances, then first 'n' channels are for first instance of the driver
         *   then n channels for next driver and so on... */
        /**< Event indicating when a frame is available. */
        tivx_queue freeFvid2FrameQ[TIVX_CAPTURE_MAX_CH];
        /**< Internal FVID2 queue */
        tivx_queue pendingFrameQ[TIVX_CAPTURE_MAX_CH];
        /**< Internal pending frame queue */
        uintptr_t fvid2_free_q_mem[TIVX_CAPTURE_MAX_CH][TIVX_CAPTURE_MAX_NUM_BUFS];
        /**< FVID2 queue mem */
        Fvid2_Frame fvid2Frames[TIVX_CAPTURE_MAX_CH][TIVX_CAPTURE_MAX_NUM_BUFS];
        /**< FVID2 frame structs */
        uintptr_t pending_frame_free_q_mem[TIVX_CAPTURE_MAX_CH][TIVX_CAPTURE_MAX_NUM_BUFS];
        /**< pending frame queue mem */
    };
    
    static tivx_target_kernel vx_capture_target_kernel1 = NULL;
    static tivx_target_kernel vx_capture_target_kernel2 = NULL;
    
    static vx_status captDrvCallback(Fvid2_Handle handle, void *appData, void *reserved);
    static uint32_t tivxCaptureExtractInCsiDataType(uint32_t format);
    static uint32_t tivxCaptureExtractCcsFormat(uint32_t format);
    static uint32_t tivxCaptureExtractDataFormat(uint32_t format);
    static vx_status tivxCaptureEnqueueFrameToDriver(
           tivx_obj_desc_object_array_t *output_desc,
           tivxCaptureParams *prms);
    static vx_status tivxCaptureSetCreateParams(
           tivxCaptureParams *prms,
           const tivx_obj_desc_user_data_object_t *obj_desc);
    static vx_status VX_CALLBACK tivxCaptureProcess(
           tivx_target_kernel_instance kernel,
           tivx_obj_desc_t *obj_desc[],
           uint16_t num_params, void *priv_arg);
    static vx_status VX_CALLBACK tivxCaptureCreate(
           tivx_target_kernel_instance kernel,
           tivx_obj_desc_t *obj_desc[],
           uint16_t num_params, void *priv_arg);
    static vx_status VX_CALLBACK tivxCaptureDelete(
           tivx_target_kernel_instance kernel,
           tivx_obj_desc_t *obj_desc[],
           uint16_t num_params, void *priv_arg);
    static vx_status VX_CALLBACK tivxCaptureControl(
           tivx_target_kernel_instance kernel,
           uint32_t node_cmd_id, tivx_obj_desc_t *obj_desc[],
           uint16_t num_params, void *priv_arg);
    static vx_status tivxCaptureGetStatistics(tivxCaptureParams *prms,
        tivx_obj_desc_user_data_object_t *usr_data_obj);
    static void tivxCaptureCopyStatistics(tivxCaptureParams *prms,
        tivx_capture_statistics_t *capt_status_prms);
    static void tivxCaptureGetChannelIndices(const tivxCaptureParams *prms,
                                             uint32_t instId,
                                             uint32_t *startChIdx,
                                             uint32_t *endChIdx);
    static uint32_t tivxCaptureGetNodeChannelNum(const tivxCaptureParams *prms,
                                                 uint32_t instId,
                                                 uint32_t chId);
    static uint32_t tivxCaptureGetDrvInstIndex(const tivxCaptureParams *prms,
                                               uint32_t instId);
    static uint32_t tivxCaptureMapInstId(uint32_t instId);
    static void tivxCapturePrintStatus(tivxCaptureInstParams *prms);
    
    /**
     *******************************************************************************
     *
     * \brief Callback function from driver to application
     *
     * Callback function gets called from Driver to application on reception of
     * a frame
     *
     * \param  handle       [IN] Driver handle for which callback has come.
     * \param  appData      [IN] Application specific data which is registered
     *                           during the callback registration.
     * \param  reserved     [IN] Reserved.
     *
     * \return  SYSTEM_LINK_STATUS_SOK on success
     *
     *******************************************************************************
     */
    static vx_status captDrvCallback(Fvid2_Handle handle, void *appData, void *reserved)
    {
        tivxCaptureParams *prms = (tivxCaptureParams*)appData;
    
        tivxEventPost(prms->frame_available);
    
        return (vx_status)VX_SUCCESS;
    }
    
    static vx_status tivxCaptureEnqueueFrameToDriver(
           tivx_obj_desc_object_array_t *output_desc,
           tivxCaptureParams *prms)
    {
        vx_status status = (vx_status)VX_SUCCESS;
        int32_t fvid2_status = FVID2_SOK;
        void *output_image_target_ptr;
        uint64_t captured_frame;
        uint32_t chId = 0U;
        static Fvid2_FrameList frmList;
        Fvid2_Frame *fvid2Frame;
        uint32_t startChIdx, endChIdx, instIdx;
        tivxCaptureInstParams *instParams;
    
        tivxGetObjDescList(output_desc->obj_desc_id, (tivx_obj_desc_t **)prms->img_obj_desc,
                           prms->numCh);
    
        /* Prepare and queue frame-list for each instance */
        for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
        {
            instParams = &prms->instParams[instIdx];
            tivxCaptureGetChannelIndices(prms, instIdx, &startChIdx, &endChIdx);
            frmList.numFrames = instParams->numCh;
            for (chId = startChIdx ; chId < endChIdx ; chId++)
            {
                if ((uint32_t)TIVX_OBJ_DESC_RAW_IMAGE == prms->img_obj_desc[0]->type)
                {
                    tivx_obj_desc_raw_image_t *raw_image;
    
                    raw_image = (tivx_obj_desc_raw_image_t *)prms->img_obj_desc[chId];
    
                    /* Question: is the fact that we are just using mem_ptr[0] and not remaining planes correct? */
                    output_image_target_ptr = tivxMemShared2TargetPtr(&raw_image->mem_ptr[0]);
    
    
                    captured_frame = ((uintptr_t)output_image_target_ptr +
                        (uint64_t)tivxComputePatchOffset(0, 0, &raw_image->imagepatch_addr[0U]));
                }
                else
                {
                    tivx_obj_desc_image_t *image;
                    image = (tivx_obj_desc_image_t *)prms->img_obj_desc[chId];
    
                    /* Question: is the fact that we are just using mem_ptr[0] and not remaining exposures correct? */
                    output_image_target_ptr = tivxMemShared2TargetPtr(&image->mem_ptr[0]);
    
                    captured_frame = ((uintptr_t)output_image_target_ptr +
                        (uint64_t)tivxComputePatchOffset(0, 0, &image->imagepatch_addr[0U]));
                }
    
                tivxQueueGet(&prms->freeFvid2FrameQ[chId], (uintptr_t*)&fvid2Frame, TIVX_EVENT_TIMEOUT_NO_WAIT);
    
                if (NULL != fvid2Frame)
                {
                    /* Put into frame list as it is for same driver instance */
                    frmList.frames[(chId - startChIdx)]           = fvid2Frame;
                    frmList.frames[(chId - startChIdx)]->chNum    = instParams->chVcMap[(chId - startChIdx)];
                    frmList.frames[(chId - startChIdx)]->addr[0U] = captured_frame;
                    frmList.frames[(chId - startChIdx)]->appData  = output_desc;
                }
                else
                {
                    VX_PRINT(VX_ZONE_ERROR, " CAPTURE: Could not retrieve buffer from buffer queue!!!\n");
                }
            }
    
            /* All the frames from frame-list */
            fvid2_status = Fvid2_queue(instParams->drvHandle, &frmList, 0);
            if (FVID2_SOK != fvid2_status)
            {
                status = (vx_status)VX_FAILURE;
                VX_PRINT(VX_ZONE_ERROR, " CAPTURE: ERROR: Frame could not be queued for frame %d !!!\n", chId);
                break;
            }
        }
    
        return status;
    }
    
    static uint32_t tivxCaptureExtractInCsiDataType(uint32_t format)
    {
        uint32_t inCsiDataType;
    
        switch (format)
        {
            case (vx_df_image)VX_DF_IMAGE_RGB:
                inCsiDataType = FVID2_CSI2_DF_RGB888;
                break;
            case (vx_df_image)VX_DF_IMAGE_RGBX:
                inCsiDataType = FVID2_CSI2_DF_RGB888;
                break;
            case (vx_df_image)VX_DF_IMAGE_U16:
            case (uint32_t)TIVX_RAW_IMAGE_P12_BIT:
                inCsiDataType = FVID2_CSI2_DF_RAW12;
                break;
            case (vx_df_image)VX_DF_IMAGE_UYVY:
            case (vx_df_image)VX_DF_IMAGE_YUYV:
                inCsiDataType = FVID2_CSI2_DF_YUV422_8B;
                break;
            default:
                inCsiDataType = 0xFFFFFFFFu;
                break;
        }
    
        return inCsiDataType;
    }
    
    static uint32_t tivxCaptureExtractCcsFormat(uint32_t format)
    {
        uint32_t ccsFormat = FVID2_CCSF_BITS12_PACKED;
    
        switch (format)
        {
            case (uint32_t)TIVX_RAW_IMAGE_P12_BIT:
                ccsFormat = FVID2_CCSF_BITS12_PACKED;
                break;
            case (vx_enum)TIVX_RAW_IMAGE_16_BIT:
            case (vx_df_image)VX_DF_IMAGE_U16:
            case (vx_df_image)VX_DF_IMAGE_UYVY:
            case (vx_df_image)VX_DF_IMAGE_YUYV:
                ccsFormat = FVID2_CCSF_BITS12_UNPACKED16;
                break;
            default:
                ccsFormat = FVID2_CCSF_MAX;
                break;
        }
    
        return ccsFormat;
    }
    
    static uint32_t tivxCaptureMapInstId(uint32_t instId)
    {
        uint32_t drvInstId = 0xFFFF;
        switch (instId)
        {
            case 0:
                drvInstId = CSIRX_INSTANCE_ID_0;
                break;
            case 1:
                drvInstId = CSIRX_INSTANCE_ID_1;
                break;
            default:
                /* do nothing */
                break;
        }
    
        return (drvInstId);
    }
    
    /* TODO: Complete this case statement */
    static uint32_t tivxCaptureExtractDataFormat(uint32_t format)
    {
        uint32_t dataFormat = FVID2_DF_BGRX32_8888;
    
        return dataFormat;
    }
    
    static vx_status tivxCaptureSetCreateParams(
           tivxCaptureParams *prms,
           const tivx_obj_desc_user_data_object_t *obj_desc)
    {
        vx_status status = (vx_status)VX_SUCCESS;
        uint32_t loopCnt = 0U, i, format, width, height, planes, stride[TIVX_IMAGE_MAX_PLANES];
        void *capture_config_target_ptr;
        tivx_capture_params_t *params;
        uint32_t chIdx, instId = 0U, instIdx;
        Csirx_CreateParams *createParams;
    
        capture_config_target_ptr = tivxMemShared2TargetPtr(&obj_desc->mem_ptr);
    
        tivxMemBufferMap(capture_config_target_ptr, obj_desc->mem_size,
            (vx_enum)VX_MEMORY_TYPE_HOST, (vx_enum)VX_READ_ONLY);
    
        params = (tivx_capture_params_t *)capture_config_target_ptr;
    
        /* Scan through all the instances provided in the Node instance and prepare CSIRX DRV instance data/cfg */
        for (instIdx = 0U ; instIdx < params->numInst ; instIdx++)
        {
            /* set instance to be used for capture */
            prms->instParams[instIdx].instId = tivxCaptureMapInstId(params->instId[instIdx]);
            prms->numOfInstUsed++;
        }
        /* Scan through all the channels provided in the Node instance and prepare CSIRX DRV instance data/cfg */
        for (chIdx = 0U ; chIdx < params->numCh ; chIdx++)
        {
            instId = tivxCaptureGetDrvInstIndex(prms, params->chInstMap[chIdx]);
            if (instId > prms->numOfInstUsed)
            {
                status = (vx_status)VX_FAILURE;
                VX_PRINT(VX_ZONE_ERROR, " CAPTURE: ERROR: Wrong Instance ID provided: %d !!!\n", params->chInstMap[chIdx]);
                break;
            }
            else
            {
                prms->instParams[instId].chVcMap[prms->instParams[instId].numCh] =
                                                            params->chVcNum[chIdx];
                prms->instParams[instId].numCh++;
            }
        }
    
        if (status == (vx_status)VX_SUCCESS)
        {
            if ((vx_enum)TIVX_OBJ_DESC_RAW_IMAGE == (vx_enum)prms->img_obj_desc[0]->type)
            {
                tivx_obj_desc_raw_image_t *raw_image;
                raw_image = (tivx_obj_desc_raw_image_t *)prms->img_obj_desc[0];
                format = raw_image->params.format[0].pixel_container; /* TODO: Question: what should be done when this is different per exposure */
                width = raw_image->params.width;
                height = raw_image->params.height + (raw_image->params.meta_height_before + raw_image->params.meta_height_after);
                planes = raw_image->params.num_exposures;
                for (i = 0; i < planes; i++)
                {
                    stride[i] = (uint32_t)raw_image->imagepatch_addr[i].stride_y;
                }
                prms->instParams[instId].raw_capture = 1U;
            }
            else
            {
                tivx_obj_desc_image_t *image;
                image = (tivx_obj_desc_image_t *)prms->img_obj_desc[0];
                format = image->format;
                width = image->imagepatch_addr[0].dim_x;
                height = image->imagepatch_addr[0].dim_y;
                planes = image->planes;
                for (i = 0; i < planes; i++)
                {
                    stride[i] = (uint32_t)image->imagepatch_addr[i].stride_y;
                }
                prms->instParams[instId].raw_capture = 0U;
            }
    
            /* Do following for each CSIRX DRV instance in the current Node */
            for (instIdx = 0U ; instIdx < params->numInst ; instIdx++)
            {
                prms->instParams[instIdx].captParams = prms;
                /* set instance configuration parameters */
                createParams = &prms->instParams[instIdx].createPrms;
                Csirx_createParamsInit(createParams);
                /* Set CSIRX D-PHY configuration parameters */
                Csirx_initDPhyCfg(&prms->instParams[instIdx].dphyCfg);
                prms->instParams[instIdx].dphyCfg.inst               = params->instId[instIdx];
    
                /* set module configuration parameters */
                createParams->instCfg.enableCsiv2p0Support = params->instCfg[instIdx].enableCsiv2p0Support;
                createParams->instCfg.enableErrbypass = (uint32_t)FALSE;
                createParams->instCfg.numDataLanes = params->instCfg[instIdx].numDataLanes;
                for (loopCnt = 0U ;
                     loopCnt < createParams->instCfg.numDataLanes ;
                     loopCnt++)
                {
                    createParams->instCfg.dataLanesMap[loopCnt] = params->instCfg[instIdx].dataLanesMap[loopCnt];
                }
    
                createParams->numCh = prms->instParams[instIdx].numCh;
                for (loopCnt = 0U ; loopCnt < createParams->numCh ; loopCnt++)
                {
                    createParams->chCfg[loopCnt].chId = loopCnt;
                    createParams->chCfg[loopCnt].chType = CSIRX_CH_TYPE_CAPT;
                    createParams->chCfg[loopCnt].vcNum = prms->instParams[instIdx].chVcMap[loopCnt];
    
                    if ((uint32_t)TIVX_OBJ_DESC_RAW_IMAGE == prms->img_obj_desc[0]->type)
                    {
                        createParams->chCfg[loopCnt].inCsiDataType =
                            FVID2_CSI2_DF_RAW12;
                    }
                    else
                    {
                        createParams->chCfg[loopCnt].inCsiDataType =
                            tivxCaptureExtractInCsiDataType(format);
                    }
                    createParams->chCfg[loopCnt].outFmt.width =
                        width;
                    createParams->chCfg[loopCnt].outFmt.height =
                        height;
                    for (i = 0; i < planes; i ++)
                    {
                        createParams->chCfg[loopCnt].outFmt.pitch[i] =
                            stride[i];
                    }
    
                    createParams->chCfg[loopCnt].outFmt.dataFormat =
                        tivxCaptureExtractDataFormat(format);
                    createParams->chCfg[loopCnt].outFmt.ccsFormat =
                        tivxCaptureExtractCcsFormat(format);
                }
                /* set frame drop buffer parameters */
                createParams->frameDropBufLen = CAPTURE_FRAME_DROP_LEN;
                createParams->frameDropBuf = (uint64_t)tivxMemAlloc(createParams->frameDropBufLen, (int32_t)TIVX_MEM_EXTERNAL);
            }
        }
    
        tivxMemBufferUnmap(capture_config_target_ptr,
           obj_desc->mem_size, (vx_enum)VX_MEMORY_TYPE_HOST,
           (vx_enum)VX_READ_ONLY);
    
        return status;
    }
    
    static vx_status VX_CALLBACK tivxCaptureProcess(
           tivx_target_kernel_instance kernel,
           tivx_obj_desc_t *obj_desc[],
           uint16_t num_params, void *priv_arg)
    {
        vx_status status = (vx_status)VX_SUCCESS;
        int32_t fvid2_status = FVID2_SOK;
        tivxCaptureParams *prms = NULL;
        tivx_obj_desc_object_array_t *output_desc;
        static Fvid2_FrameList frmList;
        vx_uint32 size, frmIdx = 0U, chId = 0U;
        vx_enum state;
        Fvid2_Frame *fvid2Frame;
        tivx_obj_desc_object_array_t *desc;
        uint32_t instIdx;
        tivxCaptureInstParams *instParams;
    
        if ( (num_params != TIVX_KERNEL_CAPTURE_MAX_PARAMS)
            || (NULL == obj_desc[TIVX_KERNEL_CAPTURE_INPUT_ARR_IDX])
            || (NULL == obj_desc[TIVX_KERNEL_CAPTURE_OUTPUT_IDX])
        )
        {
            status = (vx_status)VX_FAILURE;
        }
    
        if((vx_status)VX_SUCCESS == status)
        {
            output_desc = (tivx_obj_desc_object_array_t *)obj_desc[TIVX_KERNEL_CAPTURE_OUTPUT_IDX];
    
            status = tivxGetTargetKernelInstanceContext(kernel,
                (void **)&prms, &size);
    
            if (((vx_status)VX_SUCCESS != status) || (NULL == prms) ||
                (sizeof(tivxCaptureParams) != size))
            {
                status = (vx_status)VX_FAILURE;
            }
            else
            {
                status = tivxGetTargetKernelInstanceState(kernel, &state);
            }
        }
    
        if((vx_status)VX_SUCCESS == status)
        {
            /* Steady state: receives a buffer and returns a buffer */
            if ((vx_enum)VX_NODE_STATE_STEADY == state)
            {
                /* Providing buffers to capture source */
                status = tivxCaptureEnqueueFrameToDriver(output_desc, prms);
    
                if ((vx_status)VX_SUCCESS != status)
                {
                    status = (vx_status)VX_FAILURE;
                    VX_PRINT(VX_ZONE_ERROR, " CAPTURE: ERROR: Enqueue Frame to Driver failed !!!\n");
                }
    
                /* Starts FVID2 on initial frame */
                if ((vx_status)VX_SUCCESS == status)
                {
                    if (0U == prms->steady_state_started)
                    {
                        /* start all driver instances in the node */
                        for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
                        {
                            fvid2_status = Fvid2_start(prms->instParams[instIdx].drvHandle, NULL);
                            if (FVID2_SOK != fvid2_status)
                            {
                                status = (vx_status)VX_FAILURE;
                                VX_PRINT(VX_ZONE_ERROR, " CAPTURE: ERROR: Could not start FVID2 !!!\n");
                                break;
                            }
                        }
    
                        if (status == (vx_status)VX_SUCCESS)
                        {
                            prms->steady_state_started = 1;
                        }
                    }
                }
    
                /* Pends until a frame is available then dequeue frames from capture driver */
                if ((vx_status)VX_SUCCESS == status)
                {
                    tivx_obj_desc_t *tmp_desc[TIVX_CAPTURE_MAX_CH] = {NULL};
    
                    uint32_t is_all_ch_frame_available = 0;
    
                    for(chId = 0U ; chId < prms->numCh ; chId++)
                    {
                        tmp_desc[chId] = NULL;
                    }
    
                    while(is_all_ch_frame_available == 0U)
                    {
                        is_all_ch_frame_available = 1;
                        for(chId = 0U ; chId < prms->numCh ; chId++)
                        {
                            tivxQueuePeek(&prms->pendingFrameQ[chId], (uintptr_t*)&tmp_desc[chId]);
                            if(NULL==tmp_desc[chId])
                            {
                                is_all_ch_frame_available = 0;
                            }
                        }
    
                        if(is_all_ch_frame_available == 0U)
                        {
                            tivxEventWait(prms->frame_available, TIVX_EVENT_TIMEOUT_WAIT_FOREVER);
    
                            for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
                            {
                                instParams = &prms->instParams[instIdx];
                                fvid2_status = Fvid2_dequeue(instParams->drvHandle,
                                                             &frmList,
                                                             0,
                                                             FVID2_TIMEOUT_NONE);
    
                                if(FVID2_SOK == fvid2_status)
                                {
                                    for(frmIdx=0; frmIdx < frmList.numFrames; frmIdx++)
                                    {
                                        fvid2Frame = frmList.frames[frmIdx];
                                        chId = tivxCaptureGetNodeChannelNum(
                                                            prms,
                                                            instIdx,
                                                            fvid2Frame->chNum);
                                        desc = (tivx_obj_desc_object_array_t *)fvid2Frame->appData;
    
                                        tivxQueuePut(&prms->freeFvid2FrameQ[chId], (uintptr_t)fvid2Frame, TIVX_EVENT_TIMEOUT_NO_WAIT);
                                        tivxQueuePut(&prms->pendingFrameQ[chId], (uintptr_t)desc, TIVX_EVENT_TIMEOUT_NO_WAIT);
                                    }
                                }
                                else if (fvid2_status == FVID2_ENO_MORE_BUFFERS)
                                {
                                    /* continue: move onto next driver instance
                                      within node as current driver instance did
                                      not generate this CB */
                                }
                                else
                                {
                                    /* TIOVX-687: Note: disabling for now until investigated further */
                                    if (FVID2_EAGAIN != fvid2_status)
                                    {
                                        status = (vx_status)VX_FAILURE;
                                        VX_PRINT(VX_ZONE_ERROR,
                                            " CAPTURE: ERROR: FVID2 Dequeue failed !!!\n");
                                    }
                                }
                            }
                        }
                    }
    
                    for(chId = 0U ; chId < prms->numCh ; chId++)
                    {
                        tivxQueueGet(&prms->pendingFrameQ[chId], (uintptr_t*)&tmp_desc[chId], TIVX_EVENT_TIMEOUT_NO_WAIT);
                    }
                    /* all values in tmp_desc[] should be same */
                    obj_desc[TIVX_KERNEL_CAPTURE_OUTPUT_IDX] = (tivx_obj_desc_t *)tmp_desc[0];
                }
            }
            /* Pipe-up state: only receives a buffer; does not return a buffer */
            else
            {
                status = tivxCaptureEnqueueFrameToDriver(output_desc, prms);
            }
        }
    
        return status;
    }
    
    static vx_status VX_CALLBACK tivxCaptureCreate(
           tivx_target_kernel_instance kernel,
           tivx_obj_desc_t *obj_desc[],
           uint16_t num_params, void *priv_arg)
    {
        vx_status status = (vx_status)VX_SUCCESS;
        int32_t fvid2_status = FVID2_SOK;
        tivx_obj_desc_user_data_object_t *input_obj_desc;
        tivx_obj_desc_object_array_t *output_desc;
        tivxCaptureParams *prms = NULL;
        uint32_t chId, bufId, instIdx;
        tivxCaptureInstParams *instParams;
    
        if ( (num_params != TIVX_KERNEL_CAPTURE_MAX_PARAMS)
            || (NULL == obj_desc[TIVX_KERNEL_CAPTURE_INPUT_ARR_IDX])
            || (NULL == obj_desc[TIVX_KERNEL_CAPTURE_OUTPUT_IDX])
        )
        {
            status = (vx_status)VX_FAILURE;
        }
        else
        {
            input_obj_desc = (tivx_obj_desc_user_data_object_t *)obj_desc[TIVX_KERNEL_CAPTURE_INPUT_ARR_IDX];
            output_desc = (tivx_obj_desc_object_array_t *)obj_desc[TIVX_KERNEL_CAPTURE_OUTPUT_IDX];
    
            prms = tivxMemAlloc(sizeof(tivxCaptureParams), (vx_enum)TIVX_MEM_EXTERNAL);
    
            if (NULL != prms)
            {
                memset(prms, 0, sizeof(tivxCaptureParams));
            }
            else
            {
                VX_PRINT(VX_ZONE_ERROR, " CAPTURE: ERROR: Could allocate memory !!!\n");
                status = (vx_status)VX_ERROR_NO_MEMORY;
            }
    
            if ((vx_status)VX_SUCCESS == status)
            {
                /* Initialize steady_state_started to 0 */
                prms->steady_state_started = 0;
                /* Initialize raw capture to 0 */
                for (instIdx = 0U ; instIdx < TIVX_CAPTURE_MAX_INST ; instIdx++)
                {
                    prms->instParams[instIdx].raw_capture = 0;
                }
    
                /* Set number of channels to number of items in object array */
                prms->numCh = (uint8_t)output_desc->num_items;
    
                if (prms->numCh > TIVX_CAPTURE_MAX_CH)
                {
                    status = (vx_status)VX_ERROR_INVALID_PARAMETERS;
                    VX_PRINT(VX_ZONE_ERROR, "Object descriptor number of channels exceeds max value allowed by capture!!!\r\n");
                }
            }
    
            /* Setting CSIRX capture parameters */
            if ((vx_status)VX_SUCCESS == status)
            {
                tivxGetObjDescList(output_desc->obj_desc_id, (tivx_obj_desc_t **)prms->img_obj_desc,
                               prms->numCh);
    
                status = tivxCaptureSetCreateParams(prms, input_obj_desc);
            }
    
            /* Creating frame available event */
            if ((vx_status)VX_SUCCESS == status)
            {
                status = tivxEventCreate(&prms->frame_available);
    
                if ((vx_status)VX_SUCCESS != status)
                {
                    VX_PRINT(VX_ZONE_ERROR, "Event creation failed in capture!!!\r\n");
                }
            }
    
            /* Creating FVID2 handle */
            if ((vx_status)VX_SUCCESS == status)
            {
                for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
                {
                    instParams = &prms->instParams[instIdx];
                    Fvid2CbParams_init(&instParams->drvCbPrms);
    
                    instParams->drvCbPrms.cbFxn   = (Fvid2_CbFxn) &captDrvCallback;
                    instParams->drvCbPrms.appData = prms;
    
                    instParams->drvHandle = Fvid2_create(CSIRX_CAPT_DRV_ID,
                                                         instParams->instId,
                                                         &instParams->createPrms,
                                                         &instParams->createStatus,
                                                         &instParams->drvCbPrms);
    
                    if ((NULL == instParams->drvHandle) ||
                        (instParams->createStatus.retVal != FVID2_SOK))
                    {
                        VX_PRINT(VX_ZONE_ERROR, ": Capture Create Failed!!!\r\n");
                        status = (vx_status)VX_FAILURE;
                    }
                    else
                    {
                        /* Set CSIRX D-PHY configuration parameters */
                        Csirx_initDPhyCfg(&instParams->dphyCfg);
                        instParams->dphyCfg.inst = instParams->instId;
                        fvid2_status = Fvid2_control(
                            instParams->drvHandle, IOCTL_CSIRX_SET_DPHY_CONFIG,
                            &instParams->dphyCfg, NULL);
                        if (FVID2_SOK != fvid2_status)
                        {
                            status = (vx_status)VX_FAILURE;
                            VX_PRINT(VX_ZONE_ERROR, ": Failed to set PHY Parameters!!!\r\n");
                        }
                    }
                }
            }
    
            /* Creating FVID2 frame Q */
            if ((vx_status)VX_SUCCESS == status)
            {
                for(chId = 0u ; chId < prms->numCh ; chId++)
                {
                    status = tivxQueueCreate(&prms->freeFvid2FrameQ[chId], TIVX_CAPTURE_MAX_NUM_BUFS, prms->fvid2_free_q_mem[chId], 0);
    
                    if ((vx_status)VX_SUCCESS != status)
                    {
                        VX_PRINT(VX_ZONE_ERROR, ": Capture queue create failed!!!\r\n");
                        break;
                    }
    
                    for(bufId = 0u ; bufId < (TIVX_CAPTURE_MAX_NUM_BUFS) ; bufId++)
                    {
                        tivxQueuePut(&prms->freeFvid2FrameQ[chId], (uintptr_t)&prms->fvid2Frames[chId][bufId], TIVX_EVENT_TIMEOUT_NO_WAIT);
                    }
                }
            }
    
            /* Creating pending frame Q */
            if ((vx_status)VX_SUCCESS == status)
            {
                for(chId = 0U ; chId < prms->numCh ; chId++)
                {
                    status = tivxQueueCreate(&prms->pendingFrameQ[chId], TIVX_CAPTURE_MAX_NUM_BUFS, prms->pending_frame_free_q_mem[chId], 0);
    
                    if ((vx_status)VX_SUCCESS != status)
                    {
                        VX_PRINT(VX_ZONE_ERROR, ": Capture create failed!!!\r\n");
                        break;
                    }
                }
            }
    
            if ((vx_status)VX_SUCCESS == status)
            {
                tivxSetTargetKernelInstanceContext(kernel, prms, sizeof(tivxCaptureParams));
            }
            else if (NULL != prms)
            {
                for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
                {
                    instParams = &prms->instParams[instIdx];
                    if (NULL != instParams->drvHandle)
                    {
                        Fvid2_delete(instParams->drvHandle, NULL);
                        instParams->drvHandle = NULL;
                    }
                }
    
                if (NULL != prms->frame_available)
                {
                    tivxEventDelete(&prms->frame_available);
                }
    
                tivxMemFree(prms, sizeof(tivxCaptureParams), (vx_enum)TIVX_MEM_EXTERNAL);
            }
            else
            {
                /* do nothing */
            }
        }
    
        return status;
    }
    
    static void tivxCapturePrintStatus(tivxCaptureInstParams *prms)
    {
        int32_t fvid2_status;
        uint32_t cnt;
    
        if (NULL != prms)
        {
            fvid2_status = Fvid2_control(prms->drvHandle,
                                    IOCTL_CSIRX_GET_INST_STATUS,
                                    &prms->captStatus,
                                    NULL);
            tivx_set_debug_zone((vx_enum)VX_ZONE_INFO);
            if (FVID2_SOK == fvid2_status)
            {
                VX_PRINT(VX_ZONE_INFO,
                    "\n\r==========================================================\r\n");
                VX_PRINT(VX_ZONE_INFO,
                          ": Capture Status: Instance|%d\r\n", prms->instId);
                VX_PRINT(VX_ZONE_INFO,
                          "==========================================================\r\n");
                VX_PRINT(VX_ZONE_INFO,
                          ": FIFO Overflow Count: %d\r\n",
                          prms->captStatus.overflowCount);
                VX_PRINT(VX_ZONE_INFO,
                          ": Spurious UDMA interrupt count: %d\r\n",
                          prms->captStatus.spuriousUdmaIntrCount);
    
                VX_PRINT(VX_ZONE_INFO,
                    "  [Channel No] | Frame Queue Count |"
                    " Frame De-queue Count | Frame Drop Count |\n");
                for(cnt = 0U ; cnt < prms->numCh ; cnt ++)
                {
                    VX_PRINT(VX_ZONE_INFO,
                          "\t\t%d|\t\t%d|\t\t%d|\t\t%d|\n",
                          cnt,
                          prms->captStatus.queueCount[cnt],
                          prms->captStatus.dequeueCount[cnt],
                          prms->captStatus.dropCount[cnt]);
                }
            }
            else
            {
                VX_PRINT(VX_ZONE_ERROR, " CAPTURE: ERROR: FVID2 Control failed !!!\n");
            }
            tivx_clr_debug_zone((vx_enum)VX_ZONE_INFO);
        }
    }
    
    static vx_status VX_CALLBACK tivxCaptureDelete(
           tivx_target_kernel_instance kernel,
           tivx_obj_desc_t *obj_desc[],
           uint16_t num_params, void *priv_arg)
    {
        vx_status status = (vx_status)VX_SUCCESS;
        int32_t fvid2_status = FVID2_SOK;
        tivxCaptureParams *prms = NULL;
        static Fvid2_FrameList frmList;
        uint32_t size, chId, instIdx;
        tivxCaptureInstParams *instParams;
    
        if ( (num_params != TIVX_KERNEL_CAPTURE_MAX_PARAMS)
            || (NULL == obj_desc[TIVX_KERNEL_CAPTURE_INPUT_ARR_IDX])
            || (NULL == obj_desc[TIVX_KERNEL_CAPTURE_OUTPUT_IDX])
        )
        {
            status = (vx_status)VX_FAILURE;
        }
        else
        {
            status = tivxGetTargetKernelInstanceContext(kernel, (void **)&prms, &size);
    
            if ((vx_status)VX_SUCCESS != status)
            {
                VX_PRINT(VX_ZONE_ERROR, " CAPTURE: ERROR: Could not obtain kernel instance context !!!\n");
            }
    
            if(NULL == prms)
            {
                VX_PRINT(VX_ZONE_ERROR, "Kernel instance context is NULL!!!\n");
                status = (vx_status)VX_FAILURE;
            }
    
            if ((vx_status)VX_SUCCESS == status)
            {
                for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
                {
                    instParams = &prms->instParams[instIdx];
                    /* Stopping FVID2 Capture */
                    if ((vx_status)VX_SUCCESS == status)
                    {
                        fvid2_status = Fvid2_stop(instParams->drvHandle, NULL);
    
                        if (FVID2_SOK != fvid2_status)
                        {
                            status = (vx_status)VX_FAILURE;
                            VX_PRINT(VX_ZONE_ERROR, " CAPTURE: ERROR: FVID2 Capture not stopped !!!\n");
                        }
                    }
    
                    /* Dequeue all the request from the driver */
                    if ((vx_status)VX_SUCCESS == status)
                    {
                        Fvid2FrameList_init(&frmList);
                        do
                        {
                            fvid2_status = Fvid2_dequeue(
                                instParams->drvHandle,
                                &frmList,
                                0,
                                FVID2_TIMEOUT_NONE);
                        } while (FVID2_SOK == fvid2_status);
    
                        if (FVID2_ENO_MORE_BUFFERS != fvid2_status)
                        {
                            VX_PRINT(VX_ZONE_ERROR, " CAPTURE: ERROR: FVID2 Capture Dequeue Failed !!!\n");
                            status = (vx_status)VX_FAILURE;
                        }
                    }
    
                    if ((vx_status)VX_SUCCESS == status)
                    {
                        tivxCapturePrintStatus(instParams);
                    }
    
                    /* Deleting FVID2 handle */
                    if ((vx_status)VX_SUCCESS == status)
                    {
                        fvid2_status = Fvid2_delete(instParams->drvHandle, NULL);
    
                        if (FVID2_SOK != fvid2_status)
                        {
                            status = (vx_status)VX_FAILURE;
                            VX_PRINT(VX_ZONE_ERROR, " CAPTURE: ERROR: FVID2 Delete Failed !!!\n");
                        }
                    }
    
                    /* Free-ing kernel instance params */
                    if ( (vx_status)VX_SUCCESS == status)
                    {
                        instParams->drvHandle = NULL;
    
                        if (sizeof(tivxCaptureParams) == size)
                        {
                            tivxMemFree(prms, sizeof(tivxCaptureParams), (vx_status)TIVX_MEM_EXTERNAL);
                        }
                    }
                }
            }
    
            /* Deleting FVID2 frame Q */
            if ((vx_status)VX_SUCCESS == status)
            {
                for(chId = 0U; chId < prms->numCh ; chId++)
                {
                    tivxQueueDelete(&prms->freeFvid2FrameQ[chId]);
                }
            }
    
            /* Deleting pending frame Q */
            if ((vx_status)VX_SUCCESS == status)
            {
                for(chId= 0U ; chId < prms->numCh ; chId++)
                {
                    tivxQueueDelete(&prms->pendingFrameQ[chId]);
                }
            }
    
            /* Deleting event */
            if ((vx_status)VX_SUCCESS == status)
            {
                tivxEventDelete(&prms->frame_available);
            }
        }
    
        return status;
    }
    
    static void tivxCaptureCopyStatistics(tivxCaptureParams *prms,
        tivx_capture_statistics_t *capt_status_prms)
    {
        uint32_t i, instIdx, strmIdx;
        tivxCaptureInstParams *instParams;
    
        for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
        {
            instParams = &prms->instParams[instIdx];
            for (i = 0U ; i < instParams->numCh ; i++)
            {
                capt_status_prms->queueCount[instIdx][i]     = instParams->captStatus.queueCount[i];
                capt_status_prms->dequeueCount[instIdx][i]   = instParams->captStatus.dequeueCount[i];
                capt_status_prms->dropCount[instIdx][i]      = instParams->captStatus.dropCount[i];
            }
            capt_status_prms->overflowCount[instIdx]         = instParams->captStatus.overflowCount;
            capt_status_prms->spuriousUdmaIntrCount[instIdx] = instParams->captStatus.spuriousUdmaIntrCount;
            capt_status_prms->frontFIFOOvflCount[instIdx]    = instParams->captStatus.frontFIFOOvflCount;
            capt_status_prms->crcCount[instIdx]              = instParams->captStatus.crcCount;
            capt_status_prms->eccCount[instIdx]              = instParams->captStatus.eccCount;
            capt_status_prms->correctedEccCount[instIdx]     = instParams->captStatus.correctedEccCount;
            capt_status_prms->dataIdErrorCount[instIdx]      = instParams->captStatus.dataIdErrorCount;
            capt_status_prms->invalidAccessCount[instIdx]    = instParams->captStatus.invalidAccessCount;
            capt_status_prms->invalidSpCount[instIdx]        = instParams->captStatus.invalidSpCount;
            for (strmIdx = 0U ; strmIdx < TIVX_CAPTURE_MAX_STRM ; strmIdx++)
            {
                capt_status_prms->strmFIFOOvflCount[instIdx][strmIdx] =
                                instParams->captStatus.strmFIFOOvflCount[strmIdx];
            }
        }
    }
    
    static vx_status tivxCaptureGetStatistics(tivxCaptureParams *prms,
        tivx_obj_desc_user_data_object_t *usr_data_obj)
    {
        vx_status                             status = (vx_status)VX_SUCCESS;
        tivx_capture_statistics_t                 *capt_status_prms = NULL;
        void                                  *target_ptr;
    
        if (NULL != usr_data_obj)
        {
            target_ptr = tivxMemShared2TargetPtr(&usr_data_obj->mem_ptr);
    
            tivxMemBufferMap(target_ptr, usr_data_obj->mem_size,
                (vx_enum)VX_MEMORY_TYPE_HOST, (vx_enum)VX_WRITE_ONLY);
    
            if (sizeof(tivx_capture_statistics_t) ==
                    usr_data_obj->mem_size)
            {
                capt_status_prms = (tivx_capture_statistics_t *)target_ptr;
    
                tivxCaptureCopyStatistics(prms, capt_status_prms);
            }
            else
            {
                VX_PRINT(VX_ZONE_ERROR,
                    "tivxCaptureGetStatistics: Invalid Size \n");
                status = (vx_status)VX_ERROR_INVALID_PARAMETERS;
            }
    
            tivxMemBufferUnmap(target_ptr, usr_data_obj->mem_size,
                (vx_enum)VX_MEMORY_TYPE_HOST, (vx_enum)VX_WRITE_ONLY);
        }
        else
        {
            VX_PRINT(VX_ZONE_ERROR,
                "tivxCaptureGetStatistics: User Data Object is NULL \n");
            status = (vx_status)VX_ERROR_INVALID_PARAMETERS;
        }
    
        return (status);
    }
    
    static vx_status VX_CALLBACK tivxCaptureControl(
           tivx_target_kernel_instance kernel,
           uint32_t node_cmd_id, tivx_obj_desc_t *obj_desc[],
           uint16_t num_params, void *priv_arg)
    {
        vx_status status = (vx_status)VX_SUCCESS;
        int32_t fvid2_status = FVID2_SOK;
        uint32_t             size, instIdx;
        tivxCaptureParams *prms = NULL;
        tivxCaptureInstParams *instParams;
    
        status = tivxGetTargetKernelInstanceContext(kernel, (void **)&prms, &size);
    
        if ((vx_status)VX_SUCCESS != status)
        {
            VX_PRINT(VX_ZONE_ERROR,
                "tivxCaptureControl: Failed to Get Target Kernel Instance Context\n");
        }
        else if ((NULL == prms) ||
            (sizeof(tivxCaptureParams) != size))
        {
            VX_PRINT(VX_ZONE_ERROR,
                "tivxCaptureControl: Invalid Object Size\n");
            status = (vx_status)VX_FAILURE;
        }
        else
        {
            /* do nothing */
        }
    
        if ((vx_status)VX_SUCCESS == status)
        {
            switch (node_cmd_id)
            {
                case TIVX_CAPTURE_PRINT_STATISTICS:
                {
                    for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
                    {
                        instParams = &prms->instParams[instIdx];
                        tivxCapturePrintStatus(instParams);
                    }
                    break;
                }
                case TIVX_CAPTURE_GET_STATISTICS:
                {
                    if (NULL != obj_desc[0])
                    {
                        for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
                        {
                            instParams = &prms->instParams[instIdx];
                            fvid2_status = Fvid2_control(instParams->drvHandle,
                                                    IOCTL_CSIRX_GET_INST_STATUS,
                                                    &instParams->captStatus,
                                                    NULL);
                            if (FVID2_SOK != fvid2_status)
                            {
                                VX_PRINT(VX_ZONE_ERROR,
                                    "tivxCaptureControl: Get status returned failure\n");
                                status = (vx_status)VX_FAILURE;
                                break;
                            }
                        }
                        if ((vx_status)VX_SUCCESS == status)
                        {
                            status = tivxCaptureGetStatistics(prms,
                                (tivx_obj_desc_user_data_object_t *)obj_desc[0U]);
                            if ((vx_status)VX_SUCCESS != status)
                            {
                                VX_PRINT(VX_ZONE_ERROR,
                                    "tivxCaptureControl: Get status failed\n");
                                status = (vx_status)VX_FAILURE;
                            }
    
                        }
                    }
                    else
                    {
                        VX_PRINT(VX_ZONE_ERROR,
                            "tivxCaptureControl: User data object was NULL\n");
                        status = (vx_status)VX_FAILURE;
                    }
                    break;
                }
                default:
                {
                    VX_PRINT(VX_ZONE_ERROR,
                        "tivxCaptureControl: Invalid Command Id\n");
                    status = (vx_status)VX_FAILURE;
                    break;
                }
            }
        }
        return status;
    }
    
    void tivxAddTargetKernelCapture(void)
    {
        char target_name[TIVX_TARGET_MAX_NAME];
        vx_enum self_cpu;
    
        self_cpu = tivxGetSelfCpuId();
    
        if((self_cpu == (vx_enum)TIVX_CPU_ID_IPU1_0) || (self_cpu == (vx_enum)TIVX_CPU_ID_IPU1_1))
        {
            strncpy(target_name, TIVX_TARGET_CAPTURE1, TIVX_TARGET_MAX_NAME);
    
            vx_capture_target_kernel1 = tivxAddTargetKernelByName(
                                TIVX_KERNEL_CAPTURE_NAME,
                                target_name,
                                tivxCaptureProcess,
                                tivxCaptureCreate,
                                tivxCaptureDelete,
                                tivxCaptureControl,
                                NULL);
    
            strncpy(target_name, TIVX_TARGET_CAPTURE2, TIVX_TARGET_MAX_NAME);
    
            vx_capture_target_kernel2 = tivxAddTargetKernelByName(
                                TIVX_KERNEL_CAPTURE_NAME,
                                target_name,
                                tivxCaptureProcess,
                                tivxCaptureCreate,
                                tivxCaptureDelete,
                                tivxCaptureControl,
                                NULL);
        }
    }
    
    void tivxRemoveTargetKernelCapture(void)
    {
        vx_status status = (vx_status)VX_SUCCESS;
    
        status = tivxRemoveTargetKernel(vx_capture_target_kernel1);
        if(status == (vx_status)VX_SUCCESS)
        {
            vx_capture_target_kernel1 = NULL;
        }
        status = tivxRemoveTargetKernel(vx_capture_target_kernel2);
        if(status == (vx_status)VX_SUCCESS)
        {
            vx_capture_target_kernel2 = NULL;
        }
    }
    
    static void tivxCaptureGetChannelIndices(const tivxCaptureParams *prms,
                                             uint32_t instId,
                                             uint32_t *startChIdx,
                                             uint32_t *endChIdx)
    {
        uint32_t instIdx;
    
        *startChIdx = 0U;
        *endChIdx   = 0U;
        for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
        {
            /* get start channel ID here */
            if (instIdx == instId)
            {
                break;
            }
            else
            {
                *startChIdx += prms->instParams[instIdx].numCh;
            }
        }
        /* Get last channel ID here */
        if (instIdx < prms->numOfInstUsed)
        {
            *endChIdx = *startChIdx + prms->instParams[instIdx].numCh;
        }
    }
    
    static uint32_t tivxCaptureGetNodeChannelNum(const tivxCaptureParams *prms,
                                                 uint32_t instId,
                                                 uint32_t chId)
    {
        uint32_t instIdx, chIdx = 0U;
    
        /* Get addition of all the channels processed on all previous driver instances */
        for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
        {
            if (instIdx == instId)
            {
                break;
            }
            else
            {
                chIdx += prms->instParams[instIdx].numCh;
            }
        }
        chIdx += chId;
    
        return (chIdx);
    }
    
    static uint32_t tivxCaptureGetDrvInstIndex(const tivxCaptureParams *prms,
                                               uint32_t instId)
    {
        uint32_t instIdx, instVal;
    
        instVal = tivxCaptureMapInstId(instId);
        for (instIdx = 0U ; instIdx < prms->numOfInstUsed ; instIdx++)
        {
            if (prms->instParams[instIdx].instId == instVal)
            {
                /* Found out the index for required instance */
                break;
            }
        }
    
        return instIdx;
    }
    

  • Hi Vibhor,

    I have sent you capture node source code over email, can you please merge the changes in your code base and try first capture on instance1?

    I have tested instance0, it works fine.

    Rgds,

    Brijesh

  • Hi Brijesh,

    I already tried with those changes. vx_capture_target_without_vx_chagnes.c from my previous post has all of your changes. 

    I get following error because instId = 1 and numOfInstUsed = 1.

     

    App Create Graph Done!

    [MCU2_1] 59.277657 s: VX_ZONE_ERROR:[tivxCaptureSetCreateParams:412] CAPTURE: ERROR: Wrong Instance ID provided: 0 !!!
    1.068578 s: VX_ZONE_ERROR:[ownContextSendCmd:553] Command ack message returned failure cmd_status: -1
    1.068585 s: VX_ZONE_ERROR:[ownNodeKernelInit:486] Target kernel, TIVX_CMD_NODE_CREATE failed
    1.068672 s: VX_ZONE_ERROR:[ownGraphNodeKernelInit:583] kernel init for node 0, kernel com.ti.capture ... failed !!!
    1.068682 s: VX_ZONE_ERROR:[vxVerifyGraph:2010] Node kernel init failed
    1.068686 s: VX_ZONE_ERROR:[vxVerifyGraph:2064] Graph verify failed
    Graph 1 verify failed -1


    I modified the condition like this `if (instId > prms->numOfInstUsed)` but now I'm running into following error during graph run.


    [MCU2_1] 55.190546 s:
    [MCU2_1] 55.190597 s: IssSensor_Start status 0
    [MCU2_1] 55.190623 s: ImageSensor_RemoteServiceHandler: IM_SENSOR_CMD_STREAM_ON status 0x0
    [MCU2_1] 55.191011 s: src/fvid2_drvMgr.c @ Line 1193:
    [MCU2_1] 55.191046 s: Number of frames is zero!!
    [MCU2_1] 55.191076 s: src/csirx_drv.c @ Line 410:
    [MCU2_1] 55.191097 s: Check frame list error
    [MCU2_1] 55.191131 s: VX_ZONE_ERROR:[tivxCaptureEnqueueFrameToDriver:286] CAPTURE: ERROR: Frame could not be queued for frame 0 !!!
    [MCU2_1] 55.191184 s: VX_ZONE_ERROR:[tivxCaptureProcess:574] CAPTURE: ERROR: Enqueue Frame to Driver failed !!!
    [MCU2_1] 55.191234 s: VX_ZONE_ERROR:[tivxTargetKernelExecute:372] tivxTargetKernelExecute: Kernel process function for [com.ti.capture] returned error code: -1
    [MCU2_1] 55.191435 s: src/fvid2_drvMgr.c @ Line 1193:
    [MCU2_1] 55.191466 s: Number of frames is zero!!
    [MCU2_1] 55.191493 s: src/csirx_drv.c @ Line 410:
    [MCU2_1] 55.191513 s: Check frame list error
    [MCU2_1] 55.191587 s: VX_ZONE_ERROR:[tivxCaptureEnqueueFrameToDriver:286] CAPTURE: ERROR: Frame could not be queued for frame 0 !!!
    [MCU2_1] 55.191644 s: VX_ZONE_ERROR:[tivxCaptureProcess:574] CAPTURE: ERROR: Enqueue Frame to Driver failed !!!
    [MCU2_1] 55.191692 s: VX_ZONE_ERROR:[tivxTargetKernelExecute:372] tivxTargetKernelExecute: Kernel process function for [com.ti.capture] returned error code: -1
    [MCU2_1] 55.197174 s: src/fvid2_drvMgr.c @ Line 1193:
    [MCU2_1] 55.197209 s: Number of frames is zero!!

     

    Regards,

    Vibhor

  • Hi Vibhor,

    ok, there seems to some index issue in the Fvid2_FrameList, let me check and get back to you as soon as possible.

    Regards,

    Brijesh 

  • Hi Vibhor,

    I have changed slightly indices for the second instance. 

    Could you please try it with the attached patch? You could remove old patch and just apply attached patch. 

    https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/791/Dual_5F00_capture.patch

    Rgds,

    Brijesh

  • Hi Brijesh,

    The patch did not work. Here's the output log and display result.

    Right now we have two separate vx_graph runs using two tivx_task instances. Hope this is okay.

    Regards,

    Vibhor

    [MCU2_0]      0.000000 s: CIO: Init ... Done !!!
    [MCU2_0]      0.000000 s: ### CPU Frequency <ORG = 1000000000 Hz>, <NEW = 1000000000 Hz>
    [MCU2_0]      0.000000 s: APP: Init ... !!!
    [MCU2_0]      0.000000 s: SCICLIENT: Init ... !!!
    [MCU2_0]      0.000000 s: SCICLIENT: DMSC FW version [20.04.1-v2020.04a (Terrific Lla]
    [MCU2_0]      0.000000 s: SCICLIENT: DMSC FW revision 0x14
    [MCU2_0]      0.000000 s: SCICLIENT: DMSC FW ABI revision 3.0
    [MCU2_0]      0.000000 s: SCICLIENT: Init ... Done !!!
    [MCU2_0]      0.000000 s: UDMA: Init ... !!!
    [MCU2_0]      0.000000 s: UDMA: Init ... Done !!!
    [MCU2_0]      0.000000 s: MEM: Init ... !!!
    [MCU2_0]      0.000000 s: MEM: Created heap (DDR_SHARED_MEM, id=0, flags=0x00000004) @ d2800000 of size 16777216 bytes !!!
    [MCU2_0]      0.000000 s: MEM: Created heap (DDR_NON_CACHE_ME, id=5, flags=0x00000000) @ ce000000 of size 67108864 bytes !!!
    [MCU2_0]      0.000000 s: MEM: Init ... Done !!!
    [MCU2_0]      0.000000 s: FVID2: Init ... !!!
    [MCU2_0]      0.000000 s: FVID2: Init ... Done !!!
    [MCU2_0]      0.000000 s: VHWA: Init ... !!!
    [MCU2_0]      0.000000 s: SCICLIENT: Sciclient_pmSetModuleState module=290 state=2
    [MCU2_0]      0.000000 s: SCICLIENT: Sciclient_pmSetModuleState success
    [MCU2_0]      0.000000 s: SCICLIENT: Sciclient_pmSetModuleState module=48 state=2
    [MCU2_0]      0.000000 s: SCICLIENT: Sciclient_pmSetModuleState success
    [MCU2_0]      0.000000 s: SCICLIENT: Sciclient_pmSetModuleState module=305 state=2
    [MCU2_0]      0.000000 s: SCICLIENT: Sciclient_pmSetModuleState success
    [MCU2_0]      0.000000 s: VHWA: DOF Init ... !!!
    [MCU2_0]      0.000000 s: VHWA: DOF Init ... Done !!!
    [MCU2_0]      0.000000 s: VHWA: LDC Init ... !!!
    [MCU2_0]      0.000000 s: VHWA: LDC Init ... Done !!!
    [MCU2_0]      0.000000 s: VHWA: MSC Init ... !!!
    [MCU2_0]      0.000000 s: VHWA: MSC Init ... Done !!!
    [MCU2_0]      0.000000 s: VHWA: NF Init ... !!!
    [MCU2_0]      0.000000 s: VHWA: NF Init ... Done !!!
    [MCU2_0]      0.000000 s: VHWA: SDE Init ... !!!
    [MCU2_0]      0.000000 s: VHWA: SDE Init ... Done !!!
    [MCU2_0]      0.000000 s: VHWA: VISS Init ... !!!
    [MCU2_0]      0.000000 s: VHWA: VISS Init ... Done !!!
    [MCU2_0]      0.000000 s: VHWA: VDEC Init ... !!!
    [MCU2_0]      0.000000 s: VHWA: VDEC Init ... Done !!!
    [MCU2_0]      0.000000 s: VHWA: VENC Init ... !!!
    [MCU2_0]      0.000000 s: VHWA: VENC Init ... Done !!!
    [MCU2_0]      0.000000 s: VHWA: Init ... Done !!!
    [MCU2_0]      0.000000 s: IPC: Init ... !!!
    [MCU2_0]      0.000000 s: IPC: 5 CPUs participating in IPC !!!
    [MCU2_0]      0.000000 s: IPC: Waiting for HLOS to be ready ... !!!
    [MCU2_0]     21.547988 s: IPC: HLOS is ready !!!
    [MCU2_0]     21.553510 s: IPC: Init ... Done !!!
    [MCU2_0]     21.553581 s: APP: Syncing with 4 CPUs ... !!!
    [MCU2_0]     21.553629 s: APP: Syncing with 4 CPUs ... Done !!!
    [MCU2_0]     21.553659 s: REMOTE_SERVICE: Init ... !!!
    [MCU2_0]     21.555135 s: REMOTE_SERVICE: Init ... Done !!!
    [MCU2_0]     21.555199 s: ETHFW: Init ... !!!
    [MCU2_0]     21.654974 s: ETHFW: Version   : 0.01.01
    [MCU2_0]     21.655038 s: ETHFW: Build Date: Jul 16, 2020
    [MCU2_0]     21.655070 s: ETHFW: Build Time: 15:06:12
    [MCU2_0]     21.655092 s: ETHFW: Commit SHA: 44d02057
    [MCU2_0]     21.655119 s: ETHFW: Init ... DONE !!!
    [MCU2_0]     21.655144 s: ETHFW: Remove server Init ... !!!
    [MCU2_0]     21.698916 s: ETHFW: Remove server Init ... DONE !!!
    [MCU2_0]     21.698995 s: DSS: Init ... !!!
    [MCU2_0]     21.699021 s: DSS: Display type is eDP !!!
    [MCU2_0]     21.699043 s: DSS: SoC init ... !!!
    [MCU2_0]     21.699062 s: SCICLIENT: Sciclient_pmSetModuleState module=152 state=2
    [MCU2_0]     21.699264 s: SCICLIENT: Sciclient_pmSetModuleState success
    [MCU2_0]     21.699296 s: SCICLIENT: Sciclient_pmSetModuleState module=297 state=2
    [MCU2_0]     21.699558 s: SCICLIENT: Sciclient_pmSetModuleState success
    [MCU2_0]     21.699587 s: SCICLIENT: Sciclient_pmSetModuleState module=151 state=2
    [MCU2_0]     21.699768 s: SCICLIENT: Sciclient_pmSetModuleState success
    [MCU2_0]     21.699797 s: SCICLIENT: Sciclient_pmSetModuleClkParent module=152 clk=9 parent=11
    [MCU2_0]     21.699913 s: SCICLIENT: Sciclient_pmSetModuleClkParent success
    [MCU2_0]     21.699954 s: SCICLIENT: Sciclient_pmSetModuleClkParent module=152 clk=13 parent=18
    [MCU2_0]     21.700052 s: SCICLIENT: Sciclient_pmSetModuleClkParent success
    [MCU2_0]     21.700082 s: SCICLIENT: Sciclient_pmSetModuleClkParent module=152 clk=1 parent=2
    [MCU2_0]     21.700166 s: SCICLIENT: Sciclient_pmSetModuleClkParent success
    [MCU2_0]     21.700196 s: SCICLIENT: Sciclient_pmSetModuleClkFreq module=152 clk=1 freq=148500000
    [MCU2_0]     21.702884 s: SCICLIENT: Sciclient_pmSetModuleClkFreq success
    [MCU2_0]     21.702917 s: SCICLIENT: Sciclient_pmModuleClkRequest module=152 clk=1 state=2 flag=0
    [MCU2_0]     21.703012 s: SCICLIENT: Sciclient_pmModuleClkRequest success
    [MCU2_0]     21.703041 s: DSS: SoC init ... Done !!!
    [MCU2_0]     21.703063 s: DSS: Board init ... !!!
    [MCU2_0]     21.703086 s: DSS: Board init ... Done !!!
    [MCU2_0]     21.728979 s: DSS: Init ... Done !!!
    [MCU2_0]     21.729065 s:  VX_ZONE_INIT:Enabled
    [MCU2_0]     21.729094 s:  VX_ZONE_ERROR:Enabled
    [MCU2_0]     21.729117 s:  VX_ZONE_WARNING:Enabled
    [MCU2_0]     21.733416 s:  VX_ZONE_INIT:[tivxInit:71] Initialization Done !!!
    [MCU2_0]     21.733463 s: APP: OpenVX Target kernel init ... !!!
    [MCU2_0]     21.740495 s: APP: OpenVX Target kernel init ... Done !!!
    [MCU2_0]     21.740549 s: CSI2RX: Init ... !!!
    [MCU2_0]     21.740571 s: SCICLIENT: Sciclient_pmSetModuleState module=25 state=2
    [MCU2_0]     21.740669 s: SCICLIENT: Sciclient_pmSetModuleState success
    [MCU2_0]     21.740702 s: SCICLIENT: Sciclient_pmSetModuleState module=26 state=2
    [MCU2_0]     21.740846 s: SCICLIENT: Sciclient_pmSetModuleState success
    [MCU2_0]     21.740910 s: SCICLIENT: Sciclient_pmSetModuleState module=27 state=2
    [MCU2_0]     21.741066 s: SCICLIENT: Sciclient_pmSetModuleState success
    [MCU2_0]     21.741095 s: SCICLIENT: Sciclient_pmSetModuleState module=147 state=2
    [MCU2_0]     21.741187 s: SCICLIENT: Sciclient_pmSetModuleState success
    [MCU2_0]     21.741215 s: SCICLIENT: Sciclient_pmSetModuleState module=148 state=2
    [MCU2_0]     21.741307 s: SCICLIENT: Sciclient_pmSetModuleState success
    [MCU2_0]     21.742196 s: CSI2RX: Init ... Done !!!
    [MCU2_0]     21.742250 s: CSI2TX: Init ... !!!
    [MCU2_0]     21.742272 s: SCICLIENT: Sciclient_pmSetModuleState module=25 state=2
    [MCU2_0]     21.742364 s: SCICLIENT: Sciclient_pmSetModuleState success
    [MCU2_0]     21.742398 s: SCICLIENT: Sciclient_pmSetModuleState module=28 state=2
    [MCU2_0]     21.742544 s: SCICLIENT: Sciclient_pmSetModuleState success
    [MCU2_0]     21.742574 s: SCICLIENT: Sciclient_pmSetModuleState module=296 state=2
    [MCU2_0]     21.742689 s: SCICLIENT: Sciclient_pmSetModuleState success
    [MCU2_0]     21.743448 s: CSI2TX: Init ... Done !!!
    [MCU2_0]     21.743499 s: ISS: Init ... !!!
    [MCU2_0]     21.743544 s:
    [MCU2_0]     21.743576 s: IssSensor_Register()
    [MCU2_0]     21.743629 s: Found sensor IMX390-MAX9295-MAX9296A-LEOPARD at location 0
    [MCU2_0]     21.743662 s:
    [MCU2_0]     21.743680 s: IssSensor_Register()
    [MCU2_0]     21.743721 s: Found sensor ISX019-MAX96701-MAX96712-ZHIHUA at location 1
    [MCU2_0]     21.743752 s:
    [MCU2_0]     21.743772 s: IssSensor_Register()
    [MCU2_0]     21.743812 s: Found sensor AR0233-MAX9295-MAX9296A-JOC at location 2
    [MCU2_0]     21.743842 s: IssSensor_Init ... Done !!!
    [MCU2_0]     21.743976 s: vissRemoteServer_Init ... Done !!!
    [MCU2_0]     21.744057 s: IttRemoteServer_Init ... Done !!!
    [MCU2_0]     21.744092 s: UDMA Copy: Init ... !!!
    [MCU2_0]     21.745671 s: UDMA Copy: Init ... Done !!!
    [MCU2_0]     21.745726 s: APP: Init ... Done !!!
    [MCU2_0]     21.745751 s: APP: Run ... !!!
    [MCU2_0]     21.745772 s: IPC: Starting echo test ...
    [MCU2_0]     21.747731 s: APP: Run ... Done !!!
    [MCU2_0]     21.749322 s: IPC: Echo status: mpu1_0[x] mcu2_0[s] C66X_1[P] C66X_2[.] C7X_1[.]
    [MCU2_0]     21.749495 s: IPC: Echo status: mpu1_0[x] mcu2_0[s] C66X_1[P] C66X_2[P] C7X_1[.]
    [MCU2_0]     21.749615 s: IPC: Echo status: mpu1_0[x] mcu2_0[s] C66X_1[P] C66X_2[P] C7X_1[P]
    [C6x_1 ]      3.792823 s: CIO: Init ... Done !!!
    [C6x_1 ]      3.792855 s: ### CPU Frequency <ORG = 1350000000 Hz>, <NEW = 1350000000 Hz>
    [C6x_1 ]      3.792868 s: APP: Init ... !!!
    [C6x_1 ]      3.792876 s: SCICLIENT: Init ... !!!
    [C6x_1 ]      3.792972 s: SCICLIENT: DMSC FW version [20.04.1-v2020.04a (Terrific Lla]
    [C6x_1 ]      3.792985 s: SCICLIENT: DMSC FW revision 0x14
    [C6x_1 ]      3.792994 s: SCICLIENT: DMSC FW ABI revision 3.0
    [C6x_1 ]      3.793004 s: SCICLIENT: Init ... Done !!!
    [C6x_1 ]      3.793013 s: UDMA: Init ... !!!
    [C6x_1 ]      3.794448 s: UDMA: Init ... Done !!!
    [C6x_1 ]      3.794472 s: MEM: Init ... !!!
    [C6x_1 ]      3.794486 s: MEM: Created heap (DDR_SHARED_MEM, id=0, flags=0x00000004) @ d4000000 of size 16777216 bytes !!!
    [C6x_1 ]      3.794503 s: MEM: Created heap (L2_MEM, id=2, flags=0x00000001) @ 800000 of size 229376 bytes !!!
    [C6x_1 ]      3.794519 s: MEM: Created heap (DDR_SCRATCH_MEM, id=4, flags=0x00000001) @ d5000000 of size 50331648 bytes !!!
    [C6x_1 ]      3.794535 s: MEM: Init ... Done !!!
    [C6x_1 ]      3.794544 s: IPC: Init ... !!!
    [C6x_1 ]      3.794558 s: IPC: 5 CPUs participating in IPC !!!
    [C6x_1 ]      3.794571 s: IPC: Waiting for HLOS to be ready ... !!!
    [C6x_1 ]     20.109286 s: IPC: HLOS is ready !!!
    [C6x_1 ]     20.113539 s: IPC: Init ... Done !!!
    [C6x_1 ]     20.113571 s: APP: Syncing with 4 CPUs ... !!!
    [C6x_1 ]     21.553627 s: APP: Syncing with 4 CPUs ... Done !!!
    [C6x_1 ]     21.553642 s: REMOTE_SERVICE: Init ... !!!
    [C6x_1 ]     21.554276 s: REMOTE_SERVICE: Init ... Done !!!
    [C6x_1 ]     21.554317 s:  VX_ZONE_INIT:Enabled
    [C6x_1 ]     21.554327 s:  VX_ZONE_ERROR:Enabled
    [C6x_1 ]     21.554337 s:  VX_ZONE_WARNING:Enabled
    [C6x_1 ]     21.555214 s:  VX_ZONE_INIT:[tivxInit:71] Initialization Done !!!
    [C6x_1 ]     21.555232 s: APP: OpenVX Target kernel init ... !!!
    [C6x_1 ]     21.555601 s: APP: OpenVX Target kernel init ... Done !!!
    [C6x_1 ]     21.555623 s: UDMA Copy: Init ... !!!
    [C6x_1 ]     21.557522 s: UDMA Copy: Init ... Done !!!
    [C6x_1 ]     21.557543 s: APP: Init ... Done !!!
    [C6x_1 ]     21.557902 s: APP: Run ... !!!
    [C6x_1 ]     21.557914 s: IPC: Starting echo test ...
    [C6x_1 ]     21.558896 s: APP: Run ... Done !!!
    [C6x_1 ]     21.559330 s: IPC: Echo status: mpu1_0[x] mcu2_0[x] C66X_1[s] C66X_2[x] C7X_1[P]
    [C6x_1 ]     21.559552 s: IPC: Echo status: mpu1_0[x] mcu2_0[x] C66X_1[s] C66X_2[P] C7X_1[P]
    [C6x_1 ]     21.749020 s: IPC: Echo status: mpu1_0[x] mcu2_0[P] C66X_1[s] C66X_2[P] C7X_1[P]
    [C6x_2 ]      3.871403 s: CIO: Init ... Done !!!
    [C6x_2 ]      3.871435 s: ### CPU Frequency <ORG = 1350000000 Hz>, <NEW = 1350000000 Hz>
    [C6x_2 ]      3.871449 s: APP: Init ... !!!
    [C6x_2 ]      3.871457 s: SCICLIENT: Init ... !!!
    [C6x_2 ]      3.871554 s: SCICLIENT: DMSC FW version [20.04.1-v2020.04a (Terrific Lla]
    [C6x_2 ]      3.871567 s: SCICLIENT: DMSC FW revision 0x14
    [C6x_2 ]      3.871577 s: SCICLIENT: DMSC FW ABI revision 3.0
    [C6x_2 ]      3.871587 s: SCICLIENT: Init ... Done !!!
    [C6x_2 ]      3.871596 s: UDMA: Init ... !!!
    [C6x_2 ]      3.873037 s: UDMA: Init ... Done !!!
    [C6x_2 ]      3.873062 s: MEM: Init ... !!!
    [C6x_2 ]      3.873075 s: MEM: Created heap (DDR_SHARED_MEM, id=0, flags=0x00000004) @ d8000000 of size 16777216 bytes !!!
    [C6x_2 ]      3.873093 s: MEM: Created heap (L2_MEM, id=2, flags=0x00000001) @ 800000 of size 229376 bytes !!!
    [C6x_2 ]      3.873109 s: MEM: Created heap (DDR_SCRATCH_MEM, id=4, flags=0x00000001) @ d9000000 of size 50331648 bytes !!!
    [C6x_2 ]      3.873126 s: MEM: Init ... Done !!!
    [C6x_2 ]      3.873134 s: IPC: Init ... !!!
    [C6x_2 ]      3.873149 s: IPC: 5 CPUs participating in IPC !!!
    [C6x_2 ]      3.873161 s: IPC: Waiting for HLOS to be ready ... !!!
    [C6x_2 ]     20.488166 s: IPC: HLOS is ready !!!
    [C6x_2 ]     20.492365 s: IPC: Init ... Done !!!
    [C6x_2 ]     20.492397 s: APP: Syncing with 4 CPUs ... !!!
    [C6x_2 ]     21.553628 s: APP: Syncing with 4 CPUs ... Done !!!
    [C6x_2 ]     21.553642 s: REMOTE_SERVICE: Init ... !!!
    [C6x_2 ]     21.554293 s: REMOTE_SERVICE: Init ... Done !!!
    [C6x_2 ]     21.554332 s:  VX_ZONE_INIT:Enabled
    [C6x_2 ]     21.554343 s:  VX_ZONE_ERROR:Enabled
    [C6x_2 ]     21.554353 s:  VX_ZONE_WARNING:Enabled
    [C6x_2 ]     21.555217 s:  VX_ZONE_INIT:[tivxInit:71] Initialization Done !!!
    [C6x_2 ]     21.555235 s: APP: OpenVX Target kernel init ... !!!
    [C6x_2 ]     21.555602 s: APP: OpenVX Target kernel init ... Done !!!
    [C6x_2 ]     21.555623 s: UDMA Copy: Init ... !!!
    [C6x_2 ]     21.557644 s: UDMA Copy: Init ... Done !!!
    [C6x_2 ]     21.557666 s: APP: Init ... Done !!!
    [C6x_2 ]     21.558041 s: APP: Run ... !!!
    [C6x_2 ]     21.558051 s: IPC: Starting echo test ...
    [C6x_2 ]     21.559203 s: APP: Run ... Done !!!
    [C6x_2 ]     21.559566 s: IPC: Echo status: mpu1_0[x] mcu2_0[x] C66X_1[P] C66X_2[s] C7X_1[.]
    [C6x_2 ]     21.559617 s: IPC: Echo status: mpu1_0[x] mcu2_0[x] C66X_1[P] C66X_2[s] C7X_1[P]
    [C6x_2 ]     21.749056 s: IPC: Echo status: mpu1_0[x] mcu2_0[P] C66X_1[P] C66X_2[s] C7X_1[P]
    [C7x_1 ]      4.027483 s: CIO: Init ... Done !!!
    [C7x_1 ]      4.027509 s: ### CPU Frequency <ORG = 1000000000 Hz>, <NEW = 1000000000 Hz>
    [C7x_1 ]      4.027528 s: APP: Init ... !!!
    [C7x_1 ]      4.027539 s: SCICLIENT: Init ... !!!
    [C7x_1 ]      4.027602 s: SCICLIENT: DMSC FW version [20.04.1-v2020.04a (Terrific Lla]
    [C7x_1 ]      4.027618 s: SCICLIENT: DMSC FW revision 0x14
    [C7x_1 ]      4.027630 s: SCICLIENT: DMSC FW ABI revision 3.0
    [C7x_1 ]      4.027642 s: SCICLIENT: Init ... Done !!!
    [C7x_1 ]      4.027653 s: UDMA: Init ... !!!
    [C7x_1 ]      4.027790 s: UDMA: Init ... Done !!!
    [C7x_1 ]      4.027803 s: MEM: Init ... !!!
    [C7x_1 ]      4.027816 s: MEM: Created heap (DDR_SHARED_MEM, id=0, flags=0x00000004) @ dc000000 of size 268435456 bytes !!!
    [C7x_1 ]      4.027839 s: MEM: Created heap (L3_MEM, id=1, flags=0x00000001) @ 70020000 of size 8159232 bytes !!!
    [C7x_1 ]      4.027859 s: MEM: Created heap (L2_MEM, id=2, flags=0x00000001) @ 64800000 of size 491520 bytes !!!
    [C7x_1 ]      4.027878 s: MEM: Created heap (L1_MEM, id=3, flags=0x00000001) @ 64e00000 of size 16384 bytes !!!
    [C7x_1 ]      4.027896 s: MEM: Created heap (DDR_SCRATCH_MEM, id=4, flags=0x00000001) @ ec000000 of size 251658240 bytes !!!
    [C7x_1 ]      4.027917 s: MEM: Init ... Done !!!
    [C7x_1 ]      4.027926 s: IPC: Init ... !!!
    [C7x_1 ]      4.027938 s: IPC: 5 CPUs participating in IPC !!!
    [C7x_1 ]      4.027952 s: IPC: Waiting for HLOS to be ready ... !!!
    [C7x_1 ]     21.052140 s: IPC: HLOS is ready !!!
    [C7x_1 ]     21.054554 s: IPC: Init ... Done !!!
    [C7x_1 ]     21.054569 s: APP: Syncing with 4 CPUs ... !!!
    [C7x_1 ]     21.553628 s: APP: Syncing with 4 CPUs ... Done !!!
    [C7x_1 ]     21.553645 s: REMOTE_SERVICE: Init ... !!!
    [C7x_1 ]     21.553947 s: REMOTE_SERVICE: Init ... Done !!!
    [C7x_1 ]     21.553970 s:  VX_ZONE_INIT:Enabled
    [C7x_1 ]     21.553985 s:  VX_ZONE_ERROR:Enabled
    [C7x_1 ]     21.553996 s:  VX_ZONE_WARNING:Enabled
    [C7x_1 ]     21.554227 s:  VX_ZONE_INIT:[tivxInit:71] Initialization Done !!!
    [C7x_1 ]     21.554243 s: APP: OpenVX Target kernel init ... !!!
    [C7x_1 ]     21.554343 s: APP: OpenVX Target kernel init ... Done !!!
    [C7x_1 ]     21.554360 s: APP: Init ... Done !!!
    [C7x_1 ]     21.554372 s: APP: Run ... !!!
    [C7x_1 ]     21.554382 s: IPC: Starting echo test ...
    [C7x_1 ]     21.554813 s: APP: Run ... Done !!!
    [C7x_1 ]     21.559342 s: IPC: Echo status: mpu1_0[x] mcu2_0[x] C66X_1[P] C66X_2[x] C7X_1[s]
    [C7x_1 ]     21.559642 s: IPC: Echo status: mpu1_0[x] mcu2_0[x] C66X_1[P] C66X_2[P] C7X_1[s]
    [C7x_1 ]     21.749094 s: IPC: Echo status: mpu1_0[x] mcu2_0[P] C66X_1[P] C66X_2[P] C7X_1[s]
    APP: Init ... !!!
    MEM: Init ... !!!
    MEM: Initialized DMA HEAP (fd=4) !!!
    MEM: Init ... Done !!!
    IPC: Init ... !!!
    IPC: Init ... Done !!!
    REMOTE_SERVICE: Init ... !!!
    REMOTE_SERVICE: Init ... Done !!!
    APP: Init ... Done !!!
        44.015426 s:  VX_ZONE_INIT:Enabled
        44.015440 s:  VX_ZONE_ERROR:Enabled
        44.015445 s:  VX_ZONE_WARNING:Enabled
        44.017734 s:  VX_ZONE_INIT:[tivxInit:71] Initialization Done !!!
        44.017867 s:  VX_ZONE_INIT:[tivxHostInit:48] Initialization Done for HOST !!!
    sensor0_enabled = [1]
    Sensor 0 name = ISX019-MAX96701-MAX96712-ZHIHUA
    sensor0_input_size = 1280x960
    sensor0_number_of_cameras = [4]
    sensor1_enabled = [1]
    Sensor 1 name = IMX390-MAX9295-MAX9296A-LEOPARD
    sensor1_input_size = 1920x1080
    input_format = yvyu
    display_size = 1920x1080
    Creating context done!
    Kernel loading done!
    Querying ISX019-MAX96701-MAX96712-ZHIHUA
        44.024944 s: ISS: Querying sensor [ISX019-MAX96701-MAX96712-ZHIHUA] ... !!!
        44.025284 s: ISS: Querying sensor [ISX019-MAX96701-MAX96712-ZHIHUA] ... Done !!!
    Querying IMX390-MAX9295-MAX9296A-LEOPARD
        44.025294 s: ISS: Querying sensor [IMX390-MAX9295-MAX9296A-LEOPARD] ... !!!
        44.025555 s: ISS: Querying sensor [IMX390-MAX9295-MAX9296A-LEOPARD] ... Done !!!
        44.025560 s: ISS: Initializing sensor [ISX019-MAX96701-MAX96712-ZHIHUA], doing IM_SENSOR_CMD_PWRON ... !!!
        44.026066 s: ISS: Initializing sensor [ISX019-MAX96701-MAX96712-ZHIHUA], doing IM_SENSOR_CMD_CONFIG ... !!!
    [MCU2_0]     44.025047 s: ImageSensor_RemoteServiceHandler: IM_SENSOR_CMD_QUERY
    [MCU2_0]     44.025114 s: Received Query for ISX019-MAX96701-MAX96712-ZHIHUA
    [MCU2_0]     44.025165 s:
    [MCU2_0]     44.025199 s: IssSensor_GetSensorInfo()
    [MCU2_0]     44.025369 s: ImageSensor_RemoteServiceHandler: IM_SENSOR_CMD_QUERY
    [MCU2_0]     44.025419 s: Received Query for IMX390-MAX9295-MAX9296A-LEOPARD
    [MCU2_0]     44.025460 s:
    [MCU2_0]     44.025490 s: IssSensor_GetSensorInfo()
    [MCU2_0]     44.025627 s: ImageSensor_RemoteServiceHandler: IM_SENSOR_CMD_PWRON
    [MCU2_0]     44.025791 s:  I2C_open Successful for instance 1 !!!
    [MCU2_0]     44.025948 s:  I2C_open Successful for instance 6 !!!
    [MCU2_0]     44.025997 s: ISX019_PowerOn()
    [MCU2_0]     44.026143 s: ImageSensor_RemoteServiceHandler: IM_SENSOR_CMD_CONFIG
    [MCU2_0]     44.026193 s: Application requested features = 0x20
    [MCU2_0]
    [MCU2_0]     44.026245 s: ISX019_Config()
    [MCU2_0]     44.026269 s: quad_deser_and_serializer_config() start
    [MCU2_0]     47.529618 s: 96712: Reg Read Failed for regAddr 10
    [MCU2_0]     47.832593 s: 96712: Reg Read Failed for regAddr 11
    [MCU2_0]     49.035582 s: 96712: Reg Read Failed for regAddr e0d
    [MCU2_0]     57.235321 s: 96712: FAILED - Reg 0x18 Read Value 0x0 Written Value 0xf
        80.262069 s: ISS: Initializing sensor [ISX019-MAX96701-MAX96712-ZHIHUA] ... Done !!!
        80.262093 s: ISS: Initializing sensor [IMX390-MAX9295-MAX9296A-LEOPARD], doing IM_SENSOR_CMD_PWRON ... !!!
        80.262355 s: ISS: Initializing sensor [IMX390-MAX9295-MAX9296A-LEOPARD], doing IM_SENSOR_CMD_CONFIG ... !!!
    [MCU2_0]     80.261883 s:  End of quad_deser_and_serializer_config(), status 0 cnt 137
    [MCU2_0]     80.261960 s: IM_SENSOR_CMD_CONFIG returning status = 0
    [MCU2_0]     80.262199 s: ImageSensor_RemoteServiceHandler: IM_SENSOR_CMD_PWRON
    [MCU2_0]     80.262284 s: IMX390_PowerOn()
    [MCU2_0]     80.262425 s: ImageSensor_RemoteServiceHandler: IM_SENSOR_CMD_CONFIG
    [MCU2_0]     80.262474 s: Application requested features = 0x20
    [MCU2_0]
    [MCU2_0]     80.262527 s: IMX390_Config()
    [MCU2_0]     80.262552 s: dual_deser_and_serializer_config() start
    [MCU2_0]     80.262759 s: MAX9296 Des: Success for regAddr 313 regValue 0
    [MCU2_0]     80.282053 s: MAX9296 Des: Success for regAddr 10 regValue 15
    [MCU2_0]     80.382060 s: MAX9296 Des: Success for regAddr 12 regValue 10
    [MCU2_0]     80.482057 s: MAX9296 Des: Success for regAddr 1 regValue 2
    [MCU2_0]     80.502057 s: MAX9296 Des: Success for regAddr 2 regValue 63
    [MCU2_0]     80.522046 s: MAX9296 Des: Success for regAddr 10 regValue 31
    [MCU2_0]     80.649097 s: MAX9296 Des: Success for regAddr 1a regValue 3f
    [MCU2_0]     80.669091 s: MAX9296 Des: Success for regAddr 1c regValue ff
    [MCU2_0]     80.689088 s: MAX9296 Des: Success for regAddr 1e regValue ff
    [MCU2_0]     80.709100 s: MAX9295 Ser: Success for regAddr 2 regValue 3
    [MCU2_0]     80.729095 s: MAX9295 Ser: Success for regAddr 2be regValue 90
    [MCU2_0]     80.749088 s: MAX9295 Ser: Success for regAddr 2bf regValue 60
    [MCU2_0]     80.769083 s: MAX9295 Ser: Success for regAddr 3f1 regValue 89
    [MCU2_0]     80.789085 s: MAX9295 Ser: Success for regAddr 1c regValue cf
    [MCU2_0]     80.809099 s: MAX9295 Ser: Success for regAddr 1a regValue 3f
    [MCU2_0]     80.829089 s: MAX9296 Des: Success for regAddr 333 regValue 4e
    [MCU2_0]     80.849090 s: MAX9296 Des: Success for regAddr 334 regValue e4
    [MCU2_0]     80.869086 s: MAX9296 Des: Success for regAddr 40a regValue d0
    [MCU2_0]     80.889085 s: MAX9296 Des: Success for regAddr 44a regValue d0
    [MCU2_0]     80.909096 s: MAX9296 Des: Success for regAddr 48a regValue d0
    [MCU2_0]     80.929094 s: MAX9296 Des: Success for regAddr 4ca regValue d0
    [MCU2_0]     80.949087 s: MAX9296 Des: Success for regAddr 332 regValue f0
    [MCU2_0]     80.969086 s: MAX9296 Des: Success for regAddr 31d regValue 34
    [MCU2_0]     80.989083 s: MAX9296 Des: Success for regAddr 320 regValue 34
    [MCU2_0]     81.009096 s: MAX9296 Des: Success for regAddr 323 regValue 34
    [MCU2_0]     81.029091 s: MAX9296 Des: Success for regAddr 326 regValue 34
    [MCU2_0]     81.049090 s: MAX9296 Des: Success for regAddr 51 regValue 2
    [MCU2_0]     81.069089 s: MAX9296 Des: Success for regAddr 52 regValue 1
    [MCU2_0]     81.089085 s: MAX9296 Des: Success for regAddr 2c regValue 1
    [MCU2_0]     81.109093 s: MAX9295 Ser: Success for regAddr 2c regValue 1
    [MCU2_0]     81.129095 s: MAX9296 Des: Success for regAddr 10 regValue 31
        81.256035 s: ISS: Initializing sensor [IMX390-MAX9295-MAX9296A-LEOPARD] ... Done !!!
    Sensor init done!
    App Init Done!
    Graph 0 create done!
    Graph 1 create done!
    Capture init done!
    Channel 0 Extract init done!
    Channel 1 Extract init done!
    Channel 2 Extract init done!
    Merge init done!
    Convert init done!
    Scale init done!
    Display init done!
    Capture graph done!
    Channel 0 Extract graph done!
    Channel 0 Extract graph done!
    Channel 1 Extract graph done!
    Channel 1 Extract graph done!
    Channel 2 Extract graph done!
    Channel 2 Extract graph done!
    Merge graph done!
    Merge graph done!
    Convert graph done!
    Convert graph done!
    Scale graph done!
    mosaic 0 set node target status = 0
    Display graph done!
    Display graph done!
    Pipeline params setup done!
    App Create Graph Done!
    [MCU2_0]     81.255882 s: End of dual_deser_and_serializer_config(), status 0x0
    [MCU2_0]     81.255949 s: IM_SENSOR_CMD_CONFIG returning status = 0
    Graph 0 verify done!
    Grapy 1 verify done!
    Scaler is enabled
    scale_module[1] : sending coefficients
    App Verify Graph Done!
    tivxGraphParameterEnqueueReadyRef 0
    tivxGraphParameterEnqueueReadyRef 1
    vxGraphParameterEnqueueReadyRef 2
    Starting sensor 1
        81.409562 s: ISS: Starting sensor [IMX390-MAX9295-MAX9296A-LEOPARD] ... !!!
    [MCU2_0]     81.409704 s: ImageSensor_RemoteServiceHandler: IM_SENSOR_CMD_STREAM_ON Sensor: IMX390-MAX9295-MAX9296A-LEOPARD
    [MCU2_0]     81.409807 s:
    [MCU2_0]     81.409842 s: IssSensor_Start
    [MCU2_0]     81.409912 s: IMX390_StreamOn()
    [MCU2_0]     81.409944 s: dual_deser_and_serializer_config() start
    [MCU2_0]     81.410172 s: MAX9295 Ser: Success for regAddr 2 regValue 53
    [MCU2_0]     81.430104 s: MAX9296 Des: Success for regAddr 313 regValue 2
    [MCU2_0]     81.449878 s: End of dual_deser_and_serializer_config(), status 0x0
    [MCU2_0]     81.549895 s:
    [MCU2_0]     81.549956 s: read_max9296_status_registers()
    [MCU2_0]     81.550216 s: MAX9296 Reg 0x0 Value 0xd0
    [MCU2_0]     81.570122 s: MAX9296 Reg 0x1 Value 0x2
    [MCU2_0]     81.590122 s: MAX9296 Reg 0x2 Value 0x63
    [MCU2_0]     81.610130 s: MAX9296 Reg 0x3 Value 0x50
    [MCU2_0]     81.630126 s: MAX9296 Reg 0x5 Value 0xc0
    [MCU2_0]     81.650123 s: MAX9296 Reg 0xd Value 0x94
    [MCU2_0]     81.670125 s: MAX9296 Reg 0xe Value 0x7
    [MCU2_0]     81.690127 s: MAX9296 Reg 0x13 Value 0xde
    [MCU2_0]     81.710135 s: MAX9296 Reg 0x1a Value 0x3f
    [MCU2_0]     81.730414 s: MAX9296 Reg 0x1b Value 0x20
    [MCU2_0]     81.750132 s: MAX9296 Reg 0x1c Value 0xff
    [MCU2_0]     81.770138 s: MAX9296 Reg 0x1d Value 0x42
    [MCU2_0]     81.790130 s: MAX9296 Reg 0x1e Value 0xff
    [MCU2_0]     81.810145 s: MAX9296 Reg 0x1f Value 0x0
    [MCU2_0]     81.830230 s: MAX9296 Reg 0x20 Value 0x9f
    [MCU2_0]     81.850146 s: MAX9296 Reg 0x22 Value 0x0
    [MCU2_0]     81.870133 s: MAX9296 Reg 0x23 Value 0x0
    [MCU2_0]     81.890129 s: MAX9296 Reg 0x24 Value 0x0
    [MCU2_0]     81.910171 s: MAX9296 Reg 0x25 Value 0xff
    [MCU2_0]     81.930225 s: MAX9296 Reg 0x26 Value 0x22
    [MCU2_0]     81.950129 s: MAX9296 Reg 0x27 Value 0x22
    [MCU2_0]     81.970147 s: MAX9296 Reg 0x100 Value 0x32
    [MCU2_0]     81.990130 s: MAX9296 Reg 0x112 Value 0x32
    [MCU2_0]     82.010141 s: MAX9296 Reg 0x124 Value 0x32
    [MCU2_0]     82.030213 s: MAX9296 Reg 0x136 Value 0x32
    [MCU2_0]     82.050132 s: MAX9296 Reg 0x108 Value 0x2
    [MCU2_0]     82.070133 s: MAX9296 Reg 0x11a Value 0x62
    [MCU2_0]     82.090132 s: MAX9296 Reg 0x12c Value 0x2
    [MCU2_0]     82.110144 s: MAX9296 Reg 0x13e Value 0x2
    [MCU2_0]     82.130217 s: MAX9296 Reg 0x1dc Value 0x0
    [MCU2_0]     82.150128 s: MAX9296 Reg 0x1fc Value 0x1
    [MCU2_0]     82.170139 s: MAX9296 Reg 0x21c Value 0x0
    [MCU2_0]     82.190128 s: MAX9296 Reg 0x23c Value 0x0
    [MCU2_0]     82.210139 s: MAX9296 Reg 0x308 Value 0x61
    [MCU2_0]     82.230209 s: MAX9296 Reg 0x312 Value 0x0
    [MCU2_0]     82.250138 s: MAX9296 Reg 0x313 Value 0x2
    [MCU2_0]     82.270134 s: MAX9296 Reg 0x339 Value 0x0
    [MCU2_0]     82.290128 s: MAX9296 Reg 0x33a Value 0x2
    [MCU2_0]     82.310141 s: MAX9296 Reg 0x33b Value 0x0
    [MCU2_0]     82.330213 s: MAX9296 Reg 0x33c Value 0x2
    [MCU2_0]     82.350130 s: MAX9296 Reg 0x3f6 Value 0x0
    [MCU2_0]     82.370133 s: MAX9296 Reg 0x55c Value 0x0
    [MCU2_0]     82.390131 s: MAX9296 Reg 0x55d Value 0x0
    [MCU2_0]     82.410172 s: MAX9296 Reg 0x55e Value 0x0
    [MCU2_0]     82.430210 s: MAX9296 Reg 0x55f Value 0x0
    [MCU2_0]     82.549896 s:
    [MCU2_0]     82.549960 s: read_max9295_status_registers()
    [MCU2_0]     82.550243 s: MAX9295 Reg 0x0 Value 0xc4
    [MCU2_0]     82.570138 s: MAX9295 Reg 0x2 Value 0x53
    [MCU2_0]     82.590134 s: MAX9295 Reg 0xd Value 0x91
    [MCU2_0]     82.610135 s: MAX9295 Reg 0xe Value 0x8
    [MCU2_0]     82.630203 s: MAX9295 Reg 0x13 Value 0xde
    [MCU2_0]     82.650131 s: MAX9295 Reg 0x1a Value 0x2d
    [MCU2_0]     82.670137 s: MAX9295 Reg 0x1b Value 0x20
    [MCU2_0]     82.690130 s: MAX9295 Reg 0x1c Value 0x4f
    [MCU2_0]     82.710137 s: MAX9295 Reg 0x1d Value 0x2
    [MCU2_0]     82.730203 s: MAX9295 Reg 0x1e Value 0xfd
    [MCU2_0]     82.750130 s: MAX9295 Reg 0x1f Value 0x0
    [MCU2_0]     82.770151 s: MAX9295 Reg 0x22 Value 0x0
    [MCU2_0]     82.790130 s: MAX9295 Reg 0x23 Value 0x0
    [MCU2_0]     82.810137 s: MAX9295 Reg 0x24 Value 0x0
    [MCU2_0]     82.830197 s: MAX9295 Reg 0x25 Value 0x6
    [MCU2_0]     82.850134 s: MAX9295 Reg 0x100 Value 0x68
    [MCU2_0]     82.870129 s: MAX9295 Reg 0x108 Value 0x68
    [MCU2_0]     82.890127 s: MAX9295 Reg 0x110 Value 0x6a
    [MCU2_0]     82.910152 s: MAX9295 Reg 0x118 Value 0x68
    [MCU2_0]     82.930202 s: MAX9295 Reg 0x102 Value 0xa
    [MCU2_0]     82.950129 s: MAX9295 Reg 0x10a Value 0xa
    [MCU2_0]     82.970135 s: MAX9295 Reg 0x112 Value 0xca
    [MCU2_0]     82.990128 s: MAX9295 Reg 0x11a Value 0xa
    [MCU2_0]     83.010141 s: MAX9295 Reg 0x102 Value 0xa
    [MCU2_0]     83.030191 s: MAX9295 Reg 0x10a Value 0xa
    [MCU2_0]     83.050128 s: MAX9295 Reg 0x112 Value 0x8a
    [MCU2_0]     83.070141 s: MAX9295 Reg 0x11a Value 0xa
    [MCU2_0]     83.090130 s: MAX9295 Reg 0x102 Value 0xa
    [MCU2_0]     83.110145 s: MAX9295 Reg 0x10a Value 0xa
    [MCU2_0]     83.130191 s: MAX9295 Reg 0x112 Value 0x8a
    [MCU2_0]     83.150126 s: MAX9295 Reg 0x11a Value 0xa
    [MCU2_0]     83.170142 s: MAX9295 Reg 0x2be Value 0x98
    [MCU2_0]     83.190134 s: MAX9295 Reg 0x2bf Value 0x60
    [MCU2_0]     83.210159 s: MAX9295 Reg 0x339 Value 0x0
    [MCU2_0]     83.230189 s: MAX9295 Reg 0x33a Value 0x0
    [MCU2_0]     83.250132 s: MAX9295 Reg 0x33b Value 0x0
    [MCU2_0]     83.270155 s: MAX9295 Reg 0x33c Value 0x0
    [MCU2_0]     83.290130 s: MAX9295 Reg 0x33d Value 0x0
    [MCU2_0]     83.310137 s: MAX9295 Reg 0x33e Value 0x0
    [MCU2_0]     83.330195 s: MAX9295 Reg 0x33f Value 0x0
    [MCU2_0]     83.350133 s: MAX9295 Reg 0x340 Value 0x0
    [MCU2_0]     83.370139 s: MAX9295 Reg 0x341 Value 0x0
    [MCU2_0]     83.390133 s: MAX9295 Reg 0x342 Value 0x0
    [MCU2_0]     83.410154 s: MAX9295 Reg 0x343 Value 0x0
    [MCU2_0]     83.430193 s: MAX9295 Reg 0x344 Value 0x0
    [MCU2_0]     83.450130 s: MAX9295 Reg 0x3f1 Value 0x89
        83.470104 s: ISS: Starting sensor [IMX390-MAX9295-MAX9296A-LEOPARD] ... !!!
    Started sensor 1
    vxGraphParameterEnqueueReadyRef 3
    Done 1 refs
    Dequeue done
    Enqueue done
    
    Summary of CPU load,
    ====================
    
    CPU: mpu1_0: TOTAL LOAD =   0.36 % ( HWI =   0. 2 %, SWI =   0. 1 % )
    Starting sensor 0
        83.470425 s: ISS: Starting sensor [ISX019-MAX96701-MAX96712-ZHIHUA] ... !!!
    
    
     =========================
     Demo : Camera Demo
     =========================
    
     p: Print performance statistics
    
     c: Switch camera
    CPU: mcu2_0: TOTAL LOAD =   4.61 % ( HWI =   1. 1 %, SWI =   0.33 % )
    
     s: Save frames
    
     x: Exit
    
     Enter Choice: [MCU2_0]     83.469895 s:
    [MCU2_0]     83.469960 s: IssSensor_Start status 0
    [MCU2_0]     83.469987 s: ImageSensor_RemoteServiceHandler: IM_SENSOR_CMD_STREAM_ON status 0x0
    [MCU2_0]     83.470636 s: ImageSensor_RemoteServiceHandler: IM_SENSOR_CMD_STREAM_ON Sensor: ISX019-MAX96701-MAX96712-ZHIHUA
    [MCU2_0]     83.470725 s:
    [MCU2_0]     83.470757 s: IssSensor_Start
    [MCU2_0]     83.470792 s: ISX019_StreamOn()
    [MCU2_0]     83.470812 s: quad_deser_and_serializer_config() start
        84.574422 s: ISS: Starting sensor [ISX019-MAX96701-MAX96712-ZHIHUA] ... !!!
    Started sensor 0
    CPU:  c6x_1: TOTAL LOAD =   0. 6 % ( HWI =   0. 3 %, SWI =   0. 2 % )
    CPU:  c6x_2: TOTAL LOAD =   2.28 % ( HWI =   0. 4 %, SWI =   0. 2 % )
    [MCU2_0]     84.574176 s: 96701: slaveAddr 0x44 regAddr 0x4 attempts 1
    CPU:  c7x_1: TOTAL LOAD =   0. 8 % ( HWI =   0. 3 %, SWI =   0. 3 % )
    
    
    HWA performance statistics,
    ===========================
    
    [MCU2_0]     84.574228 s:  End of quad_deser_and_serializer_config(), status 0 cnt 6
    [MCU2_0]     84.574274 s:
    [MCU2_0]     84.574302 s: IssSensor_Start status 0
    [MCU2_0]     84.574322 s: ImageSensor_RemoteServiceHandler: IM_SENSOR_CMD_STREAM_ON status 0x0
    
    
    DDR performance statistics,
    ===========================
    
    DDR: READ  BW: AVG =     58 MB/s, PEAK =     64 MB/s
    DDR: WRITE BW: AVG =     16 MB/s, PEAK =     17 MB/s
    DDR: TOTAL BW: AVG =     74 MB/s, PEAK =     81 MB/s
    
    
    Detailed CPU performance/memory statistics,
    ===========================================
    
    CPU: mcu2_0: TASK:           IPC_RX:   0. 0 %
    CPU: mcu2_0: TASK:       REMOTE_SRV:   1.19 %
    CPU: mcu2_0: TASK:         TIVX_CPU:   0. 0 %
    CPU: mcu2_0: TASK:          TIVX_NF:   0. 0 %
    CPU: mcu2_0: TASK:        TIVX_LDC1:   0. 0 %
    CPU: mcu2_0: TASK:        TIVX_MSC1:   0. 1 %
    CPU: mcu2_0: TASK:        TIVX_MSC2:   0. 0 %
    CPU: mcu2_0: TASK:         TIVX_SDE:   0. 0 %
    CPU: mcu2_0: TASK:         TIVX_DOF:   0. 0 %
    CPU: mcu2_0: TASK:       TIVX_VISS1:   0. 0 %
    CPU: mcu2_0: TASK:       TIVX_CAPT1:   0. 0 %
    CPU: mcu2_0: TASK:       TIVX_CAPT2:   0. 1 %
    CPU: mcu2_0: TASK:       TIVX_DISP1:   0. 0 %
    CPU: mcu2_0: TASK:       TIVX_DISP2:   0. 0 %
    CPU: mcu2_0: TASK:       TIVX_VDEC1:   0. 0 %
    CPU: mcu2_0: TASK:       TIVX_VDEC2:   0. 0 %
    
    CPU: mcu2_0: HEAP:   DDR_SHARED_MEM: size =   16777216 B, free =   16650240 B ( 99 % unused)
    CPU: mcu2_0: HEAP:  DDR_NON_CACHE_M: size =   67108864 B, free =   47210496 B (  6 % unused)
    
    CPU:  c6x_1: TASK:           IPC_RX:   0. 0 %
    CPU:  c6x_1: TASK:       REMOTE_SRV:   0. 0 %
    CPU:  c6x_1: TASK:         TIVX_CPU:   0. 0 %
    CPU:  c6x_1: TASK:      IPC_TEST_RX:   0. 0 %
    CPU:  c6x_1: TASK:      IPC_TEST_TX:   0. 0 %
    CPU:  c6x_1: TASK:      IPC_TEST_TX:   0. 0 %
    CPU:  c6x_1: TASK:      IPC_TEST_TX:   0. 0 %
    CPU:  c6x_1: TASK:      IPC_TEST_TX:   0. 0 %
    
    CPU:  c6x_1: HEAP:   DDR_SHARED_MEM: size =   16777216 B, free =   16774912 B ( 99 % unused)
    CPU:  c6x_1: HEAP:           L2_MEM: size =     229376 B, free =     229376 B (100 % unused)
    CPU:  c6x_1: HEAP:  DDR_SCRATCH_MEM: size =   50331648 B, free =   50331648 B ( 14 % unused)
    
    CPU:  c6x_2: TASK:           IPC_RX:   0. 0 %
    CPU:  c6x_2: TASK:       REMOTE_SRV:   0. 0 %
    CPU:  c6x_2: TASK:         TIVX_CPU:   2.19 %
    CPU:  c6x_2: TASK:      IPC_TEST_RX:   0. 0 %
    CPU:  c6x_2: TASK:      IPC_TEST_TX:   0. 0 %
    CPU:  c6x_2: TASK:      IPC_TEST_TX:   0. 0 %
    CPU:  c6x_2: TASK:      IPC_TEST_TX:   0. 0 %
    CPU:  c6x_2: TASK:      IPC_TEST_TX:   0. 0 %
    
    CPU:  c6x_2: HEAP:   DDR_SHARED_MEM: size =   16777216 B, free =   16774912 B ( 99 % unused)
    CPU:  c6x_2: HEAP:           L2_MEM: size =     229376 B, free =     229376 B (100 % unused)
    CPU:  c6x_2: HEAP:  DDR_SCRATCH_MEM: size =   50331648 B, free =   50331648 B ( 14 % unused)
    
    CPU:  c7x_1: TASK:           IPC_RX:   0. 0 %
    CPU:  c7x_1: TASK:       REMOTE_SRV:   0. 0 %
    CPU:  c7x_1: TASK:         TIVX_CPU:   0. 0 %
    CPU:  c7x_1: TASK:      IPC_TEST_RX:   0. 0 %
    CPU:  c7x_1: TASK:      IPC_TEST_TX:   0. 0 %
    CPU:  c7x_1: TASK:      IPC_TEST_TX:   0. 0 %
    CPU:  c7x_1: TASK:      IPC_TEST_TX:   0. 0 %
    CPU:  c7x_1: TASK:      IPC_TEST_TX:   0. 0 %
    
    CPU:  c7x_1: HEAP:   DDR_SHARED_MEM: size =  268435456 B, free =  268435456 B (  4 % unused)
    CPU:  c7x_1: HEAP:           L3_MEM: size =    8159232 B, free =    8159232 B (100 % unused)
    CPU:  c7x_1: HEAP:           L2_MEM: size =     491520 B, free =     491520 B (100 % unused)
    CPU:  c7x_1: HEAP:           L1_MEM: size =      16384 B, free =      16384 B (100 % unused)
    CPU:  c7x_1: HEAP:  DDR_SCRATCH_MEM: size =  251658240 B, free =  251658240 B ( 14 % unused)
    
    
    GRAPH: app_visteon_graph_1 (#nodes =   8, #executions =      1)
     NODE:   CAPTURE2:          capture_node_s1: avg = 319553 usecs, min/max = 319553 / 319553 usecs, #executions =          1
     NODE:      DSP-2:        extract_node_s1c2: avg =  11439 usecs, min/max =  11439 /  11439 usecs, #executions =          1
     NODE:      DSP-2:        extract_node_s1c1: avg =  11447 usecs, min/max =  11447 /  11447 usecs, #executions =          1
     NODE:      DSP-2:        extract_node_s1c0: avg =  10098 usecs, min/max =  10098 /  10098 usecs, #executions =          1
     NODE:      DSP-2:            merge_node_s1: avg =  15718 usecs, min/max =  15718 /  15718 usecs, #executions =          1
     NODE:      DSP-2:                  Convert: avg =  17494 usecs, min/max =  17494 /  17494 usecs, #executions =          1
     NODE:  VPAC_MSC1:            scale_node_s1: avg =   5296 usecs, min/max =   5296 /   5296 usecs, #executions =          1
     NODE:   DISPLAY1:          display_node_s1: avg =     83 usecs, min/max =     83 /     83 usecs, #executions =          1
    
     PERF:  IMX390-MAX9295-: avg =     13 usecs, min/max =     13 /     13 usecs, #executions =          1
    
     PERF:  IMX390-MAX9295-: 76923. 7 FPS
    
    
    
    unknown input = 10
    
    
     =========================
     Demo : Camera Demo
     =========================
    
     p: Print performance statistics
    
     c: Switch camera
    
     s: Save frames
    
     x: Exit
    
     Enter Choice:

  • Hi Vibhor.

    I see capture is capturing but at very low fps, but i am not sure if it is for single instance  or for dual instance..

    Its bit difficult to review the statistics, could you please check if individual graphs are running independently fine? 

    Can we please first check if both the instances are working fine? 

    Regards,

    Brijesh

  • Hi Vibhor,

    There is an API, tivxCapturePrintStatus, in the capture node, which gets stats from the driver and prints on console. Can you try calling this API from main task, lets says, after every 50/100 frames captured? 

    I want to first check if capture is running fine and able to capture all configured channels on both the instances.

    Rgds,

    Brijesh 

  • Hi Brijesh,

    I called tivxCapturePrintStatus at the end of tivxCaptureProcess. When capture is enabled for only CSI-1 with single camera, I see the prints every frame. But when I enable all 5 cameras with two capture nodes and two graphs, I don't see these prints even once.

    Regards,

    Vibhor

  • Hi Vibhor,

    This feature is going to be supported in SDK7.1. So could you please wait and use SDK7.1 for using multi-CSI instance?

    Regards,

    Brijesh