【流媒体新手】:如何使用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相关代码,极简单。
[解决办法]
帮顶了
[解决办法]
帮你顶顶···
[解决办法]
[解决办法]
传说中每日顶一下好贴会有福的.
[解决办法]
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左右的小包发出去的,然后在那边再合并起来,然后解压缩?
能不能说个大致的流程?
[解决办法]
这个帖子真的非常好,希望高手们继续讨论下去啊,让我们这么新加入流媒体开发的菜鸟们长点见识,呵呵
[解决办法]
期待继续。
[解决办法]
if ((recevH264Data!=recH264Dataold)&&(lstp!=lst.end()))
{
memcpy(pData,recevH264Data,bufLength);
recH264Dataold=recevH264Data;
*lstp=NULL;
lstp++;
后面部分代码省略
}
}
[解决办法]
live555的原型是单线程的,如果说有赋值的话,按理不大可能会是由于内存锁住而导致的。
[解决办法]
分析的很透彻啊