jrtplib使用笔记

来源:互联网 发布:电脑屏幕防蓝光软件 编辑:程序博客网 时间:2024/05/16 11:12

一、简述

RTP 是目前解决流媒体实时传输问题的最好办法,而JRTPLIB 是一个用C++语言实现的RTP库,包括UDP通讯。刚使用JRTPLIB,对JRTPLIB的理解还不够深,当做使用时,积累的一些经验写个笔记吧。

二、RTP协议

实时传送协议(Real-time Transport Protocol或简写RTP,也可以写成RTTP)是一个网络传输协议,RTP协议详细说明了在互联网上传递音频和视频的标准数据包格式。它一开始被设计为一个多播协议,但后来被用在很多单播应用中。RTP协议常用于流媒体系统(配合RTCP协议或者RTSP协议)。因为RTP自身具有Time stamp所以在ffmpeg 中被用做一种formate。

RTP协议的详细介绍,请参考这篇文章http://www.360doc.com/content/11/1009/15/496343_154624612.shtml

三、RTPSession类

这里不介绍jrtplib的编译安装,这个很简单,网上很多地方都有讲解。

jrtplib的使用中,主要是围绕这个类来实现的,因此大家有必要去查看源码,看这类的实现。为了方便使用,我在这做了RTPSession的继承封装,下面直接贴代码了。

RTPSessionUtils.h

[cpp] view plaincopyprint?
  1. #include "rtpsession.h"  
  2. #include "rtppacket.h"  
  3. #include "rtpudpv4transmitter.h"  
  4. #include "rtpipv4address.h"  
  5. #include "rtpsessionparams.h"  
  6. #include "rtperrors.h"  
  7. #ifndef WIN32  
  8. #include <netinet/in.h>  
  9. #include <arpa/inet.h>  
  10. #else  
  11. #include <winsock2.h>  
  12. #endif // WIN32  
  13. #include "rtpsourcedata.h"  
  14. #include <stdlib.h>  
  15. #include <stdio.h>  
  16. #include <iostream>  
  17. #include <string>  
  18.   
  19. //jrtplib应用需链接的lib  
  20. #pragma comment(lib,"ws2_32.lib")  
  21. #pragma comment(lib, "jrtplib_d.lib")  
  22. #pragma comment(lib,"jthread_d.lib")  
  23.   
  24. namespace jrtplib  
  25. {  
  26.     class RTPSessionUtils : public RTPSession  
  27.     {  
  28.         typedef RTPSession base_type;  
  29.     public:  
  30.         RTPSessionUtils();  
  31.         ~RTPSessionUtils();  
  32.   
  33.         int AddDestination(const std::string& ip, uint16_t port);  
  34.         int DeleteDestination(const std::string& ip, uint16_t port);  
  35.         int CreateDefault(uint16_t port);  
  36.     protected:  
  37.         void OnNewSource(RTPSourceData *dat);  
  38.         void OnBYEPacket(RTPSourceData *dat);  
  39.         void OnRemoveSource(RTPSourceData *dat);  
  40.         void OnRTPPacket(RTPPacket *pack,const RTPTime &receivetime,  
  41.             const RTPAddress *senderaddress);  
  42.         void OnRTCPCompoundPacket(RTCPCompoundPacket *pack,const RTPTime &receivetime,  
  43.             const RTPAddress *senderaddress);  
  44.         void OnPollThreadStep();  
  45.     private:  
  46.         int GetAddrFromSource(RTPSourceData *dat, uint32_t& ip, uint16_t& port);  
  47.     };  
  48. }  
  49.   
  50. //整形的ip转成字符串ip  
  51. static std::string IPToString(const unsigned int iIP)  
  52. {  
  53.     struct in_addr inaddr;  
  54.     inaddr.s_addr = htonl(iIP);  
  55.     return std::string(inet_ntoa(inaddr));  
  56. }  
  57.   
  58. //字符串ip转成整形ip  
  59. static unsigned int IPToInt(const std::string& sIP)  
  60. {  
  61.     return inet_addr(sIP.c_str());  
  62. }  

RTPSessionUtils.cpp

[cpp] view plaincopyprint?
  1. #include "RTPSessionUtils.h"  
  2.   
  3. namespace jrtplib{  
  4.     RTPSessionUtils::RTPSessionUtils()  
  5.     {  
  6. #ifdef WIN32  
  7.         WSADATA dat;  
  8.         WSAStartup(MAKEWORD(2,2),&dat);  
  9. #endif // WIN32  
  10.     }  
  11.   
  12.     RTPSessionUtils::~RTPSessionUtils()  
  13.     {  
  14. #ifdef WIN32  
  15.         WSACleanup();  
  16. #endif // WIN32  
  17.     }  
  18.   
  19.     int RTPSessionUtils::CreateDefault(uint16_t port)  
  20.     {  
  21.         RTPUDPv4TransmissionParams transparams;  
  22.         RTPSessionParams sessparams;  
  23.         sessparams.SetOwnTimestampUnit(1.0/10.0);//必须设置  
  24.         transparams.SetPortbase(port);//port必须是偶数  
  25.         return base_type::Create(sessparams, &transparams);  
  26.   
  27.         base_type::SetDefaultPayloadType(0);  
  28.         base_type::SetDefaultTimestampIncrement(0);  
  29.         base_type::SetDefaultMark(false);  
  30.     }  
  31.   
  32.     int RTPSessionUtils::AddDestination(const std::string& ip, uint16_t port)  
  33.     {  
  34.         return base_type::AddDestination(RTPIPv4Address(ntohl(inet_addr(ip.c_str())), port));  
  35.     }  
  36.   
  37.     int RTPSessionUtils::DeleteDestination(const std::string& ip, uint16_t port)  
  38.     {  
  39.         return base_type::DeleteDestination(RTPIPv4Address(ntohl(inet_addr(ip.c_str())), port));  
  40.     }  
  41.   
  42.     int RTPSessionUtils::GetAddrFromSource(RTPSourceData *dat, uint32_t& ip, uint16_t& port)  
  43.     {  
  44.         if (dat->IsOwnSSRC())  
  45.             return -1;  
  46.   
  47.         if (dat->GetRTPDataAddress() != 0)  
  48.         {  
  49.             const RTPIPv4Address *addr = (const RTPIPv4Address *)(dat->GetRTPDataAddress());  
  50.             ip = addr->GetIP();  
  51.             port = addr->GetPort();  
  52.         }  
  53.         else if (dat->GetRTCPDataAddress() != 0)  
  54.         {  
  55.             const RTPIPv4Address *addr = (const RTPIPv4Address *)(dat->GetRTCPDataAddress());  
  56.             ip = addr->GetIP();  
  57.             port = addr->GetPort()-1;  
  58.         }  
  59.   
  60.         return 0;  
  61.     }  
  62.   
  63.     void RTPSessionUtils::OnNewSource(RTPSourceData *dat)  
  64.     {  
  65.         uint32_t ip;  
  66.         uint16_t port;  
  67.   
  68.         if (GetAddrFromSource(dat, ip, port))  
  69.             return;  
  70.           
  71.   
  72.         RTPIPv4Address dest(ip,port);  
  73.         base_type::AddDestination(dest);  
  74.   
  75.         std::cout << "OnNewSource Adding destination " << IPToString(ip) << ":" << port << std::endl;  
  76.     }  
  77.   
  78.     void RTPSessionUtils::OnRemoveSource(RTPSourceData *dat)  
  79.     {  
  80.         if (dat->ReceivedBYE())  
  81.             return;  
  82.   
  83.         uint32_t ip;  
  84.         uint16_t port;  
  85.   
  86.         if (GetAddrFromSource(dat, ip, port))  
  87.             return;  
  88.   
  89.         RTPIPv4Address dest(ip,port);  
  90.         base_type::DeleteDestination(dest);  
  91.   
  92.         std::cout << "OnRemoveSource Deleting destination " << IPToString(ip) << ":" << port << std::endl;  
  93.     }  
  94.   
  95.     void RTPSessionUtils::OnBYEPacket(RTPSourceData *dat)  
  96.     {  
  97.         uint32_t ip;  
  98.         uint16_t port;  
  99.   
  100.         if (GetAddrFromSource(dat, ip, port))  
  101.             return;  
  102.   
  103.         RTPIPv4Address dest(ip,port);  
  104.         base_type::DeleteDestination(dest);  
  105.   
  106.         std::cout << "OnBYEPacket Deleting destination " << IPToString(ip) << ":" << port << std::endl;  
  107.     }  
  108.   
  109.     //只要有rtp包就会触发  
  110.     void RTPSessionUtils::OnRTPPacket(RTPPacket *pack,const RTPTime &receivetime,  
  111.         const RTPAddress *senderaddress)  
  112.     {  
  113.         std::cout << "OnRTPPacket: data:" << pack->GetPayloadData() << std::endl;  
  114.     }  
  115.   
  116.     //收到rtcp包触发  
  117.     void RTPSessionUtils::OnRTCPCompoundPacket(RTCPCompoundPacket *pack,const RTPTime &receivetime,  
  118.         const RTPAddress *senderaddress)  
  119.     {  
  120.         std::cout << "OnRTCPCompoundPacket: data:" << pack->GetCompoundPacketData() << std::endl;  
  121.     }  
  122.   
  123.     //隔段时间就会触发,也可以用于收包回调函数  
  124.     //void RTPSessionUtils::OnPollThreadStep()  
  125.     //{  
  126.     //  BeginDataAccess();  
  127.   
  128.     //  // check incoming packets  
  129.     //  if (GotoFirstSourceWithData())  
  130.     //  {  
  131.     //      do  
  132.     //      {  
  133.     //          RTPPacket *pack;  
  134.     //          RTPSourceData *srcdat;  
  135.   
  136.     //          srcdat = GetCurrentSourceInfo();  
  137.   
  138.     //          while ((pack = GetNextPacket()) != NULL)  
  139.     //          {  
  140.     //              std::cout << "Got packet " << pack->GetExtendedSequenceNumber() << " from SSRC " << srcdat->GetSSRC() << std::endl;  
  141.     //              DeletePacket(pack);  
  142.     //          }  
  143.     //      } while (GotoNextSourceWithData());  
  144.     //  }  
  145.   
  146.     //  EndDataAccess();  
  147.     //}  
  148. }  

server.cpp

[cpp] view plaincopyprint?
  1. #include <iostream>  
  2. #include "RTPSessionUtils.h"  
  3. using namespace jrtplib;  
  4. void main()  
  5. {  
  6.     int status;  
  7.     RTPSessionUtils sess;  
  8.     status = sess.CreateDefault(8888);  
  9.     if(status)  
  10.     {  
  11.         std::cout << "RTP error:" << RTPGetErrorString(status) << std::endl;  
  12.         return;  
  13.     }  
  14.   
  15.     while (1)  
  16.     {  
  17.         std::string buf;  
  18.         std::cout << "Input send data:" ;  
  19.         std::cin >> buf;  
  20.   
  21.         sess.SendPacket((void*)buf.c_str(), buf.length(), 0, false, 0);  
  22.         if(status)  
  23.         {  
  24.             std::cout << "RTP error:" << RTPGetErrorString(status) << std::endl;  
  25.             continue;  
  26.         }  
  27.     }  
  28.   
  29.     system("pause");  
  30. }  

client.cpp

[cpp] view plaincopyprint?
  1. #include <iostream>  
  2. #include "RTPSessionUtils.h"  
  3. using namespace jrtplib;  
  4.   
  5. void main()  
  6. {  
  7.     int status;  
  8.     RTPSessionUtils sess;  
  9.     status = sess.CreateDefault(6666);  
  10.     if(status)  
  11.     {  
  12.         std::cout << "RTP error:" << RTPGetErrorString(status) << std::endl;  
  13.         return;  
  14.     }  
  15.     status = sess.AddDestination("127.0.0.1", 8888);  
  16.     if(status)  
  17.     {  
  18.         std::cout << "RTP error:" << RTPGetErrorString(status) << std::endl;  
  19.         return;  
  20.     }  
  21.   
  22.     while (1)  
  23.     {  
  24.         std::string buf;  
  25.         std::cout << "Input send data:" ;  
  26.         std::cin >> buf;  
  27.   
  28.         sess.SendPacket((void*)buf.c_str(), buf.length(), 0, false, 0);  
  29.         if(status)  
  30.         {  
  31.             std::cout << "RTP error:" << RTPGetErrorString(status) << std::endl;  
  32.             continue;  
  33.         }  
  34.     }  
  35.   
  36.     system("pause");  
  37. }  
0 0