📄 video_enc.c
字号:
addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(port); memset(&(addr.sin_zero), '\0', 8); // zero the rest of the struct if (bind (fd, (struct sockaddr *)&addr, sizeof (addr))) { HI_CloseSocket(fd); printf("UDP Socket Open error: bind socket error.\n"); return -1; } #if 0 /* set to non-blocking */ if (ioctlsocket(f, FIONBIO, &on) < 0) { WRITE_LOG_DEBUG("UDP Socket Open error: set to nonblock mode error.\n"); return -1; } #endif return fd;}#define RTP_DEFAULT_SSRC 41030HI_S32 HI_RTP_Sender_Create(RTP_SENDER_S ** ppRtpStream, RTP_PT_E pt){ RTP_SENDER_S* pSender; HI_SOCKET sock; HI_PORT port = 0; pSender = (RTP_SENDER_S*)malloc(sizeof(RTP_SENDER_S)); if (NULL == pSender) { printf("create new rtp sender error. not enough memory.\n"); return -1; } memset(pSender, 0 , sizeof(RTP_SENDER_S)); //INIT_LIST_HEAD(&pSender->targethosts); memset(pSender->targethosts, 0, sizeof(pSender->targethosts)); pSender->bActive = HI_FALSE; pSender->last_ts = 3600; *ppRtpStream = pSender; pSender->pt = pt; pSender->ssrc = RTP_DEFAULT_SSRC; sock = HI_SOCKET_Udp_Open(0); if (sock < 0 ) { printf("<RTP>create socket error.\n"); return -1; } port = HI_SOCKET_Udp_GetPort(sock); if (port & 0x1) /*odd*/ { pSender->rtcpport = port; close(sock); port -= 1; sock = HI_SOCKET_Udp_Open(0); if ( sock < 0 ) { printf("<RTP>create socket error.\n"); return -1; } port = HI_SOCKET_Udp_GetPort(sock); } pSender->rtpport = port; pSender->rtcpport = port + 1; pSender->sock = sock; int yes = 1; if (setsockopt(pSender->sock,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) { printf("HI_ERR_RTP_SOCKET\n"); return -1; } printf("Create RTP Sender at port: %d", pSender->rtpport ); return HI_SUCCESS; }RTP_TARGETHOST_S* HI_RTP_Sender_Find(IN RTP_SENDER_S* pRtpStream, IN HI_CHAR* ip, IN HI_PORT port){ int i = 0; for (i = 0 ; i < RTP_MAX_SENDER ; i++) { if ((strcmp(ip, pRtpStream->targethosts[i].remote_ip) == 0) && (port == pRtpStream->targethosts[i].remote_port)) { return (&pRtpStream->targethosts[i]); } } return NULL; }RTP_TARGETHOST_S* HI_RTP_Sender_FindAvail(IN RTP_SENDER_S* pRtpStream){ int i = 0; for (i = 0 ; i < RTP_MAX_SENDER ; i++) { if (pRtpStream->targethosts[i].bActive == HI_FALSE) { //WRITE_LOG_DEBUG("rtp host avail %d \n", i); return (&pRtpStream->targethosts[i]); } } return NULL; }HI_S32 HI_RTP_Sender_Add(IN RTP_SENDER_S* pRtpStream, IN HI_CHAR* ip, IN HI_PORT port){ RTP_TARGETHOST_S* pTarget = NULL; printf("rtp sender add ip, %s:%d", ip, port); pTarget = HI_RTP_Sender_Find(pRtpStream, ip, port); if (pTarget == NULL) { pTarget = HI_RTP_Sender_FindAvail(pRtpStream); if (pTarget == NULL) { return -1; } memset(pTarget, 0 , sizeof(RTP_TARGETHOST_S)); strcpy(pTarget->remote_ip, ip); pTarget->remote_port = port; pTarget->remote_addr.sin_family = AF_INET; // host byte order pTarget->remote_addr.sin_port = htons(pTarget->remote_port); // short, network byte order pTarget->remote_addr.sin_addr.s_addr = inet_addr(pTarget->remote_ip); memset(&(pTarget->remote_addr.sin_zero), '\0', 8); // zero the rest of the struct } pTarget->hostState = RTP_TARGETHOST_STATE_REQ_IFrame; pTarget->bActive = HI_TRUE; return HI_SUCCESS;}/*synchronization header*/HI_S32 HI_RTP_Packet(IN RTP_SENDER_S * pRtpStream , HI_S32 ts_inc, HI_U32 marker, HI_CHAR *pPayload, HI_S32 len){ RTP_HDR_S* pRtpHdr = NULL; memset(pRtpStream->buff, 0, RPT_MAX_PACKET_BUFF); pRtpStream->buffLen = 0; pRtpHdr = (RTP_HDR_S*)pRtpStream->buff; RTP_HDR_SET_VERSION(pRtpHdr, RTP_VERSION); RTP_HDR_SET_P(pRtpHdr, 0); RTP_HDR_SET_X(pRtpHdr, 0); RTP_HDR_SET_CC(pRtpHdr, 0); RTP_HDR_SET_M(pRtpHdr, marker); RTP_HDR_SET_PT(pRtpHdr, pRtpStream->pt); RTP_HDR_SET_SEQNO(pRtpHdr, htons(pRtpStream->last_sn)); RTP_HDR_SET_TS(pRtpHdr, htonl(pRtpStream->last_ts)); RTP_HDR_SET_SSRC(pRtpHdr, htonl(pRtpStream->ssrc)); pRtpStream->last_sn++; pRtpStream->last_ts += ts_inc; memcpy(pRtpStream->buff + RTP_HDR_LEN, pPayload, len); pRtpStream->buffLen = RTP_HDR_LEN + len; return HI_SUCCESS;}HI_S32 HI_RTP_Send(IN RTP_SENDER_S * pRtpStream){ RTP_TARGETHOST_S* pHost = NULL; HI_S32 iRet; int i = 0; for(i = 0;i < RTP_MAX_SENDER;i++) { pHost = &pRtpStream->targethosts[i]; //WRITE_LOG_DEBUG("***Active: %d, BuffLen: %d, hostState:%d**\n", // pHost->bActive ,pRtpStream->buffLen ,pHost->hostState ); if (pHost->bActive && pRtpStream->buffLen > 0 ) { iRet = sendto(pRtpStream->sock, pRtpStream->buff, pRtpStream->buffLen, 0, (struct sockaddr*)&pHost->remote_addr, sizeof(struct sockaddr) ); if (iRet != pRtpStream->buffLen) { perror("send rtp error."); pRtpStream->stats.sent_error++; printf("<RTP>send packet error. %s", strerror(errno)); //HI_ERRNO(HI_ERR_RTP_SEND); } else { pRtpStream->stats.sent_byte += pRtpStream->buffLen; pRtpStream->stats.sent_packet++; } if (pRtpStream->buffLen <= 16) exit(-1); } } return HI_SUCCESS;}/*for rtp**********************************************************/#define CHECK_RET(hiRet) if(hiRet!=HI_SUCCESS) return hiRet;/*config parameter form the system*/HI_U16 mode = CIF;HI_U16 normal = PAL;VENC_FORMAT_E format = VENC_FORMAT_H264;HI_S32 venc_start(void *arg){ HI_S32 hiRet; VI_CHN vi_chn; VENC_CHN venc_chn; VENC_STREAM_S venc_stream; VENC_CONFIG_S venc_config; FILE *pfile = NULL; char filename[255]; HI_U32 i, aucWriteLen = 0;; vi_chn = *((VI_CHN*)arg); /*step 1: start VI channel*/ hiRet = ViChnConfig(mode, normal, vi_chn); if (HI_SUCCESS != hiRet) { printf ("vi chn atr config failed\n"); HI_VENC_Close(); return hiRet; } /*step 2: create VIDEO encode channel*/ hiRet = HI_VENC_CreateCH(vi_chn, &venc_chn); printf("venc_chn is %d\n", venc_chn); if ( hiRet != HI_SUCCESS ) { HI_VENC_DestroyCH(venc_chn, HI_TRUE); return hiRet; } switch (format) { case VENC_FORMAT_H264: sprintf(filename, "venc_file_chn%d.h264", venc_chn); break; case VENC_FORMAT_H263: sprintf(filename, "venc_file_chn%d.263", venc_chn); break; default: break; } pfile = fopen(filename, "wb"); if ( NULL == pfile ) { printf("open file error\n"); return HI_FAILURE; } /*step 3: start video encode channel*/ hiRet = HI_VENC_StartCH(venc_chn, 0); if ( hiRet != HI_SUCCESS ) { HI_VENC_DestroyCH(venc_chn, HI_TRUE); return hiRet; } while ( 1 ) { /*step 4: get stream with BLOCK way*/ hiRet = HI_VENC_GetStream(venc_chn, &venc_stream, HI_TRUE); if ( hiRet != HI_SUCCESS ) { HI_VENC_DestroyCH(venc_chn, HI_TRUE); /*if err, we destroy venc chn forcely*/ return hiRet; } //printf("save file slice num: %u, frame len: %u\n", venc_stream.u32DataNum, venc_stream.u32DataLen); /*save stream to file*/ for ( i = 0 ; i < venc_stream.u32DataNum ; i++ ) { switch (format) { case VENC_FORMAT_H264: aucWriteLen = fwrite(venc_stream.struData[i].pAddr, venc_stream.struData[i].u32Len, 1, pfile); if ( 1 != aucWriteLen ) { printf("write file error: toLen:%u, aucLen:%d\n", venc_stream.struData[i].u32Len, aucWriteLen); exit(1); } break; case VENC_FORMAT_H263: { HI_U32 *payAddr, payLen; HI_U32 FrameLastPacketFlag, LastByteOverLapFlag, RTPModeAFlag; HI_U32 *dataAddr, dataLen; payAddr = (HI_U32*)(venc_stream.struData[i].pAddr); payLen = venc_stream.struData[i].u32Len; /*save stream file*/ FrameLastPacketFlag = venc_stream.struProp[i].FrameLastPacketFlag; LastByteOverLapFlag = venc_stream.struProp[i].LastByteOverLapFlag; RTPModeAFlag = venc_stream.struProp[i].RTPModeAFlag; if ( RTPModeAFlag == 1 ) /*A mode rtp payload head is 32 bit*/ { dataAddr = payAddr + 1; dataLen = payLen - 4; } else if ( RTPModeAFlag == 0 ) { dataAddr = payAddr + 2; dataLen = payLen - 8; } if ( LastByteOverLapFlag == 0 && FrameLastPacketFlag == 0) /*Bytes aligin*/ { dataLen--; } aucWriteLen = fwrite((HI_VOID*)dataAddr, dataLen, 1, pfile); if ( 1 != aucWriteLen ) { printf("write file error: toLen:%u, aucLen:%d\n", venc_stream.struData[i].u32Len, aucWriteLen); exit(1); } } break; default: break; } //printf("chnid=%d, Iflag=%u, seq=%u, pts=%u\n", //venc_stream.struDataInfo.ChnID, venc_stream.struDataInfo.u16IFrameFlag, //venc_stream.struDataInfo.u32Seq,venc_stream.struDataInfo.u64PTS); } /*step 5: release stream buffer*/ hiRet = HI_VENC_ReleaseStream(venc_chn, &venc_stream); if ( hiRet != HI_SUCCESS ) { HI_VENC_DestroyCH(venc_chn, HI_TRUE); /*if err, we destroy venc chn forcely*/ return hiRet; } if(g_s32VencStopFlag[venc_chn] == HI_TRUE) { g_s32VencStopFlag[venc_chn] = HI_FALSE; break; } } /*step 6: stop video encode channel*/ hiRet = HI_VENC_StopCH(venc_chn); /*step 7: destroy video encode channel*/ hiRet = HI_VENC_DestroyCH(venc_chn, HI_TRUE); fclose(pfile); return 0;}int venc_sender_start(void *arg){ HI_S32 hiRet; VI_CHN vi_chn; VENC_CHN venc_chn; VENC_STREAM_S venc_stream; VENC_CONFIG_S venc_config; RTP_SENDER_S * pSender; VSTART_ARG_S *pVstartArg = (VSTART_ARG_S*)arg; vi_chn = pVstartArg->viChn; HI_RTP_Sender_Create(&pSender, RTP_PT_H264); HI_RTP_Sender_Add(pSender, pVstartArg->ipaddr, 6666); /*step 1: start VI channel*/ hiRet = ViChnConfig(mode, normal, vi_chn); if (HI_SUCCESS != hiRet) { printf ("vi chn atr config failed\n"); HI_VENC_Close(); return hiRet; } /*step 2: create video encode channel*/ hiRet = HI_VENC_CreateCH(vi_chn, &venc_chn); printf("vi chn is %d, venc_chn is %d\n", vi_chn, venc_chn); if ( hiRet != HI_SUCCESS ) { HI_VENC_Close(); return hiRet; } /*step 3: start video encode channel*/ hiRet = HI_VENC_StartCH(venc_chn, 0); if ( hiRet != HI_SUCCESS ) { return hiRet; } FILE *pfile = NULL; char filename[255]; HI_U32 i; sprintf(filename, "venc_file_chn%d.h264", venc_chn); pfile = fopen(filename, "wb"); if ( NULL == pfile ) { printf("open file error\n"); exit(1); } while ( 1 ) { /*step 4: get stream */ hiRet = HI_VENC_GetStream(venc_chn, &venc_stream, HI_TRUE); if ( hiRet != HI_SUCCESS ) { printf("HI_VENC_GetStream error\n"); HI_VENC_Close(); return hiRet; } //printf("save file slice num: %u, frame len: %u\n", venc_stream.u32DataNum, venc_stream.u32DataLen); /*send stream with RTP*/ for ( i = 0 ; i < venc_stream.u32DataNum ; i++ ) {#if 0 aucWriteLen = fwrite(venc_stream.struData[i].pAddr, venc_stream.struData[i].u32Len, 1, pfile); if ( 1 != aucWriteLen ) { printf("write file error: toLen:%u, aucLen:%d\n", venc_stream.struData[i].u32Len, aucWriteLen); exit(1); }#endif HI_RTP_Packet(pSender, 0, 0, venc_stream.struData[i].pAddr, venc_stream.struData[i].u32Len); HI_RTP_Send(pSender); //printf("chnid=%d, Iflag=%u, seq=%u, pts=%u\n", //venc_stream.struDataInfo.ChnID, venc_stream.struDataInfo.u16IFrameFlag, //venc_stream.struDataInfo.u32Seq,venc_stream.struDataInfo.u64PTS); } /*step 5: releate stream*/ hiRet = HI_VENC_ReleaseStream(venc_chn, &venc_stream); if ( hiRet != HI_SUCCESS ) { printf("HI_VENC_GetStream error\n"); HI_VENC_Close(); return hiRet; } /*you can stop this venc thread by vstop*/ if(g_s32VencStopFlag[venc_chn] == HI_TRUE) { g_s32VencStopFlag[venc_chn] = HI_FALSE; break; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -