视频通话时,呼叫通过SIP消息协商后,定义好主被叫通话双方的codec、payloadtype、采样率等,就可以进行音视频媒体通信了。
在视频通话中,视频格式最常见的是H264了,那么在媒体通信中如何将视频H264传输,如何设置消息头及时间戳并进行发送呢?
下面进行的简单的叙述。
一、采用SPS、PPS开场。
二、FU中定义是否是关键帧
RTP的第一个字节是消息类型,如果是FU-A,第二个字节用来指示是否是I帧,是否I帧的开始或结束。
下面是个I帧开始帧的截图:
下图是I帧结束的截图:
下图是个非关键帧开始的截图:
下图是个非关键帧结束的截图:
三、关于时间戳更新
当发送的包在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; }