Windows平台实现超高分辨率或帧率硬编码

​我们在做Windows平台RTMP推送或轻量级RTSP服务模块的时候,遇到这样的问题,有些超高清场景(4K甚至更高分辨率)或高帧率场景(50帧+)的编码,比如地铁安检机数据分析检测,设备性能一般的话,软编码很容易出现瓶颈,这个时候就需要硬编。基于此,我们前几年发布了基于NVIDIA的硬编。

硬编码逻辑调用:

代码语言:csharp
复制
        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;
    }</code></pre></div></div><p>接口设计:</p><div class="rno-markdown-code"><div class="rno-markdown-code-toolbar"><div class="rno-markdown-code-toolbar-info"><div class="rno-markdown-code-toolbar-item is-type"><span class="is-m-hidden">代码语言:</span>csharp</div></div><div class="rno-markdown-code-toolbar-opt"><div class="rno-markdown-code-toolbar-copy"><i class="icon-copy"></i><span class="is-m-hidden">复制</span></div></div></div><div class="developer-code-block"><pre class="prism-token token line-numbers language-csharp"><code class="language-csharp" style="margin-left:0">        /*
     * 获取视频硬编码器信息数
     * count: 返回的数量
     * 成功返回 NT_ERC_OK
	 */
    [DllImport(@&#34;SmartPublisherSDK.dll&#34;)]
	public static extern UInt32 NT_PB_GetHWVideoEncoderInfoCount(ref Int32 count);

	/*
     * 获取视频硬编码信息
     * infos: 请先调用GetHWVideoEncoderInfoCount, 然后分配这个数组
     * info_array_size: 分配的数组大小
     * out_count: 实际返回的数量
     * 成功返回 NT_ERC_OK
	 */
    [DllImport(@&#34;SmartPublisherSDK.dll&#34;)]
    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(@&#34;SmartPublisherSDK.dll&#34;)]
	public static extern UInt32 NT_PB_SetVideoEncoder(IntPtr handle, Int32 type, Int32 encoder_id, UInt32 codec_id, Int32 param1);</code></pre></div></div><p>如果需要看自己配置的硬件设备是不是支持硬编码,可以到NVIDIA官方网站查看,当然也可以用我们的接口做检测,网站链接如下:</p><p>Video Encode and Decode GPU Support Matrix | NVIDIA Developer</p><p>​</p>