我们在做Windows平台RTMP推送或轻量级RTSP服务模块的时候,遇到这样的问题,有些超高清场景(4K甚至更高分辨率)或高帧率场景(50帧+)的编码,比如地铁安检机数据分析检测,设备性能一般的话,软编码很容易出现瓶颈,这个时候就需要硬编。基于此,我们前几年发布了基于NVIDIA的硬编。
硬编码逻辑调用:
private void LoadHWVideoEncoderInfos()
{
hw_video_encoder_infos_.Clear();
Int32 count = 0;
UInt32 ret = NTSmartPublisherSDK.NT_PB_GetHWVideoEncoderInfoCount(ref count);
if (NTBaseCodeDefine.NT_ERC_OK == ret && count > 0)
{
IntPtr ptr_hw_video_encoder_infos = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(NT_PB_HWVideoEncoderInfo)) * count);
Int32 out_count = 0;
ret = NTSmartPublisherSDK.NT_PB_GetHWVideoEncoderInfos(ptr_hw_video_encoder_infos, count, ref out_count);
if (ret != NTBaseCodeDefine.NT_ERC_OK || out_count < 1)
{
hw_video_encoder_infos_.Clear();
}
else
{
for (int i = 0; i < out_count; i++)
{
NT_PB_HWVideoEncoderInfo hw_video_encoder_info = (NT_PB_HWVideoEncoderInfo)Marshal.PtrToStructure(ptr_hw_video_encoder_infos + i * Marshal.SizeOf(typeof(NT_PB_HWVideoEncoderInfo)), typeof(NT_PB_HWVideoEncoderInfo));
hw_video_encoder_infos_.Add(hw_video_encoder_info);
}
}
Marshal.FreeHGlobal(ptr_hw_video_encoder_infos);
}
}
private bool IsSupportHWVideoEncoder(UInt32 codec_id)
{
foreach (var i in hw_video_encoder_infos_)
{
if (codec_id == i.codec_id_)
return true;
}
return false;
}
private void EnableHWVideoEncoderControls(bool is_enable)
{
btn_check_video_hardware_encoder_.Enabled = is_enable;
combobox_video_encoders_.Enabled = is_enable;
combobox_video_hardware_encoder_devices_.Enabled = is_enable;
}
接口设计:
/*
* 获取视频硬编码器信息数
* count: 返回的数量
* 成功返回 NT_ERC_OK
*/
[DllImport(@"SmartPublisherSDK.dll")]
public static extern UInt32 NT_PB_GetHWVideoEncoderInfoCount(ref Int32 count);
/*
* 获取视频硬编码信息
* infos: 请先调用GetHWVideoEncoderInfoCount, 然后分配这个数组
* info_array_size: 分配的数组大小
* out_count: 实际返回的数量
* 成功返回 NT_ERC_OK
*/
[DllImport(@"SmartPublisherSDK.dll")]
public static extern UInt32 NT_PB_GetHWVideoEncoderInfos(IntPtr infos, Int32 info_array_size, ref Int32 out_count);
/*
* 设置软硬编码类型, 编码器, codec_id, 编码器其他参数.
* type: 0为软编码, 1为硬编码, 默认是软编码.
* encoder_id: 如果是软编码, 并且用h264, 可以设置0, 0用默认编码器, 也可以设置1, 设置1将使用OpenH264编码. 如果不是h264, 请设置成0; 如果是硬编码, 128为NVIDIA video encoder (NVENC), 填其他值接口返回错误.
* param1: 如果是软编码,请设置0; 如果是硬编码且是NVENC, 这个参数用来设置GPU index, 设置-1的话SDK自动选择GPU.
* codec_id: 设置h264或h265编码, 默认是h264, 请参考NT_MEDIA_CODEC_ID, h264填 NT_MEDIA_CODEC_ID_H264, h265填 NT_MEDIA_CODEC_ID_H265.
* 注意: 软编码不支持h265, 硬编码根据实际硬件情况决定是否支持h265.
* 如果调用了这个接口,请不要再调用SetVideoEncoderType接口
* 成功返回 NT_ERC_OK
*/
[DllImport(@"SmartPublisherSDK.dll")]
public static extern UInt32 NT_PB_SetVideoEncoder(IntPtr handle, Int32 type, Int32 encoder_id, UInt32 codec_id, Int32 param1);
如果需要看自己配置的硬件设备是不是支持硬编码,可以到NVIDIA官方网站查看,当然也可以用我们的接口做检测,网站链接如下:
Video Encode and Decode GPU Support Matrix | NVIDIA Developer