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

发布时间:2023年12月28日

我们在做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

文章来源:https://blog.csdn.net/renhui1112/article/details/135251144
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。