国标中说h264数据按照RFC3984打包,但是国标的测试工具——SPVMN,却不支持RFC3984的打包方式。
无奈之下直接用RFC3550的方式打包,其实就是分包,然后加上RTP头,对于一帧的结束,在RTP头中把MARK置1,并且在一帧的开始把时间戳增加而已。
这种打包方式其实和RFC有冲突,打包处理的RTP数据用VLC播放解码不正常,但用SPVMN是可以播的。
这种方式下没有测试音视频混合的情况,待测。

贴上代码(代码不全,体现下流程和重点):

 int NewRTPPacket(unsigned short channel, unsigned short sequenceNumber, unsigned long timeStamp, \
RTSP_DATE_TIME time, const unsigned char *pRTPData, unsigned long dataLen, bool bIsKeyFrame, bool mark)
{
if (dataLen > MAX_RTP_PAYLOAD_DATA_LEN)
{
assert(false);
return -;
}
m_Sec = time.seconds;
m_MicroSec = time.microsecond;
Clear(); m_bIsKeyFrame = bIsKeyFrame;
m_channel = channel;
m_pRTPHeader->sequenceNumber = htons(sequenceNumber);
m_pRTPHeader->timeStamp = htonl(timeStamp); m_rtpDataLen = dataLen + sizeof(RTP_HEADER); CreateCommonInfo(RTP_PAYLOAD_TYPE_H264, mark, STREAM_LIVE_VIDEO); memcpy(m_pRTPData + sizeof(RTP_HEADER) + sizeof(INTERLEAVED_INFO), pRTPData, dataLen);
}
 int CreateRFC3550Packet(unsigned short channel, const unsigned char *pRTPData, unsigned long dataLen, \
bool bIsKeyFrame, unsigned long TimeStamp, bool mark)
{
CRTPPacket *pRTPPacket = m_mapRTPPacketFree[channel]->front();
m_mapRTPPacketFree[channel]->pop_front(); pRTPPacket->NewRTPPacket(channel, ++m_VSequenceNum[channel], TimeStamp, \
RTSPGetCurrTime(), pRTPData, dataLen, bIsKeyFrame, mark); m_mapRTPPacket[channel]->push_back(pRTPPacket);
DistributePacket(pRTPPacket, channel); return ;
}
  //pData是一帧数据的首地址,dataLen是该帧的长度
while(dataLen > )
{
if (dataLen > MAX_RTP_PAYLOAD_DATA_LEN)
{
CreateRFC3550Packet(channel, pData, MAX_RTP_PAYLOAD_DATA_LEN, bIsKeyFrame, m_LastFrameTs[streamType][channel], false);
dataLen -= MAX_RTP_PAYLOAD_DATA_LEN;
pData += MAX_RTP_PAYLOAD_DATA_LEN;
}
else
{
CreateRFC3550Packet(channel, pData, dataLen, bIsKeyFrame, m_LastFrameTs[streamType][channel], true);
dataLen = ;
pData = NULL;
}
}

值得一提的是,时间戳增量并不一定要严格按照固定的值增长,比如:
帧率为25帧的视频数据,时间戳增量一般为3600,但是实际的帧率可能是动态的,上一帧的时间和下一帧的时间间隔可能不是严格的40ms,实际上也不可能这么严格,
那么我在打时间戳的时候可以把这一帧的时间戳打成3500的增量,再把下一帧的增量达成3700,这也没关系。

注: 本文转载自 http://blog.csdn.net/c__allen/article/details/8960631

最新文章

  1. rpm 看 rpm 包内容
  2. [转]Linux软连接和硬链接
  3. php中时间戳和日期格式的转换
  4. Python 修饰器
  5. java利用commons-email发送邮件并进行封装
  6. ural 1348 Goat in the Garden 2
  7. poj2365---求多边形边长总和
  8. IntelliJ IDEA中创建并运行scala应用程序
  9. 如何获得android手机通讯录的字母显示(两)
  10. C# 控件的缩写
  11. Python2.7和3.5双版本共存和pip的使用
  12. Linux中jdk的安装配置
  13. 【论文阅读】Wing Loss for Robust Facial Landmark Localisation with Convolutional Neural Networks
  14. keepalived实现mycat高可用问题排查;道路坎坷,布满荆棘,定让你大吃一惊!
  15. Java synchronized解析
  16. React Native 项目整合 CodePush 全然指南
  17. 第12章—使用NoSQL数据库—使用MongoDB+Jpa操作数据库
  18. 【BZOJ4197】【Noi2015】寿司晚宴
  19. zw版【转发·台湾nvp系列Delphi例程】HALCON DispArc
  20. 外网访问用azure虚拟机搭建的网站

热门文章

  1. Ugly Number II 解答
  2. c语言通过时间种子产生随机数并选出最大值以及下标
  3. phpcms:二、头部尾部包含
  4. ServerSocketChannel实现多Selector高并发server
  5. poj 2046 Gap(bfs+hash)
  6. Java中普通代码块,构造代码块,静态代码块的代码演示样例及区分
  7. 漫话Unity3D(一)
  8. MongoDB分片技术[转]
  9. [Angular 2] Using the @Inject decorator
  10. [Cycle.js] Customizing effects from the main function