📄 video_dec.c
字号:
if (pRtpStream) { pRtpStream->runState = RTP_RUNSTATE_STOP ; } return (HI_S32)pthread_join(pRtpStream->thd, NULL);}HI_S32 HI_RTP_Recv_Destroy(IO RTP_RECV_S *pRtpStream){ if (pRtpStream == NULL) { return HI_SUCCESS; } if (pRtpStream->runState == RTP_RUNSTATE_RUNNING) { HI_RTP_Recv_Stop(pRtpStream); } HI_CloseSocket(pRtpStream->sock); return HI_SUCCESS; }HI_PORT HI_SOCKET_Udp_GetPort(HI_SOCKET fd){ int namelen = sizeof(struct sockaddr_in); struct sockaddr_in *s; if (getsockname (fd, (struct sockaddr *) s, &namelen)) { return 0; } return ntohs( s->sin_port );}HI_SOCKET HI_SOCKET_Udp_Open(HI_PORT port){ HI_SOCKET fd; struct sockaddr_in addr; if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { printf("UDP Socket Open error: create socket error.\n"); return -1; } 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 head*/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;}/*************************************************************************/char file_buf[4096];static int fbuf_pointer = 0;static int fbuf_bytes_num = 0;int buf_flush(FILE *stream){ fbuf_bytes_num = fread(file_buf,1,4096,stream); if(fbuf_bytes_num <= 0)return 0; fbuf_pointer = 0; return fbuf_bytes_num;}size_t Fread(void *ptr, size_t size, size_t nmemb, FILE *stream){ size_t num; size_t num_require = size*nmemb; int ptr_count = 0; if(fbuf_bytes_num == fbuf_pointer) { if(!buf_flush(stream))return 0; } while((fbuf_bytes_num-fbuf_pointer)<num_require) { int tmp = fbuf_bytes_num-fbuf_pointer; memcpy(ptr+ptr_count,file_buf+fbuf_pointer,tmp); ptr_count += tmp; num_require -= tmp; if(!buf_flush(stream))return ptr_count; } memcpy(ptr+ptr_count,file_buf+fbuf_pointer,num_require); fbuf_pointer += num_require; return (ptr_count+num_require);}#define VO_CHN0 0static VIDEO_NORM_E compose_mode = VIDEO_ENCODING_MODE_PAL;static HI_BOOL g_bZoomEnable = HI_TRUE;/*VO open*/HI_S32 vo_open(void){ HI_S32 s32Ret; VO_CHN_ATTR_S l_chn_attr ; VO_PUBLIC_ATTR_S l_pub_attr; HI_VO_Init(); s32Ret = HI_VO_GetPublicAttr (&l_pub_attr); ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret); l_pub_attr.enable = HI_TRUE; l_pub_attr.bOutputScale = g_bZoomEnable; /* TV mode */ l_pub_attr.display_mode = VO_MODE_BT656; l_pub_attr.tv_config.enMaster = VIDEO_CONTROL_MODE_MASTER; l_pub_attr.tv_config.compose_mode = compose_mode; l_pub_attr.tv_config.seriatim_mode = HI_TRUE; l_pub_attr.background_color = 0x00ff00; /* blue */ l_pub_attr.vo_chn_img_num = 4; l_pub_attr.pip_buf_num = 4; s32Ret = HI_VO_SetPublicAttr (&l_pub_attr); ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret); s32Ret = HI_VO_GetChnAttr(VO_CHN0, &l_chn_attr); ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret); l_chn_attr.enable = HI_TRUE; l_chn_attr.rectangle.x = 0; l_chn_attr.rectangle.y = 0; l_chn_attr.rectangle.width = 720; if(compose_mode == VIDEO_ENCODING_MODE_PAL) { l_chn_attr.rectangle.height = 576; } else { l_chn_attr.rectangle.height = 480; } l_chn_attr.zoom_enable = g_bZoomEnable; s32Ret = HI_VO_SetChnAttr (VO_CHN0, &l_chn_attr); ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret); return HI_SUCCESS;}/*VO close*/HI_S32 vo_close(void){ HI_S32 s32Ret; VO_CHN_ATTR_S l_chn_attr ; VO_PUBLIC_ATTR_S l_pub_attr ; s32Ret = HI_VO_GetChnAttr (VO_CHN0, &l_chn_attr); ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret); l_chn_attr.enable = HI_FALSE; s32Ret = HI_VO_SetChnAttr (VO_CHN0, &l_chn_attr); ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret); /* Disable VO */ s32Ret = HI_VO_GetPublicAttr (&l_pub_attr); ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret); l_pub_attr.enable = HI_FALSE ; s32Ret = HI_VO_SetPublicAttr (&l_pub_attr); ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret); return HI_SUCCESS;}HI_S32 s32vdecthreadflag;HI_S32 s32vdecsendthreadflag;/*receive frame data , it receive data and send to VO only for file read*/void* receive_thread(void *args){ VDEC_RECEIVE_THTREAD_ARGS *parg = args; HI_S32 ret; HI_BOOL bBlock = HI_TRUE; pid_t pid; pid = getpid(); printf("receive_thread pid %d\n",pid); VDEC_FRAMEINFO_S frameinfo; while(s32vdecthreadflag) { HI_VDEC_Receive(parg->ChanID, &frameinfo, NULL, bBlock); if (frameinfo.value) { /*VO will release the data, user not need to care it. if the data isn't send to VO, user need call HI_VDEC_ReleaseVideoBuf to release buffer*/ ret = HI_VO_SendData(VO_CHN0, &frameinfo); while(HI_ERR_VO_BUF_FULL == ret) { usleep(10); ret = HI_VO_SendData(VO_CHN0, &frameinfo); } ASSERT_RETURN((HI_SUCCESS == ret), (void*)ret); } /*don't call HI_VDEC_Receive frequency*/ if(HI_FALSE == bBlock) { usleep(50); } } printf("break while!\n"); pthread_exit(NULL);}/*get the video decode ability*/void test_HI_VDEC_GetCapability(){ VDEC_CAPABILITY_S Cap;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -