first commit which could ouput camera video stream
This commit is contained in:
290
src/isp/eb3516_video.c
Normal file
290
src/isp/eb3516_video.c
Normal file
@@ -0,0 +1,290 @@
|
||||
#include "eb3516_video.h"
|
||||
|
||||
#include "hi_common.h"
|
||||
#include "my_common.h"
|
||||
#include "sample_comm.h"
|
||||
#include "zlog.h"
|
||||
|
||||
#define VB_YUV_COUNT 10
|
||||
#define VB_RGB_COUNT 4
|
||||
#define ALIGN_DOWN_SIZE 2
|
||||
|
||||
typedef struct hiSAMPLE_VPSS_CONFIG_S {
|
||||
VPSS_GRP s32GrpId;
|
||||
VPSS_GRP_ATTR_S stGrpAttr;
|
||||
HI_BOOL abChnEnable[VPSS_MAX_PHY_CHN_NUM];
|
||||
VPSS_CHN_ATTR_S astChnAttrs[VPSS_MAX_PHY_CHN_NUM];
|
||||
} SAMPLE_VPSS_CONFIG_S;
|
||||
|
||||
static zlog_category_t* log = NULL;
|
||||
|
||||
// Sensor Info
|
||||
static SAMPLE_VI_CONFIG_S g_stViConfig = {0};
|
||||
static PIC_SIZE_E enPicSize;
|
||||
static SIZE_S stSize;
|
||||
static HI_U32 u32Framerate;
|
||||
|
||||
static VB_CONFIG_S g_stVbConfig = {0};
|
||||
static SAMPLE_VPSS_CONFIG_S g_stVpss0Config = {0};
|
||||
static SAMPLE_VPSS_CONFIG_S g_stVpss1Config = {0};
|
||||
|
||||
// 注意此处不能为通道 0, 因为 hi3516 的 VPSS 通道 0 只支持放大,
|
||||
// 其它通道只支持缩小
|
||||
static const VPSS_CHN g_Vpss0Chn[2] = {1, 2};
|
||||
static const VPSS_CHN g_Vpss1Chn = 1;
|
||||
static const PIC_SIZE_E g_PicSizes[3] = {PIC_1080P, PIC_720P, PIC_1080P};
|
||||
static const VENC_CHN g_VencChn[1] = {0};
|
||||
static const PAYLOAD_TYPE_E g_CodecTypes[3] = {PT_H265, PT_H264, PT_JPEG};
|
||||
|
||||
static HI_S32 VPSS_GetDefChnAttr(VPSS_CHN_ATTR_S* pstVpssChnAttr,
|
||||
VPSS_CHN VpssChn, PIC_SIZE_E enPicSize) {
|
||||
SIZE_S stSize;
|
||||
SAMPLE_COMM_SYS_GetPicSize(enPicSize, &stSize);
|
||||
pstVpssChnAttr->enChnMode = VPSS_CHN_MODE_USER;
|
||||
pstVpssChnAttr->u32Width = stSize.u32Width;
|
||||
pstVpssChnAttr->u32Height = stSize.u32Height;
|
||||
pstVpssChnAttr->enVideoFormat = VIDEO_FORMAT_LINEAR;
|
||||
pstVpssChnAttr->enPixelFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420;
|
||||
pstVpssChnAttr->enDynamicRange = DYNAMIC_RANGE_SDR8;
|
||||
pstVpssChnAttr->enCompressMode = COMPRESS_MODE_NONE; // COMPRESS_MODE_SEG;
|
||||
pstVpssChnAttr->stFrameRate.s32SrcFrameRate = -1;
|
||||
pstVpssChnAttr->stFrameRate.s32DstFrameRate = -1;
|
||||
pstVpssChnAttr->u32Depth = 0;
|
||||
pstVpssChnAttr->bMirror = HI_FALSE;
|
||||
pstVpssChnAttr->bFlip = HI_FALSE;
|
||||
pstVpssChnAttr->stAspectRatio.enMode = ASPECT_RATIO_NONE;
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
static HI_S32 VPSS_GetParams(SAMPLE_VPSS_CONFIG_S* pstVpssConfig,
|
||||
SIZE_S* pstMaxSize, HI_BOOL bSnap) {
|
||||
// 设置 VPSS 组
|
||||
pstVpssConfig->s32GrpId = !bSnap ? 0 : 1;
|
||||
pstVpssConfig->stGrpAttr.u32MaxW = pstMaxSize->u32Width;
|
||||
pstVpssConfig->stGrpAttr.u32MaxH = pstMaxSize->u32Width;
|
||||
pstVpssConfig->stGrpAttr.enPixelFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420;
|
||||
pstVpssConfig->stGrpAttr.enDynamicRange = DYNAMIC_RANGE_SDR8;
|
||||
pstVpssConfig->stGrpAttr.stFrameRate.s32SrcFrameRate = -1;
|
||||
pstVpssConfig->stGrpAttr.stFrameRate.s32DstFrameRate = -1;
|
||||
pstVpssConfig->stGrpAttr.bNrEn = HI_TRUE;
|
||||
pstVpssConfig->stGrpAttr.stNrAttr.enNrType =
|
||||
!bSnap ? VPSS_NR_TYPE_VIDEO : VPSS_NR_TYPE_SNAP;
|
||||
pstVpssConfig->stGrpAttr.stNrAttr.enCompressMode = COMPRESS_MODE_FRAME;
|
||||
pstVpssConfig->stGrpAttr.stNrAttr.enNrMotionMode = NR_MOTION_MODE_NORMAL;
|
||||
// 设置 VPSS 通道
|
||||
if (!bSnap) {
|
||||
for (HI_S32 i = 0; i < ARRAY_LENGTH(g_Vpss0Chn); i++) {
|
||||
VPSS_CHN VpssChn = g_Vpss0Chn[i];
|
||||
pstVpssConfig->abChnEnable[VpssChn] = HI_TRUE;
|
||||
VPSS_GetDefChnAttr(&pstVpssConfig->astChnAttrs[VpssChn], VpssChn,
|
||||
g_PicSizes[i]);
|
||||
if (i == 1) {
|
||||
pstVpssConfig->astChnAttrs[VpssChn].u32Depth = 2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
VPSS_CHN VpssChn = g_Vpss1Chn;
|
||||
pstVpssConfig->abChnEnable[VpssChn] = HI_TRUE;
|
||||
VPSS_GetDefChnAttr(&pstVpssConfig->astChnAttrs[VpssChn], VpssChn,
|
||||
g_PicSizes[2]);
|
||||
}
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
void eb3516VideoInit(void) {
|
||||
log = zlog_get_category("eb3516_video");
|
||||
|
||||
// Get Sensor(VI) Info: picture size , frame rate
|
||||
SAMPLE_COMM_VI_GetSensorInfo(&g_stViConfig);
|
||||
SAMPLE_COMM_VI_GetSizeBySensor(
|
||||
g_stViConfig.astViInfo[0].stSnsInfo.enSnsType, &enPicSize);
|
||||
SAMPLE_COMM_SYS_GetPicSize(enPicSize, &stSize);
|
||||
SAMPLE_COMM_VI_GetFrameRateBySensor(
|
||||
g_stViConfig.astViInfo[0].stSnsInfo.enSnsType, &u32Framerate);
|
||||
|
||||
// 配置图像缓冲区
|
||||
g_stVbConfig.u32MaxPoolCnt = 2;
|
||||
// 获取一帧图片 buffer 的大小
|
||||
g_stVbConfig.astCommPool[0].u64BlkSize = COMMON_GetPicBufferSize(
|
||||
stSize.u32Width, stSize.u32Height, PIXEL_FORMAT_YVU_SEMIPLANAR_422,
|
||||
DATA_BITWIDTH_8, COMPRESS_MODE_SEG, DEFAULT_ALIGN);
|
||||
g_stVbConfig.astCommPool[0].u32BlkCnt = VB_YUV_COUNT;
|
||||
// 获取 raw buffer 的大小
|
||||
g_stVbConfig.astCommPool[1].u64BlkSize = VI_GetRawBufferSize(
|
||||
stSize.u32Width, stSize.u32Height, PIXEL_FORMAT_RGB_BAYER_16BPP,
|
||||
COMPRESS_MODE_NONE, DEFAULT_ALIGN);
|
||||
g_stVbConfig.astCommPool[1].u32BlkCnt = VB_RGB_COUNT;
|
||||
|
||||
// 配置 VI
|
||||
g_stViConfig.s32WorkingViNum = 1;
|
||||
g_stViConfig.as32WorkingViId[0] = 0;
|
||||
// 设置 VI 传感器信息
|
||||
g_stViConfig.astViInfo[0].stSnsInfo.MipiDev =
|
||||
SAMPLE_COMM_VI_GetComboDevBySensor(
|
||||
g_stViConfig.astViInfo[0].stSnsInfo.enSnsType, 0);
|
||||
|
||||
g_stViConfig.astViInfo[0].stDevInfo.ViDev = 0;
|
||||
g_stViConfig.astViInfo[0].stDevInfo.enWDRMode = WDR_MODE_NONE;
|
||||
// 设置 VI PIPE 信息
|
||||
g_stViConfig.astViInfo[0].stPipeInfo.aPipe[0] = 0; // video pipe
|
||||
g_stViConfig.astViInfo[0].stPipeInfo.aPipe[1] = -1; // snap pipe
|
||||
g_stViConfig.astViInfo[0].stPipeInfo.aPipe[2] = -1;
|
||||
g_stViConfig.astViInfo[0].stPipeInfo.aPipe[3] = -1;
|
||||
g_stViConfig.astViInfo[0].stPipeInfo.enMastPipeMode =
|
||||
VI_OFFLINE_VPSS_OFFLINE;
|
||||
// 设置 VI 通道信息
|
||||
g_stViConfig.astViInfo[0].stChnInfo.ViChn = 0;
|
||||
g_stViConfig.astViInfo[0].stChnInfo.enPixFormat =
|
||||
PIXEL_FORMAT_YVU_SEMIPLANAR_420;
|
||||
g_stViConfig.astViInfo[0].stChnInfo.enDynamicRange = DYNAMIC_RANGE_SDR8;
|
||||
g_stViConfig.astViInfo[0].stChnInfo.enVideoFormat = VIDEO_FORMAT_LINEAR;
|
||||
g_stViConfig.astViInfo[0].stChnInfo.enCompressMode = COMPRESS_MODE_SEG;
|
||||
// 设置 VI 抓拍信息
|
||||
g_stViConfig.astViInfo[0].stSnapInfo.bSnap = HI_FALSE;
|
||||
g_stViConfig.astViInfo[0].stSnapInfo.bDoublePipe = HI_TRUE;
|
||||
g_stViConfig.astViInfo[0].stSnapInfo.VideoPipe = 0;
|
||||
g_stViConfig.astViInfo[0].stSnapInfo.SnapPipe = -1;
|
||||
g_stViConfig.astViInfo[0].stSnapInfo.enVideoPipeMode =
|
||||
VI_OFFLINE_VPSS_OFFLINE;
|
||||
g_stViConfig.astViInfo[0].stSnapInfo.enSnapPipeMode =
|
||||
VI_OFFLINE_VPSS_OFFLINE;
|
||||
|
||||
// 配置 VPSS
|
||||
VPSS_GetParams(&g_stVpss0Config, &stSize, false);
|
||||
VPSS_GetParams(&g_stVpss1Config, &stSize, true);
|
||||
|
||||
zlog_info(log, "eb3516 Video Init Finish...");
|
||||
}
|
||||
|
||||
bool eb3516VideoStart(void) {
|
||||
HI_S32 s32Ret = 0;
|
||||
|
||||
// 初始化 VB 和 MPI 系统
|
||||
s32Ret = SAMPLE_COMM_SYS_InitWithVbSupplement(&g_stVbConfig,
|
||||
VB_SUPPLEMENT_JPEG_MASK);
|
||||
if (s32Ret != HI_SUCCESS) {
|
||||
zlog_error(log, "Init VB and MPI failed with %#x!\n", s32Ret);
|
||||
goto EXIT_SYS_RST_CLK;
|
||||
}
|
||||
|
||||
// 启动 VI
|
||||
s32Ret = SAMPLE_COMM_VI_SetParam(&g_stViConfig);
|
||||
ISP_CTRL_PARAM_S stIspCtrlParam = {0};
|
||||
memset(&stIspCtrlParam, 0, sizeof(stIspCtrlParam));
|
||||
s32Ret = HI_MPI_ISP_GetCtrlParam(
|
||||
g_stViConfig.astViInfo[0].stPipeInfo.aPipe[0], &stIspCtrlParam);
|
||||
stIspCtrlParam.u32StatIntvl = u32Framerate / 30;
|
||||
s32Ret = HI_MPI_ISP_SetCtrlParam(
|
||||
g_stViConfig.astViInfo[0].stPipeInfo.aPipe[0], &stIspCtrlParam);
|
||||
s32Ret = SAMPLE_COMM_VI_StartVi(&g_stViConfig);
|
||||
if (s32Ret != HI_SUCCESS) {
|
||||
zlog_error(log, "Start VI failed with %#x!\n", s32Ret);
|
||||
goto EXIT_SYS_STOP;
|
||||
}
|
||||
zlog_info(log, "eb3516 VI Start Success...");
|
||||
|
||||
// 启动 VPSS
|
||||
s32Ret = SAMPLE_COMM_VPSS_Start(
|
||||
g_stVpss0Config.s32GrpId, g_stVpss0Config.abChnEnable,
|
||||
&g_stVpss0Config.stGrpAttr, g_stVpss0Config.astChnAttrs);
|
||||
if (s32Ret != HI_SUCCESS) {
|
||||
zlog_error(log, "Start VPSS group %d failed with %#x!\n",
|
||||
g_stVpss0Config.s32GrpId, s32Ret);
|
||||
goto EXIT_VI_STOP;
|
||||
}
|
||||
zlog_info(log, "eb3516 VPSS Start Success...");
|
||||
|
||||
// 绑定 VI->VPSS
|
||||
s32Ret = SAMPLE_COMM_VI_Bind_VPSS(
|
||||
g_stViConfig.astViInfo[0].stPipeInfo.aPipe[0],
|
||||
g_stViConfig.astViInfo[0].stChnInfo.ViChn, g_stVpss0Config.s32GrpId);
|
||||
if (s32Ret != HI_SUCCESS) {
|
||||
zlog_error(log, "VI Video Pipe bind VPSS failed with %#x!\n", s32Ret);
|
||||
goto EXIT_VPSS_STOP;
|
||||
}
|
||||
|
||||
|
||||
// Get Venc Config
|
||||
VENC_GOP_ATTR_S stGopAttr;
|
||||
SAMPLE_COMM_VENC_GetGopAttr(VENC_GOPMODE_NORMALP, &stGopAttr);
|
||||
|
||||
// 编码 h.265 4k
|
||||
s32Ret =
|
||||
SAMPLE_COMM_VENC_Creat(g_VencChn[0], g_CodecTypes[0], g_PicSizes[0],
|
||||
SAMPLE_RC_VBR, 0, HI_FALSE, &stGopAttr);
|
||||
if (s32Ret != HI_SUCCESS) {
|
||||
zlog_error(log, "Create Venc Chn %d failed with %#x!\n", g_VencChn[0],
|
||||
s32Ret);
|
||||
goto EXIT_VI_VPSS_UNBIND;
|
||||
}
|
||||
zlog_info(log, "eb3516 VENC Start Success...");
|
||||
|
||||
/*config vo*/
|
||||
SAMPLE_VO_CONFIG_S stVoConfig;
|
||||
SAMPLE_COMM_VO_GetDefConfig(&stVoConfig);
|
||||
stVoConfig.enDstDynamicRange = DYNAMIC_RANGE_SDR8;
|
||||
stVoConfig.enVoIntfType = VO_INTF_HDMI;
|
||||
stVoConfig.enPicSize = enPicSize;
|
||||
|
||||
/*start vo*/
|
||||
s32Ret = SAMPLE_COMM_VO_StartVO(&stVoConfig);
|
||||
if (HI_SUCCESS != s32Ret)
|
||||
{
|
||||
SAMPLE_PRT("start vo failed. s32Ret: 0x%x !\n", s32Ret);
|
||||
goto EXIT_VENC_H264_STOP;
|
||||
}
|
||||
zlog_info(log, "eb3516 VO Start Success...");
|
||||
|
||||
/*vpss bind vo*/
|
||||
s32Ret = SAMPLE_COMM_VPSS_Bind_VO(g_stVpss0Config.s32GrpId, g_Vpss0Chn[0], stVoConfig.VoDev, g_VencChn[0]);
|
||||
if (HI_SUCCESS != s32Ret)
|
||||
{
|
||||
SAMPLE_PRT("vo bind vpss failed. s32Ret: 0x%x !\n", s32Ret);
|
||||
goto EXIT_VO_STOP;
|
||||
}
|
||||
|
||||
|
||||
// // 绑定 VPSS[0,0]->VENC[0]
|
||||
// s32Ret = SAMPLE_COMM_VPSS_Bind_VENC(g_stVpss0Config.s32GrpId, g_Vpss0Chn[0],
|
||||
// g_VencChn[0]);
|
||||
// if (s32Ret != HI_SUCCESS) {
|
||||
// zlog_error(log, "Venc bind Vpss failed with %#x!\n", s32Ret);
|
||||
// goto EXIT_VENC_H265_STOP;
|
||||
// }
|
||||
|
||||
// Start Venc Stream
|
||||
// s32Ret = SAMPLE_COMM_VENC_StartGetStream(
|
||||
// g_VencChn + 1, sizeof(g_VencChn) / sizeof(VENC_CHN) - 2);
|
||||
// if (HI_SUCCESS != s32Ret) {
|
||||
// zlog_error(log, "Get venc stream failed!\n");
|
||||
// goto EXIT_VENC_H264_STOP;
|
||||
// }
|
||||
// zlog_info(log, "eb3516 Stream Start Success...");
|
||||
|
||||
PAUSE();
|
||||
|
||||
// SAMPLE_COMM_VENC_StopGetStream();
|
||||
zlog_info(log, "Exit process Sucessfully!");
|
||||
|
||||
|
||||
EXIT_VO_STOP:
|
||||
SAMPLE_COMM_VO_StopVO(&stVoConfig);
|
||||
EXIT_VENC_H264_STOP:
|
||||
SAMPLE_COMM_VENC_Stop(g_VencChn[1]);
|
||||
EXIT_VENC_H265_STOP:
|
||||
// SAMPLE_COMM_VENC_Stop(g_VencChn[0]);
|
||||
EXIT_VI_VPSS_UNBIND:
|
||||
SAMPLE_COMM_VI_UnBind_VPSS(g_stViConfig.astViInfo[0].stPipeInfo.aPipe[0],
|
||||
g_stViConfig.astViInfo[0].stChnInfo.ViChn,
|
||||
g_stVpss0Config.s32GrpId);
|
||||
EXIT_VPSS_STOP:
|
||||
SAMPLE_COMM_VPSS_Stop(g_stVpss0Config.s32GrpId,
|
||||
g_stVpss0Config.abChnEnable);
|
||||
EXIT_VI_STOP:
|
||||
SAMPLE_COMM_VI_StopVi(&g_stViConfig);
|
||||
EXIT_SYS_STOP:
|
||||
SAMPLE_COMM_SYS_Exit();
|
||||
EXIT_SYS_RST_CLK:
|
||||
EXIT:
|
||||
return s32Ret;
|
||||
}
|
||||
17
src/isp/eb3516_video.h
Normal file
17
src/isp/eb3516_video.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef __EB3516_VIDEO_H__
|
||||
#define __EB3516_VIDEO_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include "stdbool.h"
|
||||
|
||||
void eb3516VideoInit(void);
|
||||
bool eb3516VideoStart(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
16
src/log.conf
Normal file
16
src/log.conf
Normal file
@@ -0,0 +1,16 @@
|
||||
[global]
|
||||
|
||||
strict init = true
|
||||
default format = "%d [%V] %m%n"
|
||||
|
||||
[formats]
|
||||
|
||||
simple = "[%V] %m%n"
|
||||
detail = "[%d.%us] [%p:%F:%L] [%V] %m%n"
|
||||
|
||||
[rules]
|
||||
|
||||
*.ERROR >stdout; detail
|
||||
*.WARN >stdout;
|
||||
*.INFO >stdout; simple
|
||||
*.DEBUG "log/%c.log"; detail
|
||||
44
src/main.cpp
Normal file
44
src/main.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include <iostream>
|
||||
#include <experimental/filesystem>
|
||||
|
||||
#include "hi_common.h"
|
||||
#include "zlog.h"
|
||||
|
||||
#include "isp/eb3516_video.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int result = 0;
|
||||
std::error_code file_error;
|
||||
|
||||
zlog_category_t *log = nullptr;
|
||||
|
||||
// init log and check log.conf
|
||||
result = zlog_init("log.conf");
|
||||
if (result) {
|
||||
std::cout << "zlog init failed! Please check log.conf!\n";
|
||||
return (-1);
|
||||
}
|
||||
|
||||
// get log cat for main to print
|
||||
log = zlog_get_category("cat");
|
||||
if (!log) {
|
||||
std::cout << "Main get log failed!\n";
|
||||
return (-2);
|
||||
}
|
||||
zlog_info(log, "Init zlog Sucessfully");
|
||||
|
||||
// if (!std::experimental::filesystem::remove_all("log", file_error)) {
|
||||
// zlog_warn(log, "Can't Remove Last Logs FOR %s", file_error.message().c_str());
|
||||
// }
|
||||
|
||||
if (!std::experimental::filesystem::create_directory("log", file_error)) {
|
||||
zlog_warn(log, "Can't Create log dir FOR %s", file_error.message().c_str());
|
||||
}
|
||||
|
||||
eb3516VideoInit();
|
||||
eb3516VideoStart();
|
||||
|
||||
zlog_fini();
|
||||
|
||||
return 0;
|
||||
}
|
||||
8
src/my_common.h
Normal file
8
src/my_common.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef __MY_COMMON_H__
|
||||
#define __MY_COMMON_H__
|
||||
|
||||
#ifndef ARRAY_LENGTH
|
||||
#define ARRAY_LENGTH(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user