使用Jrtplib结合opencv2.2传输一张图像的测试

           刚刚编译出jrtplib库来,一切都不会,没接触过流媒体的东西,RTP的协议等等,不懂~~~于是先拿了简单的传输一张图像试试。 图像的部分采用opencv2.2.

           发送端是在lib的example2的基础上添加修改的,接收是在lib的example3的基础上修改的,经测试可以传输图像-----------虽然被RTP中的各种参数搞得很头大,慢慢研究研究吧,最终是要发送H.263格式的。

          发送端:----------rtpheader.h是自己写的,把大部分常用的jrtplib库中的头文件都包含进去了。

#include "rtplib/rtpheader.h"

#include <stdlib.h>
#include <iostream>
#include <core.hpp>
#include <highgui.hpp>

using namespace jrtplib;

#pragma comment(lib, "jrtplib_d.lib")
#pragma comment(lib, "jthread_d.lib")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "opencv_core220d.lib")
#pragma comment(lib, "opencv_highgui220d.lib")

using namespace cv;
using namespace std;

int main(void)
{
#ifdef WIN32
	WSADATA dat;
	WSAStartup(MAKEWORD(2,2),&dat);
#endif // WIN32
		
	RTPSession session;
	
	RTPSessionParams sessionparams;
	sessionparams.SetOwnTimestampUnit(1.0/80.0);
			
	RTPUDPv4TransmissionParams transparams;
	transparams.SetPortbase(8000);
			
	int status = session.Create(sessionparams,&transparams);
	if (status < 0)
	{
		std::cerr << RTPGetErrorString(status) << std::endl;
		exit(-1);
	}
	
	uint8_t localip[]={127,0,0,1};
	RTPIPv4Address addr(localip,2000);
	
	status = session.AddDestination(addr);
	if (status < 0)
	{
		std::cerr << RTPGetErrorString(status) << std::endl;
		exit(-1);
	}
	Mat img;
	img = imread("d:\\picture\\rtp.bmp", 0);
	if (img.empty())
	{
		cout<<"load img failed!"<<endl;
		return -1;
	}
	
	namedWindow("wnd", CV_WINDOW_AUTOSIZE);
	while(waitKey(30) != 27)
		imshow("wnd", img);
	cvDestroyAllWindows();

	cout<<"next....img depth is: "<<img.channels()<<endl;
	cout<<"total size is: "<<img.cols*img.rows*img.channels()<<endl;
	for(int i=0; i<10; ++i)
		cout<<(int)img.data[i]<<",";
	cout<<endl;

	session.SetDefaultPayloadType(96);
	session.SetDefaultMark(false);
//	session.SetDefaultTimestampIncrement(160);
	session.SetMaximumPacketSize(20000);
	session.SetDefaultTimestampIncrement(img.cols*img.rows*img.channels());
	
	uint8_t silencebuffer[160];
	for (int i = 0 ; i < 160 ; i++)
		silencebuffer[i] = i;

	RTPTime delay(1.0);
	RTPTime starttime = RTPTime::CurrentTime();
	int num = 0;

	bool done = false;
	while (!done)
	{
		//status = session.SendPacket(silencebuffer,160);
		status = session.SendPacket(img.data, img.cols*img.rows*img.channels());
		if (status < 0)
		{
			std::cerr << RTPGetErrorString(status) << std::endl;
			exit(-1);
		}
		cout<<"send img times :"<<++num<<endl;
/*		
		session.BeginDataAccess();
		if (session.GotoFirstSource())
		{
			do
			{
				RTPPacket *packet;

				while ((packet = session.GetNextPacket()) != 0)
				{
					std::cout << "Got packet with " 
					          << "extended sequence number " 
					          << packet->GetExtendedSequenceNumber() 
					          << " from SSRC " << packet->GetSSRC() 
					          << std::endl;

					session.DeletePacket(packet);
				}
			} while (session.GotoNextSource());
		}
		session.EndDataAccess();
*/			
		RTPTime::Wait(delay);
		
		RTPTime t = RTPTime::CurrentTime();
		t -= starttime;
		if (t > RTPTime(10.0))
			done = true;
	}
	
	delay = RTPTime(10.0);
	session.BYEDestroy(delay,"Time's up",9);
	
	system("pause");

#ifdef WIN32
	WSACleanup();
#endif // WIN32
	return 0;
}

      接收端:将接收的数据保存为图像-------直接显示时发现有问题,卡住了。
