rtp

实时传输协议,可以使用udp和tcp

h264 和 h265

h264有sps pps,se 帧,h265多一些,有sps pps vps等,不过不是很重要,接收的时候用的多一些,发送稍简单,以下是发送程序

mtu

最大传输单元,不管是tcp还是udp都必须要分包发送,因为超过mtu实际上被交换机等设备分帧,所以必须小于交换机等设备的最大传输单元,这样效率比较高。一般我们可以定义mtu为1400字节,当然可以再小一点,加上rtp协议头部的12字节,最多为1412字节,各位可以自己拟定。

网络发送

这一部分可以使用各类封装程序,也可以自己调用简单的socket api函数发送,具体不细节写了,读者可以自己用喜欢的程序来完成

void rtp_send_data(uint8_t *buf, int len, int last_packet_of_frame,uint32_t timestamp)
{}

发送rtp for h264

分为h264和h265

void send_rtp_h264(uint8_t * data, int dlen,uint32_t timestamp)
{int iSize = max_payload_size- RTP_HEADERS_SIZE;uint8_t buf[max_payload_size];uint8_t *pos = &buf[12];//0 -11 是rtp头部if (dlen > iSize) { //超过MTUconst uint8_t s_e_r_Start = 0x80;const uint8_t s_e_r_Mid = 0x00;const uint8_t s_e_r_End = 0x40;//获取帧头数据,1byteunsigned char naluType = (*data) & 0x1f; //获取NALU的5bit 帧类型unsigned char nal_ref_idc = (*data) & 0x60; //获取NALU的2bit 帧重要程度 00 可以丢 11不能丢//nal_ref_idc = 0x60;//组装FU-A帧头数据 2byteunsigned char f_nri_type = nal_ref_idc + 28;//F为0 1bit,nri上面获取到2bit,28为FU-A分片类型5bitunsigned char s_e_r_type = naluType;bool bFirst = true;bool mark = false;int nOffset = 1;while (!mark) {if (dlen < nOffset + iSize) {           //是否拆分结束iSize = dlen - nOffset;mark = true;s_e_r_type = s_e_r_End + naluType;}else {if (bFirst == true) {//set the starts_e_r_type = s_e_r_Start + naluType;bFirst = false;}else {s_e_r_type = s_e_r_Mid + naluType;}}*pos = f_nri_type;*(pos + 1) = s_e_r_type;memcpy(pos + 2, data + nOffset, iSize);nOffset += iSize;rtp_send_data(buf, iSize + 2, mark, timestamp);}}else {rtp_send_data(data, dlen, true, timestamp);}
}

h265

h265 稍微简单一些


void send_rtp_h265(uint8_t *buf, int len, int last_packet_of_frame,uint32_t ts)
{//RTPMuxContext *rtp_ctx = ctx->priv_data;int rtp_payload_size = max_payload_size - RTP_HEVC_HEADERS_SIZE;int nal_type = (buf[0] >> 1) & 0x3F;/* send it as one single NAL unit? */if (len <= max_payload_size) //小于对定的最大值时,直接发送(最大值一般小于mtu)  {/* use the original NAL unit buffer and transmit it as RTP payload */rtp_send_data(buf, len, 0, ts);}else //大于最大值时进行fu分组发送  {/*create the HEVC payload header and transmit the buffer as fragmentation units (FU)0                   10 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|F|   Type    |  LayerId  | TID |+-------------+-----------------+F       = 0Type    = 49 (fragmentation unit (FU))LayerId = 0TID     = 1*/buf[0] = 49 << 1;buf[1] = 1;//此处为paylaodhdr,规范赋值应该是替换hevc数据nal 的payloadhdr的type  //rtp_ctx->buf[0] = (buf[0] &0x81) | (49<<1);  //rtp_ctx->buf[1] = buf[1]  /*create the FU header0 1 2 3 4 5 6 7+-+-+-+-+-+-+-+-+|S|E|  FuType   |+---------------+S       = variableE       = variableFuType  = NAL unit type*/buf[2] = nal_type;/* set the S bit: mark as start fragment */buf[2] |= 1 << 7;/* pass the original NAL header *///此处要注意,当是分组的第一报数据时,应该覆盖掉前两个字节的数据,h264要覆盖前一个字节的数据,即是第一包要去除hevc帧数据的paylaodhdr  buf += 2;len -= 2;while (len > rtp_payload_size){/* complete and send current RTP packet */memcpy(&buf[RTP_HEVC_HEADERS_SIZE], buf, rtp_payload_size);rtp_send_data(buf, max_payload_size, 0,ts);buf += rtp_payload_size;len -= rtp_payload_size;/* reset the S bit */buf[2] &= ~(1 << 7);}/* set the E bit: mark as last fragment */buf[2] |= 1 << 6;/* complete and send last RTP packet */memcpy(&buf[RTP_HEVC_HEADERS_SIZE], buf, len);rtp_send_data(buf, len + 2, last_packet_of_frame,ts);}
}

