/****************************************************************************** * 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; 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; } 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); 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 : 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.3 : 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.4 : save frame to file *******************************************************/ s32Ret = SAMPLE_COMM_VENC_SaveStream(enPayLoadType[i], pFile[i], &stStream); if (HI_SUCCESS != s32Ret) { free(stStream.pstPack); stStream.pstPack = NULL; SAMPLE_PRT("save stream failed!\n"); break; } /******************************************************* step 2.5 : release stream *******************************************************/ s32Ret = HI_MPI_VENC_ReleaseStream(i, &stStream); if (HI_SUCCESS != s32Ret) { free(stStream.pstPack); stStream.pstPack = NULL; break; } /******************************************************* step 2.6 : free pack nodes *******************************************************/ free(stStream.pstPack); stStream.pstPack = NULL; } } } } /******************************************************* * step 3 : close save-file *******************************************************/ for (i = 0; i < s32ChnTotal; i++) { fclose(pFile[i]); } return NULL; }
HI_S32 main(int argc, char* argv[]) { HI_S32 s32Ret; HI_S32 s32EncChn; HI_CHAR para[16]; HI_U32 value = 0; HI_U32 i; VENC_RC_MODE_E eMode; VENC_RC_PARAM_S stVencRcParam; VENC_CHN_ATTR_S stVencChnAttr; if (argc < 3) { USAGE_HELP(); return -1; } s32EncChn = 0; s32EncChn = atoi(argv[1]); strcpy(para, argv[2]); s32Ret = HI_MPI_VENC_GetRcParam(s32EncChn, &stVencRcParam); CHECK_RET(s32Ret, "get Rc param"); s32Ret = HI_MPI_VENC_GetChnAttr(s32EncChn, &stVencChnAttr); CHECK_RET(s32Ret, "get Rc Attr"); eMode = stVencChnAttr.stRcAttr.enRcMode; if (0 == strcmp(para, "?")) { if (eMode == VENC_RC_MODE_H264CBR) { printf("\tstattime %d\n", stVencChnAttr.stRcAttr.stAttrH264Cbr.u32StatTime); printf("\tbitrate %d\n", stVencChnAttr.stRcAttr.stAttrH264Cbr.u32BitRate); printf("\tgop %d\n", stVencChnAttr.stRcAttr.stAttrH264Cbr.u32Gop); printf("\tqpdelta %d\n", stVencRcParam.stParamH264Cbr.s32IPQPDelta); printf("\tmaxqp %d\n", stVencRcParam.stParamH264Cbr.u32MaxQp); } else { printf("\tstattime %d\n", stVencChnAttr.stRcAttr.stAttrH265Cbr.u32StatTime); printf("\tbitrate %d\n", stVencChnAttr.stRcAttr.stAttrH265Cbr.u32BitRate); printf("\tgop %d\n", stVencChnAttr.stRcAttr.stAttrH265Cbr.u32Gop); printf("\tqpdelta %d\n", stVencRcParam.stParamH265Cbr.s32IPQPDelta); printf("\tmaxqp %d\n", stVencRcParam.stParamH265Cbr.u32MaxQp); } printf("\tmqpdelta %d\n", stVencRcParam.u32RowQpDelta); return 0; } value = atoi(argv[3]); printf("chn %d, para %s, value %d\n", s32EncChn, para, value); if (0 == strcmp(para, "stattime")) { if (eMode == VENC_RC_MODE_H264CBR) { stVencChnAttr.stRcAttr.stAttrH264Cbr.u32StatTime = value; } else { stVencChnAttr.stRcAttr.stAttrH265Cbr.u32StatTime = value; } } if (0 == strcmp(para, "thresh") && argc == 15) { for (i = 0; i < 12; i++) { stVencRcParam.u32ThrdI[i] = atoi(argv[i + 3]); stVencRcParam.u32ThrdP[i] = atoi(argv[i + 3]); } } if (0 == strcmp(para, "pthresh") && argc == 15) { for (i = 0; i < 12; i++) { stVencRcParam.u32ThrdP[i] = atoi(argv[i + 3]); } } else if (0 == strcmp(para, "bitrate")) { if (eMode == VENC_RC_MODE_H264CBR) { stVencChnAttr.stRcAttr.stAttrH264Cbr.u32BitRate = value; } else { stVencChnAttr.stRcAttr.stAttrH265Cbr.u32BitRate = value; } } else if ( 0 == strcmp(para, "framerate")) { if (eMode == VENC_RC_MODE_H264CBR) { stVencChnAttr.stRcAttr.stAttrH264Cbr.fr32DstFrmRate = value; } else { stVencChnAttr.stRcAttr.stAttrH265Cbr.fr32DstFrmRate = value; } } else if (0 == strcmp(para, "gop")) { if (eMode == VENC_RC_MODE_H264CBR) { stVencChnAttr.stRcAttr.stAttrH264Cbr.u32Gop = value; } else { stVencChnAttr.stRcAttr.stAttrH265Cbr.u32Gop = value; } } else if (0 == strcmp(para, "flut")) { if (eMode == VENC_RC_MODE_H264CBR) { stVencChnAttr.stRcAttr.stAttrH264Cbr.u32FluctuateLevel = value; } else { stVencChnAttr.stRcAttr.stAttrH265Cbr.u32FluctuateLevel = value; } } else if (0 == strcmp(para, "qpdelta")) { if (eMode == VENC_RC_MODE_H264CBR) { stVencRcParam.stParamH264Cbr.s32IPQPDelta = value; } else { stVencRcParam.stParamH265Cbr.s32IPQPDelta = value; } } else if (0 == strcmp(para, "maxqp")) { if (eMode == VENC_RC_MODE_H264CBR) { stVencRcParam.stParamH264Cbr.u32MaxQp = value; } else { stVencRcParam.stParamH265Cbr.u32MaxQp = value; } } else if (0 == strcmp(para, "level")) { if (eMode == VENC_RC_MODE_H264CBR) { stVencRcParam.stParamH264Cbr.s32QualityLevel = value; } else { stVencRcParam.stParamH265Cbr.s32QualityLevel = value; } } else if (0 == strcmp(para, "mqpdelta")) { stVencRcParam.u32RowQpDelta = value; } else if ( 0 == strcmp(para, "deblock")) { VENC_PARAM_H264_DBLK_S stH264Dblk; s32Ret = HI_MPI_VENC_GetH264Dblk(0, &stH264Dblk); CHECK_RET(s32Ret, "get deblock"); stH264Dblk.disable_deblocking_filter_idc = 2; stH264Dblk.slice_alpha_c0_offset_div2 = value; stH264Dblk.slice_beta_offset_div2 = value; s32Ret = HI_MPI_VENC_SetH264Dblk(0, &stH264Dblk); CHECK_RET(s32Ret, "get deblock"); } s32Ret = HI_MPI_VENC_SetChnAttr(s32EncChn, &stVencChnAttr); CHECK_RET(s32Ret, "set Chn Attr"); s32Ret = HI_MPI_VENC_SetRcParam(s32EncChn, &stVencRcParam); CHECK_RET(s32Ret, "set Rc param"); return 0; }