完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
jrtp使用起来比较简单,这里使用分片封包模式
#ifndef RTP_RAW_SESSION_H#define RTP_RAW_SESSION_H#include "jrtplib3/rtpsession.h"#include #include "RawSession.h"#include |
|
相关推荐
1个回答
|
|
|
RawSession::SendData(unsigned char* pSendbuf, int buflen){ //std::cout << "send packet length : " << buflen << std::endl; char sendbuf[1430]; //发送的数据缓冲 memset(sendbuf, 0, 1430); int status; if ( buflen <= MAX_RTP_PKT_LENGTH ) { memcpy(sendbuf, pSendbuf, buflen); status = this->SendPacket((void *)sendbuf, buflen); CheckError(status); } else if(buflen > MAX_RTP_PKT_LENGTH) { //设置标志位Mark为0 this->SetDefaultMark(false); //printf("buflen = %d/n",buflen); //得到该需要用多少长度为MAX_RTP_PKT_LENGTH字节的RTP包来发送 int k = 0, l = 0; #ifdef FU buflen = buflen -1; #endif k = buflen / MAX_RTP_PKT_LENGTH; l = buflen % MAX_RTP_PKT_LENGTH; int t = 0;//用指示当前发送的是第几个分片RTP包 char nalHeader = pSendbuf[0]; // NALU 头ª¡¤ while( t < k || ( t==k && l>0 ) ) { if ( ( t < (k-1) ) || ( t== (k-1) && l!=0 ) )//第一包到最后包的前一包 {#ifdef FU sendbuf[0] = (nalHeader & 0x60)|28; sendbuf[1] = (nalHeader & 0x1f); if ( 0 == t ) { sendbuf[1] |= 0x80; } memcpy(sendbuf+2, &pSendbuf[t*MAX_RTP_PKT_LENGTH + 1], MAX_RTP_PKT_LENGTH); status = this->SendPacket((void *)sendbuf, MAX_RTP_PKT_LENGTH+2);#else memcpy(sendbuf, &pSendbuf[t*MAX_RTP_PKT_LENGTH], MAX_RTP_PKT_LENGTH); status = this->SendPacket((void *)sendbuf, MAX_RTP_PKT_LENGTH);#endif CheckError(status); t++; } //最后一包 else if( ( k==t && l>0 ) || ( t== (k-1) && l==0 )) { //设置标志位Mark为1 this->SetDefaultMark(true); int iSendLen; if ( l > 0) { iSendLen = buflen - t * MAX_RTP_PKT_LENGTH; } else { iSendLen = MAX_RTP_PKT_LENGTH; } #ifdef FU sendbuf[0] = (nalHeader & 0x60)|28; sendbuf[1] = (nalHeader & 0x1f); sendbuf[1] |= 0x40; memcpy(sendbuf+2, &pSendbuf[t*MAX_RTP_PKT_LENGTH + 1], iSendLen); status = this->SendPacket((void *)sendbuf, iSendLen+2);#else memcpy(sendbuf, &pSendbuf[t*MAX_RTP_PKT_LENGTH], iSendLen); status = this->SendPacket((void *)sendbuf, iSendLen);#endif CheckError(status); t++; } } }}void RawSession::SendData(unsigned char* pSendbuf, int buflen, uint32_t timestampinc, bool mark, uint8_t pt){ char sendbuf[1430]; //发送的数据缓冲 memset(sendbuf, 0, 1430); timestampinc = timestampinc * 90; int status; if ( buflen <= MAX_RTP_PKT_LENGTH ) { memcpy(sendbuf, pSendbuf, buflen); status = this->SendPacket((void *)sendbuf, buflen, pt, mark, timestampinc); CheckError(status); } else if(buflen > MAX_RTP_PKT_LENGTH) { //设置标志位Mark为0 this->SetDefaultMark(false); //printf("buflen = %d/n",buflen); //得到该需要用多少长度为MAX_RTP_PKT_LENGTH字节的RTP包来发送 int k = 0, l = 0; #ifdef FU buflen = buflen -1; #endif k = buflen / MAX_RTP_PKT_LENGTH; l = buflen % MAX_RTP_PKT_LENGTH; int t = 0;//用指示当前发送的是第几个分片RTP包 char nalHeader = pSendbuf[0]; // NALU 头ª¡¤ while( t < k || ( t==k && l>0 ) ) { if ( ( t < (k-1) ) || ( t== (k-1) && l!=0 ) )//第一包到最后包的前一包 {#ifdef FU sendbuf[0] = (nalHeader & 0x60)|28; sendbuf[1] = (nalHeader & 0x1f); if ( 0 == t ) { sendbuf[1] |= 0x80; } memcpy(sendbuf+2, &pSendbuf[t*MAX_RTP_PKT_LENGTH + 1], MAX_RTP_PKT_LENGTH); status = this->SendPacket((void *)sendbuf, MAX_RTP_PKT_LENGTH + 2, pt, false, 0);#else memcpy(sendbuf, &pSendbuf[t*MAX_RTP_PKT_LENGTH], MAX_RTP_PKT_LENGTH); status = this->SendPacket((void *)sendbuf, MAX_RTP_PKT_LENGTH, pt, false, 0);#endif CheckError(status); t++; } //最后一包 else if( ( k==t && l>0 ) || ( t== (k-1) && l==0 )) { //设置标志位Mark为1 this->SetDefaultMark(true); int iSendLen; if ( l > 0) { iSendLen = buflen - t * MAX_RTP_PKT_LENGTH; } else { iSendLen = MAX_RTP_PKT_LENGTH; } #ifdef FU sendbuf[0] = (nalHeader & 0x60)|28; sendbuf[1] = (nalHeader & 0x1f); sendbuf[1] |= 0x40; memcpy(sendbuf+2, &pSendbuf[t*MAX_RTP_PKT_LENGTH + 1], iSendLen); status = this->SendPacket((void *)sendbuf, iSendLen+2, pt, true, timestampinc);#else memcpy(sendbuf, &pSendbuf[t*MAX_RTP_PKT_LENGTH], iSendLen); status = this->SendPacket((void *)sendbuf, iSendLen, pt, true, timestampinc);#endif CheckError(status); t++; } } } }
int Init(const std::string& ip, uint16_t destport); 初始化部分有几点需要注意的: 1.H264固定的采样率是90000HZ,对于时间戳单位应为 sessparams.SetOwnTimestampUnit(1.0/90000.0); //时间戳单位 2.如果视频帧率是25fps,那么时间戳间隔就是3600 this->SetDefaultTimestampIncrement(3600); void SendData(unsigned char* pSendbuf, int buflen); 使用分片封包模式,这里大概介绍一下 当NALU的长度超过MTU时,就必须对NALU单元进行分片封包.也称为Fragmentation Units(FUs). 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | FU indicator | FU header | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | | FU payload | | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | :...OPTIONAL RTP padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Figure 14. RTP payload format for FU-A The FU indicator octet has the following format: +---------------+ |0|1|2|3|4|5|6|7| +-+-+-+-+-+-+-+-+ |F|NRI| Type | +---------------+ 别被名字吓到这个格式就是上面提到的RTP h264负载类型,Type为FU-A The FU header has the following format: +---------------+ |0|1|2|3|4|5|6|7| +-+-+-+-+-+-+-+-+ |S|E|R| Type | +---------------+ S bit为1表示分片的NAL开始,当它为1时,E不能为1 E bit为1表示结束,当它为1,S不能为1 R bit保留位 Type就是NALU头中的Type,取1-23的那个值 这里有几个问题需要强调一下: 1.就是长度小于MTU时候,一个RTP发送一个nalu 2.每个I帧前面发送一个sps pps,这两个RTP包和接下来的I帧RTP包的时间戳相同 3.当nalu大于MTU,添加FU头,同时注意,要去掉nalu的header,就是第一个字节。FU indicator + FU header + nalu[1] |
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
2387 浏览 0 评论
Arduino Uno l两轮自平衡机器人 电机驱动无输出求解
4330 浏览 3 评论
TT电机,Arduino Uno,L298N 5AD ,MPU6050最简自平衡机器人资料
1487 浏览 0 评论
4427 浏览 0 评论
5424 浏览 0 评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-13 21:13 , Processed in 1.032375 second(s), Total 71, Slave 54 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
1979