ubuntu下jthread 和jrtplib的安装
http://blog.csdn.net/chenyu123123/article/details/8743362
一、简述
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
- #include "rtpsession.h"
- #include "rtppacket.h"
- #include "rtpudpv4transmitter.h"
- #include "rtpipv4address.h"
- #include "rtpsessionparams.h"
- #include "rtperrors.h"
- #ifndef WIN32
- #include
- #include
- #else
- #include
- #endif // WIN32
- #include "rtpsourcedata.h"
- #include
- #include
- #include
- #include
- //jrtplib应用需链接的lib
- #pragma comment(lib,"ws2_32.lib")
- #pragma comment(lib, "jrtplib_d.lib")
- #pragma comment(lib,"jthread_d.lib")
- namespace jrtplib
- {
- class RTPSessionUtils : public RTPSession
- {
- typedef RTPSession base_type;
- public:
- RTPSessionUtils();
- ~RTPSessionUtils();
- int AddDestination(const std::string& ip, uint16_t port);
- int DeleteDestination(const std::string& ip, uint16_t port);
- int CreateDefault(uint16_t port);
- protected:
- void OnNewSource(RTPSourceData *dat);
- void OnBYEPacket(RTPSourceData *dat);
- void OnRemoveSource(RTPSourceData *dat);
- void OnRTPPacket(RTPPacket *pack,const RTPTime &receivetime,
- const RTPAddress *senderaddress);
- void OnRTCPCompoundPacket(RTCPCompoundPacket *pack,const RTPTime &receivetime,
- const RTPAddress *senderaddress);
- void OnPollThreadStep();
- private:
- int GetAddrFromSource(RTPSourceData *dat, uint32_t& ip, uint16_t& port);
- };
- }
- //整形的ip转成字符串ip
- static std::string IPToString(const unsigned int iIP)
- {
- struct in_addr inaddr;
- inaddr.s_addr = htonl(iIP);
- return std::string(inet_ntoa(inaddr));
- }
- //字符串ip转成整形ip
- static unsigned int IPToInt(const std::string& sIP)
- {
- return inet_addr(sIP.c_str());
- }
RTPSessionUtils.cpp
- #include "RTPSessionUtils.h"
- namespace jrtplib{
- RTPSessionUtils::RTPSessionUtils()
- {
- #ifdef WIN32
- WSADATA dat;
- WSAStartup(MAKEWORD(2,2),&dat);
- #endif // WIN32
- }
- RTPSessionUtils::~RTPSessionUtils()
- {
- #ifdef WIN32
- WSACleanup();
- #endif // WIN32
- }
- int RTPSessionUtils::CreateDefault(uint16_t port)
- {
- RTPUDPv4TransmissionParams transparams;
- RTPSessionParams sessparams;
- sessparams.SetOwnTimestampUnit(1.0/10.0);//必须设置
- transparams.SetPortbase(port);//port必须是偶数
- return base_type::Create(sessparams, &transparams);
- base_type::SetDefaultPayloadType(0);
- base_type::SetDefaultTimestampIncrement(0);
- base_type::SetDefaultMark(false);
- }
- int RTPSessionUtils::AddDestination(const std::string& ip, uint16_t port)
- {
- return base_type::AddDestination(RTPIPv4Address(ntohl(inet_addr(ip.c_str())), port));
- }
- int RTPSessionUtils::DeleteDestination(const std::string& ip, uint16_t port)
- {
- return base_type::DeleteDestination(RTPIPv4Address(ntohl(inet_addr(ip.c_str())), port));
- }
- int RTPSessionUtils::GetAddrFromSource(RTPSourceData *dat, uint32_t& ip, uint16_t& port)
- {
- if (dat->IsOwnSSRC())
- return -1;
- if (dat->GetRTPDataAddress() != 0)
- {
- const RTPIPv4Address *addr = (const RTPIPv4Address *)(dat->GetRTPDataAddress());
- ip = addr->GetIP();
- port = addr->GetPort();
- }
- else if (dat->GetRTCPDataAddress() != 0)
- {
- const RTPIPv4Address *addr = (const RTPIPv4Address *)(dat->GetRTCPDataAddress());
- ip = addr->GetIP();
- port = addr->GetPort()-1;
- }
- return 0;
- }
- void RTPSessionUtils::OnNewSource(RTPSourceData *dat)
- {
- uint32_t ip;
- uint16_t port;
- if (GetAddrFromSource(dat, ip, port))
- return;
- RTPIPv4Address dest(ip,port);
- base_type::AddDestination(dest);
- std::cout <"OnNewSource Adding destination " <":" <
- }
- void RTPSessionUtils::OnRemoveSource(RTPSourceData *dat)
- {
- if (dat->ReceivedBYE())
- return;
- uint32_t ip;
- uint16_t port;
- if (GetAddrFromSource(dat, ip, port))
- return;
- RTPIPv4Address dest(ip,port);
- base_type::DeleteDestination(dest);
- std::cout <"OnRemoveSource Deleting destination " <":" <
- }
- void RTPSessionUtils::OnBYEPacket(RTPSourceData *dat)
- {
- uint32_t ip;
- uint16_t port;
- if (GetAddrFromSource(dat, ip, port))
- return;
- RTPIPv4Address dest(ip,port);
- base_type::DeleteDestination(dest);
- std::cout <"OnBYEPacket Deleting destination " <":" <
- }
- //只要有rtp包就会触发
- void RTPSessionUtils::OnRTPPacket(RTPPacket *pack,const RTPTime &receivetime,
- const RTPAddress *senderaddress)
- {
- std::cout <"OnRTPPacket: data:"
- }
- //收到rtcp包触发
- void RTPSessionUtils::OnRTCPCompoundPacket(RTCPCompoundPacket *pack,const RTPTime &receivetime,
- const RTPAddress *senderaddress)
- {
- std::cout <"OnRTCPCompoundPacket: data:"
- }
- //隔段时间就会触发,也可以用于收包回调函数
- //void RTPSessionUtils::OnPollThreadStep()
- //{
- // BeginDataAccess();
- // // check incoming packets
- // if (GotoFirstSourceWithData())
- // {
- // do
- // {
- // RTPPacket *pack;
- // RTPSourceData *srcdat;
- // srcdat = GetCurrentSourceInfo();
- // while ((pack = GetNextPacket()) != NULL)
- // {
- // std::cout << "Got packet "
- // DeletePacket(pack);
- // }
- // } while (GotoNextSourceWithData());
- // }
- // EndDataAccess();
- //}
- }
server.cpp
- #include
- #include "RTPSessionUtils.h"
- using namespace jrtplib;
- void main()
- {
- int status;
- RTPSessionUtils sess;
- status = sess.CreateDefault(8888);
- if(status)
- {
- std::cout <"RTP error:" << RTPGetErrorString(status) <
- return;
- }
- while (1)
- {
- std::string buf;
- std::cout <"Input send data:" ;
- std::cin >> buf;
- sess.SendPacket((void*)buf.c_str(), buf.length(), 0, false, 0);
- if(status)
- {
- std::cout <"RTP error:" << RTPGetErrorString(status) <
- continue;
- }
- }
- system("pause");
- }
client.cpp
- #include
- #include "RTPSessionUtils.h"
- using namespace jrtplib;
- void main()
- {
- int status;
- RTPSessionUtils sess;
- status = sess.CreateDefault(6666);
- if(status)
- {
- std::cout <"RTP error:" << RTPGetErrorString(status) <
- return;
- }
- status = sess.AddDestination("127.0.0.1", 8888);
- if(status)
- {
- std::cout <"RTP error:" << RTPGetErrorString(status) <
- return;
- }
- while (1)
- {
- std::string buf;
- std::cout <"Input send data:" ;
- std::cin >> buf;
- sess.SendPacket((void*)buf.c_str(), buf.length(), 0, false, 0);
- if(status)
- {
- std::cout <"RTP error:" << RTPGetErrorString(status) <
- continue;
- }
- }
- system("pause");
- }