416 lines
13 KiB
C
416 lines
13 KiB
C
/*
|
|
*******************************************************************************
|
|
* 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 <stdio.h>
|
|
#include <string.h>
|
|
#include <pthread.h>
|
|
#include <unistd.h>
|
|
|
|
#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;
|
|
}
|