int main(void) { int status,i; RTPSession s; RTPSessionParams sessparams; RTPUDPv4TransmissionParams transparams; char blaai[100]; transparams.SetPortbase(10000); sessparams.SetOwnTimestampUnit(1.0/8000.0); sessparams.SetUsePollThread(true); sessparams.SetMaximumPacketSize(10000); status = s.Create(sessparams,&transparams); s.SetLocalName((const uint8_t *)"Jori Liesenborgs",16); s.SetLocalEMail((const uint8_t *)"*****@*****.**",20); s.SetLocalNote((const uint8_t *)"Blaai",5); s.SetNameInterval(3); s.SetEMailInterval(5); s.SetNoteInterval(2); status = s.AddDestination(RTPIPv4Address(ntohl(inet_addr("192.168.2.115")),5000)); //status = s.AddDestination(RTPIPv4Address(ntohl(inet_addr("127.0.0.1")),7000)); int snd = open("/dev/dsp",O_RDWR); int val; val = 0; status = ioctl(snd,SNDCTL_DSP_STEREO,&val); val = 8; status = ioctl(snd,SNDCTL_DSP_SAMPLESIZE,&val); val = 8000; status = ioctl(snd,SNDCTL_DSP_SPEED,&val); val = 7 | (128<<16); ioctl(snd,SNDCTL_DSP_SETFRAGMENT,&val); i = 0; while (i++ < 40000) { if (i == 1000) { //std::cout <<"Disabling note" << std::endl; s.SetNoteInterval(0); } uint8_t data[PACKSIZE]; RTPTime t1 = RTPTime::CurrentTime(); status = read(snd,data,PACKSIZE); RTPTime t2 = RTPTime::CurrentTime(); t2 -= t1; printf("%d.%06d\n",t2.GetSeconds(),t2.GetMicroSeconds()); status = s.SendPacket(data,PACKSIZE,1,false,PACKSIZE); } close(snd); printf("Destroying...\n"); s.BYEDestroy(RTPTime(10,0),(const uint8_t *)"Leaving session",16); return 0; }
void CSenderDlg::OnSend() { CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "(*.*)|*.*|", NULL); if (dlg.DoModal() == IDOK) { m_SourceFile = dlg.GetPathName(); } source=fopen(m_SourceFile,"rb"); if ( source == NULL ) { AfxMessageBox("can't access the file"); } //#ifdef win32 //#endif size_t bufRead = 0; Mark=true; BYTE buffer[bufsize]; int t; t=sess.Create(5800); if(t!=0)AfxMessageBox("can't create"); if(t==0){sen=true;} sess.SetMulticastTTL(1); //設定multicast封包TTL sess.AddDestination(ntohl(inet_addr("127.0.0.1")),6900); //指定傳送目的端 //sess.AddDestination(ntohl(inet_addr("192.168.25.79")),6900); if(t!=0)AfxMessageBox("can't add destination"); (void) fseek( source, 0, SEEK_SET ); while(!feof(source)) { bufRead = fread(buffer, sizeof(BYTE), bufsize, source ); nPT=rand()%64+1; nTSTAMP=rand()%1000+1; //g_ACode.EncodeAudioData ((char*)buffer,bufsize,m_cBufOut,&iOut); //t=sess.SendPacket(m_cBufOut,iOut,nPT,Mark,nTSTAMP); t=sess.SendPacket(buffer,bufsize,nPT,Mark,nTSTAMP); if(t!=0)AfxMessageBox("can't sending"); Sleep(5); Mark=false; } (void) fflush( source ); (void) fclose( source ); AfxMessageBox("send success"); WSACleanup(); }
void* startsound(void *_ca) { FILE *source=fopen("c://12pcm.wav","rb"); if ( source == NULL ) { cout<<"can't access the file"<<endl; } //#ifdef win32 //#endif size_t bufRead = 0; bool Mark=true; #define bufsize 1024 BYTE buffer[bufsize]; int t; RTPSession sess; t=sess.Create(5800); if(t!=0)cout<<"can't create"<<endl; bool sen; if(t==0){sen=true;} int nPT ; int nTSTAMP; sess.SetMulticastTTL(1); //設定multicast封包TTL sess.AddDestination(ntohl(inet_addr("192.168.3.190")),portt); //指定傳送目的端 //sess.AddDestination(ntohl(inet_addr("192.168.25.79")),6900); if(t!=0) cout<<"can't add destination"<<endl; for (int jj=0;j<1000;j++) { (void) fseek( source, 0, SEEK_SET ); while(!feof(source)) { bufRead = fread(buffer, sizeof(BYTE), bufsize, source ); nPT=rand()%64+1; nTSTAMP=rand()%1000+1; t=sess.SendPacket(buffer,bufsize,nPT,Mark,nTSTAMP); if(t!=0)cout<<"can't sending"<<endl; Sleep(5); Mark=false; } } (void) fflush( source ); (void) fclose( source ); cout<<("send success")<<endl; WSACleanup(); return NULL; }
int main(int argc, char** argv) { #if 0 CRTPSender sender; string destip_str = "127.0.0.1"; uint32_t dest_ip = inet_addr(destip_str.c_str()); SetRTPParams(sender,dest_ip,DEST_PORT,BASE_PORT); sender.SetParamsForSendingH264(); #else RTPSession session; RTPSessionParams sessionparams; sessionparams.SetOwnTimestampUnit(1.0/90000.0); RTPUDPv4TransmissionParams transparams; transparams.SetPortbase(8000); int status = session.Create(sessionparams,&transparams); if (status < 0) { std::cerr << RTPGetErrorString(status) << std::endl; exit(-1); } uint8_t localip[]={127,0,0,1}; RTPIPv4Address addr(localip,9000); status = session.AddDestination(addr); if (status < 0) { std::cerr << RTPGetErrorString(status) << std::endl; exit(-1); } session.SetDefaultPayloadType(96); session.SetDefaultMark(false); session.SetDefaultTimestampIncrement(90000.0 /25.0); RTPTime delay(0.040); RTPTime starttime = RTPTime::CurrentTime(); #endif NALU_HEADER *nalu_hdr; FU_INDICATOR *fu_ind; FU_HEADER *fu_hdr; char sendbuf[1500]; char* nalu_payload; unsigned int timestamp_increse=0,ts_current=0; #define ddd OpenBitstreamFile("raw.264");//打开264文件,并将文件指针赋给bits,在此修改文件名实现打开别的264文件。 NALU_t *n; n = AllocNALU(8000000);//为结构体nalu_t及其成员buf分配空间。返回值为指向nalu_t存储空间的指针 bool start=false; while(!feof(bits)) { int size=GetAnnexbNALU(n);//每执行一次,文件的指针指向本次找到的NALU的末尾,下一个位置即为下个NALU的起始码0x000001 if(size<4) { printf("get nul error!\n"); continue; } dump(n);//输出NALU长度和TYPE if(!start) { if(n->nal_unit_type==5||n->nal_unit_type==6|| n->nal_unit_type==7||n->nal_unit_type==7) { printf("begin\n"); start=true; } } //将编码数据写入文件t //fwrite(pNals[i].p_payload, 1, pNals[i].i_payload, pFile); //发送编码文件 #if 1 // 当一个NALU小于MAX_RTP_PKT_LENGTH字节的时候,采用一个单RTP包发送 if(n->len<=MAX_RTP_PKT_LENGTH) { //printf("ddd0\n"); //session.SetDefaultMark(false); //设置NALU HEADER,并将这个HEADER填入sendbuf[12] nalu_hdr =(NALU_HEADER*)&sendbuf[0]; //将sendbuf[12]的地址赋给nalu_hdr,之后对nalu_hdr的写入就将写入sendbuf中; nalu_hdr->F=n->forbidden_bit; nalu_hdr->NRI=n->nal_reference_idc>>5;//有效数据在n->nal_reference_idc的第6,7位,需要右移5位才能将其值赋给nalu_hdr->NRI。 nalu_hdr->TYPE=n->nal_unit_type; nalu_payload=&sendbuf[1];//同理将sendbuf[13]赋给nalu_payload memcpy(nalu_payload,n->buf+1,n->len-1);//去掉nalu头的nalu剩余内容写入sendbuf[13]开始的字符串。 ts_current=ts_current+timestamp_increse; //status = session.SendPacket((void *)sendbuf,n->len); if(n->nal_unit_type==1 || n->nal_unit_type==5) { status = session.SendPacket((void *)sendbuf,n->len,96,true,3600); } else { status = session.SendPacket((void *)sendbuf,n->len,96,true,0);\ //如果是6,7类型的包,不应该延时;之前有停顿,原因这在这 continue; } //发送RTP格式数据包并指定负载类型为96 if (status < 0) { std::cerr << RTPGetErrorString(status) << std::endl; exit(-1); } } else if(n->len>MAX_RTP_PKT_LENGTH)
int main(void) { RTPSession sess; int portbase; unsigned long destip; int destport; char ipstr[256]; int status; char dummybuffer[1024]; struct timeval rttprev = {0,0},rtt,tv; int sock1,sock2; bool done; fd_set fdset; /* First, we'll ask for the necessary information */ printf("Enter the local portbase\n"); scanf("%d",&portbase); printf("\n"); printf("Enter the destination IP address\n"); scanf("%s",ipstr); destip = inet_addr(ipstr); if (destip == INADDR_NONE) { printf("Bad IP address specified\n"); return -1; } // The inet_addr function returns a value in network byte order, but // we need the IP address in host byte order, so we use a call to // ntohl destip = ntohl(destip); printf("Enter the destination port\n"); scanf("%d",&destport); /* Now, we'll create a RTP session, set the destination, send some packets and poll for incoming data. */ status = sess.Create(portbase); checkerror(status); /* Get the sockets, so we can use them in a 'select' call */ sess.GetRTPSocket(&sock1); sess.GetRTCPSocket(&sock2); status = sess.AddDestination(destip,destport); checkerror(status); printf("Press return to quit...\n"); done = false; while (!done) { /* Just send something */ status = sess.SendPacket("1234567890",10,0,false,10); checkerror(status); /* Wait for incoming data, or wait just one second */ tv.tv_sec = 1; tv.tv_usec = 0; FD_ZERO(&fdset); FD_SET(sock1,&fdset); FD_SET(sock2,&fdset); FD_SET(0,&fdset); // check for keypress select(FD_SETSIZE,&fdset,NULL,NULL,&tv); if (FD_ISSET(0,&fdset)) done = true; /* poll for incoming data */ status = sess.PollData(); /* check incoming packets */ if (sess.GotoFirstSourceWithData()) { do { RTPSourceData *srcdat; srcdat = sess.GetCurrentSourceInfo(); srcdat->FlushPackets(); // we don't need the actual data rtt = srcdat->INF_GetRoundTripTime(); if (rtt.tv_sec != 0 || rtt.tv_usec != 0) { if ((rtt.tv_sec != rttprev.tv_sec) || (rtt.tv_usec != rttprev.tv_usec)) { double t; t = (double)rtt.tv_sec; t += ((double)rtt.tv_usec)/1000000.0; t *= 1000.0; // we want milliseconds; printf("rtt: %f ms\n",(float)t); rttprev = rtt; } } } while (sess.GotoNextSourceWithData()); } } return 0; }
/*********************************************************************************************************** **函数:SimpleH264SendPacket **功能: **输入参数: **返回值: ***********************************************************************************************************/ int SimpleH264SendPacket(unsigned char *val,uint32_t length) { /* *val:为264的原始数据,包含0x00 0x00 0x00 0x01信息, */ int status=0; uint32_t TimestampIncrement; uint32_t send_length,valid_len=length-4; char NALU=val[4],*sendStartAddr=NULL; #define MAX_STREAM_SLICE 1024 if(SimpleRtpIsActive()!=true) { printf("rtp Session is error,%s ,%d\n",__FUNCTION__, __LINE__); return -1; } Rtp_Lock(); TimestampIncrement=sess.GetDefaultTimestampIncrement(); if(valid_len<=MAX_STREAM_SLICE) { status = sess.SendPacket((void *)&val[4],valid_len,PLOAD_TYPE,true,DefaultTimestampIncrement); checkerror(status); } else { int k=0,l=0,len=valid_len,pos=0; k=len/MAX_STREAM_SLICE; l=len%MAX_STREAM_SLICE; int t=0; while(t<=k) { if(t==0) {//发送第1包 sendStartAddr=(char *)(val+4);//发送数据的起始地址 sendStartAddr[pos-1]=(NALU&0x60)|28;//FU indicator sendStartAddr[pos]=(NALU&0x1f)|0x80;//FU header send_length=MAX_STREAM_SLICE+1;//要发送数据的长度 status = sess.SendPacket(sendStartAddr-1,send_length,PLOAD_TYPE,false,DefaultTimestampIncrement); checkerror(status); if(status<0) { goto end; } pos+=MAX_STREAM_SLICE; } else if(k==t&&l!=0) {//最后一包 sendStartAddr[pos-2]=(NALU&0x60)|28;//FU indicator sendStartAddr[pos-1]=(NALU&0x1f)|0x40;//FU header send_length=l+2;//要发送数据的长度 status = sess.SendPacket(sendStartAddr+pos-2,send_length,PLOAD_TYPE,true,0); checkerror(status); if(status<0) { goto end; } pos+=l; } else if(t<k&&0!=t) {//发送第2包-----倒数第2包 if(l==0&&t==k-1) { sendStartAddr[pos-2]=(NALU&0x60)|28;//FU indicator sendStartAddr[pos-1]=(NALU&0x1f)|0x40;//FU header } else { sendStartAddr[pos-2]=(NALU&0x60)|28;//FU indicator sendStartAddr[pos-1]=(NALU&0x1f);//FU header } send_length=MAX_STREAM_SLICE+2;//要发送数据的长度 status = sess.SendPacket(sendStartAddr+pos-2,send_length,PLOAD_TYPE,false,0); checkerror(status); if(status<0) { goto end; } pos+=MAX_STREAM_SLICE; } t++; } } #ifndef RTP_SUPPORT_THREAD checkerror(status); #endif end: Rtp_UnLock(); return status; }