鉴于很多网友找我要ortp的示例代码,因此,今天抽空把相关资料整理了一下,写了一个windows版的ortp示例程序,发布在这里供网友们参考吧。
编译及运行环境:VS2008,windows
编程语言:c/c++,ortp库为c语言封装,我用c++对其进行了进一步封装,如果需要c语言的封装接口,只需要把类中相关函数提取出来即可使用。
ortp库:ortp-0.9.1(由于是以前写的代码,故用的ortp库比较老,但不影响使用和学习,我附件中的工程中已经把ortp-0.9.1库文件添加进去了)
整个测试代码在工程的附件中,大家下载后直接编译后,在Debug目录下打开2个本程序,一个选择Client,一个选择Server,即可看到测试效果。
下面,我的相关代码发布如下(附件中有完整的工程)。
一、ORTP接收端封装类
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #ifndef CORTPCLIENT_H_
- #define CORTPCLIENT_H_
-
- #include <ortp/ortp.h>
- #include <string>
-
-
-
-
-
-
- class COrtpClient
- {
- public:
-
-
-
-
-
- COrtpClient();
- ~COrtpClient();
-
-
-
-
-
-
-
-
- static bool init();
-
-
-
-
-
-
-
-
- static bool deInit();
-
-
-
-
-
-
-
-
-
-
- bool create(const char * localip, int localport );
-
-
-
-
-
-
-
-
-
-
- bool get_recv_data( char *pBuffer, int &len );
-
- private:
-
- RtpSession *m_pSession;
-
- long m_curTimeStamp;
- int m_timeStampInc;
-
- };
-
- #endif // CortpClient_H_
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #include "CortpClient.h"
-
-
- #define PAYLOAD_TYPE_VIDEO 34
-
-
- #define VIDEO_TIME_STAMP_INC 3600
-
-
- #define READ_RECV_PER_TIME 1024
-
- COrtpClient::COrtpClient()
- {
- m_pSession = NULL;
- m_timeStampInc = 0;
- m_curTimeStamp = 0;
- }
-
- COrtpClient::~COrtpClient()
- {
- if (!m_pSession)
- {
- rtp_session_destroy(m_pSession);
- }
- }
-
- bool COrtpClient::init()
- {
- int ret;
- WSADATA wsaData;
-
-
- if ( WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
- {
- return false;
- }
-
- ortp_init();
- ortp_scheduler_init();
-
- return true;
- }
-
- bool COrtpClient::deInit()
- {
- ortp_exit();
-
- if (WSACleanup() == SOCKET_ERROR)
- {
- return false;
- }
-
- return true;
- }
-
- bool COrtpClient::create( const char * localip, int localport )
- {
- if ( m_pSession != NULL)
- {
- return false;
- }
-
-
- m_pSession = rtp_session_new(RTP_SESSION_RECVONLY);
- if ( !m_pSession)
- {
- return false;
- }
-
-
- rtp_session_set_scheduling_mode(m_pSession,1);
- rtp_session_set_blocking_mode(m_pSession,1);
- rtp_session_set_local_addr(m_pSession,localip,localport);
- rtp_session_enable_adaptive_jitter_compensation(m_pSession,1);
- rtp_session_set_jitter_compensation(m_pSession,40);
-
- rtp_session_set_payload_type(m_pSession,PAYLOAD_TYPE_VIDEO);
- m_timeStampInc = VIDEO_TIME_STAMP_INC;
-
- return true;
- }
-
- bool COrtpClient::get_recv_data( char *pBuffer, int &len )
- {
- int recvBytes = 0;
- int totalBytes = 0;
- int have_more = 1;
-
- while(have_more)
- {
- if ( totalBytes+READ_RECV_PER_TIME > len )
- {
-
- return false;
- }
- recvBytes = rtp_session_recv_with_ts(m_pSession,pBuffer+totalBytes,READ_RECV_PER_TIME,m_curTimeStamp,&have_more);
- if (recvBytes <= 0)
- {
- break;
- }
- totalBytes += recvBytes;
- }
-
-
- if (totalBytes == 0)
- {
- return false;
- }
-
-
- len = totalBytes;
-
-
- m_curTimeStamp += m_timeStampInc;
-
- return true;
- }
-
二、ORTP发送端封装类
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #ifndef CORTPSERVER_H_
- #define CORTPSERVER_H_
-
- #include <ortp/ortp.h>
-
-
-
-
-
-
- class COrtpServer
- {
- public:
-
-
-
-
-
- COrtpServer();
-
-
-
-
-
- ~COrtpServer();
-
-
-
-
-
-
-
-
- static bool init();
-
-
-
-
-
-
-
-
- static bool deInit();
-
-
-
-
-
-
-
-
-
-
- bool create(const char * destIP, int destport );
-
-
-
-
-
-
-
-
-
-
- int send_data( unsigned char *buffer, int len );
-
- private:
-
- RtpSession *m_pSession;
-
- long m_curTimeStamp;
- int m_timeStampInc;
-
- char *m_ssrc;
- };
-
- #endif // COrtpServer_H_
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #include "COrtpServer.h"
-
-
- #define PAYLOAD_TYPE_VIDEO 34
-
-
- #define VIDEO_TIME_STAMP_INC 3600
-
- COrtpServer::COrtpServer()
- {
- m_ssrc = NULL;
- m_pSession = NULL;
- m_timeStampInc = 0;
- m_curTimeStamp = 0;
- }
-
- COrtpServer::~COrtpServer()
- {
- if (!m_pSession)
- {
- rtp_session_destroy(m_pSession);
- }
- }
-
- bool COrtpServer::init()
- {
- int ret;
- WSADATA wsaData;
-
-
- if ( WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
- {
- return false;
- }
-
- ortp_init();
- ortp_scheduler_init();
-
- return true;
- }
-
- bool COrtpServer::deInit()
- {
- ortp_exit();
-
- if (WSACleanup() == SOCKET_ERROR)
- {
- return false;
- }
-
- return true;
- }
-
- bool COrtpServer::create( const char * destIP, int destport )
- {
- m_ssrc = getenv("SSRC");
-
- m_pSession = rtp_session_new(RTP_SESSION_SENDONLY);
-
- rtp_session_set_scheduling_mode(m_pSession,1);
- rtp_session_set_blocking_mode(m_pSession,1);
- rtp_session_set_remote_addr(m_pSession,destIP,destport);
-
- if(m_ssrc != NULL)
- {
- rtp_session_set_ssrc(m_pSession,atoi(m_ssrc));
- }
-
- rtp_session_set_payload_type(m_pSession,PAYLOAD_TYPE_VIDEO);
- m_timeStampInc = VIDEO_TIME_STAMP_INC;
-
- return true;
- }
-
- int COrtpServer::send_data( unsigned char *buffer, int len )
- {
- int sendBytes = 0;
-
-
- const char *sendBuffer = (const char*)buffer;
-
- sendBytes = rtp_session_send_with_ts(m_pSession,sendBuffer,len,m_curTimeStamp);
-
- if ( sendBytes > 0)
- {
- m_curTimeStamp += m_timeStampInc;
- }
-
- return sendBytes;
- }
三、测试程序
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #include <iostream>
-
- #include "COrtpClient.h"
- #include "COrtpServer.h"
-
-
- const char * LOCAL_IP_ADDR = "127.0.0.1";
-
-
- const int LOCAL_RTP_PORT = 8000;
-
-
- const int DEST_RTP_PORT = 8000;
-
-
- const char * DEST_IP_ADDR = "127.0.0.1";
-
-
- const int SEND_LEN_PER_TIME = 8*1024;
-
-
- const int RECV_BUFFER_LEN = 10*1024;
-
-
- const int RECV_LEN_PER_TIME = 1024;
-
- bool ortpServer()
- {
- COrtpServer ortpServer;
-
- COrtpServer::init();
-
- if (!ortpServer.create(DEST_IP_ADDR,DEST_RTP_PORT))
- {
- std::cout << "ortpServer.create fail!\n";
- getchar();
- getchar();
- return false;
- }
-
- unsigned char * buffer = new unsigned char[SEND_LEN_PER_TIME];
-
- while (1)
- {
- if ( ortpServer.send_data(buffer,SEND_LEN_PER_TIME) <= 0)
- {
- std::cout << "send fail!\n";
- }
-
- Sleep(100);
- std::cout << "send bytes\n";
- }
-
- delete [] buffer;
-
- COrtpClient::deInit();
-
- return true;
- }
-
- bool ortpClient()
- {
- COrtpClient ortpClient;
-
- COrtpClient::init();
-
- if (!ortpClient.create(LOCAL_IP_ADDR,LOCAL_RTP_PORT))
- {
- std::cout << "ortpClient.create fail!\n";
- getchar();
- getchar();
- return false;
- }
-
- char *buffer = new char[RECV_BUFFER_LEN];
-
- while(1)
- {
- int len = RECV_BUFFER_LEN;
- if (!ortpClient.get_recv_data(buffer,len))
- {
- Sleep(10);
- continue;
- }
-
- std::cout << "successful recv,data len =" << len << std::endl;
- }
-
- COrtpClient::deInit();
-
- delete [] buffer;
-
- return true;
- }
-
- void main()
- {
- std::cout << "enter num,1 ->client, 2->server! \n";
-
- int num;
-
- std::cin >> num;
-
- while(1)
- {
- if (num == 1)
- {
- ortpClient();
- break;
- }
- else if (num == 2)
- {
- ortpServer();
- break;
- }
- else
- {
- std::cout << "please input 1 or 2 !\n";
- }
- }
-
- getchar();
- getchar();
- }
有关ORTP的介绍、RTP的介绍、RTP的负载类型和时间戳的含义等理论性的东西,都可以在我博客中的其他文章中找到,以上就是整个工程的代码,注释不是很多,因为有些地方我也不是特别清楚,比如jitter、scheduling什么的,如果有什么其他疑问欢迎留言或者E-mail来信交流。