#![allow(non_snake_case)]
#![allow(non_camel_case_types)]
#![allow(non_upper_case_globals)]
mod error;
mod generated {
pub mod consts;
#[cfg(feature = "libloading")]
pub mod fns_libloading;
#[cfg(feature = "source")]
pub mod fns_source;
pub mod types;
}
pub use self::generated::consts::*;
pub use self::generated::types::*;
pub use error::Error;
use std::os::raw::{c_int, c_long};
#[rustfmt::skip]
pub trait API {
unsafe fn WelsCreateSVCEncoder(&self, ppEncoder: *mut *mut ISVCEncoder) -> ::std::os::raw::c_int;
unsafe fn WelsDestroySVCEncoder(&self, pEncoder: *mut ISVCEncoder);
unsafe fn WelsGetDecoderCapability(&self, pDecCapability: *mut SDecoderCapability) -> ::std::os::raw::c_int;
unsafe fn WelsCreateDecoder(&self, ppDecoder: *mut *mut ISVCDecoder) -> ::std::os::raw::c_long;
unsafe fn WelsDestroyDecoder(&self, pDecoder: *mut ISVCDecoder);
unsafe fn WelsGetCodecVersion(&self) -> OpenH264Version;
unsafe fn WelsGetCodecVersionEx(&self, pVersion: *mut OpenH264Version);
}
#[cfg(feature = "libloading")]
pub mod libloading {
pub use crate::generated::fns_libloading::*;
use crate::{ISVCDecoder, ISVCEncoder, OpenH264Version, SDecoderCapability};
use std::os::raw::{c_int, c_long};
#[rustfmt::skip]
impl super::API for APILoader {
unsafe fn WelsCreateSVCEncoder(&self, ppEncoder: *mut *mut ISVCEncoder) -> c_int { APILoader::WelsCreateSVCEncoder(self, ppEncoder) }
unsafe fn WelsDestroySVCEncoder(&self, pEncoder: *mut ISVCEncoder) { APILoader::WelsDestroySVCEncoder(self, pEncoder) }
unsafe fn WelsGetDecoderCapability(&self, pDecCapability: *mut SDecoderCapability) -> c_int { APILoader::WelsGetDecoderCapability(self, pDecCapability) }
unsafe fn WelsCreateDecoder(&self, ppDecoder: *mut *mut ISVCDecoder) -> c_long { APILoader::WelsCreateDecoder(self, ppDecoder) }
unsafe fn WelsDestroyDecoder(&self, pDecoder: *mut ISVCDecoder) { APILoader::WelsDestroyDecoder(self, pDecoder) }
unsafe fn WelsGetCodecVersion(&self) -> OpenH264Version { APILoader::WelsGetCodecVersion(self) }
unsafe fn WelsGetCodecVersionEx(&self, pVersion: *mut OpenH264Version) {APILoader::WelsGetCodecVersionEx(self, pVersion) }
}
}
#[cfg(feature = "source")]
pub mod source {
use crate::{ISVCDecoder, ISVCEncoder, OpenH264Version, SDecoderCapability};
use std::os::raw::{c_int, c_long};
#[derive(Debug)]
pub struct APILoader {}
#[rustfmt::skip]
impl APILoader {
pub fn new() -> Self { Self {} }
pub unsafe fn WelsCreateSVCEncoder(&self, ppEncoder: *mut *mut ISVCEncoder) -> ::std::os::raw::c_int { crate::generated::fns_source::WelsCreateSVCEncoder(ppEncoder) }
pub unsafe fn WelsDestroySVCEncoder(&self, pEncoder: *mut ISVCEncoder) { crate::generated::fns_source::WelsDestroySVCEncoder(pEncoder) }
pub unsafe fn WelsGetDecoderCapability(&self, pDecCapability: *mut SDecoderCapability) -> ::std::os::raw::c_int { crate::generated::fns_source::WelsGetDecoderCapability(pDecCapability) }
pub unsafe fn WelsCreateDecoder(&self, ppDecoder: *mut *mut ISVCDecoder) -> ::std::os::raw::c_long { crate::generated::fns_source::WelsCreateDecoder(ppDecoder) }
pub unsafe fn WelsDestroyDecoder(&self, pDecoder: *mut ISVCDecoder) { crate::generated::fns_source::WelsDestroyDecoder(pDecoder) }
pub unsafe fn WelsGetCodecVersion(&self) -> OpenH264Version { crate::generated::fns_source::WelsGetCodecVersion() }
pub unsafe fn WelsGetCodecVersionEx(&self, pVersion: *mut OpenH264Version) { crate::generated::fns_source::WelsGetCodecVersionEx(pVersion) }
}
#[rustfmt::skip]
impl super::API for APILoader {
unsafe fn WelsCreateSVCEncoder(&self, ppEncoder: *mut *mut ISVCEncoder) -> c_int { APILoader::WelsCreateSVCEncoder(self, ppEncoder) }
unsafe fn WelsDestroySVCEncoder(&self, pEncoder: *mut ISVCEncoder) { APILoader::WelsDestroySVCEncoder(self, pEncoder) }
unsafe fn WelsGetDecoderCapability(&self, pDecCapability: *mut SDecoderCapability) -> c_int { APILoader::WelsGetDecoderCapability(self, pDecCapability) }
unsafe fn WelsCreateDecoder(&self, ppDecoder: *mut *mut ISVCDecoder) -> c_long { APILoader::WelsCreateDecoder(self, ppDecoder) }
unsafe fn WelsDestroyDecoder(&self, pDecoder: *mut ISVCDecoder) { APILoader::WelsDestroyDecoder(self, pDecoder) }
unsafe fn WelsGetCodecVersion(&self) -> OpenH264Version { APILoader::WelsGetCodecVersion(self) }
unsafe fn WelsGetCodecVersionEx(&self, pVersion: *mut OpenH264Version) { APILoader::WelsGetCodecVersionEx(self, pVersion) }
}
}
pub enum DynamicAPI {
#[cfg(feature = "source")]
Source(source::APILoader),
#[cfg(feature = "libloading")]
Libloading(libloading::APILoader),
}
impl DynamicAPI {
#[cfg(feature = "source")]
pub fn from_source() -> Self {
let api = crate::source::APILoader::new();
Self::Source(api)
}
#[cfg(feature = "libloading")]
pub unsafe fn from_blob_path_unchecked(path: impl AsRef<std::ffi::OsStr>) -> Result<Self, Error> {
let api = unsafe { libloading::APILoader::new(path)? };
Ok(Self::Libloading(api))
}
#[cfg(feature = "libloading")]
pub fn from_blob_path(path: impl AsRef<std::ffi::OsStr>) -> Result<Self, Error> {
use sha2::Digest;
let bytes = std::fs::read(path.as_ref())?;
let sha256 = sha2::Sha256::digest(bytes)
.iter()
.map(|byte| format!("{:02x}", byte))
.collect::<String>();
let hash_is_well_known = include_str!("blobs/hashes.txt")
.lines()
.filter_map(|line| line.split_whitespace().next())
.any(|x| x == sha256);
if !hash_is_well_known {
return Err(Error::InvalidHash(sha256));
}
unsafe { Self::from_blob_path_unchecked(path) }
}
}
#[allow(unreachable_patterns)]
#[allow(unused)]
impl API for DynamicAPI {
unsafe fn WelsCreateSVCEncoder(&self, ppEncoder: *mut *mut ISVCEncoder) -> c_int {
match self {
#[cfg(feature = "source")]
DynamicAPI::Source(api) => api.WelsCreateSVCEncoder(ppEncoder),
#[cfg(feature = "libloading")]
DynamicAPI::Libloading(api) => api.WelsCreateSVCEncoder(ppEncoder),
_ => panic!("No API enabled"),
}
}
unsafe fn WelsDestroySVCEncoder(&self, pEncoder: *mut ISVCEncoder) {
match self {
#[cfg(feature = "source")]
DynamicAPI::Source(api) => api.WelsDestroySVCEncoder(pEncoder),
#[cfg(feature = "libloading")]
DynamicAPI::Libloading(api) => api.WelsDestroySVCEncoder(pEncoder),
_ => panic!("No API enabled"),
}
}
unsafe fn WelsGetDecoderCapability(&self, pDecCapability: *mut SDecoderCapability) -> c_int {
match self {
#[cfg(feature = "source")]
DynamicAPI::Source(api) => api.WelsGetDecoderCapability(pDecCapability),
#[cfg(feature = "libloading")]
DynamicAPI::Libloading(api) => api.WelsGetDecoderCapability(pDecCapability),
_ => panic!("No API enabled"),
}
}
unsafe fn WelsCreateDecoder(&self, ppDecoder: *mut *mut ISVCDecoder) -> c_long {
match self {
#[cfg(feature = "source")]
DynamicAPI::Source(api) => api.WelsCreateDecoder(ppDecoder),
#[cfg(feature = "libloading")]
DynamicAPI::Libloading(api) => api.WelsCreateDecoder(ppDecoder),
_ => panic!("No API enabled"),
}
}
unsafe fn WelsDestroyDecoder(&self, pDecoder: *mut ISVCDecoder) {
match self {
#[cfg(feature = "source")]
DynamicAPI::Source(api) => api.WelsDestroyDecoder(pDecoder),
#[cfg(feature = "libloading")]
DynamicAPI::Libloading(api) => api.WelsDestroyDecoder(pDecoder),
_ => panic!("No API enabled"),
}
}
unsafe fn WelsGetCodecVersion(&self) -> OpenH264Version {
match self {
#[cfg(feature = "source")]
DynamicAPI::Source(api) => api.WelsGetCodecVersion(),
#[cfg(feature = "libloading")]
DynamicAPI::Libloading(api) => api.WelsGetCodecVersion(),
_ => panic!("No API enabled"),
}
}
unsafe fn WelsGetCodecVersionEx(&self, pVersion: *mut OpenH264Version) {
match self {
#[cfg(feature = "source")]
DynamicAPI::Source(api) => api.WelsGetCodecVersionEx(pVersion),
#[cfg(feature = "libloading")]
DynamicAPI::Libloading(api) => api.WelsGetCodecVersionEx(pVersion),
_ => panic!("No API enabled"),
}
}
}
#[cfg(test)]
mod tests {
#[test]
#[ignore]
#[cfg(feature = "libloading")]
fn it_works() -> Result<(), crate::Error> {
_ = super::DynamicAPI::from_blob_path(r"C:\Users\rb\Downloads\openh264-2.4.0-win64.dll\openh264-2.4.0-win64.dll")?;
Ok(())
}
}