其他方式

这里建议的其他方式为使用ffmpeg,事实上ffmpeg封装了各类编码格式的rtp,可以直接调用,不详细解释,可以直接使用以下代码,当然,需要变格式时请自行改变

extern "C" {#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
}class RTP_Wrapper
{AVFormatContext * m_fmtctx = NULL;AVStream * m_st_v = NULL;AVStream * m_st_a = NULL;AVCodecContext *m_p_v = NULL;AVCodecContext *m_p_a = NULL;
public://推RTP//ffmpeg - re - i cw.ts - vcodec copy - acodec copy - f rtp_mpegts  rtp ://238.123.46.66:8001  推rtp//推UDP//ffmpeg - re - i cw.ts - vcodec copy - acodec copy - f mpegts  udp ://238.123.46.66:8001  推udpint init_rtp(AVCodecContext *v, AVCodecContext *a,const char * url, unsigned short port){int ret = -1;m_p_v = v;m_p_a = a;//AVFrame * pFrame = av_frame_alloc();//m_fmtctx = avformat_alloc_context();AVOutputFormat* fmt = av_guess_format("rtp", NULL, NULL);//AVOutputFormat* fmt = av_guess_format("rtp_mpegts", NULL, NULL);char rtp[128];sprintf(rtp, "%s:%d", url, port);ret = avformat_alloc_output_context2(&m_fmtctx, fmt, fmt->name,rtp);//printf("Writing to %s\n", m_fmtctx->filename);AVDictionary *options = NULL;av_dict_set(&options, "buffer_size", "102400", 0); //设置缓存大小,1080p可将值调大av_dict_set(&options, "send_buffer_size", "102400", 0); //设置缓存大小,1080p可将值调大avio_open(&m_fmtctx->pb, rtp, AVIO_FLAG_WRITE);//初始化AVStreamif (v != NULL){//查找编码器AVCodec *cv = avcodec_find_encoder(AV_CODEC_ID_H264);m_st_v = avformat_new_stream(m_fmtctx, cv);avcodec_parameters_from_context(m_st_v->codecpar, v);}if (a != NULL){AVCodec *ca = avcodec_find_encoder(AV_CODEC_ID_AAC);m_st_a = avformat_new_stream(m_fmtctx, ca);avcodec_parameters_from_context(m_st_a->codecpar, a);}#if 0//打开输出流char buffer[128];//设置流格式为RTP                                   sprintf(buffer, "rtp://%s:%d", "127.0.0.1", 6666);m_fmtctx->oformat = av_guess_format("rtp", buffer, NULL);if (avio_open(&m_fmtctx->pb, buffer, AVIO_FLAG_WRITE) < 0)return -1;
#endifavformat_write_header(m_fmtctx, NULL);char sdp[256];av_sdp_create(&m_fmtctx, 1, sdp, sizeof(sdp));FILE * fp = fopen("c:\\test.sdp", "wb");fwrite(sdp, 1, strlen(sdp), fp);fclose(fp);printf("%s\n", sdp);return 0;}//设置AVCodecContext编码参数    void send(AVPacket * pkt){//写文件头pkt->stream_index = m_st_v->index;pkt->pts = av_rescale_q(pkt->pts, m_p_v->time_base,m_st_v->time_base);pkt->dts = av_rescale_q(pkt->dts, m_p_v->time_base, m_st_v->time_base);pkt->pos = -1;av_interleaved_write_frame(m_fmtctx, pkt);av_packet_free(&pkt);}void UnInit(){//销毁资源if (!(m_fmtctx->oformat->flags & AVFMT_NOFILE))avio_close(m_fmtctx->pb);avformat_free_context(m_fmtctx);}
};

rtp发送h264和h265相关推荐

  1. RTMP协议封装H264和H265协议详解

    RTMP协议封装H264和H265协议详解 文章目录 RTMP协议封装H264和H265协议详解 1 RTMP和FLV 2 RTMP协议封装H264视频流 2.1 RTMP发送AVC sequence ...

  2. wireshark提取视频数据之RTP包中提取H264和H265

    wireshark提取视频数据之RTP包中提取H264和H265 文章目录 wireshark提取视频数据之RTP包中提取H264和H265 1 背景 2 提取前工作 3 H264视频从RTP包中提取 ...

  3. H264 NALU 使用PS封装 RTP发送

    最近由于项目平台需求,要将H264 NALU封装为PS再用RTP发送,PS封装按照ISO DEC-13818-1标准.一个PS包包含PS Header, PES Header, PS system h ...

  4. rtp发送 h265

    自己写的select 做TCP服务端,把tcp数据按照RTSP协议解析,掉函数直接获取一帧音频,一帧视频这种,分包成RTP发送 用ffmpeg 转载于:https://www.cnblogs.com/ ...

  5. RTP发送和接收(有图为证)

    RTP协议接收和播放 前面讲过RTP协议的重要性,说过发送RTP协议,RTP协议重要性下面我们开始写发送和接收程序,不依赖于jrtplib等RTP库,自行接收.这样,有利于以后将RTP直接转到Webr ...

  6. RTP之H264封包和解包

    RTP之H264封包和解包 目录 H264打包RTP的方法 打包方式之Single NAL Unit 打包方式之FU-A FU indication FU header 1. H264打包RTP的方法 ...

  7. RTP传输H264时的sps和pps的获取

    From: http://wmnmtm.blog.163.com/blog/static/38245714201192491746701/ 使用RTSP传输H264的时候,需要用到sdp协议描述,其中 ...

  8. RTP Payload H264

    一.简介 1.RTP和RTCP RTP全名是Real-time Transport Protocol(实时传输协议).它是IETF提出的一个标准,对应的RFC文档为RFC3550(RFC1889为其过 ...

  9. ORTP移植到Hi3518e,h.264封包rtp发送

    看到ORTP是纯C实现的rtp库,于是移植到3518e试用一下. 1.下载源码 http://www.linphone.org/technical-corner/ortp/downloads 里面有个 ...

最新文章

  1. 3、如何证明static静态变量和类无关?
  2. linux openwrt插件,OpenWrt添加软件包(一)
  3. go grpc测试_Grpc — 整体性能测试
  4. [python爬虫] 招聘信息定时系统 (二).调用pyinstaller包生成exe文件
  5. bh1750采集流程图_lcd_bh1750 通过 采集环境光照度,并在野火stm32mini板子的屏幕上显示。 SCM 机开发 272万源代码下载- www.pudn.com...
  6. 浅谈数据中台安全体系构建思路
  7. 如何看待阿里巴巴推荐的Python400集视频?零基础入门学习Python
  8. elf 取路径_PatchELF 修改linux下elf文件library搜索路径
  9. Linux下的基础命令介绍(二)
  10. 为什么微盟耗时 7 天 7 夜才找回删库数据?
  11. cvCompareHist() 直方图匹配
  12. Maximum call stack size exceeded
  13. PX4源码学习一--Pix和APM的区别
  14. Android简历附件2
  15. Some file crunching failed, see logs for details解决方案 以及.9patch点9图片的报错的详细修改方法
  16. 5G消息富媒体最新形态
  17. keepalived的主备模式下,优先访问了从机的资源,原因尚未知
  18. 谷歌浏览器设置默认搜索引擎
  19. 记一次生产大对象导致的OOM让架构师连夜排查解决
  20. matlab 反激实例(S440_Flyback.slx)

热门文章

  1. 通过Windows远程桌面连接将远程文件传输至本地
  2. SQL Server 漏洞评估工具
  3. 迷你世界远古机器人_迷你世界:第三款机器人即将上线,网友5000迷你币抽新坐骑,哭了...
  4. 蔚来、威马抢装的英伟达Orin,正成为高端智能车标配
  5. 三星Galaxy S22系列国行版获3C认证:依旧祖传25W快充
  6. iPhone 13贴膜渲染图曝光:近几代外观最大升级
  7. 就地过年的年轻人都去搜索“年夜饭”外卖了
  8. 华为公开折叠屏新专利:Mate X2有望首发搭载
  9. 网易严选退出双十一:“抵制”鼓吹过度消费
  10. 巴菲特:承认错误“抄底”航空股,不看好航空公司