I'm really excited to announce the very first release of AMFFI, a Rust wrapper for AMDs media SDK, enabling access to GPU encoding on AMD hardware, while being compilable anywhere.
AMFFI is very similar to AMDs own API in usage, such as initialization
#include "public/common/AMFFactory.h"
int main() {
AMF_RESULT res = AMF_OK;
res = g_AMFFactory.Init();
amf::AMFContextPtr context;
res = g_AMFFactory.GetFactory()->CreateContext(&context);
}
use amf_bindings::amf_init;
use amf_bindings::version::AMF_VERSION;
use amf_bindings::factory::AMFFactory;
use amf_bindings::context::AMFContext;
fn main() {
let library = amf_init().unwrap();
let factory: AMFFactory = library.init_factory(AMF_VERSION).unwrap();
let context: AMFContext = factory.create_context().unwrap();
}
However, for classes expecting inheritance, I've put a lot of effort in making it feel like the system was designed for Rust to begin with
pub trait SurfaceObserver {
fn on_surface_data_release(&mut self, surface: AMFSurface);
}
// Details
#[repr(C)]
pub(crate) struct InternalSurfaceObserver<T: SurfaceObserver> {
vtbl: &'static AMFSurfaceObserverVtbl,
this: T,
}
impl<T: SurfaceObserver> InternalSurfaceObserver<T> {
pub(crate) fn new(observer: T) -> Self {
Self {
vtbl: &AMFSurfaceObserverVtbl {
on_surface_data_release: internal_observer::<T>,
},
this: observer,
}
}
}
stdcall! {
fn internal_observer<T: SurfaceObserver>(this: *mut *const AMFSurfaceObserverVtbl, surface: AMFSurface) {
let this = unsafe { &mut *(this as *mut InternalSurfaceObserver<T>) };
this.this.on_surface_data_release(surface);
}
}
class AMF_NO_VTABLE AMFSurfaceObserver
{
public:
virtual void AMF_STD_CALL OnSurfaceDataRelease(AMFSurface* pSurface) = 0;
};