📄 video_dec.c
字号:
return; } arg.ChanID = ChanID[chindex]; arg.chnum = Maxchnum; s32vdecthreadflag = 1; /*create thread which is used for recive data*/ pthread_create(&thread, NULL, receive_thread_multi, &arg); stream.Dataaddr = (ADDR)streambuf; pts = 0; fbuf_pointer = 0; fbuf_bytes_num = 0; while(1) { if (4 != Fread(&len_nalu, 1, 4, fhStream)) { printf("read nalu length error.\n"); break; } stream.Datalen = len_nalu; len_nalu = HI_ALIGN_LENGTH(len_nalu, 2); if ( len_nalu != Fread(streambuf+4, 1,len_nalu, fhStream) ) { printf("read nalu error.\n"); break; } stream.Datalen += 4; stream.pts = pts; for (i=0;i<Maxchnum;i++) { ret = HI_VDEC_SendStream(ChanID[i], &stream, HI_TRUE); while(HI_SUCCESS != ret) { if(HI_ERR_VDEC_NO_PAYLOAD == ret)break; ret = HI_VDEC_SendStream(ChanID[i], &stream, HI_TRUE); } } pts++; if (10000== pts)break; } fclose(fhStream); /*wait until all the data is decoded over*/ usleep(500000); s32vdecthreadflag = 0; pthread_join(thread, NULL); /*destroy all the decode channel*/ for (i=0;i<Maxchnum;i++) { ret = HI_VDEC_DestroyCH(ChanID[i]); if (HI_SUCCESS == ret) { printf("test_Video_Decoder_MultiChannel:destroy ch %d\n",ChanID[i]); } } free(streambuf);}RTP_RECV_S* pRtpRecvStream = NULL;#define default_port 6666#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;/*read data form receive buffer and send it to decoder*/void* sendstream_thread(void *args){ VDEC_RECEIVE_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%2))printf("discardcount %d\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])) = 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%2))printf("discardcount %d\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])) = 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;}/*receive frame data , it receive data and send to VO for real time frame presentation,if send vo failed,discard this frame*/void* receive_thread_realmode(void *args){ VDEC_RECEIVE_THTREAD_ARGS *parg = args; HI_S32 ret; HI_BOOL bBlock = HI_FALSE; volatile HI_U64 count = 0; pid_t pid; pid = getpid(); printf("receive_thread pid %d\n",pid); VDEC_FRAMEINFO_S frameinfo; while(s32vdecthreadflag) { count ++; 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); if(HI_SUCCESS != ret) { /*if send vo failed , discard this frame*/ HI_VDEC_ReleaseVideoBuf(parg->ChanID, &frameinfo); } } /*don't call HI_VDEC_Receive frequency*/ if(!(count % 5)) { usleep(10); } } printf("break while!\n"); pthread_exit(NULL);}/*receive rtp packet from the static socket, and send it to decoder*/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_receiveframe; pthread_t thread_receivestream; static VDEC_RECEIVE_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, default_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; s32vdecthreadflag = 1; 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); arg.ChanID = ChanID; s32vdecthreadflag = 1; /*start thread to receive frame, and send it to vo*/ pthread_create(&thread_receiveframe, NULL, receive_thread_realmode, &arg); 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); s32vdecthreadflag = 0; pthread_join(thread_receiveframe, NULL); printf("after receive frame thread exit!\n"); 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);}char args[10][255];/*parameter parse*/static void parsearg(int argc){ if(0 == strcmp("dec", args[0])&& 1 == argc) { test_Video_Decoder_Process(); } else if(0 == strcmp("dec", args[0]) && 2 == argc) { test_Video_Decoder_Process1(args[1]); } else if(0 == strcmp("cap", args[0])) { test_HI_VDEC_GetCapability(); } else if(0 == strcmp("testmulti", args[0]) && 3 == argc) { test_Video_Decoder_MultiChannel(args[1],args[2]); } else if(0 == strcmp("rcv", args[0]) && 1 == argc) { test_Video_Decoder_Rtp_Receiver(); } else { printf("input dec : decode file dec.h264\n"); printf("input dec xxx: decode file xxx\n"); printf("input cap : get capability\n"); printf("input testmulti x y: test x channels decode, send channel[y] to vo!x(1~4) y(0~3) y<x\n"); printf("input rcv : receive rtp packet at port 6666\n"); }}/*adjust input parameter*/static int adjust_str(char *ptr){ int i; while(*ptr==' ' && *ptr++ != '\0'); for(i=strlen(ptr);i>0;i--) { if(*(ptr+i-1) == 0x0a || *(ptr+i-1) == ' ') *(ptr+i-1) = '\0'; else break; } for(i=0;i<10;i++) { int j = 0; while(*ptr==' ' && *ptr++ != '\0'); while((*ptr !=' ') && (*ptr!='\0')) { args[i][j++] = *ptr++; } args[i][j] = '\0'; if('\0' == *ptr) { i++; break; } args[i][j] = '\0'; } return i;}int main(int argc, char* argv[]){ char buffer[256]; char *ptr; HI_S32 ret; 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(); if ( ret != HI_SUCCESS ) { printf("HI_VDEC_Open failed!\n"); return ret; } vo_open(); //test_Video_Decoder_Process(); for(;;) { printf("> "); ptr = fgets(buffer, 255, stdin); memset(args, 0, sizeof(args)); argc = adjust_str(ptr); if(0 == strcmp("q", args[0]) || 0 == strcmp("Q", args[0])) { vo_close(); HI_VDEC_Close(); return 0; } parsearg(argc); } return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -