1、進入板子debug環境 (根據自己情況)
1) mount /dev/sda3 /root/disk
2) minicom
3) nfs
pc:
sudo vi /etc/exports
/root/disk/hi3516 *(rw,sync,no_root_squash,no_subtree_check)
sudo /etc/init.d/nfs-kernel-server restart
sudo /etc/init.d/rpcbind restart
sudo ifconfig eth1 172.16.23.157
board:
ifconfig wlan1 172.16.23.158
mount -t nfs -o nolock 172.16.23.157:/root/disk/hi3516 /root/hi3516
注意海思sdk里的mpp目錄名不要改動,改了會導致sample編譯出錯。
2、音視頻數據循環采集
a. 在sample_venc.c文件中,海思官方是把采集到的數據都保存到文件中,我們需要更改到緩存里,以便后面推送到rtsp/rtmp/hls服務端。
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 *******************************************************/ HisiPutH264DataToBuffer(&stStream); /*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; } }
b. HI_S32 HisiPutH264DataToBuffer(VENC_STREAM_S *pstStream)函數比較重要
HI_S32 HisiPutH264DataToBuffer(VENC_STREAM_S *pstStream) { HI_S32 i,j,x; HI_S32 len=0,off=0,len2=2,uplen=0; unsigned char *pstr; int iframe=0; for (i = 0; i < pstStream->u32PackCount; i++) { len+=pstStream->pstPack[i].u32Len; }
if(n<NMAX) { for (i = 0; i < pstStream->u32PackCount; i++) { memcpy(ringfifo[iput].buffer+off,pstStream->pstPack[i].pu8Addr,pstStream->pstPack[i].u32Len); off+=pstStream->pstPack[i].u32Len; pstr=pstStream->pstPack[i].pu8Addr; if(pstr[4]==0x67) { UpdateSps(pstr+4,pstStream->pstPack[i].u32Len-4); iframe=1; } if(pstr[4]==0x68) { UpdatePps(pstr+4,pstStream->pstPack[i].u32Len-4); } } ringfifo[iput].size= len; if(iframe) { // printf("I"); ringfifo[iput].frame_type = FRAME_TYPE_I; } else { ringfifo[iput].frame_type = FRAME_TYPE_P; // printf("P"); } iput = addring(iput); // printf("(%d)",iput); // fflush(stdout); n++; } return HI_SUCCESS; }
c. VENC_STREAM_S相關結構體
//定義幀碼流類型結構體: typedef structhiVENC_STREAM_S { VENC_PACK_S *pstPack; //幀碼流包結構。 HI_U32 u32PackCount; //一幀碼流的所有包的個數。 HI_U32 u32Seq; //碼流序列號。 按幀獲取幀序號;按包獲取包序號。 }VENC_STREAM_S; //定義幀碼流包結構體: typedef structhiVENC_PACK_S { HI_U32 u32PhyAddr[2]; //碼流包首地址。 HI_U8 *pu8Addr[2]; //碼流包物理地址。 HI_U32 u32Len[2]; //碼流包長度。 VENC_DATA_TYPE_U DataType; //碼流類型。 HI_U64 u64PTS; //時間戳。單位:us。 HI_BOOL bFieldEnd; //場結束標識。 取值范圍: HI_TRUE:該碼流包是該場的最后一個包。 HI_FALSE:該碼流包不是該場的最后一個包。 HI_BOOL bFrameEnd; //幀結束標識。 取值范圍: HI_TRUE:該碼流包是該幀的最后一個包。 HI_FALSE:該碼流包不是該場的最后一個包。 }VENC_PACK_S;
struct ringbuf { unsigned char *buffer; int frame_type; int size; };
c. 數據采集到ringbuf緩存中,然后通過rtsp/rtmp/hls協議推送到服務端IP,客戶端就可以通過網絡來訪問了。相關rtsp/rtmp/hls服務跟平台無關,在另外的隨筆中已經整理了。
3、 運行上面的程序,會發現圖像偏色,需要調整海思算法ISP的相關參數
HI3518平台視頻畫面偏色解決辦法,有人已經整理了http://blog.csdn.net/zqj6893/article/details/50380092
4、HI3520DV200+GV7601采集1080P視頻
http://blog.csdn.net/zqj6893/article/details/50386921
5、osd
http://bbs.ebaina.com/forum.php?mod=viewthread&tid=12659&extra=page%3D1&page=1
6. mp4v2
https://blog.csdn.net/weixin_43549602/article/details/84570642