您的位置:首页 > 运维架构

在VS2005下使用Jrtplib传送H263视频(using OpenCV2.2)

2013-02-24 23:23 507 查看


在VS2005下使用Jrtplib传送H263视频(using OpenCV2.2)

分类: 流媒体传输 opencv2011-08-05
19:23 807人阅读 评论(9) 收藏 举报

终于捣鼓出点东西了!高兴啊~~~哈哈哈哈,首先感谢网络上的资源的帮助。

1、RFC3550,3551,2190--ENU,http://www.faqs.org/rfcs/rfc3551.html

2、CodeProject上的VideoNet:http://www.codeproject.com/KB/IP/videonet.aspx

3、RFC3550--CHS,http://www.rosoo.net/a/201001/8356.html

4、CSDN以及Rosoo上的关于时间戳的讲解;

CSDN: /article/10385632.html

Rosoo:http://www.rosoo.net/a/201102/10965.html

5、关于RTP的协议分析:/article/2813510.html

6、关于H.263介绍:/article/7945697.html

7、百度百科的RTP/RTCP的词条介绍:http://baike.baidu.com/view/1149098.html

下面是程序的main源文件,需要的配置是VS2005+opencv2.2+jrtplib+h.263的编解码,所有的库文件等在压缩包中都有,整个工程的下载:http://download.csdn.net/source/3497956

main源码如下:是在前面几篇文章的基础上修改整合而成,仅用作测试

[cpp] view
plaincopyprint?

#include "header_rtph263.h"

using namespace jrtplib;

#ifdef SERVER

#undef SERVER

#endif

#define SERVER //if defined than as a sender, else as a receiver

#ifdef SERVER

#define PORT_BASE 8000

#define DEST_PORT 2000

#else

#define PORT_BASE 2000

#define DEST_PORT 3000

#endif

//#define CAMERA //if defined open default camera by opencv, else read from avi files

int ByteCount = 0;

unsigned char cdata[20000];

int cbuffer_size = 20000;

unsigned char rgbdata[400000];

int buffersize = 400000;

//编码回调

void OwnWriteFunction(int byte)

{

if(ByteCount<cbuffer_size)

{

cdata[ByteCount]=(unsigned char)byte;

++ByteCount;

}

}

void checkerror(int rtperr)

{

if (rtperr < 0)

{

std::cout << "ERROR: " << RTPGetErrorString(rtperr) << std::endl;

exit(-1);

}

}

int main(int argc, char **argv)

{

//opencv var

Mat frame;

Mat temp[3];

VideoCapture capture;

int frameCount = 0;

//h263 ----------encoder/decoder init

uchar *readData = NULL;

uchar *imgBuffer = NULL;

unsigned int yuv[WIDTH*HEIGHT*3/2];

CParam h263Param;

Bits bits;

InitLookupTable();

h263Param.format = PARAM_FORM;

InitH263Encoder(&h263Param);

WriteByteFunction = OwnWriteFunction;

InitH263Decoder();

//rtp---initialze and creation

WSADATA dat;

WSAStartup(MAKEWORD(2,2), &dat);

const size_t MaxPackSize = 20000;

RTPSession session;

RTPSessionParams sessionparams;

sessionparams.SetOwnTimestampUnit(1.0/90000.0); //for video ---see RFC2190

RTPUDPv4TransmissionParams transparams;

transparams.SetPortbase(PORT_BASE);

int status = session.Create(sessionparams,&transparams);

checkerror(status);

uint8_t localip[]={127, 0, 0, 1};

RTPIPv4Address addr(localip, DEST_PORT);

status = session.AddDestination(addr);

checkerror(status);

session.SetDefaultPayloadType(34); //PT for H.263----see RFC2190

session.SetDefaultMark(true); //true or false ?? both ok for my test

session.SetDefaultTimestampIncrement(3600); // =90000/25

session.SetMaximumPacketSize(MaxPackSize);

#ifdef SERVER

#ifdef CAMERA

capture.open(0);

#else

capture.open("d:\\video\\petsc1.avi");

#endif

if (!capture.isOpened())

{

cout<<"open video/camera failed!"<<endl;

return -1;

}

capture>>frame;

if (frame.empty())

{

cout<<"grab frame failed! exit...."<<endl;

return -1;

}

namedWindow("raw", CV_WINDOW_AUTOSIZE);

while (waitKey(40) != 27) //25 fps

{

capture>>frame;

if (frame.empty())

{

cout<<"grab frame failed! exit...."<<endl;

return -1;

}

++frameCount;

resize(frame, temp[0], cv::Size(WIDTH, HEIGHT)); //resize to CIF

imshow("raw", temp[0]);

////---------------------------compress image frames-------------------------//

ConvertRGB2YUV(WIDTH, HEIGHT, temp[0].data, yuv);

ByteCount = 0;

h263Param.format = PARAM_FORM;

h263Param.inter = CPARAM_INTRA;

h263Param.Q_intra = 8;

h263Param.data = yuv;

CompressFrame(&h263Param, &bits);

cout<<"compressed byte count is: "<<ByteCount<<endl;

///-------------------------------------------------------------------------//

status = session.SendPacket(cdata, ByteCount);

checkerror(status);

}

#else

namedWindow("got", CV_WINDOW_AUTOSIZE);

int packetNum = 0;

while(waitKey(40) != 27) //25fps

{

session.BeginDataAccess();

if (session.GotoFirstSourceWithData())

{

do

{

RTPPacket *packet;

while( (packet = session.GetNextPacket()) != NULL)

{

cout<<"packet count: "<<++packetNum<<endl;

size_t dataLen = packet->GetPayloadLength();

cout<<"payload length: "<<dataLen<<endl;

readData = packet->GetPayloadData();

imgBuffer = new uchar[dataLen];

memcpy(imgBuffer, readData, dataLen);

///----------------------------decompress--------------------------//

DecompressFrame(imgBuffer, dataLen, rgbdata, buffersize);

///----------------------------------------------------------------//

Mat GotImg(HEIGHT, WIDTH, CV_8UC3, rgbdata);

if(GotImg.empty())

{

cout<<"got image has no data, exiting...."<<endl;

return -1;

}

imshow("got", GotImg);

//release buffers and packet

delete []imgBuffer;

imgBuffer = NULL;

session.DeletePacket(packet);

}

} while (session.GotoNextSourceWithData());

}

session.EndDataAccess();

}

#endif

///////////////////////////////////////////////////////////////////

//release resources

cvDestroyAllWindows();

ExitH263Decoder();

ExitH263Encoder(&h263Param);

RTPTime delay(5.0);

session.BYEDestroy(delay, "trans over", 10);

WSACleanup();

return 0;

}

经测试在本机收发正常,在实验室的两台机子上也成功收发。

需要注意的是,整个程序由宏#define SERVER来控制是作为接受还是发送,定义了SERVER则程序作为发送方,否则作为接受方。如果是发送avi文件的话,可能需要转换一下格式,有些avi直接使用opencv打不开。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: