multimedia/device/mpp/sample/common/sample_comm_venc.c

1753 lines
61 KiB
C

/******************************************************************************
Some simple Hisilicon Hi3531 video encode functions.
Copyright (C), 2010-2011, Hisilicon Tech. Co., Ltd.
******************************************************************************
Modification: 2011-2 Created
******************************************************************************/
#ifdef __cplusplus
#if __cplusplus
extern "C"{
#endif
#endif /* End of #ifdef __cplusplus */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/time.h>
#include <fcntl.h>
#include <errno.h>
#include <pthread.h>
#include <math.h>
#include <unistd.h>
#include <signal.h>
#include "sample_comm.h"
#include "../venc/librtsp.h"
#include "../venc/rtp.h"
const HI_U8 g_SOI[2] = {0xFF, 0xD8};
const HI_U8 g_EOI[2] = {0xFF, 0xD9};
static pthread_t gs_VencPid;
static SAMPLE_VENC_GETSTREAM_PARA_S gs_stPara;
static HI_S32 gs_s32SnapCnt = 0;
/******************************************************************************
* function : Set venc memory location
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_MemConfig(HI_VOID)
{
HI_S32 i = 0;
HI_S32 s32Ret;
HI_CHAR * pcMmzName;
MPP_CHN_S stMppChnVENC;
/* group, venc max chn is 64*/
for(i=0;i<64;i++)
{
stMppChnVENC.enModId = HI_ID_VENC;
stMppChnVENC.s32DevId = 0;
stMppChnVENC.s32ChnId = i;
pcMmzName = NULL;
/*venc*/
s32Ret = HI_MPI_SYS_SetMemConf(&stMppChnVENC,pcMmzName);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_SYS_SetMemConf with %#x!\n", s32Ret);
return HI_FAILURE;
}
}
return HI_SUCCESS;
}
/******************************************************************************
* function : venc bind vpss
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_BindVpss(VENC_CHN VeChn,VPSS_GRP VpssGrp,VPSS_CHN VpssChn)
{
HI_S32 s32Ret = HI_SUCCESS;
MPP_CHN_S stSrcChn;
MPP_CHN_S stDestChn;
stSrcChn.enModId = HI_ID_VPSS;
stSrcChn.s32DevId = VpssGrp;
stSrcChn.s32ChnId = VpssChn;
stDestChn.enModId = HI_ID_VENC;
stDestChn.s32DevId = 0;
stDestChn.s32ChnId = VeChn;
s32Ret = HI_MPI_SYS_Bind(&stSrcChn, &stDestChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("failed with %#x!\n", s32Ret);
return HI_FAILURE;
}
return s32Ret;
}
/******************************************************************************
* function : venc unbind vpss
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_UnBindVpss(VENC_CHN VeChn,VPSS_GRP VpssGrp,VPSS_CHN VpssChn)
{
HI_S32 s32Ret = HI_SUCCESS;
MPP_CHN_S stSrcChn;
MPP_CHN_S stDestChn;
stSrcChn.enModId = HI_ID_VPSS;
stSrcChn.s32DevId = VpssGrp;
stSrcChn.s32ChnId = VpssChn;
stDestChn.enModId = HI_ID_VENC;
stDestChn.s32DevId = 0;
stDestChn.s32ChnId = VeChn;
s32Ret = HI_MPI_SYS_UnBind(&stSrcChn, &stDestChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("failed with %#x!\n", s32Ret);
return HI_FAILURE;
}
return s32Ret;
}
/******************************************************************************
* function : venc bind vo
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_BindVo(VO_DEV VoDev,VO_CHN VoChn,VENC_CHN VeChn)
{
HI_S32 s32Ret = HI_SUCCESS;
MPP_CHN_S stSrcChn;
MPP_CHN_S stDestChn;
stSrcChn.enModId = HI_ID_VOU;
stSrcChn.s32DevId = VoDev;
stSrcChn.s32ChnId = VoChn;
stDestChn.enModId = HI_ID_VENC;
stDestChn.s32DevId = 0;
stDestChn.s32ChnId = VeChn;
s32Ret = HI_MPI_SYS_Bind(&stSrcChn, &stDestChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("failed with %#x!\n", s32Ret);
return HI_FAILURE;
}
return s32Ret;
}
/******************************************************************************
* function : venc unbind vo
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_UnBindVo(VENC_CHN GrpChn,VO_DEV VoDev,VO_CHN VoChn)
{
HI_S32 s32Ret = HI_SUCCESS;
MPP_CHN_S stSrcChn;
MPP_CHN_S stDestChn;
stSrcChn.enModId = HI_ID_VOU;
stSrcChn.s32DevId = VoDev;
stSrcChn.s32ChnId = VoChn;
stDestChn.enModId = HI_ID_VENC;
stDestChn.s32DevId = 0;
stDestChn.s32ChnId = GrpChn;
s32Ret = HI_MPI_SYS_UnBind(&stSrcChn, &stDestChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("failed with %#x!\n", s32Ret);
return HI_FAILURE;
}
return s32Ret;
}
/******************************************************************************
* function : vdec bind venc
******************************************************************************/
HI_S32 SAMPLE_COMM_VDEC_BindVenc(VDEC_CHN VdChn,VENC_CHN VeChn)
{
HI_S32 s32Ret = HI_SUCCESS;
MPP_CHN_S stSrcChn;
MPP_CHN_S stDestChn;
stSrcChn.enModId = HI_ID_VDEC;
stSrcChn.s32DevId = 0;
stSrcChn.s32ChnId = VdChn;
stDestChn.enModId = HI_ID_VENC;
stDestChn.s32DevId = 0;
stDestChn.s32ChnId = VeChn;
s32Ret = HI_MPI_SYS_Bind(&stSrcChn, &stDestChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("failed with %#x!\n", s32Ret);
return HI_FAILURE;
}
return s32Ret;
}
/******************************************************************************
* function : venc unbind vo
******************************************************************************/
HI_S32 SAMPLE_COMM_VDEC_UnBindVenc(VDEC_CHN VdChn,VENC_CHN VeChn)
{
HI_S32 s32Ret = HI_SUCCESS;
MPP_CHN_S stSrcChn;
MPP_CHN_S stDestChn;
stSrcChn.enModId = HI_ID_VDEC;
stSrcChn.s32DevId = 0;
stSrcChn.s32ChnId = VdChn;
stDestChn.enModId = HI_ID_VENC;
stDestChn.s32DevId = 0;
stDestChn.s32ChnId = VeChn;
s32Ret = HI_MPI_SYS_UnBind(&stSrcChn, &stDestChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("failed with %#x!\n", s32Ret);
return HI_FAILURE;
}
return s32Ret;
}
/******************************************************************************
* funciton : get file postfix according palyload_type.
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_GetFilePostfix(PAYLOAD_TYPE_E enPayload, char *szFilePostfix)
{
if (PT_H264 == enPayload)
{
strcpy(szFilePostfix, ".h264");
}
else if (PT_H265 == enPayload)
{
strcpy(szFilePostfix, ".h265");
}
else if (PT_JPEG == enPayload)
{
strcpy(szFilePostfix, ".jpg");
}
else if (PT_MJPEG == enPayload)
{
strcpy(szFilePostfix, ".mjp");
}
else if (PT_MP4VIDEO == enPayload)
{
strcpy(szFilePostfix, ".mp4");
}
else
{
SAMPLE_PRT("payload type err!\n");
return HI_FAILURE;
}
return HI_SUCCESS;
}
/******************************************************************************
* funciton : save mjpeg stream.
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_SaveMJpeg(FILE* fpMJpegFile, VENC_STREAM_S *pstStream)
{
VENC_PACK_S* pstData;
HI_U32 i;
//fwrite(g_SOI, 1, sizeof(g_SOI), fpJpegFile); //in Hi3531, user needn't write SOI!
for (i = 0; i < pstStream->u32PackCount; i++)
{
pstData = &pstStream->pstPack[i];
fwrite(pstData->pu8Addr+pstData->u32Offset, pstData->u32Len-pstData->u32Offset, 1, fpMJpegFile);
fflush(fpMJpegFile);
}
return HI_SUCCESS;
}
/******************************************************************************
* funciton : save jpeg stream.
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_SaveJpeg(FILE* fpJpegFile, VENC_STREAM_S *pstStream)
{
VENC_PACK_S* pstData;
HI_U32 i;
for (i = 0; i < pstStream->u32PackCount; i++)
{
pstData = &pstStream->pstPack[i];
fwrite(pstData->pu8Addr+pstData->u32Offset, pstData->u32Len-pstData->u32Offset, 1, fpJpegFile);
fflush(fpJpegFile);
}
return HI_SUCCESS;
}
Vector *outBuf = NULL;
/******************************************************************************
* funciton : save H264 stream
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_SaveH264(FILE* fpH264File, VENC_STREAM_S *pstStream)
{
HI_S32 i;
int z = 0;
if(NULL == outBuf) {
printf("init rtp buffer!!!!!!!\r\n");
outBuf = (Vector *)malloc(sizeof(Vector*)*120);
}
for (i = 0; i < pstStream->u32PackCount; i++) {
if(pstStream->pstPack[i].DataType.enH264EType == H264E_NALU_PSLICE)
printf("pslice ");
if(pstStream->pstPack[i].DataType.enH264EType == H264E_NALU_PPS)
printf("pps ");
if(pstStream->pstPack[i].DataType.enH264EType == H264E_NALU_ISLICE) {
printf("islice ");
int packCnt = Pack264AndSend(
pstStream->pstPack[i].pu8Addr + pstStream->pstPack[i].u32Offset
,pstStream->pstPack[i].u32Len - pstStream->pstPack[i].u32Offset
, gRtspclient);
}
if(pstStream->pstPack[i].DataType.enH264EType == H264E_NALU_SEI) {
printf("sei ");
}
if(pstStream->pstPack[i].DataType.enH264EType == H264E_NALU_SPS)
printf("sps ");
if(pstStream->pstPack[i].DataType.enH264EType == H264E_NALU_IPSLICE)
printf("islice ");
fwrite(pstStream->pstPack[i].pu8Addr + pstStream->pstPack[i].u32Offset ,
pstStream->pstPack[i].u32Len - pstStream->pstPack[i].u32Offset, 1, fpH264File);
unsigned char *p = pstStream->pstPack[i].pu8Addr;
/*printf("h264 header file %d length %d nal count %d offset %x %x %x %x %x %x %x %x\r\n",
pstStream->pstPack[i].u32Len - pstStream->pstPack[i].u32Offset,
i,
pstStream->pstPack[i].u32Offset,
p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]); */
int packCnt = Pack264AndSend(
pstStream->pstPack[i].pu8Addr + pstStream->pstPack[i].u32Offset
,pstStream->pstPack[i].u32Len - pstStream->pstPack[i].u32Offset
, gRtspclient);
fflush(fpH264File);
}
return HI_SUCCESS;
}
/******************************************************************************
* funciton : save H264 stream
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_SaveH264With(FILE* fpH264File, VENC_STREAM_S *pstStream)
{
HI_S32 i;
for (i = 0; i < pstStream->u32PackCount; i++)
{
if(pstStream->pstPack[i].DataType.enH264EType == H264E_NALU_PSLICE)
printf("pslice ");
if(pstStream->pstPack[i].DataType.enH264EType == H264E_NALU_PPS)
printf("pps ");
if(pstStream->pstPack[i].DataType.enH264EType == H264E_NALU_ISLICE)
printf("islice ");
if(pstStream->pstPack[i].DataType.enH264EType == H264E_NALU_SEI)
printf("sei ");
if(pstStream->pstPack[i].DataType.enH264EType == H264E_NALU_SPS)
printf("sps ");
if(pstStream->pstPack[i].DataType.enH264EType == H264E_NALU_IPSLICE)
printf("ipslice ");
fwrite(pstStream->pstPack[i].pu8Addr + pstStream->pstPack[i].u32Offset ,
pstStream->pstPack[i].u32Len - pstStream->pstPack[i].u32Offset, 1, fpH264File);
unsigned char *p = pstStream->pstPack[i].pu8Addr;
printf("h264 header file %d length %d nal count %d offset %x %x %x %x %x %x %x %x\r\n",
pstStream->pstPack[i].u32Len - pstStream->pstPack[i].u32Offset,
i,
pstStream->pstPack[i].u32Offset,
p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]);
fflush(fpH264File);
}
return HI_SUCCESS;
}
/******************************************************************************
* funciton : save H265 stream
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_SaveH265(FILE* fpH265File, VENC_STREAM_S *pstStream)
{
HI_S32 i;
for (i = 0; i < pstStream->u32PackCount; i++)
{
fwrite(pstStream->pstPack[i].pu8Addr+pstStream->pstPack[i].u32Offset,
pstStream->pstPack[i].u32Len-pstStream->pstPack[i].u32Offset, 1, fpH265File);
fflush(fpH265File);
}
return HI_SUCCESS;
}
/******************************************************************************
* funciton : save jpeg stream
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_SaveJPEG(FILE *fpJpegFile, VENC_STREAM_S *pstStream)
{
VENC_PACK_S* pstData;
HI_U32 i;
for (i = 0; i < pstStream->u32PackCount; i++)
{
pstData = &pstStream->pstPack[i];
fwrite(pstData->pu8Addr+pstData->u32Offset, pstData->u32Len-pstData->u32Offset, 1, fpJpegFile);
fflush(fpJpegFile);
}
return HI_SUCCESS;
}
/******************************************************************************
* funciton : save snap stream
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_SaveSnap(VENC_STREAM_S *pstStream)
{
char acFile[128] = {0};
FILE *pFile;
HI_S32 s32Ret;
sprintf(acFile, "snap_%d.jpg", gs_s32SnapCnt);
pFile = fopen(acFile, "wb");
if (pFile == NULL)
{
SAMPLE_PRT("open file err\n");
return HI_FAILURE;
}
s32Ret = SAMPLE_COMM_VENC_SaveJPEG(pFile, pstStream);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("save snap picture failed!\n");
return HI_FAILURE;
}
fclose(pFile);
gs_s32SnapCnt++;
return HI_SUCCESS;
}
/******************************************************************************
* funciton : save stream
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_SaveStream(PAYLOAD_TYPE_E enType,FILE *pFd, VENC_STREAM_S *pstStream)
{
HI_S32 s32Ret;
if (PT_H264 == enType)
{
s32Ret = SAMPLE_COMM_VENC_SaveH264(pFd, pstStream);
}
else if (PT_MJPEG == enType)
{
s32Ret = SAMPLE_COMM_VENC_SaveMJpeg(pFd, pstStream);
}
else if (PT_H265 == enType)
{
s32Ret = SAMPLE_COMM_VENC_SaveH265(pFd, pstStream);
}
else
{
return HI_FAILURE;
}
return s32Ret;
}
/******************************************************************************
* funciton : Start venc stream mode (h264, mjpeg)
* note : rate control parameter need adjust, according your case.
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_Start(VENC_CHN VencChn, PAYLOAD_TYPE_E enType,
VIDEO_NORM_E enNorm, PIC_SIZE_E enSize, SAMPLE_RC_E enRcMode,HI_U32 u32Profile)
{
HI_S32 s32Ret;
VENC_CHN_ATTR_S stVencChnAttr;
VENC_ATTR_H264_S stH264Attr;
VENC_ATTR_H264_CBR_S stH264Cbr;
VENC_ATTR_H264_VBR_S stH264Vbr;
VENC_ATTR_H264_FIXQP_S stH264FixQp;
VENC_ATTR_H265_S stH265Attr;
VENC_ATTR_H265_CBR_S stH265Cbr;
VENC_ATTR_H265_VBR_S stH265Vbr;
VENC_ATTR_H265_FIXQP_S stH265FixQp;
VENC_ATTR_MJPEG_S stMjpegAttr;
VENC_ATTR_MJPEG_FIXQP_S stMjpegeFixQp;
VENC_ATTR_JPEG_S stJpegAttr;
SIZE_S stPicSize;
s32Ret = SAMPLE_COMM_SYS_GetPicSize(enNorm, enSize, &stPicSize);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("Get picture size failed!\n");
return HI_FAILURE;
}
/******************************************
step 1: Create Venc Channel
******************************************/
stVencChnAttr.stVeAttr.enType = enType;
switch(enType)
{
case PT_H264:
{
stH264Attr.u32MaxPicWidth = stPicSize.u32Width;
stH264Attr.u32MaxPicHeight = stPicSize.u32Height;
stH264Attr.u32PicWidth = stPicSize.u32Width;/*the picture width*/
stH264Attr.u32PicHeight = stPicSize.u32Height;/*the picture height*/
stH264Attr.u32BufSize = stPicSize.u32Width * stPicSize.u32Height * 2;/*stream buffer size*/
stH264Attr.u32Profile = u32Profile;/*0: baseline; 1:MP; 2:HP; 3:svc_t */
stH264Attr.bByFrame = HI_TRUE;/*get stream mode is slice mode or frame mode?*/
stH264Attr.u32BFrameNum = 0;/* 0: not support B frame; >=1: number of B frames */
stH264Attr.u32RefNum = 1;/* 0: default; number of refrence frame*/
memcpy(&stVencChnAttr.stVeAttr.stAttrH264e, &stH264Attr, sizeof(VENC_ATTR_H264_S));
if(SAMPLE_RC_CBR == enRcMode)
{
stVencChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;
stH264Cbr.u32Gop = (VIDEO_ENCODING_MODE_PAL== enNorm)?3:3;
stH264Cbr.u32StatTime = 1; /* stream rate statics time(s) */
stH264Cbr.u32SrcFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?3:3;/* input (vi) frame rate */
stH264Cbr.fr32DstFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?3:3;/* target frame rate */
switch (enSize)
{
case PIC_QCIF:
stH264Cbr.u32BitRate = 50; /* average bit rate */
break;
case PIC_QVGA: /* 320 * 240 */
stH264Cbr.u32BitRate = 50;
case PIC_CIF:
stH264Cbr.u32BitRate = 50;
break;
case PIC_D1:
case PIC_VGA: /* 640 * 480 */
stH264Cbr.u32BitRate = 1024*2;
break;
case PIC_HD720: /* 1280 * 720 */
stH264Cbr.u32BitRate = 1024*2;
break;
case PIC_HD1080: /* 1920 * 1080 */
stH264Cbr.u32BitRate = 1024*4;
break;
case PIC_5M: /* 2592 * 1944 */
stH264Cbr.u32BitRate = 1024*8;
break;
default :
stH264Cbr.u32BitRate = 1024*4;
break;
}
stH264Cbr.u32FluctuateLevel = 0; /* average bit rate */
memcpy(&stVencChnAttr.stRcAttr.stAttrH264Cbr, &stH264Cbr, sizeof(VENC_ATTR_H264_CBR_S));
}
else if (SAMPLE_RC_FIXQP == enRcMode)
{
stVencChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264FIXQP;
stH264FixQp.u32Gop = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
stH264FixQp.u32SrcFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
stH264FixQp.fr32DstFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
stH264FixQp.u32IQp = 20;
stH264FixQp.u32PQp = 23;
memcpy(&stVencChnAttr.stRcAttr.stAttrH264FixQp, &stH264FixQp,sizeof(VENC_ATTR_H264_FIXQP_S));
}
else if (SAMPLE_RC_VBR == enRcMode)
{
stVencChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264VBR;
stH264Vbr.u32Gop = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
stH264Vbr.u32StatTime = 1;
stH264Vbr.u32SrcFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
stH264Vbr.fr32DstFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
stH264Vbr.u32MinQp = 10;
stH264Vbr.u32MaxQp = 40;
switch (enSize)
{
case PIC_QCIF:
stH264Vbr.u32MaxBitRate= 256*3; /* average bit rate */
break;
case PIC_QVGA: /* 320 * 240 */
case PIC_CIF:
stH264Vbr.u32MaxBitRate = 512*3;
break;
case PIC_D1:
case PIC_VGA: /* 640 * 480 */
stH264Vbr.u32MaxBitRate = 1024*2;
break;
case PIC_HD720: /* 1280 * 720 */
stH264Vbr.u32MaxBitRate = 1024*3;
break;
case PIC_HD1080: /* 1920 * 1080 */
stH264Vbr.u32MaxBitRate = 1024*6;
break;
case PIC_5M: /* 2592 * 1944 */
stH264Vbr.u32MaxBitRate = 1024*8;
break;
default :
stH264Vbr.u32MaxBitRate = 1024*4;
break;
}
memcpy(&stVencChnAttr.stRcAttr.stAttrH264Vbr, &stH264Vbr, sizeof(VENC_ATTR_H264_VBR_S));
}
else
{
return HI_FAILURE;
}
}
break;
case PT_MJPEG:
{
stMjpegAttr.u32MaxPicWidth = stPicSize.u32Width;
stMjpegAttr.u32MaxPicHeight = stPicSize.u32Height;
stMjpegAttr.u32PicWidth = stPicSize.u32Width;
stMjpegAttr.u32PicHeight = stPicSize.u32Height;
stMjpegAttr.u32BufSize = stPicSize.u32Width * stPicSize.u32Height * 2;
stMjpegAttr.bByFrame = HI_TRUE; /*get stream mode is field mode or frame mode*/
memcpy(&stVencChnAttr.stVeAttr.stAttrMjpeg, &stMjpegAttr, sizeof(VENC_ATTR_MJPEG_S));
if(SAMPLE_RC_FIXQP == enRcMode)
{
stVencChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_MJPEGFIXQP;
stMjpegeFixQp.u32Qfactor = 90;
stMjpegeFixQp.u32SrcFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
stMjpegeFixQp.fr32DstFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
memcpy(&stVencChnAttr.stRcAttr.stAttrMjpegeFixQp, &stMjpegeFixQp,
sizeof(VENC_ATTR_MJPEG_FIXQP_S));
}
else if (SAMPLE_RC_CBR == enRcMode)
{
stVencChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_MJPEGCBR;
stVencChnAttr.stRcAttr.stAttrMjpegeCbr.u32StatTime = 1;
stVencChnAttr.stRcAttr.stAttrMjpegeCbr.u32SrcFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
stVencChnAttr.stRcAttr.stAttrMjpegeCbr.fr32DstFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
stVencChnAttr.stRcAttr.stAttrMjpegeCbr.u32FluctuateLevel = 0;
switch (enSize)
{
case PIC_QCIF:
stVencChnAttr.stRcAttr.stAttrMjpegeCbr.u32BitRate = 384*3; /* average bit rate */
break;
case PIC_QVGA: /* 320 * 240 */
case PIC_CIF:
stVencChnAttr.stRcAttr.stAttrMjpegeCbr.u32BitRate = 768*3;
break;
case PIC_D1:
case PIC_VGA: /* 640 * 480 */
stVencChnAttr.stRcAttr.stAttrMjpegeCbr.u32BitRate = 1024*3*3;
break;
case PIC_HD720: /* 1280 * 720 */
stVencChnAttr.stRcAttr.stAttrMjpegeCbr.u32BitRate = 1024*5*3;
break;
case PIC_HD1080: /* 1920 * 1080 */
stVencChnAttr.stRcAttr.stAttrMjpegeCbr.u32BitRate = 1024*10*3;
break;
case PIC_5M: /* 2592 * 1944 */
stVencChnAttr.stRcAttr.stAttrMjpegeCbr.u32BitRate = 1024*10*3;
break;
default :
stVencChnAttr.stRcAttr.stAttrMjpegeCbr.u32BitRate = 1024*10*3;
break;
}
}
else if (SAMPLE_RC_VBR == enRcMode)
{
stVencChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_MJPEGVBR;
stVencChnAttr.stRcAttr.stAttrMjpegeVbr.u32StatTime = 1;
stVencChnAttr.stRcAttr.stAttrMjpegeVbr.u32SrcFrmRate = (VIDEO_ENCODING_MODE_PAL == enNorm)?25:30;
stVencChnAttr.stRcAttr.stAttrMjpegeVbr.fr32DstFrmRate = 5;
stVencChnAttr.stRcAttr.stAttrMjpegeVbr.u32MinQfactor = 50;
stVencChnAttr.stRcAttr.stAttrMjpegeVbr.u32MaxQfactor = 95;
switch (enSize)
{
case PIC_QCIF:
stVencChnAttr.stRcAttr.stAttrMjpegeVbr.u32MaxBitRate= 256*3; /* average bit rate */
break;
case PIC_QVGA: /* 320 * 240 */
case PIC_CIF:
stVencChnAttr.stRcAttr.stAttrMjpegeVbr.u32MaxBitRate = 512*3;
break;
case PIC_D1:
case PIC_VGA: /* 640 * 480 */
stVencChnAttr.stRcAttr.stAttrMjpegeVbr.u32MaxBitRate = 1024*2*3;
break;
case PIC_HD720: /* 1280 * 720 */
stVencChnAttr.stRcAttr.stAttrMjpegeVbr.u32MaxBitRate = 1024*3*3;
break;
case PIC_HD1080: /* 1920 * 1080 */
stVencChnAttr.stRcAttr.stAttrMjpegeVbr.u32MaxBitRate = 1024*6*3;
break;
case PIC_5M: /* 2592 * 1944 */
stVencChnAttr.stRcAttr.stAttrMjpegeVbr.u32MaxBitRate = 1024*12*3;
break;
default :
stVencChnAttr.stRcAttr.stAttrMjpegeVbr.u32MaxBitRate = 1024*4*3;
break;
}
}
else
{
SAMPLE_PRT("cann't support other mode in this version!\n");
return HI_FAILURE;
}
}
break;
case PT_JPEG:
stJpegAttr.u32PicWidth = stPicSize.u32Width;
stJpegAttr.u32PicHeight = stPicSize.u32Height;
stJpegAttr.u32MaxPicWidth = stPicSize.u32Width;
stJpegAttr.u32MaxPicHeight = stPicSize.u32Height;
stJpegAttr.u32BufSize = stPicSize.u32Width * stPicSize.u32Height * 2;
stJpegAttr.bByFrame = HI_TRUE;/*get stream mode is field mode or frame mode*/
stJpegAttr.bSupportDCF = HI_FALSE;
memcpy(&stVencChnAttr.stVeAttr.stAttrJpeg, &stJpegAttr, sizeof(VENC_ATTR_JPEG_S));
break;
case PT_H265:
{
stH265Attr.u32MaxPicWidth = stPicSize.u32Width;
stH265Attr.u32MaxPicHeight = stPicSize.u32Height;
stH265Attr.u32PicWidth = stPicSize.u32Width;/*the picture width*/
stH265Attr.u32PicHeight = stPicSize.u32Height;/*the picture height*/
stH265Attr.u32BufSize = stPicSize.u32Width * stPicSize.u32Height * 2;/*stream buffer size*/
if(u32Profile >=1)
stH265Attr.u32Profile = 0;/*0:MP; */
else
stH265Attr.u32Profile = u32Profile;/*0:MP*/
stH265Attr.bByFrame = HI_TRUE;/*get stream mode is slice mode or frame mode?*/
stH265Attr.u32BFrameNum = 0;/* 0: not support B frame; >=1: number of B frames */
stH265Attr.u32RefNum = 1;/* 0: default; number of refrence frame*/
memcpy(&stVencChnAttr.stVeAttr.stAttrH265e, &stH265Attr, sizeof(VENC_ATTR_H265_S));
if(SAMPLE_RC_CBR == enRcMode)
{
stVencChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_H265CBR;
stH265Cbr.u32Gop = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
stH265Cbr.u32StatTime = 1; /* stream rate statics time(s) */
stH265Cbr.u32SrcFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;/* input (vi) frame rate */
stH265Cbr.fr32DstFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;/* target frame rate */
switch (enSize)
{
case PIC_QCIF:
stH265Cbr.u32BitRate = 256; /* average bit rate */
break;
case PIC_QVGA: /* 320 * 240 */
case PIC_CIF:
stH265Cbr.u32BitRate = 512;
break;
case PIC_D1:
case PIC_VGA: /* 640 * 480 */
stH265Cbr.u32BitRate = 1024*2;
break;
case PIC_HD720: /* 1280 * 720 */
stH265Cbr.u32BitRate = 1024*3;
break;
case PIC_HD1080: /* 1920 * 1080 */
stH265Cbr.u32BitRate = 1024*4;
break;
case PIC_5M: /* 2592 * 1944 */
stH265Cbr.u32BitRate = 1024*8;
break;
default :
stH265Cbr.u32BitRate = 1024*4;
break;
}
stH265Cbr.u32FluctuateLevel = 0; /* average bit rate */
memcpy(&stVencChnAttr.stRcAttr.stAttrH265Cbr, &stH265Cbr, sizeof(VENC_ATTR_H265_CBR_S));
}
else if (SAMPLE_RC_FIXQP == enRcMode)
{
stVencChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_H265FIXQP;
stH265FixQp.u32Gop = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
stH265FixQp.u32SrcFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
stH265FixQp.fr32DstFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
stH265FixQp.u32IQp = 20;
stH265FixQp.u32PQp = 23;
memcpy(&stVencChnAttr.stRcAttr.stAttrH265FixQp, &stH265FixQp,sizeof(VENC_ATTR_H265_FIXQP_S));
}
else if (SAMPLE_RC_VBR == enRcMode)
{
stVencChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_H265VBR;
stH265Vbr.u32Gop = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
stH265Vbr.u32StatTime = 1;
stH265Vbr.u32SrcFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
stH265Vbr.fr32DstFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
stH265Vbr.u32MinQp = 10;
stH265Vbr.u32MaxQp = 40;
switch (enSize)
{
case PIC_QCIF:
stH265Vbr.u32MaxBitRate= 256*3; /* average bit rate */
break;
case PIC_QVGA: /* 320 * 240 */
case PIC_CIF:
stH265Vbr.u32MaxBitRate = 512*3;
break;
case PIC_D1:
case PIC_VGA: /* 640 * 480 */
stH265Vbr.u32MaxBitRate = 1024*2;
break;
case PIC_HD720: /* 1280 * 720 */
stH265Vbr.u32MaxBitRate = 1024*3;
break;
case PIC_HD1080: /* 1920 * 1080 */
stH265Vbr.u32MaxBitRate = 1024*6;
break;
case PIC_5M: /* 2592 * 1944 */
stH265Vbr.u32MaxBitRate = 1024*8;
break;
default :
stH265Vbr.u32MaxBitRate = 1024*4;
break;
}
memcpy(&stVencChnAttr.stRcAttr.stAttrH265Vbr, &stH265Vbr, sizeof(VENC_ATTR_H265_VBR_S));
}
else
{
return HI_FAILURE;
}
}
break;
default:
return HI_ERR_VENC_NOT_SUPPORT;
}
s32Ret = HI_MPI_VENC_CreateChn(VencChn, &stVencChnAttr);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_VENC_CreateChn [%d] faild with %#x!\n",\
VencChn, s32Ret);
return s32Ret;
}
/******************************************
step 2: Start Recv Venc Pictures
******************************************/
s32Ret = HI_MPI_VENC_StartRecvPic(VencChn);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_VENC_StartRecvPic faild with%#x!\n", s32Ret);
return HI_FAILURE;
}
return HI_SUCCESS;
}
/******************************************************************************
* funciton : Stop venc ( stream mode -- H264, MJPEG )
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_Stop(VENC_CHN VencChn)
{
HI_S32 s32Ret;
/******************************************
step 1: Stop Recv Pictures
******************************************/
s32Ret = HI_MPI_VENC_StopRecvPic(VencChn);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_VENC_StopRecvPic vechn[%d] failed with %#x!\n",\
VencChn, s32Ret);
return HI_FAILURE;
}
/******************************************
step 2: Distroy Venc Channel
******************************************/
s32Ret = HI_MPI_VENC_DestroyChn(VencChn);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_VENC_DestroyChn vechn[%d] failed with %#x!\n",\
VencChn, s32Ret);
return HI_FAILURE;
}
return HI_SUCCESS;
}
/******************************************************************************
* funciton : Start snap
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_SnapStart(VENC_CHN VencChn, SIZE_S *pstSize)
{
HI_S32 s32Ret;
VENC_CHN_ATTR_S stVencChnAttr;
VENC_ATTR_JPEG_S stJpegAttr;
/******************************************
step 1: Create Venc Channel
******************************************/
stVencChnAttr.stVeAttr.enType = PT_JPEG;
stJpegAttr.u32MaxPicWidth = pstSize->u32Width;
stJpegAttr.u32MaxPicHeight = pstSize->u32Height;
stJpegAttr.u32PicWidth = pstSize->u32Width;
stJpegAttr.u32PicHeight = pstSize->u32Height;
stJpegAttr.u32BufSize = pstSize->u32Width * pstSize->u32Height * 2;
stJpegAttr.bByFrame = HI_TRUE;/*get stream mode is field mode or frame mode*/
stJpegAttr.bSupportDCF = HI_FALSE;
memcpy(&stVencChnAttr.stVeAttr.stAttrJpeg, &stJpegAttr, sizeof(VENC_ATTR_JPEG_S));
s32Ret = HI_MPI_VENC_CreateChn(VencChn, &stVencChnAttr);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_VENC_CreateChn [%d] faild with %#x!\n",\
VencChn, s32Ret);
return s32Ret;
}
return HI_SUCCESS;
}
/******************************************************************************
* funciton : Stop snap
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_SnapStop(VENC_CHN VencChn)
{
HI_S32 s32Ret;
s32Ret = HI_MPI_VENC_StopRecvPic(VencChn);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_VENC_StopRecvPic vechn[%d] failed with %#x!\n", VencChn, s32Ret);
return HI_FAILURE;
}
s32Ret = HI_MPI_VENC_DestroyChn(VencChn);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_VENC_DestroyChn vechn[%d] failed with %#x!\n", VencChn, s32Ret);
return HI_FAILURE;
}
return HI_SUCCESS;
}
/******************************************************************************
* funciton : snap process
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_SnapProcess (VENC_CHN VencChn)
{
struct timeval TimeoutVal;
fd_set read_fds;
HI_S32 s32VencFd;
HI_S32 s32VencStreamFd;
VENC_CHN_STAT_S stStat;
VENC_STREAM_S stStream;
HI_S32 s32Ret;
VENC_RECV_PIC_PARAM_S stRecvParam;
printf("press any key to snap one pic\n");
//getchar();
/******************************************
step 2: Start Recv Venc Pictures
******************************************/
stRecvParam.s32RecvPicNum = 1;
s32Ret = HI_MPI_VENC_StartRecvPicEx(VencChn,&stRecvParam);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_VENC_StartRecvPic faild with%#x!\n", s32Ret);
return HI_FAILURE;
}
/******************************************
step 3: recv picture
******************************************/
s32VencFd = HI_MPI_VENC_GetFd(VencChn);
s32VencStreamFd = HI_MPI_VENC_GetFd(0);
if (s32VencFd < 0)
{
SAMPLE_PRT("HI_MPI_VENC_GetFd faild with%#x!\n", s32VencFd);
return HI_FAILURE;
}
printf("\r\nsnap venc picture is %d fd is %d stream %d fd is %d\r\n",VencChn,s32VencFd,0,s32VencStreamFd);
FD_ZERO(&read_fds);
FD_SET(s32VencFd, &read_fds);
FD_SET(s32VencStreamFd, &read_fds);
TimeoutVal.tv_sec = 2;
TimeoutVal.tv_usec = 0;
s32Ret = select(s32VencFd + 1, &read_fds, NULL, NULL, &TimeoutVal);
if (s32Ret < 0)
{
SAMPLE_PRT("snap select failed!\n");
return HI_FAILURE;
}
else if (0 == s32Ret)
{
printf("select timeout \r\n");
return HI_FAILURE;
}
else
{
if (FD_ISSET(s32VencFd, &read_fds))
{
printf("venc picture \r\n");
s32Ret = HI_MPI_VENC_Query(VencChn, &stStat);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("HI_MPI_VENC_Query failed with %#x!\n", s32Ret);
return HI_FAILURE;
}
/*******************************************************
suggest to check both u32CurPacks and u32LeftStreamFrames at the same time,for example:
if(0 == stStat.u32CurPacks || 0 == stStat.u32LeftStreamFrames)
{
SAMPLE_PRT("NOTE: Current frame is NULL!\n");
return HI_SUCCESS;
}
*******************************************************/
if(0 == stStat.u32CurPacks)
{
SAMPLE_PRT("NOTE: Current frame is NULL!\n");
return HI_SUCCESS;
}
printf("recieve %d packs %d %d\r\n",stStat.u32CurPacks,stStat.u32LeftRecvPics,stStat.u32LeftStreamFrames);
stStream.pstPack = (VENC_PACK_S*)malloc(sizeof(VENC_PACK_S) * stStat.u32CurPacks);
if (NULL == stStream.pstPack)
{
SAMPLE_PRT("malloc memory failed!\n");
return HI_FAILURE;
}
stStream.u32PackCount = stStat.u32CurPacks;
s32Ret = HI_MPI_VENC_GetStream(VencChn, &stStream, -1);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_VENC_GetStream failed with %#x!\n", s32Ret);
free(stStream.pstPack);
stStream.pstPack = NULL;
return HI_FAILURE;
}
/*s32Ret = SAMPLE_COMM_VENC_SaveSnap(&stStream);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_VENC_GetStream failed with %#x!\n", s32Ret);
free(stStream.pstPack);
stStream.pstPack = NULL;
return HI_FAILURE;
}*/
s32Ret = HI_MPI_VENC_ReleaseStream(VencChn, &stStream);
if (s32Ret)
{
SAMPLE_PRT("HI_MPI_VENC_ReleaseStream failed with %#x!\n", s32Ret);
free(stStream.pstPack);
stStream.pstPack = NULL;
return HI_FAILURE;
}
free(stStream.pstPack);
stStream.pstPack = NULL;
}
if(FD_ISSET(s32VencStreamFd,&read_fds)) {
printf("venc stream \r\n");
s32Ret = HI_MPI_VENC_Query(0, &stStat);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("HI_MPI_VENC_Query failed with %#x!\n", s32Ret);
return HI_FAILURE;
}
/*******************************************************
suggest to check both u32CurPacks and u32LeftStreamFrames at the same time,for example:
if(0 == stStat.u32CurPacks || 0 == stStat.u32LeftStreamFrames)
{
SAMPLE_PRT("NOTE: Current frame is NULL!\n");
return HI_SUCCESS;
}
*******************************************************/
if(0 == stStat.u32CurPacks)
{
SAMPLE_PRT("NOTE: Current frame is NULL!\n");
return HI_SUCCESS;
}
printf("recieve %d packs %d %d\r\n",stStat.u32CurPacks,stStat.u32LeftRecvPics,stStat.u32LeftStreamFrames);
stStream.pstPack = (VENC_PACK_S*)malloc(sizeof(VENC_PACK_S) * stStat.u32CurPacks);
if (NULL == stStream.pstPack)
{
SAMPLE_PRT("malloc memory failed!\n");
return HI_FAILURE;
}
/*
stStream.u32PackCount = stStat.u32CurPacks;
s32Ret = HI_MPI_VENC_GetStream(0, &stStream, -1);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_VENC_GetStream failed with %#x!\n", s32Ret);
free(stStream.pstPack);
stStream.pstPack = NULL;
return HI_FAILURE;
}
s32Ret = HI_MPI_VENC_ReleaseStream(0, &stStream);
if (s32Ret)
{
SAMPLE_PRT("HI_MPI_VENC_ReleaseStream failed with %#x!\n", s32Ret);
free(stStream.pstPack);
stStream.pstPack = NULL;
return HI_FAILURE;
}
free(stStream.pstPack);
stStream.pstPack = NULL;*/
}
}
/******************************************
step 4: stop recv picture
******************************************/
s32Ret = HI_MPI_VENC_StopRecvPic(VencChn);
if (s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("HI_MPI_VENC_StopRecvPic failed with %#x!\n", s32Ret);
return HI_FAILURE;
}
return HI_SUCCESS;
}
/******************************************************************************
* funciton : get stream from each channels and save them
******************************************************************************/
HI_VOID* SAMPLE_COMM_VENC_GetVencStreamProc(HI_VOID *p)
{
HI_S32 i;
HI_S32 s32ChnTotal;
VENC_CHN_ATTR_S stVencChnAttr;
SAMPLE_VENC_GETSTREAM_PARA_S *pstPara;
HI_S32 maxfd = 0;
struct timeval TimeoutVal;
fd_set read_fds;
HI_S32 VencFd[VENC_MAX_CHN_NUM];
HI_CHAR aszFileName[VENC_MAX_CHN_NUM][64];
FILE *pFile[VENC_MAX_CHN_NUM];
char szFilePostfix[10];
VENC_CHN_STAT_S stStat;
VENC_STREAM_S stStream;
HI_S32 s32Ret;
VENC_CHN VencChn;
printf("venc stream chn is %d\r\n",VencChn);
PAYLOAD_TYPE_E enPayLoadType[VENC_MAX_CHN_NUM];
pstPara = (SAMPLE_VENC_GETSTREAM_PARA_S*)p;
s32ChnTotal = pstPara->s32Cnt;
printf("input count is %d\r\n",pstPara->s32Cnt);
/******************************************
step 1: check & prepare save-file & venc-fd
******************************************/
if (s32ChnTotal >= VENC_MAX_CHN_NUM)
{
SAMPLE_PRT("input count invaild\n");
return NULL;
}
for (i = 0; i < s32ChnTotal; i++)
{
/* decide the stream file name, and open file to save stream */
VencChn = i;
s32Ret = HI_MPI_VENC_GetChnAttr(VencChn, &stVencChnAttr);
if(s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("HI_MPI_VENC_GetChnAttr chn[%d] failed with %#x!\n", \
VencChn, s32Ret);
break;
// return NULL;
}
enPayLoadType[i] = stVencChnAttr.stVeAttr.enType;
s32Ret = SAMPLE_COMM_VENC_GetFilePostfix(enPayLoadType[i], szFilePostfix);
if(s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("SAMPLE_COMM_VENC_GetFilePostfix [%d] failed with %#x!\n", \
stVencChnAttr.stVeAttr.enType, s32Ret);
return NULL;
}
sprintf(aszFileName[i], "stream_chn%d%s", i, szFilePostfix);
pFile[i] = fopen(aszFileName[i], "wb");
if (!pFile[i])
{
SAMPLE_PRT("open file[%s] failed!\n",
aszFileName[i]);
return NULL;
}
/* Set Venc Fd. */
VencFd[i] = HI_MPI_VENC_GetFd(i);
printf("venc fd %d %d",i,VencFd[i]);
if (VencFd[i] < 0)
{
SAMPLE_PRT("HI_MPI_VENC_GetFd failed with %#x!\n",
VencFd[i]);
return NULL;
}
if (maxfd <= VencFd[i])
{
maxfd = VencFd[i];
}
}
/******************************************
step 2: Start to get streams of each channel.
******************************************/
while (HI_TRUE == pstPara->bThreadStart)
{
FD_ZERO(&read_fds);
for (i = 0; i < s32ChnTotal; i++)
{
FD_SET(VencFd[i], &read_fds);
}
TimeoutVal.tv_sec = 2;
TimeoutVal.tv_usec = 0;
s32Ret = select(maxfd + 1, &read_fds, NULL, NULL, &TimeoutVal);
if (s32Ret < 0)
{
SAMPLE_PRT("select failed!\n");
break;
}
else if (s32Ret == 0)
{
SAMPLE_PRT("get venc stream time out, exit thread\n");
continue;
}
else
{
for (i = 0; i < s32ChnTotal; i++)
{
if (FD_ISSET(VencFd[i], &read_fds))
{
/*******************************************************
step 2.1 : query how many packs in one-frame stream.
*******************************************************/
memset(&stStream, 0, sizeof(stStream));
s32Ret = HI_MPI_VENC_Query(i, &stStat);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_VENC_Query chn[%d] failed with %#x!\n", i, s32Ret);
break;
}
/*******************************************************
step 2.2 :suggest to check both u32CurPacks and u32LeftStreamFrames at the same time,for example:
if(0 == stStat.u32CurPacks || 0 == stStat.u32LeftStreamFrames)
{
SAMPLE_PRT("NOTE: Current frame is NULL!\n");
continue;
}
*******************************************************/
if(0 == stStat.u32CurPacks)
{
SAMPLE_PRT("NOTE: Current frame is NULL!\n");
continue;
}
/*******************************************************
step 2.3 : malloc corresponding number of pack nodes.
*******************************************************/
stStream.pstPack = (VENC_PACK_S*)malloc(sizeof(VENC_PACK_S) * stStat.u32CurPacks);
if (NULL == stStream.pstPack)
{
SAMPLE_PRT("malloc stream pack failed!\n");
break;
}
/*******************************************************
step 2.4 : call mpi to get one-frame stream
*******************************************************/
stStream.u32PackCount = stStat.u32CurPacks;
s32Ret = HI_MPI_VENC_GetStream(i, &stStream, HI_TRUE);
if (HI_SUCCESS != s32Ret)
{
free(stStream.pstPack);
stStream.pstPack = NULL;
SAMPLE_PRT("HI_MPI_VENC_GetStream failed with %#x!\n", \
s32Ret);
break;
}
/*******************************************************
step 2.5 : save frame to file
*******************************************************/
if(i == 2){
s32Ret = SAMPLE_COMM_VENC_SaveStream(enPayLoadType[i], pFile[i], &stStream);
if (HI_SUCCESS != s32Ret)
{
printf("SAMPLE_COMM_VENC_SaveStream error\r\n");
free(stStream.pstPack);
stStream.pstPack = NULL;
SAMPLE_PRT("save stream failed!\n");
break;
}
}
/*******************************************************
step 2.6 : release stream
*******************************************************/
s32Ret = HI_MPI_VENC_ReleaseStream(i, &stStream);
if (HI_SUCCESS != s32Ret)
{
printf("HI_MPI_VENC_ReleaseStream error\r\n");
free(stStream.pstPack);
stStream.pstPack = NULL;
break;
}
/*******************************************************
step 2.7 : free pack nodes
*******************************************************/
if(stStream.pstPack != NULL){
free(stStream.pstPack);
stStream.pstPack = NULL;
}
}
}
}
}
/*******************************************************
* step 3 : close save-file
*******************************************************/
for (i = 0; i < s32ChnTotal; i++)
{
fclose(pFile[i]);
}
return NULL;
}
/******************************************************************************
* funciton : get svc_t stream from h264 channels and save them
******************************************************************************/
HI_VOID *SAMPLE_COMM_VENC_GetVencStreamProc_Svc_t(void *p)
{
HI_S32 i=0;
HI_S32 s32Cnt=0;
HI_S32 s32ChnTotal;
VENC_CHN_ATTR_S stVencChnAttr;
SAMPLE_VENC_GETSTREAM_PARA_S *pstPara;
HI_S32 maxfd = 0;
struct timeval TimeoutVal;
fd_set read_fds;
HI_S32 VencFd[VENC_MAX_CHN_NUM];
HI_CHAR aszFileName[VENC_MAX_CHN_NUM][64];
FILE *pFile[VENC_MAX_CHN_NUM];
char szFilePostfix[10];
VENC_CHN_STAT_S stStat;
VENC_STREAM_S stStream;
HI_S32 s32Ret;
VENC_CHN VencChn;
PAYLOAD_TYPE_E enPayLoadType[VENC_MAX_CHN_NUM];
pstPara = (SAMPLE_VENC_GETSTREAM_PARA_S*)p;
s32ChnTotal = pstPara->s32Cnt;
/******************************************
step 1: check & prepare save-file & venc-fd
******************************************/
if (s32ChnTotal >= VENC_MAX_CHN_NUM)
{
SAMPLE_PRT("input count invaild\n");
return NULL;
}
for (i = 0; i < s32ChnTotal; i++)
{
/* decide the stream file name, and open file to save stream */
VencChn = i;
s32Ret = HI_MPI_VENC_GetChnAttr(VencChn, &stVencChnAttr);
if(s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("HI_MPI_VENC_GetChnAttr chn[%d] failed with %#x!\n", \
VencChn, s32Ret);
return NULL;
}
enPayLoadType[i] = stVencChnAttr.stVeAttr.enType;
s32Ret = SAMPLE_COMM_VENC_GetFilePostfix(enPayLoadType[i], szFilePostfix);
if(s32Ret != HI_SUCCESS)
{
SAMPLE_PRT("SAMPLE_COMM_VENC_GetFilePostfix [%d] failed with %#x!\n", \
stVencChnAttr.stVeAttr.enType, s32Ret);
return NULL;
}
for(s32Cnt =0; s32Cnt<3; s32Cnt++)
{
sprintf(aszFileName[i+s32Cnt], "Tid%d%s", i+s32Cnt, szFilePostfix);
pFile[i+s32Cnt] = fopen(aszFileName[i+s32Cnt], "wb");
if (!pFile[i+s32Cnt])
{
SAMPLE_PRT("open file[%s] failed!\n",
aszFileName[i+s32Cnt]);
return NULL;
}
}
/* Set Venc Fd. */
VencFd[i] = HI_MPI_VENC_GetFd(i);
if (VencFd[i] < 0)
{
SAMPLE_PRT("HI_MPI_VENC_GetFd failed with %#x!\n",
VencFd[i]);
return NULL;
}
if (maxfd <= VencFd[i])
{
maxfd = VencFd[i];
}
}
/******************************************
step 2: Start to get streams of each channel.
******************************************/
while (HI_TRUE == pstPara->bThreadStart)
{
FD_ZERO(&read_fds);
for (i = 0; i < s32ChnTotal; i++)
{
FD_SET(VencFd[i], &read_fds);
}
TimeoutVal.tv_sec = 2;
TimeoutVal.tv_usec = 0;
s32Ret = select(maxfd + 1, &read_fds, NULL, NULL, &TimeoutVal);
if (s32Ret < 0)
{
SAMPLE_PRT("select failed!\n");
break;
}
else if (s32Ret == 0)
{
SAMPLE_PRT("get venc stream time out, exit thread\n");
continue;
}
else
{
for (i = 0; i < s32ChnTotal; i++)
{
if (FD_ISSET(VencFd[i], &read_fds))
{
/*******************************************************
step 2.1 : query how many packs in one-frame stream.
*******************************************************/
memset(&stStream, 0, sizeof(stStream));
s32Ret = HI_MPI_VENC_Query(i, &stStat);
if (HI_SUCCESS != s32Ret)
{
SAMPLE_PRT("HI_MPI_VENC_Query chn[%d] failed with %#x!\n", i, s32Ret);
break;
}
/*******************************************************
step 2.2 :suggest to check both u32CurPacks and u32LeftStreamFrames at the same time,for example:
if(0 == stStat.u32CurPacks || 0 == stStat.u32LeftStreamFrames)
{
SAMPLE_PRT("NOTE: Current frame is NULL!\n");
continue;
}
*******************************************************/
if(0 == stStat.u32CurPacks)
{
SAMPLE_PRT("NOTE: Current frame is NULL!\n");
continue;
}
/*******************************************************
step 2.3 : malloc corresponding number of pack nodes.
*******************************************************/
stStream.pstPack = (VENC_PACK_S*)malloc(sizeof(VENC_PACK_S) * stStat.u32CurPacks);
if (NULL == stStream.pstPack)
{
SAMPLE_PRT("malloc stream pack failed!\n");
break;
}
/*******************************************************
step 2.4 : call mpi to get one-frame stream
*******************************************************/
stStream.u32PackCount = stStat.u32CurPacks;
s32Ret = HI_MPI_VENC_GetStream(i, &stStream, HI_TRUE);
if (HI_SUCCESS != s32Ret)
{
free(stStream.pstPack);
stStream.pstPack = NULL;
SAMPLE_PRT("HI_MPI_VENC_GetStream failed with %#x!\n", \
s32Ret);
break;
}
/*******************************************************
step 2.5 : save frame to file
*******************************************************/
#if 1
for(s32Cnt=0;s32Cnt<3;s32Cnt++)
{
switch(s32Cnt)
{
case 0:
if(BASE_IDRSLICE == stStream.stH264Info.enRefType ||
BASE_PSLICE_REFBYBASE == stStream.stH264Info.enRefType)
{
s32Ret = SAMPLE_COMM_VENC_SaveStream(enPayLoadType[i], pFile[i+s32Cnt], &stStream);
}
break;
case 1:
if(BASE_IDRSLICE == stStream.stH264Info.enRefType ||
BASE_PSLICE_REFBYBASE == stStream.stH264Info.enRefType ||
BASE_PSLICE_REFBYENHANCE== stStream.stH264Info.enRefType)
{
//s32Ret = SAMPLE_COMM_VENC_SaveStream(enPayLoadType[i], pFile[i+s32Cnt], &stStream);
}
break;
case 2:
//s32Ret = SAMPLE_COMM_VENC_SaveStream(enPayLoadType[i], pFile[i+s32Cnt], &stStream);
break;
}
if (HI_SUCCESS != s32Ret)
{
free(stStream.pstPack);
stStream.pstPack = NULL;
SAMPLE_PRT("save stream failed!\n");
break;
}
}
#else
for(s32Cnt=0;s32Cnt<3;s32Cnt++)
{
if(s32Cnt == 0)
{
if (NULL != pFile[i+s32Cnt])
{
if(BASE_IDRSLICE == stStream.stH264Info.enRefType ||
BASE_PSLICE_REFBYBASE == stStream.stH264Info.enRefType)
{
s32Ret = SAMPLE_COMM_VENC_SaveStream(enPayLoadType[i], pFile[i+s32Cnt], &stStream);
}
}
}
else if(s32Cnt == 1)
{
if (NULL != pFile[i+s32Cnt])
{
if(BASE_IDRSLICE == stStream.stH264Info.enRefType ||
BASE_PSLICE_REFBYBASE == stStream.stH264Info.enRefType||
BASE_PSLICE_REFBYENHANCE== stStream.stH264Info.enRefType)
{
s32Ret = SAMPLE_COMM_VENC_SaveStream(enPayLoadType[i], pFile[i+s32Cnt], &stStream);
}
}
}
else
{
if (NULL != pFile[i+s32Cnt])
{
s32Ret = SAMPLE_COMM_VENC_SaveStream(enPayLoadType[i], pFile[i+s32Cnt], &stStream);
}
}
}
if (HI_SUCCESS != s32Ret)
{
free(stStream.pstPack);
stStream.pstPack = NULL;
SAMPLE_PRT("save stream failed!\n");
break;
}
#endif
/*******************************************************
step 2.6 : release stream
*******************************************************/
s32Ret = HI_MPI_VENC_ReleaseStream(i, &stStream);
if (HI_SUCCESS != s32Ret)
{
free(stStream.pstPack);
stStream.pstPack = NULL;
break;
}
/*******************************************************
step 2.7 : free pack nodes
*******************************************************/
free(stStream.pstPack);
stStream.pstPack = NULL;
}
}
}
}
/*******************************************************
step 3 : close save-file
*******************************************************/
for (i = 0; i < s32ChnTotal; i++)
{
for (s32Cnt = 0; s32Cnt < 3; s32Cnt++)
{
if (pFile[i+s32Cnt])
{
fclose(pFile[i+s32Cnt]);
}
}
}
return NULL;
}
/******************************************************************************
* funciton : start get venc stream process thread
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_StartGetStream(HI_S32 s32Cnt)
{
gs_stPara.bThreadStart = HI_TRUE;
gs_stPara.s32Cnt = s32Cnt;
return pthread_create(&gs_VencPid, 0, SAMPLE_COMM_VENC_GetVencStreamProc, (HI_VOID*)&gs_stPara);
}
/******************************************************************************
* funciton : start get venc svc-t stream process thread
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_StartGetStream_Svc_t(HI_S32 s32Cnt)
{
gs_stPara.bThreadStart = HI_TRUE;
gs_stPara.s32Cnt = s32Cnt;
return pthread_create(&gs_VencPid, 0, SAMPLE_COMM_VENC_GetVencStreamProc_Svc_t, (HI_VOID*)&gs_stPara);
}
/******************************************************************************
* funciton : stop get venc stream process.
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_StopGetStream()
{
if (HI_TRUE == gs_stPara.bThreadStart)
{
gs_stPara.bThreadStart = HI_FALSE;
pthread_join(gs_VencPid, 0);
}
return HI_SUCCESS;
}
HI_VOID SAMPLE_COMM_VENC_ReadOneFrame( FILE * fp, HI_U8 * pY, HI_U8 * pU, HI_U8 * pV,
HI_U32 width, HI_U32 height, HI_U32 stride, HI_U32 stride2)
{
HI_U8 * pDst;
HI_U32 u32Row;
pDst = pY;
for ( u32Row = 0; u32Row < height; u32Row++ )
{
fread( pDst, width, 1, fp );
pDst += stride;
}
pDst = pU;
for ( u32Row = 0; u32Row < height/2; u32Row++ )
{
fread( pDst, width/2, 1, fp );
pDst += stride2;
}
pDst = pV;
for ( u32Row = 0; u32Row < height/2; u32Row++ )
{
fread( pDst, width/2, 1, fp );
pDst += stride2;
}
}
HI_S32 SAMPLE_COMM_VENC_PlanToSemi(HI_U8 *pY, HI_S32 yStride,
HI_U8 *pU, HI_S32 uStride,
HI_U8 *pV, HI_S32 vStride,
HI_S32 picWidth, HI_S32 picHeight)
{
HI_S32 i;
HI_U8* pTmpU, *ptu;
HI_U8* pTmpV, *ptv;
HI_S32 s32HafW = uStride >>1 ;
HI_S32 s32HafH = picHeight >>1 ;
HI_S32 s32Size = s32HafW*s32HafH;
pTmpU = malloc( s32Size ); ptu = pTmpU;
pTmpV = malloc( s32Size ); ptv = pTmpV;
if((pTmpU==HI_NULL)||(pTmpV==HI_NULL))
{
printf("malloc buf failed\n");
return HI_FAILURE;
}
memcpy(pTmpU,pU,s32Size);
memcpy(pTmpV,pV,s32Size);
for(i = 0;i<s32Size>>1;i++)
{
*pU++ = *pTmpV++;
*pU++ = *pTmpU++;
}
for(i = 0;i<s32Size>>1;i++)
{
*pV++ = *pTmpV++;
*pV++ = *pTmpU++;
}
free( ptu );
free( ptv );
return HI_SUCCESS;
}
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */