RTP实时音视频数据传输,发送端和接收端

来源:互联网 发布:rmvb视频剪辑软件 编辑:程序博客网 时间:2024/05/18 00:51

1.项目前期工作(配置好环境)

点击打开链接

2.发送端文件编写(见下面的send.cpp)

3.接收端文件编写(见下面的receive.cpp)

4.编译文件

(1)发送端

                      g++ -o send send.cpp -I /usr/local/include/jrtplib3/ -ljrtp

(2)接收端

                      g++ -o receive  receive.cpp -I /usr/local/include/jrtplib3/ -ljrtp

附录:

(1)send.cpp

#include "rtpsession.h"#include "rtppacket.h"#include "rtpudpv4transmitter.h"#include "rtpipv4address.h"#include "rtpsessionparams.h"#include "rtperrors.h"#include "rtpmemorymanager.h"#ifndef WIN32#include <netinet/in.h>#include <arpa/inet.h>#else#include <winsock2.h>#endif // WIN32#include <stdlib.h>#include <stdio.h>#include <iostream>#include <string>//// This function checks if there was a RTP error. If so, it displays an error// message and exists.//void checkerror(int rtperr){if (rtperr < 0){std::cout << "ERROR: " << RTPGetErrorString(rtperr) << std::endl;exit(-1);}}//// The main routine//#ifdef RTP_SUPPORT_THREADclass MyMemoryManager : public RTPMemoryManager{public:MyMemoryManager() { mutex.Init();alloccount = 0; freecount = 0; }~MyMemoryManager() { std::cout << "alloc: " << alloccount << " free: " << freecount << std::endl; }void *AllocateBuffer(size_t numbytes, int memtype){mutex.Lock();void *buf = malloc(numbytes);std::cout << "Allocated " << numbytes << " bytes at location " << buf << " (memtype = " << memtype << ")" << std::endl;alloccount++;mutex.Unlock();return buf;}void FreeBuffer(void *p){mutex.Lock();std::cout << "Freeing block " << p << std::endl;freecount++;free(p);mutex.Unlock();}private:int alloccount,freecount;JMutex mutex;};#elseclass MyMemoryManager : public RTPMemoryManager{public:MyMemoryManager() { alloccount = 0; freecount = 0; }~MyMemoryManager() { std::cout << "alloc: " << alloccount << " free: " << freecount << std::endl; }void *AllocateBuffer(size_t numbytes, int memtype){void *buf = malloc(numbytes);std::cout << "Allocated " << numbytes << " bytes at location " << buf << " (memtype = " << memtype << ")" << std::endl;alloccount++;return buf;}void FreeBuffer(void *p){std::cout << "Freeing block " << p << std::endl;freecount++;free(p);}private:int alloccount,freecount;};#endif // RTP_SUPPORT_THREADint main(void){#ifdef WIN32WSADATA dat;WSAStartup(MAKEWORD(2,2),&dat);#endif // WIN32MyMemoryManager mgr;RTPSession sess(&mgr);uint16_t portbase,destport;uint32_t destip;std::string ipstr;int status,i,num;        // First, we'll ask for the necessary informationstd::cout << "Enter local portbase:" << std::endl;std::cin >> portbase;std::cout << std::endl;std::cout << "Enter the destination IP address" << std::endl;std::cin >> ipstr;destip = inet_addr(ipstr.c_str());if (destip == INADDR_NONE){std::cerr << "Bad IP address specified" << std::endl;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// ntohldestip = ntohl(destip);std::cout << "Enter the destination port" << std::endl;std::cin >> destport;std::cout << std::endl;std::cout << "Number of packets you wish to be sent:" << std::endl;std::cin >> num;// Now, we'll create a RTP session, set the destination, send some// packets and poll for incoming data.RTPUDPv4TransmissionParams transparams;RTPSessionParams sessparams;// IMPORTANT: The local timestamp unit MUST be set, otherwise//            RTCP Sender Report info will be calculated wrong// In this case, we'll be sending 10 samples each second, so we'll// put the timestamp unit to (1.0/10.0)sessparams.SetOwnTimestampUnit(1.0/10.0);sessparams.SetAcceptOwnPackets(true);transparams.SetPortbase(portbase);status = sess.Create(sessparams,&transparams);checkerror(status);RTPIPv4Address addr(destip,destport);status = sess.AddDestination(addr);checkerror(status);for (i = 1 ; i <= num ; i++){printf("\nSending packet %d/%d\n",i,num);// send the packetstatus = sess.SendPacket((void *)"1234567890",10,0,false,10);checkerror(status);sess.BeginDataAccess();// check incoming packetsif (sess.GotoFirstSourceWithData()){do{RTPPacket *pack;while ((pack = sess.GetNextPacket()) != NULL){// You can examine the data hereprintf("Got packet !\n");// we don't longer need the packet, so// we'll delete itsess.DeletePacket(pack);}} while (sess.GotoNextSourceWithData());}sess.EndDataAccess();#ifndef RTP_SUPPORT_THREADstatus = sess.Poll();checkerror(status);#endif // RTP_SUPPORT_THREADRTPTime::Wait(RTPTime(1,0));}sess.BYEDestroy(RTPTime(10,0),0,0);#ifdef WIN32WSACleanup();#endif // WIN32return 0;}
(2) receive.cpp

#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>//// This function checks if there was a RTP error. If so, it displays an error// message and exists.//void checkerror(int rtperr){if (rtperr < 0){std::cout << "ERROR: " << RTPGetErrorString(rtperr) << std::endl;exit(-1);}}//// The new class routine//class MyRTPSession : public RTPSession{protected:void OnNewSource(RTPSourceData *dat){if (dat->IsOwnSSRC())return;uint32_t ip;uint16_t port;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;}elsereturn;RTPIPv4Address dest(ip,port);AddDestination(dest);struct in_addr inaddr;inaddr.s_addr = htonl(ip);std::cout << "Adding destination " << std::string(inet_ntoa(inaddr)) << ":" << port << std::endl;}void OnBYEPacket(RTPSourceData *dat){if (dat->IsOwnSSRC())return;uint32_t ip;uint16_t port;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;}elsereturn;RTPIPv4Address dest(ip,port);DeleteDestination(dest);struct in_addr inaddr;inaddr.s_addr = htonl(ip);std::cout << "Deleting destination " << std::string(inet_ntoa(inaddr)) << ":" << port << std::endl;}void OnRemoveSource(RTPSourceData *dat){if (dat->IsOwnSSRC())return;if (dat->ReceivedBYE())return;uint32_t ip;uint16_t port;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;}elsereturn;RTPIPv4Address dest(ip,port);DeleteDestination(dest);struct in_addr inaddr;inaddr.s_addr = htonl(ip);std::cout << "Deleting destination " << std::string(inet_ntoa(inaddr)) << ":" << port << std::endl;}};//// The main routine// int main(void){#ifdef WIN32WSADATA dat;WSAStartup(MAKEWORD(2,2),&dat);#endif // WIN32MyRTPSession sess;uint16_t portbase;std::string ipstr;int status,i,num;        // First, we'll ask for the necessary informationstd::cout << "Enter local portbase:" << std::endl;std::cin >> portbase;std::cout << std::endl;std::cout << std::endl;std::cout << "Number of seconds you wish to wait:" << std::endl;std::cin >> num;// Now, we'll create a RTP session, set the destination// and poll for incoming data.RTPUDPv4TransmissionParams transparams;RTPSessionParams sessparams;// IMPORTANT: The local timestamp unit MUST be set, otherwise//            RTCP Sender Report info will be calculated wrong// In this case, we'll be just use 8000 samples per second.sessparams.SetOwnTimestampUnit(1.0/8000.0);sessparams.SetAcceptOwnPackets(true);transparams.SetPortbase(portbase);status = sess.Create(sessparams,&transparams);checkerror(status);for (i = 1 ; i <= num ; i++){sess.BeginDataAccess();// check incoming packetsif (sess.GotoFirstSourceWithData()){do{RTPPacket *pack;while ((pack = sess.GetNextPacket()) != NULL){// You can examine the data hereprintf("Got packet !\n");// we don't longer need the packet, so// we'll delete itsess.DeletePacket(pack);}} while (sess.GotoNextSourceWithData());}sess.EndDataAccess();#ifndef RTP_SUPPORT_THREADstatus = sess.Poll();checkerror(status);#endif // RTP_SUPPORT_THREADRTPTime::Wait(RTPTime(1,0));}sess.BYEDestroy(RTPTime(10,0),0,0);#ifdef WIN32WSACleanup();#endif // WIN32return 0;}




原创粉丝点击