开源RTP源代码.docx
- 文档编号:9138826
- 上传时间:2023-02-03
- 格式:DOCX
- 页数:27
- 大小:100.25KB
开源RTP源代码.docx
《开源RTP源代码.docx》由会员分享,可在线阅读,更多相关《开源RTP源代码.docx(27页珍藏版)》请在冰豆网上搜索。
开源RTP源代码
开源RTP库JRTPLIB 初学 [转]
(2008-12-1018:
58:
00)
转载
标签:
it
分类:
技术无限
RTP是一个实时通讯网络协议,网络上的音视频传输可以用它来做,像QQ的语音聊天等都是使用这个。
real开发的在线rm文件播放协议rstp也是基于RTP协议,可以自己搜索一下,在网上可找到“RTP实时网络协议rfc3550.pdf”文档,有详细介绍。
JRTPLIB是一个开源的RTP协议实现库,支持Windows和unix平台,应该也很多人用了,封装的类方式很不错。
他的主页是 http:
//research.edm.uhasselt.be/~jori/page/index.php?
n=CS.Jrtplib ,
帮助文档:
http:
//research.edm.uhasselt.be/jori/jrtplib/documentation/index.html
RTPSessionClassReferencehttp:
//research.edm.uhasselt.be/jori/jrtplib/documentation/classRTPSession.html
从他主页上下载完整的JRTPLIB 源码包下来解压就行了,不过JRTPLIB用到了他的JThread库,在主页上可以找到,也把JThread库下载下来就行了。
解压之后再examples目录下有几个例子,我试了一下,example2.cpp和example4.cpp两个,刚好一个可以作为客户端,一个作为服务器端,在vc2003中测试了一下。
首先建一个win32console项目,把把JRTPLIBexample2.cpp 和example4.cpp加进了,再把JRTPLIB 和 JThread添加到工程中来。
在include目下中指定JRTPLIB 和 JThread的src源码目录。
下一步把工程属性中把“RuntimeLibrary”改成“Multi-threadedDebugDLL(/MDd)”,需要改成这个JThread才能编译通过。
最后包含一个Ws2_32.lib这个lib库,我是直接在example2.cpp和example4.cpp前面添加#pragmacomment(lib,"Ws2_32.lib")这一句了,在工程属性修改应该一样的。
两个例子的代码如下也贴一下吧:
#pragmacomment(lib,"Ws2_32.lib")
#include"rtpsession.h"
#include"rtppacket.h"
#include"rtpudpv4transmitter.h"
#include"rtpipv4address.h"
#include"rtpsessionparams.h"
#include"rtperrors.h"
#ifndefWIN32
#include
#include
#else
#include
#endif//WIN32
#include"rtpsourcedata.h"
#include
#include
#include
#include
#ifdefRTP_SUPPORT_THREAD
ThisfunctionchecksiftherewasaRTPerror.Ifso,itdisplaysanerror
messageandexists.
voidcheckerror(intrtperr)
{
if(rtperr<0)
{
std:
:
cout<<"ERROR:
"< : endl; exit(-1); } } Thenewclassroutine classMyRTPSession: publicRTPSession { protected: voidOnPollThreadStep(); voidProcessRTPPacket(constRTPSourceData&srcdat,constRTPPacket&rtppack); }; voidMyRTPSession: : OnPollThreadStep() { BeginDataAccess(); checkincomingpackets if(GotoFirstSourceWithData()) { do { RTPPacket*pack; RTPSourceData*srcdat; srcdat=GetCurrentSourceInfo(); while((pack=GetNextPacket())! =NULL) { ProcessRTPPacket(*srcdat,*pack); DeletePacket(pack); } }while(GotoNextSourceWithData()); } EndDataAccess(); } voidMyRTPSession: : ProcessRTPPacket(constRTPSourceData&srcdat,constRTPPacket&rtppack) { Youcaninspectthepacketandthesource'sinfohere std: : cout<<"Gotpacket"< : endl; } Themainroutine intmain(void) { #ifdefWIN32 WSADATAdat; WSAStartup(MAKEWORD(2,2),&dat); #endif//WIN32 MyRTPSessionsess; uint16_tportbase; std: : stringipstr; intstatus,num; First,we'llaskforthenecessaryinformation std: : cout<<"Enterlocalportbase: "< : endl; std: : cin>>portbase; std: : cout< : endl; std: : cout< : endl; std: : cout<<"Numberofsecondsyouwishtowait: "< : endl; std: : cin>>num; Now,we'llcreateaRTPsession,setthedestination andpollforincomingdata. RTPUDPv4TransmissionParamstransparams; RTPSessionParamssessparams; IMPORTANT: ThelocaltimestampunitMUSTbeset,otherwise RTCPSenderReportinfowillbecalculatedwrong Inthiscase,we'llbejustuse8000samplespersecond. sessparams.SetOwnTimestampUnit(1.0/8000.0); transparams.SetPortbase(portbase); status=sess.Create(sessparams,&transparams); checkerror(status); Waitanumberofseconds RTPTime: : Wait(RTPTime(num,0)); sess.BYEDestroy(RTPTime(10,0),0,0); #ifdefWIN32 WSACleanup(); #endif//WIN32 return0; } #else intmain(void) { std: : cerr<<"Threadsupportisrequiredforthisexample"< : endl; return0; } #endif//RTP_SUPPORT_THREAD ============================================================================= #pragmacomment(lib,"Ws2_32.lib") #include"rtpsession.h" #include"rtpsessionparams.h" #include"rtpudpv4transmitter.h" #include"rtpipv4address.h" #include"rtptimeutilities.h" #include"rtppacket.h" #include #include intmain(void) { #ifdefWIN32 WSADATAdat; WSAStartup(MAKEWORD(2,2),&dat); #endif//WIN32 RTPSessionsession; RTPSessionParamssessionparams; sessionparams.SetOwnTimestampUnit(1.0/8000.0); RTPUDPv4TransmissionParamstransparams; transparams.SetPortbase(8000); intstatus=session.Create(sessionparams,&transparams); if(status<0) { std: : cerr< : endl; exit(-1); } uint8_tlocalip[]={127,0,0,1}; RTPIPv4Addressaddr(localip,9000); status=session.AddDestination(addr); if(status<0) { std: : cerr< : endl; exit(-1); } session.SetDefaultPayloadType(96); session.SetDefaultMark(false); session.SetDefaultTimestampIncrement(160); uint8_tsilencebuffer[160]; for(inti=0;i<160;i++) silencebuffer[i]=128; //RTPTimedelay(0.020); RTPTimedelay(3.000); RTPTimestarttime=RTPTime: : CurrentTime(); booldone=false; while(! done) { status=session.SendPacket(silencebuffer,160); if(status<0) { std: : cerr< : endl; exit(-1); } session.BeginDataAccess(); if(session.GotoFirstSource()) { do { RTPPacket*packet; while((packet=session.GetNextPacket())! =0) { std: : cout<<"Gotpacketwith" <<"extendedsequencenumber" < <<"fromSSRC"< < : endl; session.DeletePacket(packet); } }while(session.GotoNextSource()); } session.EndDataAccess(); RTPTime: : Wait(delay); RTPTimet=RTPTime: : CurrentTime(); t-=starttime; if(t>RTPTime(60.0)) done=true; } delay=RTPTime(10.0); session.BYEDestroy(delay,"Time'sup",9); #ifdefWIN32 WSACleanup(); #endif//WIN32 return0; } 使用RTP发送h.264的例子代码分析 2011-08-1111: 50: 10| 分类: 网络+协议| 标签: |字号大中小 订阅 参考: 首先声明,以下代码为帖子中ttxk的,注释是我加的,对ttxk和jessiepan表示感谢,jessiepan的钻研精神很不错,很负责任的楼主。 他遇到的问题估计我也会遇到。 以下是根据rfc3894阅读ttxk的代码的笔记。 下一阶段可能是用一个rtp库将rtp传输部分和对应的接受处理部分完成。 UINTMediaStreamH264: : TransportData(PBYTEpData,UINTdataSize,intpts) { //当前缓存头 PBYTEp_buffer=pData; //当前缓存大小 inti_buffer=dataSize; //已经发送大小 UINTwriteSize=0; //寻找第一个头[3BYTE,0x00,0x00,0x01] while(i_buffer>4&&(p_buffer[0]! =0||p_buffer[1]! =0||p_buffer[2]! =1)) { i_buffer--; p_buffer++; } /*Splitnalunits*/ while(i_buffer>4) { inti_offset; inti_size=i_buffer; inti_skip=i_buffer; /*searchnalend*/ for(i_offset=4;i_offset+2 { //寻找下一个头来找到当前帧结束位置 if(p_buffer[i_offset]==0&&p_buffer[i_offset+1]==0&&p_buffer[i_offset+2]==1) { /*wefoundanotherstartcode*/ //判断下一个头是两个还是三个0x00,如果p_buffer[i_offset-1]表明下一个头是三个0x00+0x01,i_size要多减一 i_size=i_offset-(p_buffer[i_offset-1]==0? 1: 0); i_skip=i_offset; break; } } /*TODOaddSTAP-Atoremovealotofoverheadwithsmallslice/sei/...*/ //发送当前找到的一帧 UINTiWrite=TransportH264Nal(p_buffer,i_size,pts,(i_size>=i_buffer)); if(iWrite>0) writeSize+=iWrite; i_buffer-=i_skip; p_buffer+=i_skip; } returnwriteSize; } //发送一帧264数据,一般一帧以一个RTP包发送,过长帧分为多个RTP包传送。 UINTMediaStreamH264: : TransportH264Nal(constPBYTEpNal,UINTnalSize,INT32pts,BOOLisLast) { //应该是对进程加锁 ATLockatlock(&m_tlockRun); if(m_bRun==FALSE) return0; //每帧最小长度至少为5 if(nalSize<5) return0; /*mtu是MTU,应是个全局变量,如下介绍,在IP网估计可设为1500左右的一个值 聚合包是本荷载规范的NAL单元聚合安排。 本计划的引入是反映两个主要目标网络差异巨大的MTU: 有线IP网络(MTU通常被以太网的MTU限制;大约1500字节),基于无线通信系统的IP或非IP(ITU-TH.324/M)网络,它的优先传输最大单元是254或更少。 为了阻止连个世界媒体的转换以及避免不必要的打包负担,引入聚合单元安排。 */ UINTmtu=m_nMTU; //按照opal的经验可以将i_max设为1400 constinti_max=mtu-RTP_HEADER_SIZE;/*payloadmaxinonepacket*/ inti_nal_hdr;//NAL的头 inti_nal_type; i_nal_hdr=pNal[3]; i_nal_type=i_nal_hdr&0x1f;//前两个BYTE中第一个BYTE的最后一个bit和第二个BYTE是type stringsps; stringpps; //对于nal_unit_type等于7,8(指示顺序参数集或图像参数集)的NAL单元,H.264编码器应该设置NRI为11(二进制格式) if(i_nal_type==7||i_nal_type==8) { /*XXXWhydoyouwanttoremovethem? Itwillbreakstreamingwith *SPS/PPSchange(broadcast)? */ return0; } /*Skipstartcode*/ PBYTEp_data=pNal; inti_data=nalSize; //跳过头部的3个BYTE的h264帧头(0x000x000x01) p_data+=3; i_data-=3;//NAL+NALU的长度 intwriteSize=0; //如果此帧数据长度小于一个udp包内容的最大长度直接发送,负责按照FU格式发送一帧发送多个包 if(i_data<=i_max) //单个NAL单元的传输顺序必须和NAL解码顺序一致。 { /*SingleNALunitpacket*/ //writeSize=m_pRtpTransport->SetRtpData(p_data,i_data,pts,isLast); //发送数据 writeSize=m_pRtpTransport->Write(p_data,i_data,m_nRtpPayloadType,pts,0,isLast); if(writeSize<=0) return0; returnwriteSize; } else //STAP类型的包,是STAP-A的方式,由后面的28决定 { /*FU-AFragmentationUnitwithoutinterleaving*/ constinti_count=(i_data-1+i_max-2-1)/(i_max-2);//需要分多少个包 inti; p_data++; i_data--; for(i=0;i { //计算每个NALUDATA的长度,判断是否是最后一包,不是最后一包时都是i_max-2,最后一包是i_data(也即最后一包实际的长度) constinti_payload=(i_data<(i_max-2))? i_data: (i_max-2); //计算每个NALU的长度 constintnalSize=2+i_payload; m_Packet.ExtendBuffer(nalSize); /*FUindicator*/ /*i_nal_hdr&01100000 FU指示字节有以下格式: +---------------+ |0|1|2|3|4|5|6|7| +-+-+-+-+-+-+-+-+ |F|NRI| Type | +---------------+ FU指示字节的类型域的28,29表示FU-A和FU-B。 F的使用在5。 3描述。 NRI域的值必
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 开源 RTP 源代码
![提示](https://static.bdocx.com/images/bang_tan.gif)