Tool/software:
Hi Ti team
there are two camera with 1920*1536 resolution on J722s platform in SDK 10.1
when we set lookup Table of glbce to isp driver . one camera stream is ok,
but the other camera is flicking on the screen .
when we don't set the lookup Table of glbce , both of two cameras are ok .
please help me check.
best regards
sungenben
Hi sungenben,
Which sdk release are you using? Are both of these camera complete different? Is GLBCE context save and restore are enabled for these camera?
Regards,
Brijesh
Hi Brijesh
we use sdk 10.1
yes both of two cameras are the same ,but have own parameters .
yes we are enable the save and restore as below
vissDrvPrms->enableGlbceSaveRestoreCtx=TRUE;
BTW ,if we set the same lookup Table of glbce for two cameras ,
both of camera streams are ok .
best regards
sungenben
Hi Brijesh
I had added my source code ,could you help me check?
/******************************************************************************* * vx_vpac_ce_viss_target.c * * Target of ISP kernel for Cogent ISP framework. * * Copyright (c) 2015-2020 Cogent Embedded Inc. * ALL RIGHTS RESERVED. * * The source code contained or described herein and all documents related to the * source code("Software") or their modified versions are owned by * Cogent Embedded Inc. or its affiliates. * * No part of the Software may be used, copied, reproduced, modified, published, * uploaded, posted, transmitted, distributed, or disclosed in any way without * prior express written permission from Cogent Embedded Inc. * * Cogent Embedded Inc. grants a nonexclusive, non-transferable, royalty-free * license to use the Software to Licensee without the right to sublicense. * Licensee agrees not to distribute the Software to any third-party without * the prior written permission of Cogent Embedded Inc. * * Unless otherwise agreed by Cogent Embedded Inc. in writing, you may not remove * or alter this notice or any other notice embedded in Software in any way. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENt-> IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. *******************************************************************************/ /* ========================================================================== */ /* Include Files */ /* ========================================================================== */ #include "tivx_hwa_ce_viss_priv.h" #include "tivx_kernel_vpac_ce_viss.h" #include "utils/perf_stats/include/app_perf_stats.h" #include <utils/udma/include/app_udma.h> #include <common_sensor_api.h> #include <vx_vpac_ce_common.h> #include <inttypes.h> #include <stdlib.h> /* ========================================================================== */ /* Macros & Typedefs */ /* ========================================================================== */ /* #undef below to see performance without VISS GLBCE context save/restore */ #define VHWA_VISS_GLBCE_CTX_SAVE_RESTORE_ENABLE /* #undef below to see performance using CPU for VISS GLBCE context save/restore */ #define VHWA_VISS_GLBCE_CTX_SAVE_RESTORE_USE_DMA /* ========================================================================== */ /* Structure Declarations */ /* ========================================================================== */ /* ========================================================================== */ /* Function Declarations */ /* ========================================================================== */ static vx_status VX_CALLBACK tivxVpacCeVissCreate( tivx_target_kernel_instance kernel, tivx_obj_desc_t *obj_desc[], uint16_t num_params, void *priv_arg); static vx_status VX_CALLBACK tivxVpacCeVissDelete( tivx_target_kernel_instance kernel, tivx_obj_desc_t *obj_desc[], uint16_t num_params, void *priv_arg); static vx_status VX_CALLBACK tivxVpacCeVissProcess( tivx_target_kernel_instance kernel, tivx_obj_desc_t *obj_desc[], uint16_t num_params, void *priv_arg); static void tivxVpacVissSetInputParams(tivxVpacCeIspObj *ispObj, const tivx_obj_desc_raw_image_t *raw_img_desc); static vx_status tivxVpacVissSetOutputParams(tivxVpacCeIspObj *ispObj, const tivx_vpac_ce_isp_params_t *vissPrms, tivx_obj_desc_image_t *obj_desc[]); static vx_status tivxVpacVissMapFormat(uint32_t *fmt, uint32_t *ccsFmt, uint32_t out_id, uint32_t vxFmt, uint32_t mux_val); static vx_status tivxVpacVissMapStorageFormat(uint32_t *ccsFmt, uint32_t vxFmt); static void tivxVpacVissSetIsInvalidFlag(tivx_obj_desc_t *obj_desc[]); int32_t tivxVpacCeVissFrameComplCb(Fvid2_Handle handle, void *appData); static vx_status vhwaVissAllocMemForCtx(tivxVpacCeIspObj *ispObj); static void vhwaVissFreeCtxMem(tivxVpacCeIspObj *ispObj); static void vhwaVissRestoreCtx(const tivxVpacCeIspObj *ispObj); static void vhwaVissSaveCtx(const tivxVpacCeIspObj *ispObj); /* ========================================================================== */ /* Global Variables */ /* ========================================================================== */ static tivx_target_kernel vx_vpac_ce_viss_target_kernel = NULL; extern tivxVpacCeIspObj g_ceIspObjs[VHWA_M2M_VISS_MAX_HANDLES]; /* ========================================================================== */ /* Function Definitions */ /* ========================================================================== */ void tivxAddTargetKernelVpacCeViss(void) { vx_status status = (vx_status)VX_FAILURE; char target_name[TIVX_TARGET_MAX_NAME]; vx_enum self_cpu; self_cpu = tivxGetSelfCpuId(); if (self_cpu == (vx_enum)TIVX_CPU_ID_MCU2_0) { strncpy(target_name, TIVX_TARGET_VPAC_CE_VISS, TIVX_TARGET_MAX_NAME); status = (vx_status)VX_SUCCESS; } else { VX_PRINT(VX_ZONE_ERROR, "Invalid CPU ID\n"); status = (vx_status)VX_FAILURE; } if (status == (vx_status)VX_SUCCESS) { vx_vpac_ce_viss_target_kernel = tivxAddTargetKernelByName( TIVX_KERNEL_VPAC_CE_VISS_NAME, target_name, tivxVpacCeVissProcess, tivxVpacCeVissCreate, tivxVpacCeVissDelete, NULL, NULL); } if (NULL == vx_vpac_ce_viss_target_kernel) { VX_PRINT(VX_ZONE_ERROR, "Failed to add target kernel by name %s\n", TIVX_TARGET_VPAC_CE_VISS); } } void tivxRemoveTargetKernelVpacCeViss(void) { vx_status status = (vx_status)VX_SUCCESS; status = tivxRemoveTargetKernel(vx_vpac_ce_viss_target_kernel); if (status == (vx_status)VX_SUCCESS) { vx_vpac_ce_viss_target_kernel = NULL; } else { VX_PRINT(VX_ZONE_ERROR, "Failed to Remove Viss TargetKernel\n"); } } /* Setting the output descriptor flags to invalid if received raw_image is invalid */ static void tivxVpacVissSetIsInvalidFlag(tivx_obj_desc_t *obj_desc[]) { uint32_t cnt; uint32_t out_start; if (tivxFlagIsBitSet(obj_desc[TIVX_KERNEL_VPAC_CE_VISS_RAW_IDX]->flags, TIVX_REF_FLAG_IS_INVALID) == 1U) { for (cnt = 0U; cnt < TIVX_KERNEL_VPAC_CE_VISS_MAX_IMAGE_OUTPUT; cnt++) { out_start = TIVX_KERNEL_VPAC_CE_VISS_OUT0_IDX; if (NULL != obj_desc[out_start]) { tivxFlagBitSet(&obj_desc[out_start]->flags, TIVX_REF_FLAG_IS_INVALID); } out_start++; } } else { for (cnt = 0U; cnt < TIVX_KERNEL_VPAC_CE_VISS_MAX_IMAGE_OUTPUT; cnt++) { out_start = TIVX_KERNEL_VPAC_CE_VISS_OUT0_IDX; if (NULL != obj_desc[out_start]) { tivxFlagBitClear(&obj_desc[out_start]->flags, TIVX_REF_FLAG_IS_INVALID); } out_start++; } } } /* ========================================================================== */ /* OPENVX Callbacks */ /* ========================================================================== */ static vx_status VX_CALLBACK tivxVpacCeVissCreate( 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; uint32_t cnt; tivxVpacCeIspObj *ispObj = NULL; tivx_vpac_ce_isp_params_t *ispPrms = NULL; tivx_obj_desc_image_t *img_desc[TIVX_KERNEL_VPAC_CE_VISS_MAX_IMAGE_OUTPUT]; tivx_obj_desc_raw_image_t *raw_img_desc = (tivx_obj_desc_raw_image_t *)obj_desc[TIVX_KERNEL_VPAC_CE_VISS_RAW_IDX]; tivx_obj_desc_user_data_object_t *config_desc = (tivx_obj_desc_user_data_object_t *)obj_desc[TIVX_KERNEL_VPAC_CE_VISS_CONFIGURATION_IDX]; for (cnt = 0U; cnt < TIVX_KERNEL_VPAC_CE_VISS_MAX_IMAGE_OUTPUT; cnt++) { img_desc[cnt] = (tivx_obj_desc_image_t *) obj_desc[TIVX_KERNEL_VPAC_CE_VISS_OUT0_IDX + cnt]; } status = tivxVpacCeMapUserDesc((void **)&ispPrms, config_desc, sizeof(tivx_vpac_ce_isp_params_t), (vx_enum)VX_READ_ONLY); if ((vx_status)VX_SUCCESS != status) { VX_PRINT(VX_ZONE_ERROR, "Failed to Map Parameters Descriptor\n"); } else { ispObj = &g_ceIspObjs[ispPrms->context_id]; /* local copy */ memcpy((void *)&ispObj->ispPrms, (void *)ispPrms, sizeof(tivx_vpac_ce_isp_params_t)); tivxVpacCeUnmapUserDesc((void **)&ispPrms, config_desc, (vx_enum)VX_READ_ONLY); ispPrms = &ispObj->ispPrms; } if ((vx_status)VX_SUCCESS == status) { status = tivxEventCreate(&ispObj->eventProcessCmpl); if ((vx_status)VX_SUCCESS != status) { VX_PRINT(VX_ZONE_ERROR, "Failed to allocate Event\n"); } } if ((vx_status)VX_SUCCESS == status) { status = tivxEventCreate(&ispObj->eventVissCmpl); if ((vx_status)VX_SUCCESS != status) { VX_PRINT(VX_ZONE_ERROR, "Failed to allocate Event\n"); } tivxEventPost(ispObj->eventVissCmpl); } if ((vx_status)VX_SUCCESS == status) { status = tivxEventCreate(&ispObj->eventRcCmpl); if ((vx_status)VX_SUCCESS != status) { VX_PRINT(VX_ZONE_ERROR, "Failed to allocate Event\n"); } } if ((vx_status)VX_SUCCESS == status) { Vhwa_M2mVissCreateArgs createArgs; Vhwa_m2mVissCreateArgsInit(&createArgs); Fvid2_CbParams cbPrms; cbPrms.cbFxn = tivxVpacCeVissFrameComplCb; cbPrms.appData = ispObj; ispObj->handle = Fvid2_create(FVID2_VHWA_M2M_VISS_DRV_ID, VHWA_M2M_VISS_DRV_INST0, &createArgs, NULL, &cbPrms); if (NULL == ispObj->handle) { VX_PRINT(VX_ZONE_ERROR, "Failed to Open Driver\n"); status = (vx_status)VX_ERROR_NO_RESOURCES; } } /* #<{(| before writing configuration set application buffer |)}># */ if ((vx_status) VX_SUCCESS == status) { status = tivxVpacCeVissSetConfigBuffer(ispObj); if (VX_SUCCESS != status) { VX_PRINT(VX_ZONE_ERROR, "Failed to set ConfigBuf in driver\n"); } } /* Allocate memory for the GLBCE Statistics */ if ((vx_status)VX_SUCCESS == status) { status = vhwaVissAllocMemForCtx(ispObj); } if ((vx_status)VX_SUCCESS == status) { Vhwa_M2mVissParams *vissDrvPrms = &ispObj->vissPrms; Vhwa_m2mVissParamsInit(vissDrvPrms); vissDrvPrms->enableDpc = (uint32_t)FALSE; vissDrvPrms->enableGlbce = (uint32_t)TRUE; vissDrvPrms->enableNsf4 = (uint32_t)TRUE; vissDrvPrms->edgeEnhancerMode = VHWA_M2M_VISS_EE_ON_LUMA8; vissDrvPrms->enableGlbceSaveRestoreCtx=TRUE; // vissDrvPrms->cfa_mode=1; vissDrvPrms->chromaMode=0; vissDrvPrms->enableCac=0; tivxVpacVissSetInputParams(ispObj, raw_img_desc); status = tivxVpacVissSetOutputParams(ispObj, ispPrms, img_desc); if ((vx_status)VX_SUCCESS != status) { VX_PRINT(VX_ZONE_ERROR, "Failed to set Output Params\n"); } } if ((vx_status)VX_SUCCESS == status) { int32_t fvid2_status = Fvid2_control(ispObj->handle, IOCTL_VHWA_M2M_VISS_SET_PARAMS, (void *)&ispObj->vissPrms, NULL); if (FVID2_SOK != fvid2_status) { VX_PRINT(VX_ZONE_ERROR, "Failed to set Params in driver\n"); status = (vx_status)VX_FAILURE; } } if ((vx_status)VX_SUCCESS == status) { status = tivxSetTargetKernelInstanceContext(kernel, ispObj, sizeof(tivxVpacCeIspObj)); if ((vx_status)VX_SUCCESS != status) { VX_PRINT(VX_ZONE_ERROR, "Failed to set target kernel instance\n"); } } if ((vx_status)VX_SUCCESS == status) { /* Set up the input frame list */ for (cnt = 0U; cnt < ispObj->num_in_buf; cnt++) { ispObj->inFrmList.frames[cnt] = &ispObj->inFrm[cnt]; } ispObj->inFrmList.numFrames = ispObj->num_in_buf; /* Set up the output frame list */ for (cnt = 0U; cnt < VHWA_M2M_VISS_MAX_OUTPUTS; cnt++) { ispObj->outFrmList.frames[cnt] = &ispObj->outFrm[cnt]; } ispObj->outFrmList.numFrames = VHWA_M2M_VISS_MAX_OUTPUTS; } if ((vx_status)VX_SUCCESS != status) { if (NULL != ispObj) { if (NULL != ispObj->handle) { Fvid2_delete(ispObj->handle, NULL); ispObj->handle = NULL; } if (NULL != ispObj->eventProcessCmpl) { tivxEventDelete(&ispObj->eventProcessCmpl); } if (NULL != ispObj->eventRcCmpl) { tivxEventDelete(&ispObj->eventRcCmpl); } if (NULL != ispObj->eventVissCmpl) { tivxEventDelete(&ispObj->eventVissCmpl); } vhwaVissFreeCtxMem(ispObj); } } return (status); } static vx_status VX_CALLBACK tivxVpacCeVissDelete( 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; uint32_t size; tivxVpacCeIspObj *ispObj = NULL; status = tivxGetTargetKernelInstanceContext(kernel, (void **)&ispObj, &size); if ((vx_status)VX_SUCCESS != status) { VX_PRINT(VX_ZONE_ERROR, "Incorrect kernel instance context\n"); } else if ((NULL == ispObj) || (sizeof(tivxVpacCeIspObj) != size)) { VX_PRINT(VX_ZONE_ERROR, "Incorrect Object Size\n"); status = (vx_status)VX_FAILURE; } else { Fvid2_delete(ispObj->handle, NULL); ispObj->handle = NULL; if (NULL != ispObj->eventProcessCmpl) { tivxEventDelete(&ispObj->eventProcessCmpl); } if (NULL != ispObj->eventRcCmpl) { tivxEventDelete(&ispObj->eventRcCmpl); } if (NULL != ispObj->eventVissCmpl) { tivxEventDelete(&ispObj->eventVissCmpl); } vhwaVissFreeCtxMem(ispObj); } return (status); } static vx_status VX_CALLBACK tivxVpacCeVissProcess( 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; uint32_t cnt; uint32_t buf_cnt; uint32_t size; tivxVpacCeIspObj *ispObj = NULL; uint64_t cur_time; tivx_obj_desc_image_t *img_desc[TIVX_KERNEL_VPAC_CE_VISS_MAX_IMAGE_OUTPUT]; tivx_obj_desc_raw_image_t *raw_img_desc = (tivx_obj_desc_raw_image_t *)obj_desc[TIVX_KERNEL_VPAC_CE_VISS_RAW_IDX]; for (cnt = 0U; cnt < TIVX_KERNEL_VPAC_CE_VISS_MAX_IMAGE_OUTPUT; cnt++) { img_desc[cnt] = (tivx_obj_desc_image_t *) obj_desc[TIVX_KERNEL_VPAC_CE_VISS_OUT0_IDX + cnt]; } status = tivxGetTargetKernelInstanceContext(kernel, (void **)&ispObj, &size); if ((vx_status)VX_SUCCESS != status) { VX_PRINT(VX_ZONE_ERROR, "Incorrect kernel instance context\n"); } else if ((NULL == ispObj) || (sizeof(tivxVpacCeIspObj) != size)) { VX_PRINT(VX_ZONE_ERROR, "Incorrect Object Size\n"); status = (vx_status)VX_FAILURE; } if ((vx_status)VX_SUCCESS == status) { tivxVpacVissSetIsInvalidFlag(obj_desc); } if ((vx_status)VX_SUCCESS == status) { for (cnt = 0u; cnt < ispObj->num_in_buf; cnt++) { ispObj->inFrm[cnt].addr[0u] = tivxMemShared2PhysPtr( raw_img_desc->img_ptr[cnt].shared_ptr, (int32_t)raw_img_desc->img_ptr[cnt].mem_heap_region); } for (cnt = 0u; cnt < TIVX_KERNEL_VPAC_CE_VISS_MAX_IMAGE_OUTPUT; cnt++) { for (buf_cnt = 0U; buf_cnt < ispObj->num_out_buf_addr[cnt]; buf_cnt++) { ispObj->outFrm[cnt].addr[buf_cnt] = tivxMemShared2PhysPtr( img_desc[cnt]->mem_ptr[buf_cnt].shared_ptr, (int32_t)img_desc[cnt]->mem_ptr[buf_cnt].mem_heap_region); } } ispObj->outFrm[VHWA_M2M_VISS_OUT_H3A_IDX].addr[0u] = (uint64_t)ispObj->h3a_stats_data; /*.. Propagate timestamps. WARNING: Output index 2 is YUV image */ img_desc[2u]->base.timestamp = raw_img_desc->base.timestamp; } tivxEventWait(ispObj->eventRcCmpl, TIVX_EVENT_TIMEOUT_WAIT_FOREVER); cur_time = tivxPlatformGetTimeInUsecs(); if ((vx_status)VX_SUCCESS == status) { vhwaVissRestoreCtx(ispObj); fvid2_status = Fvid2_processRequest(ispObj->handle, &ispObj->inFrmList, &ispObj->outFrmList, FVID2_TIMEOUT_FOREVER); if (FVID2_SOK != fvid2_status) { VX_PRINT(VX_ZONE_ERROR, "Failed to Submit Request\n"); status = (vx_status)VX_FAILURE; } else { tivxEventWait(ispObj->eventProcessCmpl, TIVX_EVENT_TIMEOUT_WAIT_FOREVER); fvid2_status = Fvid2_getProcessedRequest(ispObj->handle, &ispObj->inFrmList, &ispObj->outFrmList, 0); if (FVID2_SOK != fvid2_status) { VX_PRINT(VX_ZONE_ERROR, "Failed to Get Processed Request\n"); status = (vx_status)VX_FAILURE; } //VX_PRINT(VX_ZONE_ERROR, "success to Get Processed Request\n"); } vhwaVissSaveCtx(ispObj); } if ((vx_status)VX_SUCCESS == status) { if (ispObj->yuvData.valid) { tivxYuvEmbData *g = &ispObj->yuvData; tivx_shared_mem_ptr_t *ptr = &img_desc[g->output_idx]->mem_ptr[g->buf_idx]; uint8_t *data = (uint8_t *)tivxMemShared2TargetPtr(ptr); tivxMemBufferMap((void *)data, sizeof(g->data), (vx_enum)VX_MEMORY_TYPE_HOST, (vx_enum)VX_WRITE_ONLY); if (NULL == data) { VX_PRINT(VX_ZONE_ERROR, "Failed to map YUV embedded data image patch\n"); } else { memcpy(data, g->data, sizeof(g->data)); tivxMemBufferUnmap((void *)data, sizeof(g->data), (vx_enum)VX_MEMORY_TYPE_HOST, (vx_enum)VX_WRITE_ONLY); } } tivxEventPost(ispObj->eventVissCmpl); cur_time = tivxPlatformGetTimeInUsecs() - cur_time; appPerfStatsHwaUpdateLoad(APP_PERF_HWA_CE_VISS, (uint32_t)cur_time, raw_img_desc->params.width * raw_img_desc->params.height); } return (status); } /* ========================================================================== */ /* Local Functions */ /* ========================================================================== */ static vx_status tivxVpacVissSetOutputParams(tivxVpacCeIspObj *ispObj, const tivx_vpac_ce_isp_params_t *ispPrms, tivx_obj_desc_image_t *obj_desc[]) { vx_status status = (vx_status)VX_SUCCESS; uint32_t cnt; uint32_t out_cnt; uint32_t mux_val[TIVX_KERNEL_VPAC_CE_VISS_MAX_IMAGE_OUTPUT]; uint32_t out_start; Vhwa_M2mVissOutputParams *outPrms = NULL; Vhwa_M2mVissParams *vissDrvPrms; tivx_obj_desc_image_t *im_desc; mux_val[0U] = ispPrms->mux_output0; mux_val[1U] = ispPrms->mux_output1; mux_val[2U] = ispPrms->mux_output2; mux_val[3U] = ispPrms->mux_output3; mux_val[4U] = ispPrms->mux_output4; vissDrvPrms = &ispObj->vissPrms; out_start = TIVX_KERNEL_VPAC_CE_VISS_OUT0_IDX; for (out_cnt = 0u; out_cnt < TIVX_KERNEL_VPAC_CE_VISS_MAX_IMAGE_OUTPUT; out_cnt++) { ispObj->num_out_buf_addr[out_cnt] = 0U; im_desc = obj_desc[out_cnt]; if (NULL != obj_desc[out_cnt]) { outPrms = &vissDrvPrms->outPrms[out_cnt]; status = tivxVpacVissMapFormat(&outPrms->fmt.dataFormat, &outPrms->fmt.ccsFormat, out_start, im_desc->format, mux_val[out_cnt]); if ((vx_status)VX_SUCCESS == status) { outPrms->enable = TRUE; outPrms->fmt.width = im_desc->width; outPrms->fmt.height = im_desc->height; for (cnt = 0u; cnt < TIVX_IMAGE_MAX_PLANES; cnt++) { outPrms->fmt.pitch[cnt] = (uint32_t)im_desc->imagepatch_addr[cnt].stride_y; } } else { VX_PRINT(VX_ZONE_ERROR, "Failed to map format for output%d\n", out_cnt); } /* TODO: See if there are any others here */ if ((FVID2_DF_YUV420SP_UV == outPrms->fmt.dataFormat) || (FVID2_DF_YUV422SP_UV == outPrms->fmt.dataFormat)) { ispObj->num_out_buf_addr[out_cnt] = 2U; } else { ispObj->num_out_buf_addr[out_cnt] = 1U; } } if ((vx_status)VX_SUCCESS != status) { break; } out_start++; } if ((vx_status)VX_SUCCESS == status) { outPrms = &vissDrvPrms->outPrms[VHWA_M2M_VISS_OUT_H3A_IDX]; outPrms->enable = (uint32_t)TRUE; outPrms->fmt.dataFormat = FVID2_DF_RAW; } return (status); } static void tivxVpacVissSetInputParams(tivxVpacCeIspObj *ispObj, const tivx_obj_desc_raw_image_t *raw_img_desc) { Fvid2_Format *fmt; Vhwa_M2mVissParams *vissDrvPrms; vissDrvPrms = &ispObj->vissPrms; fmt = &vissDrvPrms->inFmt; /* Set number of inputs */ if (1U == raw_img_desc->params.num_exposures) { vissDrvPrms->inputMode = VHWA_M2M_VISS_MODE_SINGLE_FRAME_INPUT; } else if (2U == raw_img_desc->params.num_exposures) { vissDrvPrms->inputMode = VHWA_M2M_VISS_MODE_TWO_FRAME_MERGE; } else if (3U == raw_img_desc->params.num_exposures) { vissDrvPrms->inputMode = VHWA_M2M_VISS_MODE_THREE_FRAME_MERGE; } else { /* do nothing */ } /* Set the Input Format */ fmt->width = raw_img_desc->params.width; fmt->height = raw_img_desc->params.height; fmt->pitch[0] = (uint32_t)raw_img_desc->imagepatch_addr[0U].stride_y; fmt->dataFormat = FVID2_DF_RAW; switch (raw_img_desc->params.format[0U].pixel_container) { case (vx_enum)TIVX_RAW_IMAGE_8_BIT: fmt->ccsFormat = FVID2_CCSF_BITS8_PACKED; break; case (vx_enum)TIVX_RAW_IMAGE_16_BIT: fmt->ccsFormat = FVID2_CCSF_BITS12_UNPACKED16; break; case (vx_enum)TIVX_RAW_IMAGE_P12_BIT: fmt->ccsFormat = FVID2_CCSF_BITS12_PACKED; break; default: /* do nothing */ break; } ispObj->num_in_buf = 1u; switch (vissDrvPrms->inputMode) { case VHWA_M2M_VISS_MODE_SINGLE_FRAME_INPUT: ispObj->num_in_buf = 1u; break; case VHWA_M2M_VISS_MODE_TWO_FRAME_MERGE: ispObj->num_in_buf = 2u; break; case VHWA_M2M_VISS_MODE_THREE_FRAME_MERGE: ispObj->num_in_buf = 3u; break; default: ispObj->num_in_buf = 1u; break; } return; } static vx_status tivxVpacVissMapStorageFormat(uint32_t *ccsFmt, uint32_t vxFmt) { vx_status status = (vx_status)VX_SUCCESS; if ((vx_df_image)VX_DF_IMAGE_U16 == vxFmt) { *ccsFmt = FVID2_CCSF_BITS12_UNPACKED16; } else if ((vx_df_image)TIVX_DF_IMAGE_P12 == vxFmt) { *ccsFmt = FVID2_CCSF_BITS12_PACKED; } else if ((vx_df_image)VX_DF_IMAGE_U8 == vxFmt) { *ccsFmt = FVID2_CCSF_BITS8_PACKED; } else { VX_PRINT(VX_ZONE_ERROR, "Invalid Storage Format \n"); status = (vx_status)VX_ERROR_INVALID_PARAMETERS; } return (status); } static vx_status tivxVpacVissMapFormat(uint32_t *fmt, uint32_t *ccsFmt, uint32_t out_id, uint32_t vxFmt, uint32_t mux_val) { vx_status status = (vx_status)VX_SUCCESS; switch (mux_val) { case 0U: { /* Map single plane storage format */ status = tivxVpacVissMapStorageFormat(ccsFmt, vxFmt); if ((vx_status)VX_SUCCESS != status) { VX_PRINT(VX_ZONE_ERROR, "Map Storage Format Failed\n"); } /* Map data format on mux val0 */ else if ((TIVX_KERNEL_VPAC_CE_VISS_OUT0_IDX == out_id) || (TIVX_KERNEL_VPAC_CE_VISS_OUT2_IDX == out_id)) { *fmt = FVID2_DF_LUMA_ONLY; } else if ((TIVX_KERNEL_VPAC_CE_VISS_OUT1_IDX == out_id) || (TIVX_KERNEL_VPAC_CE_VISS_OUT3_IDX == out_id)) { *fmt = FVID2_DF_CHROMA_ONLY; } else { VX_PRINT(VX_ZONE_ERROR, "mux0 not supported on output4\n"); status = (vx_status)VX_ERROR_INVALID_PARAMETERS; } break; } case 1U: { /* Map single plane storage format */ status = tivxVpacVissMapStorageFormat(ccsFmt, vxFmt); if ((vx_status)VX_SUCCESS != status) { VX_PRINT(VX_ZONE_ERROR, "Map Storage Format Failed\n"); } /* Map data format on mux val1 */ else if (TIVX_KERNEL_VPAC_CE_VISS_OUT2_IDX == out_id) { *fmt = FVID2_DF_RED; } else if (TIVX_KERNEL_VPAC_CE_VISS_OUT3_IDX == out_id) { *fmt = FVID2_DF_GREEN; } else if (TIVX_KERNEL_VPAC_CE_VISS_OUT4_IDX == out_id) { *fmt = FVID2_DF_BLUE; } else { VX_PRINT(VX_ZONE_ERROR, "mux1 not supported on output0/1\n"); status = (vx_status)VX_ERROR_INVALID_PARAMETERS; } break; } case 2U: { /* Map single plane storage format */ status = tivxVpacVissMapStorageFormat(ccsFmt, vxFmt); if ((vx_status)VX_SUCCESS != status) { VX_PRINT(VX_ZONE_ERROR, "Map Storage Format Failed\n"); } /* Map data format on mux val2 */ else if ((TIVX_KERNEL_VPAC_CE_VISS_OUT1_IDX == out_id) || (TIVX_KERNEL_VPAC_CE_VISS_OUT2_IDX == out_id) || (TIVX_KERNEL_VPAC_CE_VISS_OUT3_IDX == out_id) || (TIVX_KERNEL_VPAC_CE_VISS_OUT4_IDX == out_id)) { *fmt = FVID2_DF_RAW; } else { VX_PRINT(VX_ZONE_ERROR, "mux2 not supported on output0\n"); status = (vx_status)VX_ERROR_INVALID_PARAMETERS; } break; } case 3U: { /* Map single plane storage format */ status = tivxVpacVissMapStorageFormat(ccsFmt, vxFmt); if ((vx_status)VX_SUCCESS != status) { VX_PRINT(VX_ZONE_ERROR, "Map Storage Format Failed\n"); } /* Map data format on mux val2 */ else if ((TIVX_KERNEL_VPAC_CE_VISS_OUT0_IDX == out_id) || (TIVX_KERNEL_VPAC_CE_VISS_OUT2_IDX == out_id)) { *fmt = FVID2_DF_GREY; } else if (TIVX_KERNEL_VPAC_CE_VISS_OUT4_IDX == out_id) { *fmt = FVID2_DF_SATURATION; } else { VX_PRINT(VX_ZONE_ERROR, "mux3 not supported on output1/3\n"); status = (vx_status)VX_ERROR_INVALID_PARAMETERS; } break; } case 4U: { if ((vx_df_image)VX_DF_IMAGE_NV12 == vxFmt) { *ccsFmt = FVID2_CCSF_BITS8_PACKED; } else if ((vx_df_image)TIVX_DF_IMAGE_NV12_P12 == vxFmt) { *ccsFmt = FVID2_CCSF_BITS12_PACKED; } else { VX_PRINT(VX_ZONE_ERROR, "only NV12 supported on mux4\n"); status = (vx_status)VX_ERROR_INVALID_PARAMETERS; } if ((vx_status)VX_SUCCESS == status) { if ((TIVX_KERNEL_VPAC_CE_VISS_OUT0_IDX == out_id) || (TIVX_KERNEL_VPAC_CE_VISS_OUT2_IDX == out_id)) { *fmt = FVID2_DF_YUV420SP_UV; } else { VX_PRINT(VX_ZONE_ERROR, "only output0/2 supports on mux4\n"); status = (vx_status)VX_ERROR_INVALID_PARAMETERS; } } break; } case 5U: { *ccsFmt = FVID2_CCSF_BITS8_PACKED; if (TIVX_KERNEL_VPAC_CE_VISS_OUT2_IDX == out_id || TIVX_KERNEL_VPAC_CE_VISS_OUT0_IDX== out_id ) { if ((vx_df_image)VX_DF_IMAGE_UYVY == vxFmt) { *fmt = FVID2_DF_YUV422I_UYVY; } else if ((vx_df_image)VX_DF_IMAGE_YUYV == vxFmt) { *fmt = FVID2_DF_YUV422I_YUYV; } else { VX_PRINT(VX_ZONE_ERROR, "only UYVY/YUYV formats supported \n"); status = (vx_status)VX_ERROR_INVALID_PARAMETERS; } } else { VX_PRINT(VX_ZONE_ERROR, "mux5 is supported only on output2 \n"); status = (vx_status)VX_ERROR_INVALID_PARAMETERS; } break; } #ifdef VPAC3L case 6U: { /* Map single plane storage format */ status = tivxVpacVissMapStorageFormat(ccsFmt, vxFmt); /* Only packed 8 and unpacked 16 IR supported in this case*/ if (TIVX_KERNEL_VPAC_CE_VISS_OUT0_IDX == out_id) { *fmt = FVID2_DF_RAW08; } else if (TIVX_KERNEL_VPAC_CE_VISS_OUT2_IDX == out_id) { *fmt = FVID2_DF_RAW16; *ccsFmt = FVID2_CCSF_BITS16_PACKED; } else { VX_PRINT(VX_ZONE_ERROR, "mux6 is supported only on output0/2 \n"); status = (vx_status)VX_ERROR_INVALID_PARAMETERS; } break; } case 7U: { /* Map single plane storage format */ status = tivxVpacVissMapStorageFormat(ccsFmt, vxFmt); /* Only packed 12 IR supported in this case */ if (TIVX_KERNEL_VPAC_CE_VISS_OUT0_IDX == out_id) { *fmt = FVID2_DF_RAW12; } else { VX_PRINT(VX_ZONE_ERROR, "mux7 is supported only on output0 \n"); status = (vx_status)VX_ERROR_INVALID_PARAMETERS; } break; } #endif default: { VX_PRINT(VX_ZONE_ERROR, "Invalid value of mux \n"); status = (vx_status)VX_ERROR_INVALID_PARAMETERS; break; } } return (status); } static vx_status vhwaVissAllocMemForCtx(tivxVpacCeIspObj *ispObj) { vx_status status = (vx_status)VX_SUCCESS; int32_t fvid2_status = FVID2_SOK; Glbce_Control glbceCtrl; if (NULL != ispObj) { glbceCtrl.module = GLBCE_MODULE_GET_STATS_INFO; glbceCtrl.statsInfo = &ispObj->glbceStatInfo; fvid2_status = Fvid2_control(ispObj->handle, IOCTL_GLBCE_GET_CONFIG, (void *)&glbceCtrl, NULL); if (FVID2_SOK != fvid2_status) { ispObj->glbce_ctx_mem_phys_ptr = 0u; status = (vx_status)VX_FAILURE; VX_PRINT(VX_ZONE_ERROR, "Failed to get GLBCE Stats Info!!!\n"); } else { tivxMemBufferAlloc(&ispObj->glbce_ctx_mem_ptr, ispObj->glbceStatInfo.size, (vx_enum)TIVX_MEM_EXTERNAL); if ((int32_t)NULL == (int32_t)ispObj->glbce_ctx_mem_ptr.host_ptr) { ispObj->glbce_ctx_mem_phys_ptr = 0u; status = (vx_status)VX_ERROR_NO_MEMORY; VX_PRINT(VX_ZONE_ERROR, "Failed to allocate memory!!!\n"); } else { ispObj->glbce_ctx_mem_phys_ptr = tivxMemShared2PhysPtr( ispObj->glbce_ctx_mem_ptr.shared_ptr, (int32_t)ispObj->glbce_ctx_mem_ptr.mem_heap_region); VX_PRINT(VX_ZONE_INFO, "TIOVX: VISS: GLBCE ctx mem @ 0x%08x or size %d B\n", (uint32_t)ispObj->glbce_ctx_mem_phys_ptr, ispObj->glbceStatInfo.size); #if defined(SOC_AM62A) || defined(SOC_J722S) /* Set Buffer for GLBCE ctx */ fvid2_status = Fvid2_control(ispObj->handle, IOCTL_GLBCE_SET_EXT_CNTXT_PTR, (void *)ispObj->glbce_ctx_mem_ptr.shared_ptr, NULL); if (FVID2_SOK != fvid2_status) { VX_PRINT(VX_ZONE_ERROR, "Failed to set Buffer for GLBCE ctx\n"); status = (vx_status)VX_FAILURE; } #endif } } } else { status = (vx_status)VX_FAILURE; } return (status); } static void vhwaVissFreeCtxMem(tivxVpacCeIspObj *ispObj) { if (NULL != ispObj) { if (0u != ispObj->glbce_ctx_mem_phys_ptr) { tivxMemBufferFree(&ispObj->glbce_ctx_mem_ptr, ispObj->glbceStatInfo.size); ispObj->glbce_ctx_mem_phys_ptr = 0u; } } } static void vhwaVissRestoreCtx(const tivxVpacCeIspObj *ispObj) { int32_t status; #if !defined(SOC_AM62A) && !defined(SOC_J722S) #ifdef VHWA_VISS_GLBCE_CTX_SAVE_RESTORE_ENABLE #ifdef VHWA_VISS_GLBCE_CTX_SAVE_RESTORE_USE_DMA int32_t status; #endif app_udma_copy_1d_prms_t prms; if ((NULL != ispObj) && (0u != ispObj->glbce_ctx_mem_phys_ptr)) { prms.src_addr = ispObj->glbce_ctx_mem_phys_ptr; prms.dest_addr = ispObj->glbceStatInfo.addr; prms.length = ispObj->glbceStatInfo.size; #ifdef VHWA_VISS_GLBCE_CTX_SAVE_RESTORE_USE_DMA status = appUdmaCopy1D(NULL, &prms); if (0 != status) { VX_PRINT(VX_ZONE_ERROR, "Failed to restore Context !!!\n"); } #else memcpy((void*)(uint32_t)prms.dest_addr, (void*)(uint32_t)prms.src_addr, prms.length); #endif } #endif #endif } static void vhwaVissSaveCtx(const tivxVpacCeIspObj *ispObj) { int32_t status; #if !defined(SOC_AM62A) && !defined(SOC_J722S) #ifdef VHWA_VISS_GLBCE_CTX_SAVE_RESTORE_ENABLE #ifdef VHWA_VISS_GLBCE_CTX_SAVE_RESTORE_USE_DMA int32_t status; #endif app_udma_copy_1d_prms_t prms; if ((NULL != ispObj) && (0u != ispObj->glbce_ctx_mem_phys_ptr)) { prms.src_addr = ispObj->glbceStatInfo.addr; prms.dest_addr = ispObj->glbce_ctx_mem_phys_ptr; prms.length = ispObj->glbceStatInfo.size; #ifdef VHWA_VISS_GLBCE_CTX_SAVE_RESTORE_USE_DMA status = appUdmaCopy1D(NULL, &prms); if (0 != status) { VX_PRINT(VX_ZONE_ERROR, "Failed to restore Context !!!\n"); } #else memcpy((void*)(uint32_t)prms.dest_addr, (void*)(uint32_t)prms.src_addr, prms.length); #endif } #endif #endif } /* ========================================================================== */ /* Control Command Implementation */ /* ========================================================================== */ /* ========================================================================== */ /* Driver Callbacks */ /* ========================================================================== */ int32_t tivxVpacCeVissFrameComplCb(Fvid2_Handle handle, void *appData) { tivxVpacCeIspObj *ispObj = (tivxVpacCeIspObj *)appData; if (NULL != ispObj) { tivxEventPost(ispObj->eventProcessCmpl); } return FVID2_SOK; }
best regards
sungenben
hi sungenben,
but here i see below code, which means glbce context save/restore is not enabled for J722S device.
#if !defined(SOC_AM62A) && !defined(SOC_J722S)
Can you please check in the file ti-processor-sdk-rtos-j722s-evm-10_01_00_04\imaging\utils\hwa\src\app_hwa.c, below code is present?
#if defined(MCU_PLUS_SDK)
initPrms.udmaDrvHndl = drvHandle;
initPrms.udmaDrvHndlBcdma = drvHandleBcdma;
/* enable config through UDMA */
initPrms.configThroughUdmaFlag = gConfigThroughUDMA;
initPrms.copyGlbceCtxThroughBcdmaFlag = true;
#else
initPrms.udmaDrvHndl = appUdmaGetObj();
/* Set configThroughUDMA to true to support multi handle */
initPrms.configThroughUdmaFlag = true;
#endif
status = Vhwa_m2mVissInit(&initPrms);
Regards,
Brijesh
Hi Brijesh
yes , I can see the source the same as you show .
what can I do for support two cameras ?
best regards
sungenben
Hi sun genben,
Then the GLBCE context save/restore is already enabled. Most likely this flicker in one camera is not coming because of GLBCE, is Exposure changing very frequently? This could be one reason why you are observing flicker.
Regards,
Brijesh
Hi Brijesh
you can see the video that I had attached .
currently we set the GLBCE every frame with the different environment .
we had checked the flicker caused by GPBCE .
if we use the same GBLCE for two cameras , the streams don't occur flicker
best regards
sungenben
Hi sungenben,
Sorry, did not get the last statement, what do you mean by "same GBLCE for two cameras"? Is GLBCE settings are different for both the cameras?
Regards,
Brijesh
Hi Brijesh
if we set different look lut of GLBCE for two cameras every frame , one screen is flickering ,the other is ok .
if we set look lut of GLBCE for A camera every frame (different look lut), B camera is set the same look lut with A every frame . both two camera streams are ok ,no flicker occur.
if we don't update Look lut of GLBCE ,both two camera streams are ok ,no flicker occur.
best regards
sungenben.
Hi Brijesh
uint32_t asymLut[GLBCE_ASYMMETRY_LUT_SIZE];
which is in the glbce_cfg.h in the below path
rtos_sdk/mcu_plus_sdk_j722s/source/drivers/vhwa/include/
best regards
sungenben
Hi sungenben,
Yes, if you hare Asym LUT difference for both the cameras, you need to see them to both the camera before submitting the frame. Any specific reason for using different Aym Lut for both these cameras?
Regards,
Brijesh
Hi Brijesh
currently our production is CMS , the cameras are located both side of car
we are dynamic to adjust the asymLut with environment , so if different environment in two cameras , the asymLut is different .
In order to have own parameters for different cameras ,so TI set the save/restore function
is that right ? we had used our algorithms in the TDA4VL ,and It's OK
best regards
sungenben
Hi sungenben,
on TDA4VL, we have support for restoring the context for each camera on every frame. This feature is not yet supported on TDA4AEN. This is why GLBCE Asym Lut is not being restored and we will need to explicitly set it in the Node.. You might have update the node to call API for setting GLBCE settings for both the cameras.
Regards,
Brijesh
Hi Brijesh
->on TDA4VL, we have support for restoring the context for each camera on every frame. This feature is not yet supported on TDA4AEN
when does TI plan to achieve this feature on TDA4VEN?
best regards
sungenben
Hi sungenben,
Please refer to roadmap slides for this. Only GLBCE context save and restore is supported on TDA4AEN.
Regards,
Brijesh
Hi Brijesh
Could you help me check because I don't know the roadmap slides ?
best regards
sungenben
Hi sungenben,
As per the current plan, this feature will be available in the SDK11.2 timeframe.
Regards,
Brijesh
Hi sungenben,
you can see the video that I had attached .
currently we set the GLBCE every frame with the different environment .
Is that a horizontal tearing line in your attached video?