首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 媒体动画 > 多媒体 >

【流媒体新手】:怎么使用jrtplib传输H.264的视频流

2012-03-13 
【流媒体新手】:如何使用jrtplib传输H.264的视频流?刚下了一个老版本的jrtplib-3.5.1和jthread-1.2.0,用VC++

【流媒体新手】:如何使用jrtplib传输H.264的视频流?
刚下了一个老版本的jrtplib-3.5.1和jthread-1.2.0,用VC++ 6.0均编译通过,并且有编译过jrtplib中带的examples.可以看到用example中的程序发送简单的rtp数据包和接收rtp数据包的大概流程,但我如果要用jrtplib来传输H.264的视频流,该如何做呢? 

这一两天在看rfc3550和rfc3984,看得一头雾水.. 还是不太明白我该从哪里入手? 不知道哪位朋友能不能提供几个用jrtplib封装H.264视频流进行传输的例子? 小弟将不胜感激啊!

先拜谢了! thanks~~

[解决办法]
路过,帮顶。。。
[解决办法]
帮顶
[解决办法]

/^\/^\
_|__| O|
\/ /~ \_/ \
\____|__________/ \
\_______ \
`\ \ \
| | \
/ / \
/ / \\
/ / \ \
/ / \ \
/ / _----_ \ \
/ / _-~ ~-_ | |
( ( _-~ _--_ ~-_ _/ |
\ ~-____-~ _-~ ~-_ ~-_-~ /
~-_ _-~ ~-_ _-~
~--______-~ ~-___-~
[解决办法]
楼主这个问题给的分太少老~~ 起码给500分才够~~

可以通过生成SDP文件给播放器在指定端口接收数据播放,如果你不用动态调整编码器什么的就不用考虑另外发送RTCP.
而且RTCP必须自己实现RTSP服务结合起来用,没有实现RTSP服务,就谈不上实现RTCP.

具体H264字节流拆包和RTP封包方法如下:

UINT MediaStreamH264::TransportData(PBYTE pData, UINT dataSize, int pts)
{
PBYTE p_buffer = pData;
inti_buffer = dataSize;

UINT writeSize = 0;

while( i_buffer > 4 && ( p_buffer[0] != 0 || p_buffer[1] != 0 || p_buffer[2] != 1 ) )
{
i_buffer--;
p_buffer++;
}

/* Split nal units */
while( i_buffer > 4 )
{
int i_offset;
int i_size = i_buffer;
int i_skip = i_buffer;

/* search nal end */
for( i_offset = 4; i_offset+2 < i_buffer ; i_offset++)
{
if( p_buffer[i_offset] == 0 && p_buffer[i_offset+1] == 0 && p_buffer[i_offset+2] == 1 )
{
/* we found another startcode */
i_size = i_offset - ( p_buffer[i_offset-1] == 0 ? 1 : 0);
i_skip = i_offset;
break;

}
/* TODO add STAP-A to remove a lot of overhead with small slice/sei/... */
UINT iWrite = TransportH264Nal(p_buffer, i_size, pts, (i_size >= i_buffer) );
if (iWrite > 0 )
writeSize += iWrite;

i_buffer -= i_skip;
p_buffer += i_skip;
}
return writeSize;
}

UINT MediaStreamH264::TransportH264Nal(const PBYTE pNal, UINT nalSize, INT32 pts, BOOL isLast)
{
ATLock atlock(&m_tlockRun);

if (m_bRun == FALSE)
return 0;

if( nalSize < 5 )
return 0;

UINTmtu = m_nMTU;

const int i_max = mtu - RTP_HEADER_SIZE; /* payload max in one packet */
int i_nal_hdr;
int i_nal_type;

i_nal_hdr = pNal[3];
i_nal_type = i_nal_hdr&0x1f;

string sps;
string pps;

if( i_nal_type == 7 || i_nal_type == 8 )
{
/* XXX Why do you want to remove them ? It will break streaming with 
* SPS/PPS change (broadcast) ? */
return 0;
}

/* Skip start code */
PBYTE p_data = pNal;
inti_data = nalSize;

p_data += 3;
i_data -= 3;

int writeSize = 0;

if( i_data <= i_max )
{
/* Single NAL unit packet */


//writeSize = m_pRtpTransport->SetRtpData(p_data, i_data, pts, isLast);
writeSize = m_pRtpTransport->Write(p_data, i_data, m_nRtpPayloadType, pts, 0, isLast);
if (writeSize <= 0)
return 0;
return writeSize;
}
else
{
/* FU-A Fragmentation Unit without interleaving */
const int i_count = ( i_data-1 + i_max-2 - 1 ) / (i_max-2);
int i;

p_data++;
i_data--;

for( i = 0; i < i_count; i++ )
{
const int i_payload = (i_data < (i_max-2)) ? i_data : (i_max-2);
const int nalSize = 2 + i_payload;

m_Packet.ExtendBuffer(nalSize);

/* FU indicator */
m_Packet.m_pData[0] = 0x00 | (i_nal_hdr & 0x60) | 28;
/* FU header */
m_Packet.m_pData[1] = ( i == 0 ? 0x80 : 0x00 ) | ( (i == i_count-1) ? 0x40 : 0x00 ) | i_nal_type;

/* FU payload */
memcpy( &m_Packet.m_pData[2], p_data, i_payload );

m_Packet.m_DataSize = nalSize;

//int iWrite = m_pRtpTransport->SetRtpData(m_Packet.m_pData, m_Packet.m_DataSize, pts, isLast && (i == i_count-1));
int iWrite = m_pRtpTransport->Write(m_Packet.m_pData, m_Packet.m_DataSize, m_nRtpPayloadType, pts, 0, isLast && (i == i_count-1));
if (iWrite > 0)
writeSize += iWrite;

i_data -= i_payload;
p_data += i_payload;
}
}
return writeSize;
}

[解决办法]
俺也只编译过JRTP的exmaple
你要是做直接看ffplay的源代码好了
好象最新的例子也支持RTSP/RTP了,
[解决办法]
都跟你说了,如果你没有实现RTSP服务,就没必要考虑RTCP,不考虑RTCP,干嘛还用jrtplib?
用jrtplib就是图用它封装的RTCP方便.
如果不图RTCP,还不如用其他的RTP库来发送数据来的好用方便.

你那个问题是bind失败.看看设置的bind地址是多少?
组播确实和路由支持有关系.但是跟bind没关系.先把bind失败问题解决吧.
[解决办法]
顶下
[解决办法]


JIEFEN
[解决办法]
可能是你的IP地址设置错误,检查一下。
[解决办法]
顶下!!
[解决办法]
jrtplib没做分包,需要自己实现。
可参考opal下面的plugin,video\h264相关代码,极简单。
[解决办法]
帮顶了
[解决办法]
帮你顶顶···
[解决办法]

探讨
ttxk,还有个小问题问下你,我今天有用抓包的工具,看组播的发送和接收.请问,jrtplib是不是自动解决分包问题?
rtpSession.SendPacket(testBuf, byteCnt, 0, false, 10UL);
在用这个函数发送数据时,发送buffer内的长度>1536 Byte,用抓包软件可以看到发送的数据包被拆分成若干个 1518 Byte长度的包了. 那照这么说,如果我用jrtplib来传输H.264的视频流,拆包的工作就不再需要我来做, 直接把buffer的指针给到rtpSession.SendPacket() 这个函数的参数,就OK了? 那这样,写代码就简单多了呀..

[解决办法]
有高手啊/真高。我得好好学习了
[解决办法]
探讨
引用:
ttxk,还有个小问题问下你,我今天有用抓包的工具,看组播的发送和接收.请问,jrtplib是不是自动解决分包问题?
rtpSession.SendPacket(testBuf, byteCnt, 0, false, 10UL);
在用这个函数发送数据时,发送buffer内的长度>1536 Byte,用抓包软件可以看到发送的数据包被拆分成若干个 1518 Byte长度的包了. 那照这么说,如果我用jrtplib来传输H.264的视频流,拆包的工作就不再需要我来做, 直接把buffer的指…

[解决办法]
顶!!!!!!!!
------解决方案--------------------


探讨
有看到jrtplib文档中的这个函数,尝试过最大值为 65535 .
void SetMaximumPacketSize(size_t max)
Sets the maximum allowed packet size for the session.
也就是说,我只要把H.264的字节流拆包成规定最大值(64K byte)长度以内的rtp包,来传输,就可以了吗?

[解决办法]
都是高手啊!
最近也在看h264 ,了解了一些h264实现原理,
现在热火朝天地看h264测试模型:JM 代码,都快把我看的快疯掉了。

今天也把jrtplib编译了一下,自带例子也能运行,也想研究下如何传输h264 视频流,
楼主你搞懂了别忘了教教我们这些小弟啊!



[解决办法]
opal下面有一个h264组RTP流,并解RTP流,利用ffmpeg编码解码的程序,写的很好,可以参考一下。
另外,linphone也带了这样的插件。
jrtplib同作者还写了个emiplib,可以传263,忘记了是否有264没有,不过可以参考看看。
[解决办法]
路过,最近要做一个视频服务器,采用linux+cgi+thttpd,发现要传送视频流还是绕不开rtp协议,痛苦学习中……共勉之!
[解决办法]
都是高人啊,看一下,得到很大帮助
[解决办法]
用dshow filter解码,可以用CyberLink 264 Decoder Filter.
能够启用显卡硬件h264解码(如果支持),解码过程基本不耗cpu.
[解决办法]
想实现翻转? 那还是用回ffdshow吧.里面有很多实时处理滤镜,翻转,旋转,字幕等等功能都有.
[解决办法]
顶下~
最近也在研究~
代码收下咯~
O(∩_∩)O~
[解决办法]
啥东西???
[解决办法]
密切关注!
[解决办法]
我也顶下,不能沉了。
[解决办法]
你提问的问题,我前一段时间全都解决了,我是用写了一个RTSP/RTP 流媒体服务器,将实时的流转码成H.264后发送到给客户端,用到了jrtplib发送H.264数据.你具体有什么问题可以请教我,不过要给分啊

[解决办法]
我的流媒体服务器可以用VLC,quicktime player和RealPlayer还有手机上的coreplayer等播发器播放,只要输入正确的URL就可以
[解决办法]
各位好,小弟接触RTP/RTCP/RTSP一点都不久,最近需要做一个类似如下功能的东东,请各位帮忙解答解答,谢谢! 

功能说明:在服务端将一个多媒体文件(如H.264)用RTP打包后发送到另一台机子的客户端,客户端用VLC或MPLAYER接收数据流。功能就是这样,应该不算很难,但由于是刚刚接触,对这方面的知识都不是很了解,所以就有劳各位了。 

饭要一口一口吃,我想把实现分为4步骤: 
1.单纯用UDP传输文件,让VLC或MPLAYER接收UDP流(注:这个实现服务端传输没问题,只是想问下 VLC或MPLAYER能直接接收这样的UDP数据吗,如果可以该怎么进行,我试过直接在服务端传输UDP数据,MPLAYER使用udp://10.0.0.127:6666,但MPLAYER一点反应都没有。) 

2. 在原始数据基础上加上RTP头(问题跟上述一样,这样VLC能接收到数据并播放吗?) 
  
3. 在第2步基础上使用RTCP控制 

4. 在第3步基础上加上RTSP 上边的步骤只是俺这个菜鸟通过皮毛接触后想的,也不知道正不正确,恳请大家帮忙解答下,谢谢了!!! 


弱弱的问下,是不是VLC一定要使用SDP啊,如要需要,这个SDP文件是通过服务端一并发送的还是就在客户端写好数据呢? 
还有,用UDP传输数据时,是不是服务端直接发送数据啊,我只记得之前编UDP程序的时候是客户端先SENDTO,服务端RECIVE,这样服务端获取了客户端的具体信息后方开始数据传输,那上边这个需要这样的步骤吗,要需要该怎么弄啊,难道VLC会自个SENDTO数据到服务端???? 

[解决办法]
RTP,H264的新手,密切关注此贴!
[解决办法]
探讨
引用:
你提问的问题,我前一段时间全都解决了,我是用写了一个RTSP/RTP 流媒体服务器,将实时的流转码成H.264后发送到给客户端,用到了jrtplib发送H.264数据.你具体有什么问题可以请教我,不过要给分啊


小刚哥,你是用jrtplib写了一个RTSP/RTP 的流媒体服务器吗?我看jrtplib的资料上说,jrtplib是只实现了rtcp和rtp的协议,没有实现rtsp的.那你的streaming server和PC client端(比如:VLC播放器)要建立连接,前面的rtsp和sdp的东西,是怎么做的呢? 封装了另外开源的rtsp的库来实现的吗?

分不是问题! 我现在的可用分,足够给你升到两颗星星(★★)了,:-)

[解决办法]
> 佩服...
> 在这里见到了传说中的高手.

[解决办法]
传说中每日顶一下好贴会有福的.
[解决办法]
http://ttxk.blog.163.com/blog/static/16335079200981463658245/
把H264的字节流文件复用为TS流文件的小工具.

http://ttxk.blog.163.com/blog/static/16335079200972564032657/
使用UDP或者RTP协议发送TS流文件的小工具.

可以用shell命令行方式调用这2个小工具实现发送H264流文件 ~~!
[解决办法]
看来楼主做的事情跟小弟的差不多,不过小弟还得在客户端自己写一个播放器,学习中
[解决办法]
不错,学习了
[解决办法]
关注
[解决办法]
看看天书
[解决办法]
RTP 新手 关注关注 这个拆包 的很有价值 学习学习
[解决办法]
楼主,你最后是不是把压缩的流分成一个一个1.5k左右的小包发出去的,然后在那边再合并起来,然后解压缩?

能不能说个大致的流程?


[解决办法]
这个帖子真的非常好,希望高手们继续讨论下去啊,让我们这么新加入流媒体开发的菜鸟们长点见识,呵呵
[解决办法]
期待继续。
[解决办法]

探讨
ttxk 大哥,你那工具是windows下的?我要arm-linux平台下的东西...呵呵,ttxk,你就是VLC群里的"裤子"?
你搞的那些东西open source 不? 都是从VLC里抽离出来的东西,共享给大家,让我们也好多学习\学习嘛!

[解决办法]
ttxk 大哥:
您能推荐个网址或者给点什么资料来学习用jrtplib传输播放流媒体吗?我的邮箱是lmj_zhang@126.com,网上介绍的关于jrtplib的例子全是关于传一串数字的,感觉就没有真正地应用过jrtplib库,想用jrtplib+DirectShow+H.264做个流媒体的网络播放器,但毫无头绪,都不知道怎么下手.
谢谢了!
[解决办法]
to : lmjmn123

1,我也没怎么用过jrtplib。

2,做网络播放器,要看你接受什么样的数据流。

如果是接收H264InTs就比较简单。做一个数据源filter,在指定端口接收TS数据,然后向后推送就行了。找个现成的TsDemux filter以及相关的解码filter注册到系统里就行。

如果是使用3GPP,或者ISMA,或者DVB-H点播协议接收H264数据流,你需要写一个RTSP请求,根据相关协议在服务端获取到媒体流的相关信息和数据库端口,再在指定端口上接收RTP数据,解除RTP封装后,还原为H264的字节流数据,然后将数据向后推送。同样需要找个能够解码H264字节流的filter注册到系统里面。
[解决办法]
我在进行H264的RTP传输过程中也碰到问题了。
在传输字节流的时候解码端可以正常编码并显示图像,但在按照RFC3984的方法封装了字节流之后,在接收端
重组成NALU并交给解码端进行编码就出现问题了。
上网看了一下有些人说不用传输PPS和SPS,说可以从SDP中获得。ttxk给出的代码好像也是这样的。但我不明白为什么字节流没问题,而RTP传输就出现问题了呢?这两种传输方式有什么重要区别吗?
另外在进行RTP传输的时候需要注意什么问题呢?如果我不用SDP获取相关参数,而仍然传输PPS和SPS,这样有没有问题呢?


[解决办法]
你另开帖子问吧,一个帖子问一个问题就行了,不要没完没了的在一个帖子里问N多问题 ,尊重一下回你帖子的人。
[解决办法]
刚转做流媒体方面,学习学习!
[解决办法]
太猛了 帮助顶一下~
[解决办法]
学习学习,又要开始搞这个了.
[解决办法]
智能连接做了没,怎么做的?我的source filter for h264做好了,但是它不会智能连接
[解决办法]
HRESULT CPushPinBitmapSet::FillBuffer(IMediaSample *pSample) 

BYTE *pData; 
long cbData; 

//步骤没错吧?会不会lstp没赋值?list <BYTE*>::iterator lstp = lst.begin(); 
recevH264Data=*lstp;



if ((recevH264Data!=recH264Dataold)&&(lstp!=lst.end())) 

memcpy(pData,recevH264Data,bufLength); 
recH264Dataold=recevH264Data; 
*lstp=NULL; 
lstp++; 
后面部分代码省略 



[解决办法]
live555的原型是单线程的,如果说有赋值的话,按理不大可能会是由于内存锁住而导致的。
[解决办法]
分析的很透彻啊

热点排行