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

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

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


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


      下面进行的简单的叙述。


    一、采用SPS、PPS开场。


f32d94238ad54df99badf6f117af6707.png

fcc94936708944a8b276261a0e0302d7.png


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


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


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


71cd74bd16a24619844f15bf0a4bec42.png


下图是I帧结束的截图:


d09b7f219379493fbcbd177014dfa203.png


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


f1b213aa20584a4f98f6a8025ce83c69.png


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


08fcce75dfe7433f8ea55a2f2ee37c05.png


三、关于时间戳更新


当发送的包在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;
}
相关文章
|
缓存 网络协议 5G
剖析KCP以及KCP在游戏中是如何使用的
剖析KCP以及KCP在游戏中是如何使用的
|
存储 C语言 C++
66 C++ - 流的概念和流类库的结构
66 C++ - 流的概念和流类库的结构
90 0
|
网络协议 网络架构
数据从发出到接收的细节介绍{封装与解封装}
本文将介绍了详细的封装在每一层的具体的操作,可以让大家学习到数据从发出到收到的具体过程。
|
4月前
|
编解码 Android开发 开发者
如何在轻量级RTSP服务中玩转H.264扩展SEI,实现自定义数据的发送与接收?
【9月更文挑战第4天】本文详细介绍了如何在轻量级RTSP服务中实现H.264标准的扩展SEI功能,包括环境准备、依赖引入、RTSP服务创建、自定义SEI数据发送与接收等步骤,并提供了具体代码示例,帮助开发者更好地利用SEI在视频流中嵌入元数据。
96 2
|
5月前
|
编解码 Android开发
### 揭秘!如何在轻量级RTSP服务中玩转H.264扩展SEI,实现自定义数据的发送与接收?
【8月更文挑战第14天】本文介绍如何在轻量级RTSP服务中实现H.264的SEI功能,允许在视频流中嵌入自定义数据。首先确保环境已安装Android Studio并具备基础开发技能。接着,通过Gradle添加必要依赖如`jrtsp`。创建RTSP服务并配置H.264编码器支持SEI。编码过程中可添加自定义SEI数据,并在客户端解析这些数据。此方案适用于需在视频流中传递元数据的应用场景。
58 0
|
网络协议 程序员 网络架构
数据封装与解封装过程
数据封装与解封装过程
293 0
|
8月前
RTP头部封装的实现
RTP头部封装的实现
89 0
数据的封装和解封装
数据的封装和解封装
40 0
|
存储 网络协议 开发工具
XTCP 一个便捷的TCP消息包拼装和解析框架
XTCP 一个便捷的TCP消息包拼装和解析框架
705 0

热门文章

最新文章

下一篇
开通oss服务