0
点赞
收藏
分享

微信扫一扫

如何使用RTP封装H264视频数据


        视频通话时,呼叫通过SIP消息协商后,定义好主被叫通话双方的codec、payloadtype、采样率等,就可以进行音视频媒体通信了。

       在视频通话中,视频格式最常见的是H264了,那么在媒体通信中如何将视频H264传输,如何设置消息头及时间戳并进行发送呢?

       下面进行的简单的叙述。

     一、采用SPS、PPS开场。

     

如何使用RTP封装H264视频数据_音视频

如何使用RTP封装H264视频数据_视频通话_02

二、FU中定义是否是关键帧

RTP的第一个字节是消息类型,如果是FU-A,第二个字节用来指示是否是I帧,是否I帧的开始或结束。

下面是个I帧开始帧的截图:

如何使用RTP封装H264视频数据_关键帧_03

下图是I帧结束的截图:

如何使用RTP封装H264视频数据_视频通话_04

下图是个非关键帧开始的截图:

如何使用RTP封装H264视频数据_时间戳_05

下图是个非关键帧结束的截图:

 

如何使用RTP封装H264视频数据_时间戳_06

 三、关于时间戳更新

当发送的包在FU-A的start和end之间时,时间戳不能变。之后当FU-A发送到END之后,下次发包时,时间戳才能变更。

四、部分代码样例

bool TRTP::sendvideo(const char* buffer, int length,uint32_t ts)
{
int ret=0;
bool mark = false;
nalu_header_t fuidf ;
if(m_videoCodecId == AV_CODEC_ID_H264)
{
fuidf.type = buffer[0] & 0x1F;
if(fuidf.type==nalu_type_sps)
{
mark = true;
ts = 0;
}
else if(fuidf.type==nalu_type_pps)
{
mark = true;
ts = 0;
}
else if(fuidf.type==nalu_type_no_idr)
{
mark = true;
}
else if(fuidf.type==nalu_type_fu_a)
{
char fu_header
= buffer[1];
int startflag = fu_header & 0x40;
if(startflag==0x40)
{
mark = true;
}
}
else
{
mark = true;
}
}

if(mark==0)
ts = 0;
//LOG(DETAIL,"mark = %d ts=%d",mark,ts);
if(fuidf.type==nalu_type_sps || fuidf.type==nalu_type_pps)
{
char extent[1]={0x00};

ret = m_rtpSession.SendPacketEx(buffer, length, m_payloadType, mark, ts,0xbede,extent,1);
}
else if(fuidf.type==nalu_type_fu_a && mark== true)
{

char extent[1]={0x00};
ret = m_rtpSession.SendPacketEx(buffer, length, m_payloadType, mark, ts,0xbede,extent,1);
}
else
{
ret = m_rtpSession.SendPacket(buffer, length, m_payloadType, mark, ts);
}
//ret = m_rtpSession.SendPacketNew(buffer, length);
return ret>0;
}

举报

相关推荐

0 条评论