use std::ffi::c_void;
use std::os::raw::{c_int, c_uint};
pub(super) const NV_ENC_SUCCESS: c_uint = 0;
pub(super) const NV_ENC_ERR_INVALID_PTR: c_uint = 6;
pub(super) const NV_ENC_ERR_INVALID_PARAM: c_uint = 8;
pub(super) const NV_ENC_ERR_ENCODER_NOT_INITIALIZED: c_uint = 11;
pub(super) const NV_ENC_ERR_LOCK_BUSY: c_uint = 13;
pub(super) const NV_ENC_ERR_NEED_MORE_INPUT: c_uint = 17;
pub(super) const NV_ENC_ERR_ENCODER_BUSY: c_uint = 18;
pub(super) const NV_ENC_DEVICE_TYPE_CUDA: c_uint = 1;
pub(super) const NV_ENC_BUFFER_FORMAT_IYUV: c_uint = 0x00000100;
pub(super) const NV_ENC_BUFFER_FORMAT_YUV420_10BIT: c_uint = 0x00010000;
pub(super) const NV_ENC_PIC_FLAG_FORCEIDR: c_uint = 0x02;
pub(super) const NV_ENC_PIC_FLAG_EOS: c_uint = 0x08;
pub(super) const NV_ENC_PIC_TYPE_P: c_uint = 0;
pub(super) const NV_ENC_PIC_TYPE_I: c_uint = 2;
pub(super) const NV_ENC_PIC_TYPE_IDR: c_uint = 3;
#[allow(dead_code)]
pub(super) const NV_ENC_TUNING_INFO_HIGH_QUALITY: c_uint = 1;
pub(super) const NV_ENC_PARAMS_RC_CONSTQP: u32 = 0x0;
pub(super) const NV_ENC_PARAMS_RC_VBR: u32 = 0x1;
pub(super) const RC_FLAG_ENABLE_LOOKAHEAD: u32 = 1 << 5;
pub(super) const RC_FLAG_ZERO_REORDER_DELAY: u32 = 1 << 9;
#[allow(dead_code)]
pub(super) const NV_ENC_PARAMS_RC_VBR_HQ: u32 = 0x20;
pub(super) const RING_SIZE: usize = 4;
pub(super) const NVENCAPI_MAJOR: u32 = 13;
pub(super) const NVENCAPI_MINOR: u32 = 0;
pub(super) const NVENCAPI_VERSION: u32 = NVENCAPI_MAJOR | (NVENCAPI_MINOR << 24);
pub(super) const fn struct_version(ver: u32) -> u32 {
NVENCAPI_VERSION | (ver << 16) | (0x7 << 28)
}
pub(super) const NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER: u32 = struct_version(1); pub(super) const NV_ENC_INITIALIZE_PARAMS_VER: u32 = struct_version(7) | (1u32 << 31); pub(super) const NV_ENC_CREATE_INPUT_BUFFER_VER: u32 = struct_version(2); pub(super) const NV_ENC_CREATE_BITSTREAM_BUFFER_VER: u32 = struct_version(1); pub(super) const NV_ENC_LOCK_INPUT_BUFFER_VER: u32 = struct_version(1); pub(super) const NV_ENC_LOCK_BITSTREAM_VER: u32 = struct_version(2) | (1u32 << 31); pub(super) const NV_ENC_PIC_PARAMS_VER: u32 = struct_version(7) | (1u32 << 31); pub(super) const NV_ENC_CONFIG_VER: u32 = struct_version(9) | (1u32 << 31); pub(super) const NV_ENC_PRESET_CONFIG_VER: u32 = struct_version(5) | (1u32 << 31);
#[repr(C)]
#[derive(Clone, Copy, PartialEq, Eq)]
pub(super) struct Guid {
pub(super) data1: u32,
pub(super) data2: u16,
pub(super) data3: u16,
pub(super) data4: [u8; 8],
}
pub(super) const NV_ENC_CODEC_AV1_GUID: Guid = Guid {
data1: 0x0a352289,
data2: 0x0aa7,
data3: 0x4759,
data4: [0x86, 0x2d, 0x5d, 0x15, 0xcd, 0x16, 0xd2, 0x54],
};
pub(super) const NV_ENC_CODEC_H264_GUID: Guid = Guid {
data1: 0x6bc82762,
data2: 0x4e63,
data3: 0x4ca4,
data4: [0xaa, 0x85, 0x1e, 0x50, 0xf3, 0x21, 0xf6, 0xbf],
};
pub(super) const NV_ENC_CODEC_HEVC_GUID: Guid = Guid {
data1: 0x790cdc88,
data2: 0x4522,
data3: 0x4d7b,
data4: [0x94, 0x25, 0xbd, 0xa9, 0x97, 0x5f, 0x76, 0x03],
};
pub(super) const NV_ENC_H264_PROFILE_HIGH_GUID: Guid = Guid {
data1: 0xe7cbc309,
data2: 0x4f7a,
data3: 0x4b89,
data4: [0xaf, 0x2a, 0xd5, 0x37, 0xc9, 0x2b, 0xe3, 0x10],
};
pub(super) const NV_ENC_HEVC_PROFILE_MAIN_GUID: Guid = Guid {
data1: 0xb514c39a,
data2: 0xb55b,
data3: 0x40fa,
data4: [0x87, 0x8f, 0xf1, 0x25, 0x3b, 0x4d, 0xfd, 0xec],
};
pub(super) const NV_ENC_HEVC_PROFILE_MAIN10_GUID: Guid = Guid {
data1: 0xfa4d2b6c,
data2: 0x3a5b,
data3: 0x411a,
data4: [0x80, 0x18, 0x0a, 0x3f, 0x5e, 0x3c, 0x9b, 0xe5],
};
pub(super) fn nvenc_codec_guid(codec: crate::frame::VideoCodec) -> Guid {
use crate::frame::VideoCodec;
match codec {
VideoCodec::Av1 => NV_ENC_CODEC_AV1_GUID,
VideoCodec::H264 => NV_ENC_CODEC_H264_GUID,
VideoCodec::H265 => NV_ENC_CODEC_HEVC_GUID,
}
}
pub(super) fn nvenc_profile_guid(codec: crate::frame::VideoCodec, ten_bit: bool) -> Guid {
use crate::frame::VideoCodec;
match codec {
VideoCodec::H264 => NV_ENC_H264_PROFILE_HIGH_GUID,
VideoCodec::H265 if ten_bit => NV_ENC_HEVC_PROFILE_MAIN10_GUID,
VideoCodec::H265 => NV_ENC_HEVC_PROFILE_MAIN_GUID,
VideoCodec::Av1 => Guid { data1: 0, data2: 0, data3: 0, data4: [0u8; 8] },
}
}
#[repr(C)]
pub(super) struct NvEncCapsParam {
pub(super) version: u32,
pub(super) caps_to_query: c_uint,
pub(super) reserved: [u32; 62],
}
pub(super) const NV_ENC_CAPS_WIDTH_MAX: c_uint = 16;
pub(super) const NV_ENC_CAPS_HEIGHT_MAX: c_uint = 17;
pub(super) const NV_ENC_CAPS_SUPPORT_10BIT_ENCODE: c_uint = 39;
#[allow(dead_code)]
pub(super) const NV_ENC_PRESET_P5_GUID: Guid = Guid {
data1: 0x21c6e6b4,
data2: 0x297a,
data3: 0x4cba,
data4: [0x99, 0x8f, 0xb6, 0xcb, 0xde, 0x72, 0xad, 0xe3],
};
#[allow(dead_code)]
pub(super) const NV_ENC_PRESET_P6_GUID: Guid = Guid {
data1: 0x8e75c279,
data2: 0x6299,
data3: 0x4ab6,
data4: [0x83, 0x02, 0x0b, 0x21, 0x5a, 0x33, 0x5c, 0xf5],
};
#[allow(dead_code)]
pub(super) const NV_ENC_PRESET_P7_GUID: Guid = Guid {
data1: 0x84848c12,
data2: 0x6f71,
data3: 0x4c13,
data4: [0x93, 0x1b, 0x53, 0xe2, 0x83, 0xf5, 0x79, 0x74],
};
pub(super) fn guid_from_bytes(bytes: [u8; 16]) -> Guid {
Guid {
data1: u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]),
data2: u16::from_le_bytes([bytes[4], bytes[5]]),
data3: u16::from_le_bytes([bytes[6], bytes[7]]),
data4: [
bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15],
],
}
}
pub(super) type CUresult = c_int;
pub(super) type CUdevice = c_int;
pub(super) type CUcontext = *mut c_void;
pub(super) type FnCuInit = unsafe extern "C" fn(c_uint) -> CUresult;
pub(super) type FnCuDeviceGet = unsafe extern "C" fn(*mut CUdevice, c_int) -> CUresult;
pub(super) type FnCuCtxCreate = unsafe extern "C" fn(*mut CUcontext, c_uint, CUdevice) -> CUresult;
pub(super) type FnCuCtxDestroy = unsafe extern "C" fn(CUcontext) -> CUresult;
pub(super) type FnCuCtxPushCurrent = unsafe extern "C" fn(CUcontext) -> CUresult;
pub(super) type FnCuCtxPopCurrent = unsafe extern "C" fn(*mut CUcontext) -> CUresult;
pub(super) const NV_ENCODE_API_FUNCTION_LIST_VER: u32 = struct_version(2);
pub(super) type FnNvEncodeAPIGetMaxSupportedVersion = unsafe extern "C" fn(*mut u32) -> c_uint;
pub(super) type FnNvEncodeAPICreateInstance =
unsafe extern "C" fn(*mut super::buffers::NvEncFunctionList) -> c_uint;
pub(super) type FnNvEncGetEncodeGUIDCount =
unsafe extern "C" fn(*mut c_void, *mut u32) -> c_uint;
pub(super) type FnNvEncGetEncodeGUIDs =
unsafe extern "C" fn(*mut c_void, *mut Guid, u32, *mut u32) -> c_uint;
pub(super) type FnNvEncGetEncodeCaps =
unsafe extern "C" fn(*mut c_void, Guid, *mut NvEncCapsParam, *mut c_int) -> c_uint;
pub(super) type FnNvEncOpenEncodeSessionEx =
unsafe extern "C" fn(*mut super::ffi::NvEncOpenEncodeSessionExParams, *mut *mut c_void)
-> c_uint;
pub(super) type FnNvEncInitializeEncoder =
unsafe extern "C" fn(*mut c_void, *mut super::ffi::NvEncInitializeParams) -> c_uint;
pub(super) type FnNvEncCreateInputBuffer =
unsafe extern "C" fn(*mut c_void, *mut super::buffers::NvEncCreateInputBuffer) -> c_uint;
pub(super) type FnNvEncDestroyInputBuffer =
unsafe extern "C" fn(*mut c_void, *mut c_void) -> c_uint;
pub(super) type FnNvEncCreateBitstreamBuffer =
unsafe extern "C" fn(*mut c_void, *mut super::buffers::NvEncCreateBitstreamBuffer) -> c_uint;
pub(super) type FnNvEncDestroyBitstreamBuffer =
unsafe extern "C" fn(*mut c_void, *mut c_void) -> c_uint;
pub(super) type FnNvEncLockInputBuffer =
unsafe extern "C" fn(*mut c_void, *mut super::buffers::NvEncLockInputBuffer) -> c_uint;
pub(super) type FnNvEncUnlockInputBuffer =
unsafe extern "C" fn(*mut c_void, *mut c_void) -> c_uint;
pub(super) type FnNvEncEncodePicture =
unsafe extern "C" fn(*mut c_void, *mut super::buffers::NvEncPicParams) -> c_uint;
pub(super) type FnNvEncLockBitstream =
unsafe extern "C" fn(*mut c_void, *mut super::buffers::NvEncLockBitstream) -> c_uint;
pub(super) type FnNvEncUnlockBitstream =
unsafe extern "C" fn(*mut c_void, *mut c_void) -> c_uint;
pub(super) type FnNvEncDestroyEncoder =
unsafe extern "C" fn(*mut c_void) -> c_uint;
pub(super) type FnNvEncGetEncodePresetConfigEx =
unsafe extern "C" fn(*mut c_void, Guid, Guid, u32, *mut super::ffi::NvEncPresetConfig)
-> c_uint;
const _: () = assert!(NV_ENC_BUFFER_FORMAT_YUV420_10BIT == 0x00010000);
const _: () = assert!(NV_ENC_BUFFER_FORMAT_IYUV == 0x00000100);