#include "rtplib/rtpheader.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>
#include <core.hpp>
#include <highgui.hpp>

#pragma comment(lib, "opencv_core220d.lib")
#pragma comment(lib, "opencv_highgui220d.lib")

using namespace cv;
using namespace std;
using namespace jrtplib;

//
// 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;
		}
		else
			return;

		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;
		}
		else
			return;

		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;
		}
		else
			return;

		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 WIN32
	WSADATA dat;
	WSAStartup(MAKEWORD(2,2),&dat);
#endif // WIN32

	RTPSession sess;
	uint16_t portbase;
	std::string ipstr;
	int status,i,num;

	uint8_t *pBuffer;
	uint8_t *pPayloadData;

	uchar *imgbuf = NULL;
	uchar *packBuffer = NULL;

	// First, we'll ask for the necessary information

	std::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/80.0);		

	sessparams.SetAcceptOwnPackets(true);
	transparams.SetPortbase(portbase);
	sess.SetMaximumPacketSize(20000);

	status = sess.Create(sessparams,&transparams);	
	checkerror(status);
	
	int packagenum = 0;
//	namedWindow("wnd", CV_WINDOW_AUTOSIZE);

	for (i = 1 ; i <= num ; i++)
	{
		sess.BeginDataAccess();

		// check incoming packets
		if (sess.GotoFirstSourceWithData())
		{
			cout<<"circle :"<<i<<endl;
			do
			{
				RTPPacket *pack;
				while ((pack = sess.GetNextPacket()) != NULL)
				{
					// You can examine the data here
					printf("Got packet num: %d!\n", packagenum++);
					
					size_t datalen = pack->GetPayloadLength();
					cout<<"payload size :"<<datalen<<endl;
/*
					pBuffer = new uint8_t[datalen];
					pPayloadData = (uint8_t *)pack->GetPayloadData();
					memcpy(pBuffer, pPayloadData, datalen);
					std::cout<<"packet payload data is:"<<std::endl;

					for (int i=0; i<10; ++i)
					{
						std::cout<<(int)pBuffer[i]<<",";
					}
					std::cout<<std::endl;
					
					delete []pBuffer;
					pBuffer = NULL;
*/					
					packBuffer = (uchar *)pack->GetPayloadData();
					imgbuf = new uchar[datalen];
					memcpy(imgbuf, packBuffer, datalen);

					Mat img(107, 105, CV_8UC1, imgbuf);
					char name[20];
					sprintf_s(name, 20, "img%d.bmp", packagenum);

					if(!img.empty())
					{	//imshow("wnd", img);
						imwrite(string(name), img);
					}
					else
						cout<<"received no data"<<endl;
					delete [] imgbuf;
					imgbuf = NULL;
					
					// we don't longer need the packet, so
					// we'll delete it
					sess.DeletePacket(pack);
				}
			} 
			while (sess.GotoNextSourceWithData());
		}

		sess.EndDataAccess();

#ifndef RTP_SUPPORT_THREAD
		status = sess.Poll();
		checkerror(status);
#endif // RTP_SUPPORT_THREAD

		RTPTime::Wait(RTPTime(1,0));
	}

	sess.BYEDestroy(RTPTime(10,0),0,0);

	system("pause");

#ifdef WIN32
	WSACleanup();
#endif // WIN32
	return 0;
}


评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值