GB/T28181-2022针对H.265编码细化及技术实现

简介: 新版国家标准GB/T28181-2022《公共安全视频监控联网系统信息传输、交换、控制技术要求》已于2022年12月30日发布,并将于2023年7月1日正式实施。

技术背景

新版国家标准GB/T28181-2022《公共安全视频监控联网系统信息传输、交换、控制技术要求》已于2022年12月30日发布,并将于2023年7月1日正式实施。


国家标准GB/T28181-2022《公共安全视频监控联网系统信息传输、交换、控制技术要求》规定了公共安全视频监控联网系统(以下简称“联网系统”)的互联结构,传输、交换、控制的基本要求和安全性要求,以及控制、传输流程和协议接口等技术要求。适用于公共安全视频监控联网系统的方案设计、系统检测、验收以及与之相关的设备研发、生产。其他视频监控联网系统可参照执行。


新版国家标准GB/T28181-2022《公共安全视频监控联网系统信息传输、交换、控制技术要求》代替了GB/T28181—2016《公共安全视频监控联网系统信息传输、交换、控制技术要求》,与GB/T28181—2016相比,除结构调整和编辑性改动外,相关主要技术有一些变化。例如更改了标准范围,删除了“联网系统信息”“数字接入”“模拟接入”“模数混合型监控系统”“数字型监控系统”“监控点”“监控中心”的术语和定义,更改了“SIP监控域”“非SIP监控域”“级联”“互联”的术语和定义,更改了“SIP监控域互联结构示意图”,更改了“联网系统通信协议结构图”,媒体流通道增加了H.265、G.722.1、AAC等等。

GB/T28181-2022规范描述

基于RTP的视音频数据PS封装


基于RTP的PS封装首先按照ISO/IEC 13818-1:2019将视音频流封装成PS包,再将PS包以负载的方式封装成RTP包。


进行PS封装时,应将母个悦team Map),系统头和PSM放置于PS包头之后、第一十 ti(System Header)和 PSM(Program Stream Map),系统头和PSM放置于PS包头之后、第一个PES包


之前。


典型的视频关键帧PS包结构如图C.1所示,其中 PESV为视频PES包,PESA为音频PES包,视频非关键帧的PS包结构中一般不包含系统头和PSM。PS包中各部分的具体数据结构参见ISO/IEC13818-1 :2019中的相关描述。

6ccd6a6e6c194f36a7c86cd8aa7c6aeb.png

系统头应包含对PS包中码流种类的描述,其中视频和音频的流ID(stream_id)取值如下:


a)视频流ID:0xEO;


b)音频流ID:0xCO。


针对本文件规定的几种视音频格式,PSM中流类型(stream_type)的取值如下:


a) MPEG-4视频流:0x10;


b)H.264视频流:0x1B;


c) SVAC视频流:0x80;


d)H.265视频流:0x24;


e)G.711A律音频流:0x90;


f)G.711U律音频流:0x91;


g)G.722.1音频流:0x92;


h)G.723.1音频流:0x93;


i)G.729音频流:0x99;


j)sVAC音频流:0x9B;


k)AAC音频流:0xOF。


PS包封装的其他具体技术规范详见ISO/IEC 13818-1:2019。


PS包的RTP封装格式参照IETF RFC 2250,RTP的主要参数设置如下:a)负载类型( payload type) :96;


b)编码名称(encoding name) ; PS;c)时钟频率(clock rate):90kHz;


d)SDP描述中“m”字段的“media”项:video。


基于RTP的视音频封装


H.265视频流的RTP封装


H.265的RTP载荷格式应符合IETF RFC 7798的相关规定。


H.265视频流RTP包的负载类型(Payload Type)标识号选定:从IETF RFC3551协议表5的动态范围(96~~127)中选择,建议定为100,根据实际需要填充。


H.265视频编﹑解码技术要求不再赘述,这里需要注意的是:为了保证码流解析的效率,比特流中应当在每个Ⅰ帧之前都出现相应的视频参数集(Video Param-eter Set,VPS)、序列参数集(Sequence Parameter Set, SPS)和图像参数集(Picture Parameter Set,PPS)。

技术实现

实际上,我们在实现GB28181-2016的时候,就已经支持了H.265编码,需要注意的是,由于H.265编码复杂度比较高,Android平台一般建议硬编码:

48dd317dd5d74fcb9867aa96f3012719.jpg

编码类型选择如下:

        //视频编码类型选择++++++++++
        videoEncodeTypeSelector = (Spinner)findViewById(R.id.videoEncodeTypeSelector);
        final String[] videoEncodeTypes = new String[]{"软编(H.264)", "硬编(H.264)", "硬编(H.265)"};
        ArrayAdapter<String> adapterVideoEncodeType = new ArrayAdapter<String>(this,
                android.R.layout.simple_spinner_item, videoEncodeTypes);
        adapterVideoEncodeType.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        videoEncodeTypeSelector.setAdapter(adapterVideoEncodeType);
        videoEncodeTypeSelector.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view,
                                       int position, long id) {
                if (isRTSPPublisherRunning || isPushingRtmp || isGB28181StreamRunning || isRecording) {
                    Log.e(TAG, "Could not switch video encoder type during publishing..");
                    return;
                }
                videoEncodeType = position;
                Log.i(TAG, "[视频编码类型]Currently choosing: " + videoEncodeTypes[position] + ", videoEncodeType: " + videoEncodeType);
            }
            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });

接口设计:

    /**
     * Author: daniusdk.com
     *
   * Set Video H.265(hevc) hardware encoder, if support H.265(hevc) hardware encoder, it will return 0(设置H.265硬编码)
   *
   * @param kbps: the kbps of different resolution.
   *
   * @return {0} if successful
   */
  public native int SetSmartPublisherVideoHevcHWEncoder(long handle, int kbps);


如果需要用native mediacodec编码,可以设置底层ndk硬编码模式:

  /**
   * 设置视频硬编码是否使用 Native Media NDK, 默认是不使用, 安卓5.0以下设备不支持
   * @param handle
   * @param is_native: 0表示不使用, 1表示使用, sdk默认是0.
   * @return {0} if successful
   */
  public native int SetNativeMediaNDK(long handle, int is_native);


除此之外,我们针对H.264、H.265硬编码还做了更精细化的处理:

  /*
  * 设置视频硬编码码率控制模式
  * @param hw_bitrate_mode: -1表示使用默认值, 不设置也会使用默认值, 0:CQ, 1:VBR, 2:CBR, 3:CBR_FD, 请参考:android.media.MediaCodecInfo.EncoderCapabilities
  * 注意硬编码和手机硬件有关,多数手机只支持部分码率模式, 另外硬编码设备差异很大,不同设备同一码率控制模式效果可能不一样
  * @return {0} if successful
  */
  public native int SetVideoHWEncoderBitrateMode(long handle, int hw_bitrate_mode);
  /*
   * 设置视频硬编码复杂度, 安卓5.0及以上支持
   * @param hw_complexity: -1表示不设置, 请参考:android.media.MediaCodecInfo.EncoderCapabilities.getComplexityRange() 和 android.media.MediaFormat.KEY_COMPLEXITY
   * 注意硬编码和手机硬件有关,部分手机可能不支持此设置
   * @return {0} if successful
   */
  public native int SetVideoHWEncoderComplexity(long handle, int hw_complexity);
  /*
   * 设置视频硬编码质量, 安卓9及以上支持, 仅当硬编码器码率控制模式(BitrateMode)是CQ(constant-quality mode)时才有效
   * @param hw_quality: -1表示不设置, 请参考:android.media.MediaCodecInfo.EncoderCapabilities.getQualityRange() 和 android.media.MediaFormat.KEY_QUALITY
   * 注意硬编码和手机硬件有关,部分手机可能不支持此设置
   * @return {0} if successful
   */
  public native int SetVideoHWEncoderQuality(long handle, int hw_quality);
  /*
   * 设置H.264硬编码Profile, 安卓7及以上支持
   * @param hw_avc_profile: 0表示使用默认值, 0x01: Baseline, 0x02: Main, 0x08: High, 0x10000: ConstrainedBaseline, 0x80000: ConstrainedHigh;
   * 注意: ConstrainedBaseline 和 ConstrainedHigh 可能多数设备不支持,
   * H.264推荐使用 High 或者 ConstrainedHigh, 如果您使用的手机硬解码解不了,那还是设置Baseline
   * 如果设置的Profile硬编码器不支持,应编码器会使用默认值
   * 具体参考:android.media.MediaCodecInfo.CodecProfileLevel
   * @return {0} if successful
   */
  public native int SetAVCHWEncoderProfile(long handle, int hw_avc_profile);
  /*
   * 设置H.264硬编码Level, 这个只有在设置了Profile的情况下才有效, 安卓7及以上支持
   * @param hw_avc_level: 0表示使用默认值, 0x100: Level3, 0x200: Level3.1, 0x400: Level3.2,
   * 0x800: Level4, 0x1000: Level4.1, 0x2000: Level4.2,
   * 0x4000: Level5, 0x8000: Level5.1,  0x10000: Level5.2,
   * 0x20000: Level6, 0x40000: Level6.1,  0x80000: Level6.2,
   * 如果设置的level太高硬编码器不支持,SDK内部会做相应调整
   * 注意: 640*480@25fps最小支持的是Level3, 720p最小支持的是Level3.1, 1080p最小支持的是Level4
   * 具体参考:android.media.MediaCodecInfo.CodecProfileLevel
   * @return {0} if successful
   */
  public native int SetAVCHWEncoderLevel(long handle, int hw_avc_level);
  /*
   * 设置视频硬编码最大码率, 安卓没有相关文档说明, 所以不建议设置,
   * @param hw_max_bitrate: 每秒最大码率, 单位bps
   * @return {0} if successful
   */
  public native int SetVideoHWEncoderMaxBitrate(long handle, long hw_max_bitrate);


外部调用如下:

int hevcHWKbps = setHardwareEncoderKbps(false, video_width_, video_height_);
hevcHWKbps = hevcHWKbps*fps/25;
Log.i(TAG, "hevcHWKbps: " + hevcHWKbps);
int isSupportHevcHWEncoder = libPublisher
    .SetSmartPublisherVideoHevcHWEncoder(publisherHandle, hevcHWKbps);
if (isSupportHevcHWEncoder == 0) {
  libPublisher.SetNativeMediaNDK(publisherHandle, 0);
  libPublisher.SetVideoHWEncoderBitrateMode(publisherHandle, 0); // 0:CQ, 1:VBR, 2:CBR
  libPublisher.SetVideoHWEncoderQuality(publisherHandle, 39);
  // libPublisher.SetVideoHWEncoderMaxBitrate(publisherHandle, ((long)hevcHWKbps)*1200);
  Log.i(TAG, "Great, it supports hevc hardware encoder!");
}


技术总结

GB28181-2022针对H.265编码说明,弥补了2016规范的不足,H.265编码,移动端软编特别是针对高分辨率帧率,性能瓶颈很大,更合理的方案是实现高效率的H.265硬编模式,GB28181-2022,让H.265支持终于体现在规范层面,有理有据,相信会有更广阔的用武之地。

相关文章
|
NoSQL 搜索推荐 openCL
【C/C++ 调试 GDB指南 】gdb调试基本操作
【C/C++ 调试 GDB指南 】gdb调试基本操作
805 2
|
9月前
|
机器学习/深度学习 人工智能 PyTorch
从零开始:如何训练自己的AI模型
### 从零开始:如何训练自己的AI模型 训练AI模型如同培养新生儿,需耐心与技巧。首先明确目标(如图像识别、自然语言处理),选择框架(TensorFlow、PyTorch)。接着收集并预处理数据,确保多样性和准确性。然后设计模型结构,如卷积神经网络(CNN),并通过代码实现训练。训练后评估模型性能,调优以避免过拟合。最后部署模型至实际应用。通过猫狗分类器案例,掌握关键步骤和常见问题。训练AI模型是不断迭代优化的过程,实践才能真正掌握精髓。
|
9月前
|
存储 机器学习/深度学习 编解码
图片转码服务能力升级-基于人眼主观优化的图片编码技术
图片转码服务能力升级-基于人眼主观优化的图片编码技术
132 0
使用阿里云快速构建海外镜像实战案例
关于如何使用阿里云服务快速构建海外镜像的实战案例,包括在GitHub创建项目和在阿里云配置镜像仓库的详细步骤。
582 2
使用阿里云快速构建海外镜像实战案例
|
存储 搜索推荐 Java
微服务SpringCloud ES分布式全文搜索引擎简介 下载安装及简单操作入门
微服务SpringCloud ES分布式全文搜索引擎简介 下载安装及简单操作入门
327 2
|
负载均衡 算法 Linux
快速掌握keepalived
快速掌握keepalived
387 0
|
算法 搜索推荐 Shell
Shell编程之数组排序算法(冒泡排序、直接选择排序、反转排序)
1、数组排序(使用tr、sort、for) 操作步骤; 使用tr命令将数组内每个元素之间的空格替换为换行符; 之后使用sort命令按从小到大重新排序; 最后使用for循环遍历排序后的元素值。
624 0
大学物理(上)-期末知识点结合习题复习(4)——质点运动学-动能定理 力做功 保守力与非保守力 势能 机械能守恒定律 完全弹性碰撞
大学物理(上)-期末知识点结合习题复习(4)——质点运动学-动能定理 力做功 保守力与非保守力 势能 机械能守恒定律 完全弹性碰撞
430 0
|
Python
使用PyInstaller将Python应用程序打包成EXE文件
使用PyInstaller将Python应用程序打包成EXE文件
1103 0
|
XML NoSQL Linux
内存泄漏专题(3)内存泄漏调试神器valgrind
内存泄漏专题(3)内存泄漏调试神器valgrind
300 0