#include "AppControl/AppControl.h" #include "PrjCfg.h" #include "UIApp/AppLib.h" #include "GxUSB.h" #include "UIAppUsbCam.h" #include "ImageApp/ImageApp_UsbMovie.h" #include "vendor_isp.h" #include "SysSensor.h" #if 1 #define THIS_DBGLVL 2 // 0=FATAL, 1=ERR, 2=WRN, 3=UNIT, 4=FUNC, 5=IND, 6=MSG, 7=VALUE, 8=USER /////////////////////////////////////////////////////////////////////////////// #define __MODULE__ UIApp_UVAC #define __DBGLVL__ ((THIS_DBGLVL>=PRJ_DBG_LVL)?THIS_DBGLVL:PRJ_DBG_LVL) #define __DBGFLT__ "*" //*=All, [mark]=CustomClass #include "kwrap/debug.h" /////////////////////////////////////////////////////////////////////////////// #define UVAC_VENDCMD_CURCMD 0x01 #define UVAC_VENDCMD_VERSION 0x02 #define UVAC_PRJ_SET_LIVEVIEW_SAVEFILE 0 //1V + 1F #define UVAC_PRJ_SET_LIVEVIEW_1V_ONLY 1 //1V only #define UVAC_PRJ_SET_LIVEVIEW_2V 2 //2V #define UVAC_MAX_WIDTH 1920 #define UVAC_MAX_HEIGHT 1080 #define UVAC_MAX_FRAMERATE 30 #if (1)//(DISABLE == UVAC_MODE_2_PATH) //only support 1V #define UVAC_PRJ_SET_THIS UVAC_PRJ_SET_LIVEVIEW_1V_ONLY #else #define UVAC_PRJ_SET_THIS UVAC_PRJ_SET_LIVEVIEW_2V //#define UVAC_PRJ_SET_THIS UVAC_PRJ_SET_LIVEVIEW_SAVEFILE //#define UVAC_PRJ_SET_THIS UVAC_PRJ_SET_LIVEVIEW_1V_ONLY #endif #if (0)//(UVAC_PRJ_SET_THIS == UVAC_PRJ_SET_LIVEVIEW_SAVEFILE) //Single Video liveview and movie-recording a file #define UVAC_2PATH DISABLE #define UVAC_SAVE_FILE ENABLE #define UVAC_TEST_FOR_CPU_EXCEPTION_MFK DISABLE #elif (UVAC_PRJ_SET_THIS == UVAC_PRJ_SET_LIVEVIEW_1V_ONLY) //Single Video liveview only #define UVAC_2PATH DISABLE #define UVAC_SAVE_FILE DISABLE #define UVAC_TEST_FOR_CPU_EXCEPTION_MFK ENABLE //ENABLE DISABLE #else //Two Video liveview #define UVAC_2PATH ENABLE #define UVAC_SAVE_FILE DISABLE #define UVAC_TEST_FOR_CPU_EXCEPTION_MFK ENABLE //ENABLE DISABLE #endif #define UVAC_WINUSB_INTF DISABLE //ENABLE DISABLE UVAC_VEND_DEV_DESC gUIUvacDevDesc = {0}; UINT8 gUIUvacVendCmdVer[8] = {'1', '.', '0', '8', '.', '0', '0', '7'}; typedef struct _VEND_CMD_ { UINT32 cmd; UINT8 data[36]; //<= 60 } VEND_CMD, *PVEND_CMD; typedef struct { UINT32 uiWidth; UINT32 uiHeight; UINT32 uiVidFrameRate; UINT32 uiH264TBR; UINT32 uiMJPEGTBR; } UVC_TARGET_SIZE_PARAM; static UVC_TARGET_SIZE_PARAM g_UvcVidSizeTable[] = { {1920, 1080, 30, 1200 * 1024, 3 * 1800 * 1024}, {1280, 720, 30, 450 * 1024, 4 * 800 * 1024}, }; #if UVAC_2PATH static UVC_TARGET_SIZE_PARAM g_Uvc2VidSizeTable[] = { {1920, 1080, 30, 1200 * 1024, 3 * 1800 * 1024}, {1280, 720, 30, 450 * 1024, 4 * 800 * 1024}, }; #endif /** * 1.NVT_UI_UVAC_RESO_CNT < UVAC_VID_RESO_MAX_CNT * 2.Discrete fps: * The values of fps[] must be in a decreasing order and 0 shall be put to the last one. * The element, fpsCnt, must be correct for the values in fps[] * 3.Must be a subset of g_MovieRecSizeTable[] for MFK-available. * */ static UVAC_VID_RESO gUIUvacVidReso[NVT_UI_UVAC_RESO_CNT] = { {1920, 1080, 1, 30, 0, 0}, //16:9 {1280, 720, 1, 30, 0, 0}, //16:9 }; #if UVAC_2PATH static UVAC_VID_RESO gUvc2MjpgReso[] = { { 1920, 1080, 1, 30, 0, 0}, { 1280, 720, 1, 30, 0, 0}, }; static UVAC_VID_RESO gUvc2H264Reso[] = { { 1920, 1080, 1, 30, 0, 0}, { 1280, 720, 1, 30, 0, 0}, }; #endif //NVT_UI_UVAC_AUD_SAMPLERATE_CNT <= UVAC_AUD_SAMPLE_RATE_MAX_CNT UINT32 gUIUvacAudSampleRate[NVT_UI_UVAC_AUD_SAMPLERATE_CNT] = { NVT_UI_FREQUENCY_32K }; _ALIGNED(64) static UINT16 m_UVACSerialStrDesc3[] = { 0x0320, // 20: size of String Descriptor = 32 bytes // 03: String Descriptor type '9', '8', '5', '2', '0', // 98520-00000-001 (default) '0', '0', '0', '0', '0', '0', '0', '1', '0', '0' }; _ALIGNED(64) const static UINT8 m_UVACManuStrDesc[] = { USB_VENDER_DESC_STRING_LEN * 2 + 2, // size of String Descriptor = 6 bytes 0x03, // 03: String Descriptor type USB_VENDER_DESC_STRING }; _ALIGNED(64) const static UINT8 m_UVACProdStrDesc[] = { USB_PRODUCT_DESC_STRING_LEN * 2 + 2, // size of String Descriptor = 6 bytes 0x03, // 03: String Descriptor type USB_PRODUCT_DESC_STRING }; //======= end movie mode related setting ====== //0:OK //1...:TBD static UINT32 xUvacVendReqCB(PUVAC_VENDOR_PARAM pParam) { if (pParam) { DBG_IND("bHostToDevice = 0x%x\r\n", pParam->bHostToDevice); DBG_IND("uiReguest = 0x%x\r\n", pParam->uiReguest); DBG_IND("uiValue = 0x%x\r\n", pParam->uiValue); DBG_IND("uiIndex = 0x%x\r\n", pParam->uiIndex); DBG_IND("uiDataAddr = 0x%x\r\n", pParam->uiDataAddr); DBG_IND("uiDataSize = 0x%x\r\n", pParam->uiDataSize); } else { DBG_ERR(" Input parameter NULL\r\n"); } return 0; } //0:OK //1...:TBD static UINT32 xUvacVendReqIQCB(PUVAC_VENDOR_PARAM pParam) { if (pParam) { DBG_IND("bHostToDevice = 0x%x\r\n", pParam->bHostToDevice); DBG_IND("uiReguest = 0x%x\r\n", pParam->uiReguest); DBG_IND("uiValue = 0x%x\r\n", pParam->uiValue); DBG_IND("uiIndex = 0x%x\r\n", pParam->uiIndex); DBG_IND("uiDataAddr = 0x%x\r\n", pParam->uiDataAddr); DBG_IND("uiDataSize = 0x%x\r\n", pParam->uiDataSize); } else { DBG_ERR(" Input parameter NULL\r\n"); } return 0; } static void xUSBMakerInit_UVAC(UVAC_VEND_DEV_DESC *pUVACDevDesc) { pUVACDevDesc->pManuStringDesc = (UVAC_STRING_DESC *)m_UVACManuStrDesc; pUVACDevDesc->pProdStringDesc = (UVAC_STRING_DESC *)m_UVACProdStrDesc; pUVACDevDesc->pSerialStringDesc = (UVAC_STRING_DESC *)m_UVACSerialStrDesc3; pUVACDevDesc->VID = USB_VID; pUVACDevDesc->PID = USB_PID_PCCAM; pUVACDevDesc->fpVendReqCB = xUvacVendReqCB; pUVACDevDesc->fpIQVendReqCB = xUvacVendReqIQCB; } void xUvac_ConfigMovieSizeCB(PNVT_USBMOVIE_VID_RESO pVidReso) { UINT32 tbr; if (pVidReso) { if (pVidReso->dev_id == 0) { if (pVidReso->codec == UVAC_VIDEO_FORMAT_H264) { tbr = g_UvcVidSizeTable[pVidReso->ResoIdx].uiH264TBR; } else { tbr = g_UvcVidSizeTable[pVidReso->ResoIdx].uiMJPEGTBR; } DBGD(tbr); pVidReso->tbr = tbr; } #if UVAC_2PATH else { if (pVidReso->codec == UVAC_VIDEO_FORMAT_H264) { tbr = g_Uvc2VidSizeTable[pVidReso->ResoIdx].uiH264TBR; } else { tbr = g_Uvc2VidSizeTable[pVidReso->ResoIdx].uiMJPEGTBR; } DBGD(tbr); pVidReso->tbr = tbr; } #endif } } UINT8 xUvacWinUSBCB(UINT32 ControlCode, UINT8 CS, UINT8 *pDataAddr, UINT32 *pDataLen) { DBG_IND("xUvacWinUSBCB ctrl=0x%x, cs=0x%x, pData=0x%x, len=%d\r\n", ControlCode, CS, pDataAddr, *pDataLen); return TRUE; } // sample code for UVC extension unit #if 0 static BOOL xUvac_EU_ID_01_CB(UINT8 request, UINT8 *pData, UINT32 *pDataLen) { switch (request){ case GET_LEN: pData[0] = 0x02; pData[1] = 0x00; *pDataLen = 2; //must be 2 according to UVC spec return TRUE; case GET_INFO: pData[0] = SUPPORT_GET_REQUEST | SUPPORT_SET_REQUEST; *pDataLen = 1; //must be 1 according to UVC spec return TRUE; case GET_MIN: pData[0] = 0x00; pData[1] = 0x00; *pDataLen = 2; return TRUE; case GET_MAX: pData[0] = 0xFF; pData[1] = 0xFF; *pDataLen = 2; return TRUE; case GET_RES: pData[0] = 0x01; pData[1] = 0x00; *pDataLen = 2; return TRUE; case GET_DEF: pData[0] = 0x00; pData[1] = 0x00; *pDataLen = 2; return TRUE; case GET_CUR: pData[0] = 0x02; pData[1] = 0x00; *pDataLen = 0x02; return TRUE; case SET_CUR: // TODO return TRUE; } DBG_ERR("set raw_seq not support!\r\n"); return FALSE; } static BOOL xUvac_EU_ID_04_CB(UINT8 request, UINT8 *pData, UINT32 *pDataLen) { switch (request){ case GET_LEN: pData[0] = 0x32; pData[1] = 0x00; *pDataLen = 2; //must be 2 according to UVC spec return TRUE; case GET_INFO: pData[0] = SUPPORT_GET_REQUEST | SUPPORT_SET_REQUEST; *pDataLen = 1; //must be 1 according to UVC spec return TRUE; case GET_MIN: pData[0] = 0x00; pData[1] = 0x00; *pDataLen = 2; return TRUE; case GET_MAX: pData[0] = 0xFF; pData[1] = 0xFF; *pDataLen = 2; return TRUE; case GET_RES: pData[0] = 0x01; pData[1] = 0x00; *pDataLen = 2; return TRUE; case GET_DEF: pData[0] = 0x00; pData[1] = 0x00; *pDataLen = 2; return TRUE; case GET_CUR: pData[0] = 0x32; pData[1] = 0x00; *pDataLen = 0x32; return TRUE; case SET_CUR: { DBG_DUMP("%d: ", *pDataLen); UINT32 i; for (i = 0; i < *pDataLen; i++) { DBG_DUMP("%02x ", pData[i]); } DBG_DUMP("\r\n"); } return TRUE; } DBG_ERR("set raw_seq not support!\r\n"); return FALSE; } BOOL xUvacEU_CB(UINT32 CS, UINT8 request, UINT8 *pData, UINT32 *pDataLen) { BOOL ret = FALSE; if (request == SET_CUR){ DBG_DUMP("%s: SET_CUR, CS=0x%02X, request = 0x%X, pData=0x%X, len=%d\r\n", __func__, CS, request, pData, *pDataLen); } switch (CS){ case EU_CONTROL_ID_01: ret = xUvac_EU_ID_01_CB(request, pData, pDataLen); break; case EU_CONTROL_ID_02: case EU_CONTROL_ID_03: break; case EU_CONTROL_ID_04: ret = xUvac_EU_ID_04_CB(request, pData, pDataLen); break; case EU_CONTROL_ID_05: case EU_CONTROL_ID_06: case EU_CONTROL_ID_07: case EU_CONTROL_ID_08: case EU_CONTROL_ID_09: case EU_CONTROL_ID_10: case EU_CONTROL_ID_11: case EU_CONTROL_ID_12: case EU_CONTROL_ID_13: case EU_CONTROL_ID_14: case EU_CONTROL_ID_15: case EU_CONTROL_ID_16: //not supported now break; default: break; } if (request != SET_CUR) { DBG_DUMP("%s: CS=0x%02X, request = 0x%X, pData=0x%X, len=%d\r\n", __func__, CS, request, pData, *pDataLen); } if (ret && request == SET_CUR){ *pDataLen = 0; } return ret; } #endif INT32 UVACExe_OnOpen(VControl *pCtrl, UINT32 paramNum, UINT32 *paramArray) { UVAC_VID_RESO_ARY uvacVidResoAry = {0}; UVAC_AUD_SAMPLERATE_ARY uvacAudSampleRateAry = {0}; USBMOVIE_SENSOR_INFO sen_cfg = {0}; DBG_IND(" ++\r\n"); Ux_DefaultEvent(pCtrl, NVTEVT_EXE_OPEN, paramNum, paramArray); //=>System_OnSensorAttach if (GxUSB_GetIsUSBPlug()) { UsbMovie_CommPoolInit(); ImageApp_UsbMovie_Config(USBMOVIE_CFG_SET_MOVIE_SIZE_CB, (UINT32)xUvac_ConfigMovieSizeCB); #if UVAC_2PATH DBG_IND("UVAC_2PATH Enable, Set Channel:%d\r\n", (UINT32)UVAC_CHANNEL_2V2A); ImageApp_UsbMovie_Config(USBMOVIE_CFG_CHANNEL, UVAC_CHANNEL_2V2A); #else DBG_IND("UVAC_2PATH Disable, Set Channel:%d\r\n", (UINT32)UVAC_CHANNEL_1V1A); ImageApp_UsbMovie_Config(USBMOVIE_CFG_CHANNEL, UVAC_CHANNEL_1V1A); #endif uvacVidResoAry.aryCnt = NVT_UI_UVAC_RESO_CNT;//MOVIE_SIZE_ID_MAX; uvacVidResoAry.pVidResAry = &gUIUvacVidReso[0]; #if NVT_UI_UVAC_RESO_INTERNAL DBG_DUMP("Use UVAC internal resolution table\r\n"); #else ImageApp_UsbMovie_SetParam(0, UVAC_PARAM_VID_RESO_ARY, (UINT32)&uvacVidResoAry); DBG_IND("Vid Reso:%d\r\n", uvacVidResoAry.aryCnt); #endif #if UVAC_2PATH uvacVidResoAry.aryCnt = sizeof(gUvc2MjpgReso)/sizeof(UVAC_VID_RESO); uvacVidResoAry.pVidResAry = &gUvc2MjpgReso[0]; uvacVidResoAry.bDefaultFrameIndex = 1; ImageApp_UsbMovie_SetParam(0, UVAC_PARAM_UVC2_MJPG_FRM_INFO, (UINT32)&uvacVidResoAry); uvacVidResoAry.aryCnt = sizeof(gUvc2H264Reso)/sizeof(UVAC_VID_RESO); uvacVidResoAry.pVidResAry = &gUvc2H264Reso[0]; uvacVidResoAry.bDefaultFrameIndex = 1; ImageApp_UsbMovie_SetParam(0, UVAC_PARAM_UVC2_H264_FRM_INFO, (UINT32)&uvacVidResoAry); #endif uvacAudSampleRateAry.aryCnt = NVT_UI_UVAC_AUD_SAMPLERATE_CNT; uvacAudSampleRateAry.pAudSampleRateAry = &gUIUvacAudSampleRate[0]; ImageApp_UsbMovie_SetParam(0, UVAC_PARAM_AUD_SAMPLERATE_ARY, (UINT32)&uvacAudSampleRateAry); DBG_IND("Aud SampleRate:%d\r\n", uvacAudSampleRateAry.aryCnt); xUSBMakerInit_UVAC(&gUIUvacDevDesc); ImageApp_UsbMovie_SetParam(0, UVAC_PARAM_UVAC_VEND_DEV_DESC, (UINT32)&gUIUvacDevDesc); DBG_IND("VID=0x%x, PID=0x%x\r\n", gUIUvacDevDesc.VID, gUIUvacDevDesc.PID); // enable to register UVC extension unit callback #if 0 DBG_IND("VendCb:0x%x\r\n", (UINT32)xUvacEU_CB); ImageApp_UsbMovie_SetParam(0, UVAC_PARAM_EU_CTRL, (UINT32)xUvacEU_CB); #endif //ImageUnit_SetParam(ISF_CTRL, UVAC_PARAM_EU_CTRL, (UINT32)0x01); #if UVAC_WINUSB_INTF DBG_IND("Enable WinUSB\r\n"); ImageApp_UsbMovie_SetParam(0, UVAC_PARAM_WINUSB_ENABLE, TRUE); DBG_IND("WinUSBCb:0x%x\r\n", (UINT32)xUvacWinUSBCB); ImageApp_UsbMovie_SetParam(0, UVAC_PARAM_WINUSB_CB, (UINT32)xUvacWinUSBCB); #else DBG_IND("DISABLE WinUSB\r\n"); ImageApp_UsbMovie_SetParam(0, UVAC_PARAM_WINUSB_ENABLE, FALSE); #endif //xUvac_AE_SetUIInfo(AE_UI_EV, AE_EV_00); //DBG_IND("Set Parameter for MFK\r\n"); //xUvac_InitSetMFK(); // get sensor info sen_cfg.rec_id = 0; System_GetSensorInfo(0, SENSOR_DRV_CFG, &(sen_cfg.vcap_cfg)); System_GetSensorInfo(0, SENSOR_SENOUT_FMT, &(sen_cfg.senout_pxlfmt)); System_GetSensorInfo(0, SENSOR_CAPOUT_FMT, &(sen_cfg.capout_pxlfmt)); System_GetSensorInfo(0, SENSOR_DATA_LANE, &(sen_cfg.data_lane)); System_GetSensorInfo(0, SENSOR_AE_PATH, &(sen_cfg.ae_path)); System_GetSensorInfo(0, SENSOR_AWB_PATH, &(sen_cfg.awb_path)); System_GetSensorInfo(0, SENSOR_IQ_PATH, &(sen_cfg.iq_path)); ImageApp_UsbMovie_Config(USBMOVIE_CFG_SENSOR_INFO, (UINT32)&sen_cfg); ImageApp_UsbMovie_SetParam(0, UVAC_PARAM_VCAP_FUNC, (HD_VIDEOCAP_FUNC_AE | HD_VIDEOCAP_FUNC_AWB)); //ImageApp_UsbMovie_SetParam(0, UVAC_PARAM_VPROC_FUNC, (HD_VIDEOPROC_FUNC_WDR | HD_VIDEOPROC_FUNC_DEFOG | HD_VIDEOPROC_FUNC_COLORNR | HD_VIDEOPROC_FUNC_3DNR)); ImageApp_UsbMovie_SetParam(0, UVAC_PARAM_VPROC_FUNC, (HD_VIDEOPROC_FUNC_WDR | HD_VIDEOPROC_FUNC_COLORNR | HD_VIDEOPROC_FUNC_3DNR)); #if UVAC_2PATH sen_cfg.rec_id = 1; System_GetSensorInfo(1, SENSOR_DRV_CFG, &(sen_cfg.vcap_cfg)); System_GetSensorInfo(1, SENSOR_SENOUT_FMT, &(sen_cfg.senout_pxlfmt)); System_GetSensorInfo(1, SENSOR_CAPOUT_FMT, &(sen_cfg.capout_pxlfmt)); System_GetSensorInfo(1, SENSOR_DATA_LANE, &(sen_cfg.data_lane)); System_GetSensorInfo(1, SENSOR_AE_PATH, &(sen_cfg.ae_path)); System_GetSensorInfo(1, SENSOR_AWB_PATH, &(sen_cfg.awb_path)); System_GetSensorInfo(1, SENSOR_IQ_PATH, &(sen_cfg.iq_path)); ImageApp_UsbMovie_Config(USBMOVIE_CFG_SENSOR_INFO, (UINT32)&sen_cfg); ImageApp_UsbMovie_SetParam(1, UVAC_PARAM_VCAP_FUNC, (HD_VIDEOCAP_FUNC_AE | HD_VIDEOCAP_FUNC_AWB)); //ImageApp_UsbMovie_SetParam(1, UVAC_PARAM_VPROC_FUNC, (HD_VIDEOPROC_FUNC_WDR | HD_VIDEOPROC_FUNC_DEFOG | HD_VIDEOPROC_FUNC_COLORNR | HD_VIDEOPROC_FUNC_3DNR)); ImageApp_UsbMovie_SetParam(1, UVAC_PARAM_VPROC_FUNC, (HD_VIDEOPROC_FUNC_WDR | HD_VIDEOPROC_FUNC_COLORNR | HD_VIDEOPROC_FUNC_3DNR)); #endif #if (_BOARD_DRAM_SIZE_ == 0x04000000) ImageApp_UsbMovie_SetParam(0, UVAC_PARAM_VCAP_OUTFUNC, HD_VIDEOCAP_OUTFUNC_DIRECT); ImageApp_UsbMovie_SetParam(0, UVAC_PARAM_UVAC_TBR_H264, NVT_USBMOVIE_TBR_H264_DEFAULT); #endif #if (SENSOR_SIEPATGEN == ENABLE) ImageApp_UsbMovie_SetParam(0, UVAC_PARAM_VCAP_PAT_GEN, HD_VIDEOCAP_SEN_PAT_COLORBAR); #endif // set image mirror/flip (HD_VIDEO_DIR_NONE / HD_VIDEO_DIR_MIRRORX / HD_VIDEO_DIR_MIRRORY / HD_VIDEO_DIR_MIRRORXY) ImageApp_UsbMovie_SetParam(0, UVAC_PARAM_IPL_MIRROR, HD_VIDEO_DIR_NONE); DBG_IND("+ImageApp_UsbMovie_Open\r\n"); ImageApp_UsbMovie_Open(); DBG_IND("-ImageApp_UsbMovie_Open\r\n"); //ImageApp_UsbMovie_SetParam(0, UVAC_PARAM_IPL_MIRROR, HD_VIDEO_DIR_MIRRORX); } else { DBG_ERR("USB NOT connected!\r\n"); } return NVTEVT_CONSUME; } INT32 UVACExe_OnClose(VControl *pCtrl, UINT32 paramNum, UINT32 *paramArray) { DBG_IND(" +\r\n"); ImageApp_UsbMovie_Close(); Ux_DefaultEvent(pCtrl, NVTEVT_EXE_CLOSE, paramNum, paramArray); DBG_IND(" ---\r\n"); return NVTEVT_CONSUME; } #else INT32 UVACExe_OnOpen(VControl *pCtrl, UINT32 paramNum, UINT32 *paramArray) { return NVTEVT_CONSUME; } INT32 UVACExe_OnClose(VControl *pCtrl, UINT32 paramNum, UINT32 *paramArray) { return NVTEVT_CONSUME; } #endif //////////////////////////////////////////////////////////// EVENT_ENTRY CustomUSBPCCObjCmdMap[] = { {NVTEVT_EXE_OPEN, UVACExe_OnOpen}, {NVTEVT_EXE_CLOSE, UVACExe_OnClose}, {NVTEVT_NULL, 0}, //End of Command Map }; CREATE_APP(CustomUSBPCCObj, APP_SETUP)