📄 receiver.c
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include "avcommon.h"#include "hi_rtp.h"#include "avsync.h"#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; 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;}#define PACKET_HEADER_SIZE 8#define RECEIVEBUF_NUM 200HI_S32 file_fd;HI_S32 onrecv_count = 0;HI_CHAR receivebuf[RECEIVEBUF_NUM][2048+PACKET_HEADER_SIZE];volatile HI_S32 read_pointer;volatile HI_S32 write_pointer;#define HI_ALIGN_LENGTH(v,a) ((((v) + ((a)-1)) & (~((a)-1))))HI_S32 s32vdecsendthreadflag;RTP_RECV_S* pRtpRecvStream = NULL;/*read data form receive buffer and send it to decoder*/void* sendstream_thread(void *args){ VDEC_THTREAD_ARGS *parg = args; HI_S32 retrycount = 0; VDEC_STREAM_S stream; HI_S32 ret; pid_t pid; pid = getpid(); printf("sendstream thread pid %d\n",pid); while(s32vdecsendthreadflag) { while(read_pointer != write_pointer) { stream.Dataaddr = (ADDR)&receivebuf[read_pointer][8]; stream.Datalen = *((HI_S32 *)(&receivebuf[read_pointer][0])); stream.pts = *((HI_S32 *)(&receivebuf[read_pointer][4])); ret = HI_VDEC_SendStream(parg->ChanID, &stream, HI_TRUE); while(HI_SUCCESS != ret) { if(HI_ERR_VDEC_NO_PAYLOAD == ret)break; if(retrycount > 80000) { printf("HI_VDEC_SendStream failed at %d retries\n",retrycount); //exit(1); break; } retrycount++; if(!((retrycount)%3)) { usleep(10); } ret = HI_VDEC_SendStream(parg->ChanID, &stream, HI_TRUE); } retrycount = 0; read_pointer++; //printf("read_pointer %d\n",read_pointer); if(read_pointer == RECEIVEBUF_NUM)read_pointer = 0; } usleep(100); } printf("sendstream_thread break while!\n"); pthread_exit(NULL);}volatile long discardcount=0;/*deal with rtp packet*/int onrecv(IN struct hiRTP_RECV_S * pRtpStream, unsigned char * pBuff, unsigned int len, int *ext_args){ RTP_HDR_S *pheader = (RTP_HDR_S *)pBuff; //write(file_fd, pBuff+12, len-12); onrecv_count++; if (read_pointer <= write_pointer) { /*overload warning*/ if(write_pointer-read_pointer >= RECEIVEBUF_NUM*4/5) { discardcount++; if(!(discardcount%100))printf("discardcount %ld\n",discardcount);fflush(stdout); return 1; } if(read_pointer+RECEIVEBUF_NUM == write_pointer+1) { printf("no receive buf !\n"); exit(-1); return 1; } *((HI_S32 *)(&receivebuf[write_pointer][0])) = len - RTP_HDR_LEN; *((HI_S32 *)(&receivebuf[write_pointer][4])) = ntohl(pheader->ts); memcpy(&receivebuf[write_pointer][8],(void *)(pBuff + RTP_HDR_LEN),len - RTP_HDR_LEN); write_pointer++; if(RECEIVEBUF_NUM == write_pointer)write_pointer=0; } else { /*overload warning*/ if(write_pointer+RECEIVEBUF_NUM-read_pointer >= RECEIVEBUF_NUM*4/5) { //printf("receive buf is nearly full! \n"); discardcount++; if(!(discardcount%100))printf("discardcount %ld\n",discardcount);fflush(stdout); return 1; } if(write_pointer+1 == read_pointer) { printf("no receive buf !\n"); exit(-1); return 1; } *((HI_S32 *)(&receivebuf[write_pointer][0])) = len - RTP_HDR_LEN; *((HI_S32 *)(&receivebuf[write_pointer][4])) = ntohl(pheader->ts); memcpy(&receivebuf[write_pointer][8],(void *)(pBuff + RTP_HDR_LEN),len - RTP_HDR_LEN); write_pointer++; } if (len > 0x800)printf("stream.Datalen %x\n",len); //printf("ChanID %d",ChanID);#if 0 ret = HI_VDEC_SendStream(ChanID, &stream); while(HI_SUCCESS != ret) { /*防止解码器挂死后程序进入无限死循环*/ if(retrycount > 500000) { printf("HI_VDEC_SendStream failed at %d retries\n",retrycount); return -1; } ret = HI_VDEC_SendStream(ChanID, &stream); retrycount++; }#endif return 1;}void test_Video_Decoder_Rtp_Receiver(){ VDEC_CHN ChanID; VDEC_ATTR_TYPE_E type = VDEC_ATTR_ALL; VDEC_ChannelPara_S config; HI_S32 ret; pthread_t thread_receivestream; static VDEC_THTREAD_ARGS arg; char filename[255] = "receive.h264"; file_fd = open(filename, O_RDWR | O_TRUNC | O_CREAT ,0664); /*set config value*/ config.type = VDEC_H264; config.framenumber = 5; config.picformat = VDEC_DEFAULT_PICTUREFORMAT; ret = HI_VDEC_CreateCH(&ChanID, type, &config); if (HI_SUCCESS == ret) { printf("test_Video_Decoder_Rtp_Receiver:Create a Channel: %d\n",ChanID); } else { printf("test_Video_Decoder_Rtp_Receiver:Failed to Create a Channel!!!\n"); return; } if (HI_SUCCESS == HI_RTP_Recv_Create(&pRtpRecvStream, VIDEO_PORT, onrecv, &ChanID)) { printf("Create RTP Recevier OK.\n"); } /*init the receive buffer*/ memset(receivebuf, 0 , sizeof(receivebuf)); read_pointer = 0; write_pointer = 0; arg.ChanID = ChanID; s32vdecsendthreadflag = 1; /*start thread to send stream*/ pthread_create(&thread_receivestream, NULL, sendstream_thread, &arg); /*start rtp thread to receive data */ HI_RTP_Recv_Start(pRtpRecvStream); AVSYNC_Frame2Vo_Start(ChanID); while(1) { int c; c = getchar(); if('q' == c)break; } s32vdecsendthreadflag = 0; pthread_join(thread_receivestream, NULL); printf("after send stream thread exit!\n"); usleep(100); AVSYNC_Frame2Vo_Stop(); HI_RTP_Recv_Destroy(pRtpRecvStream); printf("after receive rtp thread exit!\n"); usleep(100); HI_VDEC_DestroyCH(ChanID); close(file_fd); printf("onrecv_count %d\n",onrecv_count);}RTP_RECV_S* pRtpAudioRecvStream = NULL;void test_Audio_Decoder_Rtp_Receiver(){ AUDIO_CODEC_FORMAT_E enType = AUDIO_CODEC_FORMAT_AAC; ADEC_CHN decChnID; int ret; printf("test_Audio_Decoder_Rtp_Receiver pid %d\n",getpid());fflush(stdout); if(AUDIO_CODEC_FORMAT_AAC == enType) { /* Set the sample rate of audio AD and SIO as 48K.*/ SetADSampleRate(SET_48K_SAMPLERATE); SetAiSampleRate(0, AUDIO_SAMPLE_RATE_48); } else { /* Set the sample rate of audio AD and SIO as 8K.*/ SetADSampleRate(SET_8K_SAMPLERATE); SetAiSampleRate(0, AUDIO_SAMPLE_RATE_8); } /* Create and start audio decoder channel */ ret = HI_ADEC_CreateCH(0, enType, HI_TRUE, &decChnID); ASSERT_RETURN((HI_SUCCESS==ret), ret); printf("1 decChnID %d\n",decChnID); ret = HI_ADEC_StartCH(decChnID, 0); ASSERT_RETURN((HI_SUCCESS==ret), ret); if (HI_SUCCESS == HI_RTP_Recv_Create(&pRtpAudioRecvStream, AUDIO_PORT, audio_onrecv, &decChnID)) { printf("Create AUDIO RTP Recevier OK.\n"); } /*start rtp thread to receive data */ HI_RTP_Recv_Start(pRtpAudioRecvStream); while(1) { sleep(1); } }int main(int argc, char *argv[]){ int ret; pthread_t video_thread; pthread_t audio_thread; printf("main pid %d\n",getpid()); if(argc >= 2) { compose_mode = (VIDEO_NORM_E)(atoi(argv[1])); } printf("compose_mode = %d [0~PAL, 1~NTSC]\n", compose_mode); if(argc >= 3) { g_bZoomEnable = (atoi(argv[2]) == 1) ? HI_TRUE : HI_FALSE; } printf("Zoom enbale is %s\n", g_bZoomEnable?"TRUE":"FALSE"); /*open video decode device*/ ret = HI_VDEC_Open(); ASSERT_RETURN((HI_SUCCESS==ret), ret); /*open vo device*/ ret = vo_open(); ASSERT_RETURN((HI_SUCCESS==ret), ret); /*open audio decode device*/ ret = HI_ADEC_Open(); ASSERT_RETURN((HI_SUCCESS==ret), ret); AVSYNC_Start(); //test_Video_Decoder_Rtp_Receiver(); pthread_create(&video_thread, NULL, (void *)test_Video_Decoder_Rtp_Receiver, NULL); pthread_create(&audio_thread, NULL, (void *)test_Audio_Decoder_Rtp_Receiver, NULL); while(1) { sleep(1); } AVSYNC_Stop(); vo_close(); HI_VDEC_Close();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -