GB28181国标支持H.265编码吗?

时间:2022-10-05 07:16:44

好多开发者聊到GB28181的时候,不可避免的提到H.265编码国标平台是否支持?实际上,GB/T28181-2016里面,并未提及H.265编解码相关,具体参见以下说明:

视音频编/解码技术要求

联网系统中,对视音频编/解码的技术要求包括编/解码的档次和级别、工具选项、码流语法的规定以及比特流和解码器的一致性测试等。具体要求如下:

视频编码应支持 H.264、SVAC 或 MPEG-4 视频编码标准,视频解码应同时支持 H.264、SVAC 和MPEG-4 视频解码标准。

音频编码应支持 G.711或 G.723.1或 G.729或SVAC音频编码标准,音频解码应同时支持 G.711、G.723.1、G.729和SVAC音频解码标准,可扩展支持ITU-TRec.G.722.1-1999音频解码标准。

基于 H.264的视频编、解码技术要求
E.1.1 H.264的档次和级别

采用 H.264标准的视频编码应至少支持ITU-T Rec.H.264-2005视频标准的基本档次(Baseline Profile),级别(Level)应至少支持到 Level1.3,标清应用宜扩展支持到 Level3,高清应用宜扩展支持到Level4;视频解码所支持的档次和级别应不低于编码支持的最高档次和级别,至少应支持到 H.264视频标准基本档次的 Level3;视频解码宜扩展支持 H.264主档次(MainProfile)中的隔行扫描和 B帧工具,且相邻两 P帧间的 B帧个数不大于2。

采用 H.264标准的高清视频编码应至少支持ITU-TRec.H.264-2005视频标准的基本档次(BaselineProfile),宜扩展支持 H.264 主档次(MainProfile)和高级档次(HighProfile),级别(Level)宜扩展支持到 Level4;视频解码所支持的档次和级别应不低于编码支持的最高档次和级别,至少应支持到H.264 视频标准高级档次(HighProfile)的 Level4。H.264主档次和高级档次视频编码标准的具体描述详见ITU-TRec.H.264-2005中的相关规定。

E.1.1.1 H.264基本档次的选项和工具

H.264基本档次支持的选项和工具主要有:

  • a) I片和 P片(Slice);
  • b) 基于内容自适应的变长编码 CAVLC;
  • c) 容错工具:FMO、ASO、RS;
  • d) 去块效应滤波器(DeblockingFilter);
  • e) 多参考帧编码。

采用 H.264编码标准的视频流应为 H.264Baseline视频流,编码应支持上述 Baseline选项和工具中的部分或全部,可不支持容错工具;H.264的解码至少应支持上述除容错工具外的全部选项和工具。

多参考帧编码时,P片的参考帧数一般不大于2帧。为了保证码流解析的效率,比特流中应当在每个I帧之前都出现相应的SPS 和 PPS

E.1.1.2 H.264级别的限制

H.264级别(Level1~4)的限制如表 E.1所示,表中“—”表示未做相应的限制。

GB28181国标支持H.265编码吗?

GB28181接入端到底要不要支持H.265?

问题来了,如果GB28181平台端上去H.265的数据怎么办?如果做的比较好的平台端,不需要web播放的话,也可以转成其他如RTMP(需要RTMP支持扩展H.265)等播放,由于web端不支持H.265的播放,好多第三方国标平台,是先把H.265转H.264后再播放,这样导致的问题是,平台端性能消耗比较大,而且处理不好的话,容易导致实时音视频延迟或不同步问题。

以Android平台GB28181设备接入为例,我们实现了几种模式的编码,如H.264软编、H.264硬编、H.265硬编,而且硬编码,还实现了基于native madiacodec的硬编,进一步提高了编码效率,相关设置如下:

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) {

}
});

Init的时候,设置如下:

if(videoEncodeType == 1)  {
int h264HWKbps = setHardwareEncoderKbps(true, video_width_, video_height_);
h264HWKbps = h264HWKbps*fps/25;

Log.i(TAG, "h264HWKbps: " + h264HWKbps);

int isSupportH264HWEncoder = libPublisher
.SetSmartPublisherVideoHWEncoder(publisherHandle, h264HWKbps);

if (isSupportH264HWEncoder == 0) {
libPublisher.SetNativeMediaNDK(publisherHandle, 1);
Log.i(TAG, "Great, it supports h.264 hardware encoder!");
}
}
else if (videoEncodeType == 2) {
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, 1);
Log.i(TAG, "Great, it supports hevc hardware encoder!");
}
}

如果GB28181平台端对H.265支持不好,最简单的做法,还是直接让设备接入端设置成H.264软编或硬编码。