jrtplib使用注意事项
一、說明
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的編譯安裝。這個非常easy,網上非常多地方都有解說。
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 <netinet/in.h> #include <arpa/inet.h> #else #include <winsock2.h> #endif // WIN32 #include "rtpsourcedata.h" #include <stdlib.h> #include <stdio.h> #include <iostream> #include <string>//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 WIN32WSADATA dat;WSAStartup(MAKEWORD(2,2),&dat); #endif // WIN32}RTPSessionUtils::~RTPSessionUtils(){ #ifdef WIN32WSACleanup(); #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 " << IPToString(ip) << ":" << port << std::endl;}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 " << IPToString(ip) << ":" << port << std::endl;}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 " << IPToString(ip) << ":" << port << std::endl;}//僅僅要有rtp包就會觸發void RTPSessionUtils::OnRTPPacket(RTPPacket *pack,const RTPTime &receivetime,const RTPAddress *senderaddress){std::cout << "OnRTPPacket: data:" << pack->GetPayloadData() << std::endl;}//收到rtcp包觸發void RTPSessionUtils::OnRTCPCompoundPacket(RTCPCompoundPacket *pack,const RTPTime &receivetime,const RTPAddress *senderaddress){std::cout << "OnRTCPCompoundPacket: data:" << pack->GetCompoundPacketData() << std::endl;}//隔段時間就會觸發,也能夠用于收包回調函數//void RTPSessionUtils::OnPollThreadStep()//{// BeginDataAccess();// // check incoming packets// if (GotoFirstSourceWithData())// {// do// {// RTPPacket *pack;// RTPSourceData *srcdat;// srcdat = GetCurrentSourceInfo();// while ((pack = GetNextPacket()) != NULL)// {// std::cout << "Got packet " << pack->GetExtendedSequenceNumber() << " from SSRC " << srcdat->GetSSRC() << std::endl;// DeletePacket(pack);// }// } while (GotoNextSourceWithData());// }// EndDataAccess();//} }
server.cpp
#include <iostream> #include "RTPSessionUtils.h" using namespace jrtplib; void main() {int status;RTPSessionUtils sess;status = sess.CreateDefault(8888);if(status){std::cout << "RTP error:" << RTPGetErrorString(status) << std::endl;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) << std::endl;continue;}}system("pause"); }
client.cpp
#include <iostream> #include "RTPSessionUtils.h" using namespace jrtplib;void main() {int status;RTPSessionUtils sess;status = sess.CreateDefault(6666);if(status){std::cout << "RTP error:" << RTPGetErrorString(status) << std::endl;return;}status = sess.AddDestination("127.0.0.1", 8888);if(status){std::cout << "RTP error:" << RTPGetErrorString(status) << std::endl;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) << std::endl;continue;}}system("pause"); }轉載于:https://www.cnblogs.com/hrhguanli/p/4565530.html
總結
以上是生活随笔為你收集整理的jrtplib使用注意事项的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Qt 车牌识别 (EasyPR)
- 下一篇: Flutter 添加 armeabi-v