EasyNVR摄像机网页直播中,推流组件EasyRTMP推送RTMP扩展支持HEVC(H.265)的方案
众所周知,RTMP标准协议实际是不支持HEVC(H.265)编码格式的,同样,现行的H5标准里面,也没有对H.265的描述,所以,在很大程度上,H5网页浏览器是无法接入HEVC(H.265)的,但是,在很多原生客户端中,对HEVC(H.265)的需求是非常大的,那么,像EasyNVR中,如果需要接入HEVC(H.265)流的时候,我们应该如何支持呢?
不久前刚实现EasyRTMP扩展支持h265推送,当时在网上也查找了很多资料,发现都不尽详细,而官方也没有更新对HEVC(H265,后文统称HEVC)tag的支持,反正是走了不少弯路,当然,在广大网友以及ffmpeg代码的帮助下我最终实现了通过EasyRTMP推送HEVC视频帧数据到EasyDSS,这里我将把实现过程详细的记录下来,供广大网友参考。
首先, RTMP头部信息封装并没有定义HEVC,我们采用CDN联盟的HEVC(H.265)扩展标准,将HEVC的VideoTagHeader定义为12,详见下图:

然后,我们在H.264封装的基础上进行改进,以支持HEVC头部的封装,而HEVC头有
SPS PPS VPS,我们参考ffmpeg的HEVCDecoderConfigurationRecord结构对metadata进行封装,该结构体代码如下:
typedef struct HVCCNALUnitArray {
uint8_t array_completeness;
uint8_t NAL_unit_type;
uint16_t numNalus;
uint16_t *nalUnitLength;
uint8_t **nalUnit;
} HVCCNALUnitArray;
typedef struct HEVCDecoderConfigurationRecord {
uint8_t configurationVersion;
uint8_t general_profile_space;
uint8_t general_tier_flag;
uint8_t general_profile_idc;
uint32_t general_profile_compatibility_flags;
uint64_t general_constraint_indicator_flags;
uint8_t general_level_idc;
uint16_t min_spatial_segmentation_idc;
uint8_t parallelismType;
uint8_t chromaFormat;
uint8_t bitDepthLumaMinus8;
uint8_t bitDepthChromaMinus8;
uint16_t avgFrameRate;
uint8_t constantFrameRate;
uint8_t numTemporalLayers;
uint8_t temporalIdNested;
uint8_t lengthSizeMinusOne;
uint8_t numOfArrays;
HVCCNALUnitArray *array;
} HEVCDecoderConfigurationRecord;
参考ffmeg对该结构进行初始化如下:
static void hvcc_init(HEVCDecoderConfigurationRecord *hvcc)
{
memset(hvcc, 0, sizeof(HEVCDecoderConfigurationRecord));
hvcc->configurationVersion = 1;
hvcc->lengthSizeMinusOne = 3; // 4 bytes
/*
* The following fields have all their valid bits set by default,
* the ProfileTierLevel parsing code will unset them when needed.
*/
hvcc->general_profile_compatibility_flags = 0xffffffff;
hvcc->general_constraint_indicator_flags = 0xffffffffffff;
/*
* Initialize this field with an invalid value which can be used to detect
* whether we didn't see any VUI (in which case it should be reset to zero).
*/
hvcc->min_spatial_segmentation_idc = MAX_SPATIAL_SEGMENTATION + 1;
}
需要注意的是,该结构其他参数我们其实可以不特别关心,我们只需要在HVCCNALUnitArray数组中把HEVC的VPS,SPS和PPS信息填入即可。
最后,填写好Metadata信息后,我们还需要在发送帧数据的时候做一下修改,将I帧的tag头改成12,P帧tag不变,设置成1即可,如下代码所示:
int i = 0;
if(bIsKeyFrame)
{
//body[i++] = 0x17;// 2:Pframe 7:AVC
body[i++] = (m_metadata.nVideoCodec == FLV_CODECID_HEVC) ? 0x1C:0x17;// 1:Iframe 7:AVC 12:HEVC
if (m_bWaitingKeyFrame)
{
m_bWaitingKeyFrame = false;
}
}
else
{
//body[i++] = 0x27;// 2:Pframe 7:AVC
body[i++] = (m_metadata.nVideoCodec == FLV_CODECID_HEVC) ? 0x2C:0x27;// 1:Iframe 7:AVC 12:HEVC
}
body[i++] = 0x01;// AVC NALU
body[i++] = 0x00;
body[i++] = 0x00;
body[i++] = 0x00;
// NALU size
body[i++] = size>>24;
body[i++] = size>>16;
body[i++] = size>>8;
body[i++] = size&0xff;
EasyRTMP是TSINGSEE青犀开放平台(http://open.tsingsee.com)一套调用简单、功能完善、运行高效稳定的RTMP功能组件,经过多年实战和线上运行打造,支持RTMP推送断线重连、环形缓冲、智能丢帧、网络事件回调,支持Windows、Linux、arm(hisiv100/hisiv200/hisiv300/hisiv400/etc…)、Android、iOS平台,支持市面上绝大部分的RTMP流媒体服务器,包括Red5、Ngnix_rtmp、crtmpserver等主流RTMP服务器,能够完美应用于各种行业的直播需求,手机直播、桌面直播、摄像机直播、课堂直播等等方面!
EasyNVR摄像机网页直播中,推流组件EasyRTMP推送RTMP扩展支持HEVC(H.265)的方案的更多相关文章
- EasyNVR摄像机网页直播之问题解决:Failed:SYSTEM\CurrentCont......\Application\EasyNVR_Service registry key already
背景分析 经常使用EasyNVR产品的用户都知道,作为音视频行业互联网直播产品,EasyNVR主要功能在于通过RTSP/ONvif协议,接入前端音视频采集设备,通过EasyNVR软硬件产品将拉取过来的 ...
- EasyRTMP推送扩展支持HEVC(H265) RTMP推送之Metadata结构填写详解
我们在<EasyNVR摄像机网页直播中,推流组件EasyRTMP推送RTMP扩展支持HEVC(H.265)的方案>中描述了关于EasyRTMP进行RTMP HEVC(H.265)推流的概括 ...
- 最简单的基于FFmpeg的推流器(以推送RTMP为例)
===================================================== 最简单的基于FFmpeg的推流器系列文章列表: <最简单的基于FFmpeg的推流器(以 ...
- EasyRTMP手机直播推送rtmp流flash无法正常播放问题
本文转自EasyDarwin团队Kim的博客:http://blog.csdn.net/jinlong0603/article/details/52960750 问题简介 EasyRTMP是EasyD ...
- IOS中程序如何进行推送消息(本地推送,远程推送)
[1]-------------什么是推送消息? 我就以一张图解释------------ [2]-----------IOS程序中如何进行本地推送?----------- 2.1,先征求用户同意 1 ...
- MVC 中使用 SignalR 实现推送功能
MVC 中使用 SignalR 实现推送功能 一,简介 Signal 是微软支持的一个运行在 Dot NET 平台上的 html websocket 框架.它出现的主要目的是实现服务器主动推送(Pus ...
- 在 Asp.NET MVC 中使用 SignalR 实现推送功能 [转]
在 Asp.NET MVC 中使用 SignalR 实现推送功能 罗朝辉 ( http://blog.csdn.net/kesalin ) CC许可,转载请注明出处 一,简介 Signal 是微软支持 ...
- (转)基于libRTMP的流媒体直播之 AAC、H264 推送
参考: 1,基于libRTMP的流媒体直播之 AAC.H264 推送 http://billhoo.blog.51cto.com/2337751/1557646
- EasyNVR摄像机网页无插件直播方案H5前端构建之:使用BootstrapPagination以分页形式展示数据信息
背景介绍 EasyNVR核心在于摄像机的音视频流的获取.转换.转码与高性能分发,同时同步完成对实时直播流的录像存储,在客户端(PC浏览器.Android.iOS.微信)进行录像文件的检索.回放和下载. ...
随机推荐
- Cloudera Certified Associate Administrator案例之Install篇
Cloudera Certified Associate Administrator案例之Install篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.创建主机模板(为了给主 ...
- PC软件/web网站/小程序/手机APP产品如何增加个人收款接口
接入前准备 通过 XorPay 注册个人收款接口,原理是帮助你签约支付宝和微信(不需要营业执照)支持个人支付宝和个人微信支付接口,大概几分钟可以开通,开通后即可永久使用 PC 网站接入 效果:用户点击 ...
- 美好的童年伙伴:360 智能儿童手表 P1体验评测
写在前面 少年儿童作为祖国的花朵,未来的栋梁,也是我们每个做家长的心头肉.近年来各种新闻报道中校园欺凌.虐待事件频发,虽然依然只是个别事件,但我们依然会心怀担忧. 360作为安防软件起家的专业公司,凭 ...
- springboot+Mybatis+MySql 一个update标签中执行多条update sql语句
Mysql是不支持这种骚操作的,但是不代表并不能实现,只需要在jdbc配置文件中稍微做一下修改就行. driver=com.mysql.jdbc.Driver url=jdbc:mysql://127 ...
- debug版本的DLL调用release版本的DLL引发的一个问题
stl的常用结构有 vector.list.map等. 今天碰到需要在不同dll间传递这些类型的参数,以void*作为转换参数. 比如 DLL2 的接口 add(void*pVoid); 1.在DLL ...
- Hadoop跨集群迁移数据(整理版)
1. 什么是DistCp DistCp(分布式拷贝)是用于大规模集群内部和集群之间拷贝的工具.它使用Map/Reduce实现文件分发,错误处理和恢复,以及报告生成.它把文件和目录的列表作为map任务的 ...
- git基本操作及设置
$ git config --global user.name "wstmljf" $ git config --global user.email "wstmljf@1 ...
- 02-Flutter移动电商实战-建立项目和编写入口文件
环境搭建请参考之前写的一篇文章:Flutter_初体验_创建第一个应用 1.创建项目 采用AndroidStudio构建本项目,FIle>New>New Flutter Project… ...
- vue中前端弹窗队列展示
在前端写一个弹窗可能很简单,那如果同时有多个弹窗呢 这样的话就要考虑弹窗的展示问题,肯定是不能叠加在一起的,这时候就要通过队列(先进先出)来展示 思路就是根据队列来实现,至于具体的实现方式,可以在项目 ...
- HDU 1542.Atlantis-线段树求矩形面积并(离散化、扫描线/线段树)-贴模板
好久没写过博客了,这学期不是很有热情去写博客,写过的题也懒得写题解.现在来水一水博客,写一下若干年前的题目的题解. Atlantis Time Limit: 2000/1000 MS (Java/Ot ...