/* ******************************************************************************* * Copyright (c) 2010-2022 VATICS(KNERON) Inc. All rights reserved. * * +-----------------------------------------------------------------+ * | THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED | * | AND COPIED IN ACCORDANCE WITH THE TERMS AND CONDITIONS OF SUCH | * | A LICENSE AND WITH THE INCLUSION OF THE THIS COPY RIGHT NOTICE. | * | THIS SOFTWARE OR ANY OTHER COPIES OF THIS SOFTWARE MAY NOT BE | * | PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. THE | * | OWNERSHIP AND TITLE OF THIS SOFTWARE IS NOT TRANSFERRED. | * | | * | THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT | * | ANY PRIOR NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY | * | VATICS(KNERON) INC. | * +-----------------------------------------------------------------+ * ******************************************************************************* */ #include #include #include #include #include "vmf/video_source.h" #include "vmf/fec_layout.h" #include "comm/video_buf.h" #include "vmf/video_encoder.h" #include "fec_api.h" #include "lvgl_example.h" //extern VMF_LAYOUT_T g_tLayout; //extern VMF_VSRC_HANDLE_T* g_ptVsrcHandle; static VMF_FEC_PTZ_CONFIG_T g_tFecPtzConfig[4]; static VMF_FEC_CELL_CONFIG_T g_tFecCellConfig[4]; static VMF_FEC_CELL_CONFIG_T g_tPIPFecCellConfig[2]; static VMF_FEC_LYT_CONFIG_T g_tFecLytConfig; static pthread_t eptz_thread; static int stop_eptz_thread = 1; static void *eptz_tester(void *); static void setup_lyt_spec(VMF_ENC_SPEC_T *, VMF_VENC_CODEC_TYPE); static void setup_fec_layout(VMF_FEC_LYT_CONFIG_T *, unsigned int, VMF_VENC_CODEC_TYPE); static int setup_fec_4r_eptz(unsigned int, int, VMF_VENC_CODEC_TYPE); static int setup_fec_4r_hcut(unsigned int, VMF_VENC_CODEC_TYPE); static int setup_fec_pip(unsigned int, VMF_VENC_CODEC_TYPE); static int setup_fec_1r(unsigned int, VMF_VENC_CODEC_TYPE); static int setup_fec_1r_area(unsigned int, VMF_VENC_CODEC_TYPE); static int setup_fec_p180(unsigned int, VMF_VENC_CODEC_TYPE); static int setup_fec_p360_separate(unsigned int, VMF_VENC_CODEC_TYPE); static void release_eptz_tester(void); void *eptz_tester(void* user_data __attribute__((unused))) { const unsigned int pan_step = 2; const unsigned int tilt_step = 2; g_tFecLytConfig.bCoeffOnly = 1; while (!stop_eptz_thread) { g_tFecPtzConfig[0].fPan += pan_step; g_tFecPtzConfig[0].fPan = (g_tFecPtzConfig[0].fPan <= 180)? g_tFecPtzConfig[0].fPan : -180; // Pan range: [-180, 180] g_tFecPtzConfig[0].fTilt += tilt_step; g_tFecPtzConfig[0].fTilt = (g_tFecPtzConfig[0].fTilt <= 180)? g_tFecPtzConfig[0].fTilt : -180; // Tilt range: [-180, 180] g_tFecCellConfig[0].eFecMode = VMF_FEC_COEF_MODE_PTZ; g_tFecCellConfig[0].pFecConfig = g_tFecPtzConfig; //! setup layout VMF_FEC_LYT_Quad(g_ptVsrcHandle, &g_tFecLytConfig, g_tFecCellConfig); usleep(DELAY_TIME); } return NULL; } void setup_lyt_spec(VMF_ENC_SPEC_T *ptSpec, VMF_VENC_CODEC_TYPE eCodecType) { if (eCodecType == VMF_VENC_CODEC_TYPE_H265){ ptSpec->bEncH265 = 1; } else if (eCodecType == VMF_VENC_CODEC_TYPE_H264){ ptSpec->bEncH264 = 1; } else if (eCodecType == VMF_VENC_CODEC_TYPE_MJPG){ ptSpec->bEncJPEG = 1; } } void setup_fec_layout(VMF_FEC_LYT_CONFIG_T *ptFecLayout, unsigned int output_index, VMF_VENC_CODEC_TYPE eCodecType) { ptFecLayout->dwOutputId = output_index; ptFecLayout->tLayout.dwCanvasWidth = g_tLayout.dwCanvasWidth; ptFecLayout->tLayout.dwCanvasHeight = g_tLayout.dwCanvasHeight; ptFecLayout->tLayout.dwVideoWidth = g_tLayout.dwVideoWidth; ptFecLayout->tLayout.dwVideoHeight = g_tLayout.dwVideoHeight; ptFecLayout->tLayout.dwVideoPosX = g_tLayout.dwVideoPosX; ptFecLayout->tLayout.dwVideoPosY = g_tLayout.dwVideoPosY; ptFecLayout->dwClearBackColor = 0; //! full FEC layout dont need to setup back color ptFecLayout->eGridSize = VMF_FEC_GRID_8X8; ptFecLayout->eLayoutMethod = VMF_FEC_METHOD_GTR; setup_lyt_spec(&ptFecLayout->tEncSpec, eCodecType); } int setup_fec_4r_eptz(unsigned int output_index, int enable, VMF_VENC_CODEC_TYPE eCodecType) { const unsigned int dwNum = 4; size_t i = 0; memset(g_tFecPtzConfig, 0, (sizeof(VMF_FEC_PTZ_CONFIG_T) * dwNum)); memset(g_tFecCellConfig, 0, (sizeof(VMF_FEC_CELL_CONFIG_T) * dwNum)); memset(&g_tFecLytConfig, 0, sizeof(VMF_FEC_LYT_CONFIG_T)); setup_fec_layout(&g_tFecLytConfig, output_index, eCodecType); g_tFecLytConfig.eGridSize = VMF_FEC_GRID_32X32; //! setup cell config parameters for (i = 0; i < dwNum; ++i) { g_tFecPtzConfig[i].fZoom = 1; g_tFecPtzConfig[i].fFocalLength = 0.65; g_tFecPtzConfig[i].eAppType = VMF_FEC_APP_TABL; g_tFecPtzConfig[i].eLensType = VMF_FEC_LENS_STEREOGRAPHIC; if (VMF_FEC_APP_WALL != g_tFecPtzConfig[i].eAppType) { g_tFecPtzConfig[i].fPan = i * 90;//(360 / ptz_num); g_tFecPtzConfig[i].fTilt = 35; } else { g_tFecPtzConfig[i].fPan = (0 == (i >> 1)) ? 35 : -20; g_tFecPtzConfig[i].fTilt = (0 == (i % 2)) ? 20 : -20; } g_tFecCellConfig[i].eFecMode = VMF_FEC_COEF_MODE_PTZ; g_tFecCellConfig[i].pFecConfig = g_tFecPtzConfig + i; } //! setup layout VMF_FEC_LYT_Quad(g_ptVsrcHandle, &g_tFecLytConfig, g_tFecCellConfig); if (enable) { stop_eptz_thread = 0; pthread_create(&eptz_thread, NULL, &eptz_tester, NULL); } return 0; } int setup_fec_4r_hcut(unsigned int output_index, VMF_VENC_CODEC_TYPE eCodecType) { const unsigned int dwNum = 4; size_t i = 0; memset(g_tFecPtzConfig, 0, (sizeof(VMF_FEC_PTZ_CONFIG_T) * dwNum)); memset(g_tFecCellConfig, 0, (sizeof(VMF_FEC_CELL_CONFIG_T) * dwNum)); memset(&g_tFecLytConfig, 0, sizeof(VMF_FEC_LYT_CONFIG_T)); setup_fec_layout(&g_tFecLytConfig, output_index, eCodecType); g_tFecLytConfig.eGridSize = VMF_FEC_GRID_32X32; //! setup cell config parameters for (i = 0; i < dwNum; ++i) { g_tFecPtzConfig[i].fZoom = 1; g_tFecPtzConfig[i].fFocalLength = 0.65; g_tFecPtzConfig[i].eAppType = VMF_FEC_APP_TABL; g_tFecPtzConfig[i].eLensType = VMF_FEC_LENS_STEREOGRAPHIC; if (VMF_FEC_APP_WALL != g_tFecPtzConfig[i].eAppType) { g_tFecPtzConfig[i].fPan = i * 90;//(360 / ptz_num); g_tFecPtzConfig[i].fTilt = 35; } else { g_tFecPtzConfig[i].fPan = (0 == (i >> 1)) ? 35 : -20; g_tFecPtzConfig[i].fTilt = (0 == (i % 2)) ? 20 : -20; } g_tFecCellConfig[i].eFecMode = VMF_FEC_COEF_MODE_PTZ; g_tFecCellConfig[i].pFecConfig = g_tFecPtzConfig + i; } //! setup layout VMF_FEC_LYT_Quad_Hcut(g_ptVsrcHandle, &g_tFecLytConfig, g_tFecCellConfig); return 0; } int setup_fec_pip(unsigned int output_index, VMF_VENC_CODEC_TYPE eCodecType) { const unsigned int dwNum = 2; size_t i = 0; VMF_FEC_P180_CONFIG_T tFecP180Config; VMF_FEC_PTZ_CONFIG_T tFecPtzConfig; memset(&tFecP180Config, 0, sizeof(VMF_FEC_P180_CONFIG_T)); memset(&tFecPtzConfig, 0, sizeof(VMF_FEC_PTZ_CONFIG_T)); memset(g_tPIPFecCellConfig, 0, (sizeof(VMF_FEC_CELL_CONFIG_T) * dwNum)); memset(&g_tFecLytConfig, 0, sizeof(VMF_FEC_LYT_CONFIG_T)); setup_fec_layout(&g_tFecLytConfig, output_index, eCodecType); g_tFecLytConfig.eGridSize = VMF_FEC_GRID_16X16; //! setup cell config parameters for (i = 0; i < dwNum; ++i) { if(i == 0){ printf("i = 0\n"); tFecP180Config.fPan = 0; tFecP180Config.fTilt = 0; tFecP180Config.fZoom = 1; tFecP180Config.fFocalLength = 0.7; tFecP180Config.fRectCurvature = 0.65; tFecP180Config.fRectSlope = 0.8; tFecP180Config.eModeType = VMF_FEC_MODE_PANO_180_ONE_DIRECTION; g_tPIPFecCellConfig[i].eFecMode = VMF_FEC_COEF_MODE_P180; g_tPIPFecCellConfig[i].pFecConfig = &tFecP180Config; } else if(i == 1){ printf("i = 1\n"); tFecPtzConfig.fZoom = 1; tFecPtzConfig.fFocalLength = 0.85; tFecPtzConfig.eAppType = VMF_FEC_APP_WALL; tFecPtzConfig.eLensType = VMF_FEC_LENS_STEREOGRAPHIC; tFecPtzConfig.fPan = 0; tFecPtzConfig.fTilt = -45; g_tPIPFecCellConfig[i].eFecMode = VMF_FEC_COEF_MODE_PTZ; g_tPIPFecCellConfig[i].pFecConfig = &tFecPtzConfig; } } const unsigned int rectangle[2][2] = { {g_tFecLytConfig.tLayout.dwCanvasWidth, g_tFecLytConfig.tLayout.dwCanvasHeight}, {320, 240} }; const unsigned int offset[2][2] = { {0, 0}, {g_tFecLytConfig.tLayout.dwCanvasWidth-320, g_tFecLytConfig.tLayout.dwCanvasHeight-240} }; printf("Width = %d\n", g_tFecLytConfig.tLayout.dwCanvasWidth); printf("Height = %d\n", g_tFecLytConfig.tLayout.dwCanvasHeight); //! setup layout VMF_FEC_LYT_Double_Customize(g_ptVsrcHandle, &g_tFecLytConfig, g_tPIPFecCellConfig, rectangle, offset); print_msg("[%s] done\n", __func__); return 0; } int setup_fec_1r(unsigned int output_index, VMF_VENC_CODEC_TYPE eCodecType) { VMF_FEC_PTZ_CONFIG_T tFecPtzConfig; VMF_FEC_CELL_CONFIG_T tFecCellConfig; VMF_FEC_LYT_CONFIG_T tFecLytConfig; memset(&tFecPtzConfig, 0, sizeof(VMF_FEC_PTZ_CONFIG_T) ); memset(&tFecCellConfig, 0, sizeof(VMF_FEC_CELL_CONFIG_T)); memset(&tFecLytConfig, 0, sizeof(VMF_FEC_LYT_CONFIG_T)); setup_fec_layout(&tFecLytConfig, output_index, eCodecType); tFecPtzConfig.fZoom = 1; tFecPtzConfig.fFocalLength = 0.65; tFecPtzConfig.eAppType = VMF_FEC_APP_TABL; tFecPtzConfig.eLensType = VMF_FEC_LENS_STEREOGRAPHIC; if (VMF_FEC_APP_WALL != tFecPtzConfig.eAppType) { tFecPtzConfig.fPan = 0;//(360 / ptz_num); tFecPtzConfig.fTilt = 35; } else { tFecPtzConfig.fPan = (0 == (0 >> 1)) ? 35 : -20; tFecPtzConfig.fTilt = (0 == (0 % 2)) ? 20 : -20; } tFecCellConfig.eFecMode = VMF_FEC_COEF_MODE_PTZ; tFecCellConfig.pFecConfig = &tFecPtzConfig; VMF_FEC_LYT_Single(g_ptVsrcHandle, &tFecLytConfig, &tFecCellConfig); print_msg("[%s] done\n", __func__); return 0; } int setup_fec_1r_area(unsigned int output_index, VMF_VENC_CODEC_TYPE eCodecType) { VMF_FEC_AREA_CONFIG_T tFecAreaConfig; VMF_FEC_CELL_CONFIG_T tFecCellConfig; VMF_FEC_LYT_CONFIG_T tFecLytConfig; memset(&tFecAreaConfig, 0, sizeof(VMF_FEC_AREA_CONFIG_T)); memset(&tFecCellConfig, 0, sizeof(VMF_FEC_CELL_CONFIG_T)); memset(&tFecLytConfig, 0, sizeof(VMF_FEC_LYT_CONFIG_T)); setup_fec_layout(&tFecLytConfig, output_index, eCodecType); tFecAreaConfig.dwCenterX = g_tLayout.dwVideoWidth/2; tFecAreaConfig.dwCenterY = g_tLayout.dwCanvasHeight/2; tFecAreaConfig.fZoom = 1; tFecAreaConfig.fFocalLength = 0.65; tFecAreaConfig.eAppType = VMF_FEC_APP_TABL; tFecAreaConfig.eLensType = VMF_FEC_LENS_STEREOGRAPHIC; tFecAreaConfig.dwOutRadius = 100; tFecCellConfig.eFecMode = VMF_FEC_COEF_MODE_AREA; tFecCellConfig.pFecConfig = &tFecAreaConfig; VMF_FEC_LYT_Single(g_ptVsrcHandle, &tFecLytConfig, &tFecCellConfig); print_msg("[%s] done\n", __func__); return 0; } int setup_fec_p180(unsigned int output_index, VMF_VENC_CODEC_TYPE eCodecType) { VMF_FEC_P180_CONFIG_T tFecP180Config; VMF_FEC_CELL_CONFIG_T tFecCellConfig; VMF_FEC_LYT_CONFIG_T tFecLytConfig; memset(&tFecP180Config, 0, sizeof(VMF_FEC_P180_CONFIG_T)); memset(&tFecCellConfig, 0, sizeof(VMF_FEC_CELL_CONFIG_T)); memset(&tFecLytConfig, 0, sizeof(VMF_FEC_LYT_CONFIG_T)); setup_fec_layout(&tFecLytConfig, output_index, eCodecType); //! setup P180 cell config parameters tFecP180Config.fPan = 0; tFecP180Config.fTilt = 0; tFecP180Config.fZoom = 1.5; tFecP180Config.fFocalLength = 0.7; tFecP180Config.fRectCurvature = 0.65; tFecP180Config.fRectSlope = 0.8; tFecP180Config.eModeType = VMF_FEC_MODE_PANO_180_TWO_DIRECTION; tFecCellConfig.eFecMode = VMF_FEC_COEF_MODE_P180; tFecCellConfig.pFecConfig = &tFecP180Config; //! setup layout VMF_FEC_LYT_Single(g_ptVsrcHandle, &tFecLytConfig, &tFecCellConfig); print_msg("[%s] done\n", __func__); return 0; } int setup_fec_p360_separate(unsigned int output_index, VMF_VENC_CODEC_TYPE eCodecType) { VMF_FEC_P360_CONFIG_T tFecP360Config; VMF_FEC_CELL_CONFIG_T tFecCellConfig; VMF_FEC_LYT_CONFIG_T tFecLytConfig; memset(&tFecP360Config, 0, sizeof(VMF_FEC_P360_CONFIG_T)); memset(&tFecCellConfig, 0, sizeof(VMF_FEC_CELL_CONFIG_T)); memset(&tFecLytConfig, 0, sizeof(VMF_FEC_LYT_CONFIG_T)); setup_fec_layout(&tFecLytConfig, output_index, eCodecType); //! setup P360 cell config parameters tFecP360Config.fPan = 0; tFecP360Config.fTilt = 5; tFecP360Config.fZoom = 1.0; tFecP360Config.fFocalLength = 0.7; tFecP360Config.eLensType = VMF_FEC_LENS_EQUIDISTANT; tFecP360Config.eAppType = VMF_FEC_APP_TABL; tFecP360Config.eModeType = VMF_FEC_MODE_PANO_360_SEPE; tFecCellConfig.eFecMode = VMF_FEC_COEF_MODE_P360; tFecCellConfig.pFecConfig = &tFecP360Config; //! setup layout VMF_FEC_LYT_P360_Separated(g_ptVsrcHandle, &tFecLytConfig, &tFecCellConfig); print_msg("[%s] done\n", __func__); return 0; } void release_eptz_tester(void) { if (!stop_eptz_thread) { stop_eptz_thread = 1; pthread_join(eptz_thread, NULL); } } int setup_fec_mode(unsigned int dwIndex, FEC_MODE mode, unsigned int enable, VMF_VENC_CODEC_TYPE eCodecType) { release_eptz_tester(); switch(mode) { case FEC_MODE_1R: setup_fec_1r(dwIndex, eCodecType); break; case FEC_MODE_1R_AREA: setup_fec_1r_area(dwIndex, eCodecType); break; case FEC_MODE_4R: setup_fec_4r_eptz(dwIndex, enable, eCodecType); break; case FEC_MODE_4R_HCUT: setup_fec_4r_hcut(dwIndex, eCodecType); break; case FEC_MODE_360: setup_fec_p360_separate(dwIndex, eCodecType); break; case FEC_MODE_180: setup_fec_p180(dwIndex, eCodecType); break; case FEC_MODE_PIP: setup_fec_pip(dwIndex, eCodecType); break; default: print_msg("[%s] Invalid FEC MODE\n", __func__); return -1; } return 0; }