RTP传输H264码流,使用JRTP接收不到数据

BlueCheney1990 2014-12-26 06:07:59
最近在做H264视频传输的项目,使用了JRTP。发送端先使用x264编码YUV文件,然后使用JRTP发出数据。使用VLC-0.9.6能正常播放,SDP文件如下:
m=video 1234 RTP/AVP 96
a=rtpmap:96 H264
a=framerate:25
c=IN IP4 114.214.166.190

但是使用JRTP库参考网上例子自己写了一个接收端程序却收不到数据。接收端程序如下:
#include "./jrtp/rtpsession.h"
#include "./jrtp/rtppacket.h"
#include "./jrtp/rtpudpv4transmitter.h"
#include "./jrtp/rtpipv4address.h"
#include "./jrtp/rtpsessionparams.h"
#include "./jrtp/rtperrors.h"
#include "./jrtp/rtpmemorymanager.h"
#include "./jrtp/rtpsourcedata.h"

#include "./jthread/jthread.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>

using namespace jrtplib;

#ifdef WIN32
#pragma comment(lib, "jrtplib_d.lib")
#pragma comment(lib, "jthread_d.lib")
#pragma comment(lib, "ws2_32.lib")
#endif

class MyRTPSession : public RTPSession
{
protected:
void OnPollThreadStep();
void ProcessRTPPacket(const RTPSourceData &srcdat, const RTPPacket &packet);
};

void checkerror(int rtperr)
{
if (rtperr < 0)
{
std::cout << "ERROR: " << RTPGetErrorString(rtperr) << std::endl;
exit(-1);
}
}

void MyRTPSession::OnPollThreadStep() //处理RTCP数据包
{
bool done = false;
int total = 0;

RTPTime delay(0.020);
RTPTime starttime = RTPTime::CurrentTime();

while (!done)
{
#ifndef RTP_SUPPORT_THREAD
int status = Poll();
checkerror(status);
#endif

BeginDataAccess();

if (GotoFirstSourceWithData())
{
do
{
RTPSourceData *srcdat;

srcdat = GetCurrentSourceInfo();
if (srcdat->SR_HasInfo())//打印SR信息
{
std::cout << "SR Info:" << std::endl;
std::cout << "GetSSRC :%u " << srcdat->GetSSRC() << std::endl;
std::cout << "number :%d " << total++ << std::endl;
std::cout << "SR_GetByteCount :%u " << srcdat->SR_GetByteCount() << std::endl;
std::cout << "SR_GetPacketCount :%u " << srcdat->SR_GetPacketCount() << std::endl;
}
srcdat->FlushPackets();
} while (GotoNextSource());
}

EndDataAccess();

RTPTime::Wait(delay);

RTPTime t = RTPTime::CurrentTime();
t -= starttime;
if (t > RTPTime(60.0))
done = true;
}
}

void MyRTPSession::ProcessRTPPacket(const RTPSourceData &srcdat, const RTPPacket &rtppack)
{
// You can inspect the packet and the source's info here
if (srcdat.SR_HasInfo())
{
std::cout << "SR Info:" << std::endl;
std::cout << "GetSSRC :%u " << srcdat.GetSSRC() << std::endl;
std::cout << "SR_GetByteCount :%u " << srcdat.SR_GetByteCount() << std::endl;
std::cout << "SR_GetPacketCount :%u " << srcdat.SR_GetPacketCount() << std::endl;
}
}

int main(void)
{
#ifdef WIN32
WSADATA dat;
WSAStartup(MAKEWORD(2, 2), &dat);
#endif // WIN32

MyRTPSession sess;
uint16_t portbase, port;
std::string ipstr;
int status;

portbase = 8000;
ipstr = "127.0.0.1";
//std::cout << "Enter local portbase:" << std::endl;
//std::cin >> portbase;
//std::cout << std::endl;

RTPUDPv4TransmissionParams transparams;
RTPSessionParams sessparams;
sessparams.SetOwnTimestampUnit(1.0 / 90000.0);

transparams.SetPortbase(portbase);
status = sess.Create(sessparams, &transparams);
checkerror(status);
uint32_t destip = inet_addr(ipstr.c_str());
if (destip == INADDR_NONE){
std::cerr << "Bad IP address specified" << std::endl;
return -1;
}
destip = ntohl(destip);
port = 1234;
RTPIPv4Address addr(destip, port);

status = sess.AddDestination(addr);
checkerror(status);

sessparams.SetUsePollThread(true);

std::cout << "Prepare for data receive..." << std::endl;

while (1) //处理RTP数据包
{
bool done = false;
int total = 0;

RTPTime delay(0.020);
RTPTime starttime = RTPTime::CurrentTime();

while (!done)
{
#ifndef RTP_SUPPORT_THREAD
int status = Poll();
checkerror(status);
#endif

sess.BeginDataAccess();

if (sess.GotoFirstSourceWithData())
{
do
{
RTPPacket *pack;

while ((pack = sess.GetNextPacket()) != NULL)
{
std::cout << "Seq_num :" << pack->GetSequenceNumber() << std::endl;
std::cout << "CSRC : " << pack->GetCSRCCount() << std::endl;
std::cout << "SSRC : " << pack->GetSSRC() << std::endl;
std::cout << "Timestamp : " << pack->GetTimestamp() << std::endl;
std::cout << "Packet Length : " << pack->GetPacketLength() << std::endl;
sess.DeletePacket(pack);
}
} while (sess.GotoNextSourceWithData());
}

sess.EndDataAccess();

RTPTime::Wait(delay);

RTPTime t = RTPTime::CurrentTime();
t -= starttime;
if (t > RTPTime(60.0))
done = true;
}
}

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

#ifdef WIN32
WSACleanup();
#endif // WIN32

return 0;
}

发送端设置目标地址为127.0.0.1,目标端口为1234,portbase为6000。不知道接收端程序问题出在哪儿?还有一个始终不明白的是,portbase和目标端口有什么区别?为何要设置portbase?
谢谢各位大神的回复!
...全文
613 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
张希 2015-11-12
  • 打赏
  • 举报
回复
portbase是发送端的端口号 destbase是接收端的端口号
BlueCheney1990 2014-12-27
  • 打赏
  • 举报
回复
已经能正确收到rtp包了。客户端和服务器都重载了OnPollThreadStep函数,但是还是不能收到rtcp数据包,不知道问题出在哪儿?
BlueCheney1990 2014-12-26
  • 打赏
  • 举报
回复
找到问题所在了,需要将客户端的portbase和port同时设置为1234.
BlueCheney1990 2014-12-26
  • 打赏
  • 举报
回复
还有一个问题是,接收端和发送端的portbase必须设置为一样的吗?我试过设置为一样的还是不能接收。
RTPTime::Wait(delay);
 
            RTPTime t = RTPTime::CurrentTime();
            t -= starttime;
            if (t > RTPTime(60.0))
                done = true;
这几个语句位置错了,应该在里层的while循环之外,是为了终止最外层while死循环的。

2,542

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