打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
h264拆包方法

h264拆包方法
http://www.365afchina.com/forum.php?mod=viewthread&tid=885&fromuid=1


 

收藏点知识论坛留着慢慢学习,关于h264拆包:http://bbs.rosoo.net/archiver/tid-26.html
关于解析h264视频流:http://bbs.rosoo.net/archiver/tid-578.html
h264 RTP Payload 格式:http://bbs.rosoo.net/archiver/tid-23.html
可以通过生成SDP文件给播放器在指定端口接收数据播放,如果你不用动态调整编码器什么的就不用考虑另外发送RTCP. 
而且RTCP必须自己实现RTSP服务结合起来用,没有实现RTSP服务,就谈不上实现RTCP. 

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

UINT MediaStreamH264::TransportData(PBYTE pData, UINT dataSize, int pts) 

PBYTE p_buffer = pData; 
int i_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; 

UINT mtu = 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; 
int i_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; 
}


如何把MPEG4(或H.264)的视频流拆分成一个个的RTP包?
MPEG-4和H.264拆分RTP包的方法原理基本上相同的,具体实现上还是有差别的,可以查看不同的RFC文档,H.264的是RFC3984。
一个rtp包的最大长度为多少,rtp包头信息怎么填,payload type等于多少?
一个rtp包如果是经过UDP传输的原则上不要超过1460,原因如下:RTP基于UDP之上的传输协议,而UDP属于运输层,我们知道以太网数据帧的长度必须在46-1500字节之间,这是由以太网的物理特性决定的,这个1500字节被成为链路层的MTU(最大传输单元),去除IP数据报的首部20字节和UDP首部的8字节,所以UDP数据报的数据区最大长度为1472字节,考虑到RTP包头的12个字节,这样RTP载荷的最大尺寸为1460字节。如果要封装进RTP载荷的数据大于1460字节,而且不在应用层数据装载进RTP分组之前进行载荷的拆分,这样就会产生大于IP网络MTU的分组。如此一来底层的协议(IP)将会对这种大的分组进行拆分,分为几个小于IP MTU尺寸的IP分组。这样就无法检测数据是否丢失,原因如下:IP和UDP协议都没有提供分组到达的检测,如果拆分后第一个分组成功接收,而后续分组丢失。由于第一个分组中包含完整的RTP头信息,而RTP头中也没有关于RTP载荷长度的指示,因此不能判读该RTP分组是否有丢失,而只能认为是完成接收了,这样就会造成解码时的错误信息。
rtp头的信息就按照RFC标准填写。
payload type因为没有定义,所以可以是96-127之间的任意值.
RTCP包要不要我来发送,如何发送,什么时候发送,发什么内容??
如果用jrtplib会自动发送RTCP包。



转自:http://hjzgq133.blog.163.com/blog/static/14201545020113711949537/

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
H264关于RTP协议的实现
H.264的网络提取层的错误恢复_燃烧的心
TCP、UDP、IP 协议分析
妥了,计算机网络这11种协议报文格式要烂熟于心!
实时传输协议RTP (Real-time Transport Protocol)
RTP协议
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服