Skip to content

Commit

Permalink
draft: implement proper lifetimes for xilinx structs
Browse files Browse the repository at this point in the history
  • Loading branch information
Xaeroxe committed Jan 8, 2025
1 parent aa9e1f2 commit 494a05a
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 87 deletions.
4 changes: 4 additions & 0 deletions xilinx/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
pub mod sys;
pub use sys::*;

/*---- context ----*/
pub mod xrm_context;
pub use xrm_context::*;

/*---- transcoder ----*/
pub mod xlnx_transcoder_utils;
pub use xlnx_transcoder_utils::*;
Expand Down
38 changes: 19 additions & 19 deletions xilinx/src/xlnx_dec_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{ffi::CString, os::raw::c_char, str::from_utf8};
use libloading::{Library, Symbol};
use simple_error::{bail, SimpleError};

use crate::{strcpy_to_arr_i8, sys::*, xrm_precision_1000000_bitmask};
use crate::{strcpy_to_arr_i8, sys::*, xrm_precision_1000000_bitmask, XrmContext};

const DEC_PLUGIN_NAME: &[u8] = b"xrmU30DecPlugin\0";

Expand All @@ -14,17 +14,17 @@ pub struct XlnxDecBuffer<'a> {
pub allocated: usize,
}

pub struct XlnxDecoderXrmCtx {
pub struct XlnxDecoderXrmCtx<'a> {
pub xrm_reserve_id: Option<u64>,
pub device_id: Option<u32>,
pub dec_load: i32,
pub(crate) decode_res_in_use: bool,
pub(crate) xrm_ctx: xrmContext,
pub(crate) xrm_ctx: &'a XrmContext,
pub(crate) cu_list_res: Box<xrmCuListResourceV2>,
}

impl XlnxDecoderXrmCtx {
pub fn new(xrm_ctx: xrmContext, device_id: Option<u32>, reserve_id: Option<u64>, dec_load: i32) -> Self {
impl<'a> XlnxDecoderXrmCtx<'a> {
pub fn new(xrm_ctx: &'a XrmContext, device_id: Option<u32>, reserve_id: Option<u64>, dec_load: i32) -> Self {
Self {
xrm_reserve_id: reserve_id,
device_id,
Expand All @@ -38,7 +38,7 @@ impl XlnxDecoderXrmCtx {

/// Calculates the decoder load uing the xrmU30Dec plugin.
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub fn xlnx_calc_dec_load(xrm_ctx: xrmContext, xma_dec_props: *mut XmaDecoderProperties) -> Result<i32, SimpleError> {
pub fn xlnx_calc_dec_load(xrm_ctx: &XrmContext, xma_dec_props: *mut XmaDecoderProperties) -> Result<i32, SimpleError> {
let func_id = 0;
let mut plugin_param: xrmPluginFuncParam = Default::default();
unsafe {
Expand All @@ -59,7 +59,7 @@ pub fn xlnx_calc_dec_load(xrm_ctx: xrmContext, xma_dec_props: *mut XmaDecoderPro
}

unsafe {
let ret = xrmExecPluginFunc(xrm_ctx, DEC_PLUGIN_NAME.as_ptr() as *mut i8, func_id, &mut plugin_param);
let ret = xrmExecPluginFunc(xrm_ctx.raw(), DEC_PLUGIN_NAME.as_ptr() as *mut i8, func_id, &mut plugin_param);
if ret != XRM_SUCCESS as i32 {
bail!("XRM decoder plugin failed to calculate decoder load. error: {}", ret);
}
Expand Down Expand Up @@ -107,18 +107,18 @@ fn xlnx_fill_dec_pool_props(cu_pool_prop: &mut xrmCuPoolPropertyV2, dec_load: i3
Ok(())
}

pub fn xlnx_reserve_dec_resource(xlnx_dec_ctx: &mut XlnxDecoderXrmCtx) -> Result<Box<xrmCuPoolResInforV2>, SimpleError> {
pub fn xlnx_reserve_dec_resource(xlnx_dec_ctx: &mut XlnxDecoderXrmCtx<'_>) -> Result<Box<xrmCuPoolResInforV2>, SimpleError> {
let mut cu_pool_prop: Box<xrmCuPoolPropertyV2> = Box::new(Default::default());
let mut cu_pool_res_infor: Box<xrmCuPoolResInforV2> = Box::new(Default::default());
xlnx_fill_dec_pool_props(&mut cu_pool_prop, xlnx_dec_ctx.dec_load, xlnx_dec_ctx.device_id)?;

unsafe {
let num_cu_pool = xrmCheckCuPoolAvailableNumV2(xlnx_dec_ctx.xrm_ctx, cu_pool_prop.as_mut());
let num_cu_pool = xrmCheckCuPoolAvailableNumV2(xlnx_dec_ctx.xrm_ctx.raw(), cu_pool_prop.as_mut());
if num_cu_pool <= 0 {
bail!("no decoder resources available for allocation")
}

let xrm_reserve_id = xrmCuPoolReserveV2(xlnx_dec_ctx.xrm_ctx, cu_pool_prop.as_mut(), cu_pool_res_infor.as_mut());
let xrm_reserve_id = xrmCuPoolReserveV2(xlnx_dec_ctx.xrm_ctx.raw(), cu_pool_prop.as_mut(), cu_pool_res_infor.as_mut());
if xrm_reserve_id == 0 {
bail!("failed to reserve decode cu pool")
}
Expand All @@ -129,7 +129,7 @@ pub fn xlnx_reserve_dec_resource(xlnx_dec_ctx: &mut XlnxDecoderXrmCtx) -> Result
}

/// Allocates decoder CU
fn xlnx_dec_cu_alloc(xma_dec_props: &mut XmaDecoderProperties, xlnx_dec_ctx: &mut XlnxDecoderXrmCtx) -> Result<(), SimpleError> {
fn xlnx_dec_cu_alloc(xma_dec_props: &mut XmaDecoderProperties, xlnx_dec_ctx: &mut XlnxDecoderXrmCtx<'_>) -> Result<(), SimpleError> {
// Allocate xrm decoder
let mut decode_cu_list_prop = Box::new(xrmCuListPropertyV2 {
cuNum: 2,
Expand Down Expand Up @@ -169,7 +169,7 @@ fn xlnx_dec_cu_alloc(xma_dec_props: &mut XmaDecoderProperties, xlnx_dec_ctx: &mu
}
}

if unsafe { xrmCuListAllocV2(xlnx_dec_ctx.xrm_ctx, decode_cu_list_prop.as_mut(), xlnx_dec_ctx.cu_list_res.as_mut()) } != XRM_SUCCESS as _ {
if unsafe { xrmCuListAllocV2(xlnx_dec_ctx.xrm_ctx.raw(), decode_cu_list_prop.as_mut(), xlnx_dec_ctx.cu_list_res.as_mut()) } != XRM_SUCCESS as _ {
bail!(
"failed to allocate decode cu list from reserve id {:?} and device id {:?}",
xlnx_dec_ctx.xrm_reserve_id,
Expand All @@ -194,7 +194,7 @@ fn xlnx_dec_cu_alloc(xma_dec_props: &mut XmaDecoderProperties, xlnx_dec_ctx: &mu
/// Attempts to create decoder session
pub(crate) fn xlnx_create_dec_session(
xma_dec_props: &mut XmaDecoderProperties,
xlnx_dec_ctx: &mut XlnxDecoderXrmCtx,
xlnx_dec_ctx: &mut XlnxDecoderXrmCtx<'_>,
) -> Result<*mut XmaDecoderSession, SimpleError> {
xlnx_dec_cu_alloc(xma_dec_props, xlnx_dec_ctx)?;

Expand All @@ -206,17 +206,17 @@ pub(crate) fn xlnx_create_dec_session(
Ok(dec_session)
}

impl Drop for XlnxDecoderXrmCtx {
impl<'a> Drop for XlnxDecoderXrmCtx<'a> {
fn drop(&mut self) {
if self.xrm_ctx.is_null() {
return;
}
unsafe {
if self.xrm_ctx.raw().is_null() {
return;
}
if let Some(xrm_reserve_id) = self.xrm_reserve_id {
let _ = xrmCuPoolRelinquishV2(self.xrm_ctx, xrm_reserve_id);
let _ = xrmCuPoolRelinquishV2(self.xrm_ctx.raw(), xrm_reserve_id);
}
if self.decode_res_in_use {
let _ = xrmCuListReleaseV2(self.xrm_ctx, self.cu_list_res.as_mut());
let _ = xrmCuListReleaseV2(self.xrm_ctx.raw(), self.cu_list_res.as_mut());
}
}
}
Expand Down
12 changes: 8 additions & 4 deletions xilinx/src/xlnx_decoder.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
use std::marker::PhantomData;

use crate::sys::*;
use crate::xlnx_dec_utils::*;
use crate::{XlnxError, XlnxErrorType};
use simple_error::{bail, SimpleError};

pub struct XlnxDecoder {
pub struct XlnxDecoder<'a> {
pub dec_session: *mut XmaDecoderSession,
pub frame_props: XmaFrameProperties,
in_buf: XmaDataBuffer,
pub out_frame: *mut XmaFrame,
pub flush_sent: bool,
decoder_ctx_lifetime: PhantomData<XlnxDecoderXrmCtx<'a>>,
}

impl XlnxDecoder {
pub fn new(xma_dec_props: &mut XmaDecoderProperties, xlnx_dec_ctx: &mut XlnxDecoderXrmCtx) -> Result<Self, SimpleError> {
impl<'a> XlnxDecoder<'a> {
pub fn new(xma_dec_props: &mut XmaDecoderProperties, xlnx_dec_ctx: &mut XlnxDecoderXrmCtx<'a>) -> Result<Self, SimpleError> {
let dec_session = xlnx_create_dec_session(xma_dec_props, xlnx_dec_ctx)?;

let mut frame_props: XmaFrameProperties = Default::default();
Expand Down Expand Up @@ -41,6 +44,7 @@ impl XlnxDecoder {
in_buf,
out_frame,
flush_sent: false,
decoder_ctx_lifetime: PhantomData,
})
}

Expand Down Expand Up @@ -126,7 +130,7 @@ impl XlnxDecoder {
}
}

impl Drop for XlnxDecoder {
impl<'a> Drop for XlnxDecoder<'a> {
fn drop(&mut self) {
unsafe {
if !self.dec_session.is_null() {
Expand Down
32 changes: 16 additions & 16 deletions xilinx/src/xlnx_enc_utils.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
use crate::{strcpy_to_arr_i8, sys::*, xrm_precision_1000000_bitmask};
use crate::{strcpy_to_arr_i8, sys::*, xrm_precision_1000000_bitmask, XrmContext};
use libloading::{Library, Symbol};
use simple_error::{bail, SimpleError};
use std::{ffi::CString, os::raw::c_char, str::from_utf8};

const ENC_PLUGIN_NAME: &[u8] = b"xrmU30EncPlugin\0";

pub struct XlnxEncoderXrmCtx {
pub struct XlnxEncoderXrmCtx<'a> {
pub xrm_reserve_id: Option<u64>,
pub device_id: Option<u32>,
pub enc_load: i32,
pub(crate) encode_res_in_use: bool,
pub(crate) xrm_ctx: xrmContext,
pub(crate) xrm_ctx: &'a XrmContext,
pub(crate) cu_list_res: Box<xrmCuListResourceV2>,
}

impl XlnxEncoderXrmCtx {
pub fn new(xrm_ctx: xrmContext, device_id: Option<u32>, reserve_id: Option<u64>, enc_load: i32) -> Self {
impl<'a> XlnxEncoderXrmCtx<'a> {
pub fn new(xrm_ctx: &'a XrmContext, device_id: Option<u32>, reserve_id: Option<u64>, enc_load: i32) -> Self {
Self {
xrm_reserve_id: reserve_id,
device_id,
Expand All @@ -29,7 +29,7 @@ impl XlnxEncoderXrmCtx {

/// Calculates the encoder load uing the xrmU30Enc plugin.
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub fn xlnx_calc_enc_load(xrm_ctx: xrmContext, xma_enc_props: *mut XmaEncoderProperties) -> Result<i32, SimpleError> {
pub fn xlnx_calc_enc_load(xrm_ctx: &XrmContext, xma_enc_props: *mut XmaEncoderProperties) -> Result<i32, SimpleError> {
let func_id = 0;
let mut plugin_param: xrmPluginFuncParam = Default::default();
unsafe {
Expand All @@ -50,7 +50,7 @@ pub fn xlnx_calc_enc_load(xrm_ctx: xrmContext, xma_enc_props: *mut XmaEncoderPro
}

unsafe {
let ret = xrmExecPluginFunc(xrm_ctx, ENC_PLUGIN_NAME.as_ptr() as *mut i8, func_id, &mut plugin_param);
let ret = xrmExecPluginFunc(xrm_ctx.raw(), ENC_PLUGIN_NAME.as_ptr() as *mut i8, func_id, &mut plugin_param);
if ret != XRM_SUCCESS as i32 {
bail!("XRM encoder plugin failed to calculate encoder load. error: {}", ret);
}
Expand Down Expand Up @@ -110,12 +110,12 @@ pub fn xlnx_reserve_enc_resource(xlnx_enc_ctx: &mut XlnxEncoderXrmCtx) -> Result
xlnx_fill_enc_pool_props(&mut cu_pool_prop, enc_count, xlnx_enc_ctx.enc_load, xlnx_enc_ctx.device_id)?;

unsafe {
let num_cu_pool = xrmCheckCuPoolAvailableNumV2(xlnx_enc_ctx.xrm_ctx, cu_pool_prop.as_mut());
let num_cu_pool = xrmCheckCuPoolAvailableNumV2(xlnx_enc_ctx.xrm_ctx.raw(), cu_pool_prop.as_mut());
if num_cu_pool <= 0 {
bail!("no encoder resources avaliable for allocation")
}

let xrm_reserve_id: u64 = xrmCuPoolReserveV2(xlnx_enc_ctx.xrm_ctx, cu_pool_prop.as_mut(), cu_pool_res_infor.as_mut());
let xrm_reserve_id: u64 = xrmCuPoolReserveV2(xlnx_enc_ctx.xrm_ctx.raw(), cu_pool_prop.as_mut(), cu_pool_res_infor.as_mut());
if xrm_reserve_id == 0 {
bail!("failed to reserve encode cu pool")
}
Expand Down Expand Up @@ -166,7 +166,7 @@ fn xlnx_enc_cu_alloc(xma_enc_props: &mut XmaEncoderProperties, xlnx_enc_ctx: &mu
}
}

if unsafe { xrmCuListAllocV2(xlnx_enc_ctx.xrm_ctx, encode_cu_list_prop.as_mut(), xlnx_enc_ctx.cu_list_res.as_mut()) } != XRM_SUCCESS as _ {
if unsafe { xrmCuListAllocV2(xlnx_enc_ctx.xrm_ctx.raw(), encode_cu_list_prop.as_mut(), xlnx_enc_ctx.cu_list_res.as_mut()) } != XRM_SUCCESS as _ {
bail!(
"failed to allocate encode cu list from reserve id {:?} and device id {:?}",
xlnx_enc_ctx.xrm_reserve_id,
Expand Down Expand Up @@ -202,17 +202,17 @@ pub(crate) fn xlnx_create_enc_session(
Ok(enc_session)
}

impl Drop for XlnxEncoderXrmCtx {
impl<'a> Drop for XlnxEncoderXrmCtx<'a> {
fn drop(&mut self) {
if self.xrm_ctx.is_null() {
return;
}
unsafe {
if self.xrm_ctx.raw().is_null() {
return;
}
if let Some(xrm_reserve_id) = self.xrm_reserve_id {
let _ = xrmCuPoolRelinquishV2(self.xrm_ctx, xrm_reserve_id);
let _ = xrmCuPoolRelinquishV2(self.xrm_ctx.raw(), xrm_reserve_id);
}
if self.encode_res_in_use {
let _ = xrmCuListReleaseV2(self.xrm_ctx, self.cu_list_res.as_mut());
let _ = xrmCuListReleaseV2(self.xrm_ctx.raw(), self.cu_list_res.as_mut());
}
}
}
Expand Down
14 changes: 9 additions & 5 deletions xilinx/src/xlnx_encoder.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
use std::marker::PhantomData;

use crate::{sys::*, xlnx_enc_utils::*, xlnx_error::*};
use simple_error::SimpleError;

pub struct XlnxEncoder {
pub struct XlnxEncoder<'a> {
enc_session: *mut XmaEncoderSession,
pub out_buffer: *mut XmaDataBuffer,
pub flush_frame_sent: bool,
encoder_ctx_lifetime: PhantomData<XlnxEncoderXrmCtx<'a>>,
}

impl XlnxEncoder {
pub fn new(xma_enc_props: &mut XmaEncoderProperties, xlnx_enc_ctx: &mut XlnxEncoderXrmCtx) -> Result<Self, SimpleError> {
impl<'a> XlnxEncoder<'a> {
pub fn new(xma_enc_props: &mut XmaEncoderProperties, xlnx_enc_ctx: &mut XlnxEncoderXrmCtx<'a>) -> Result<Self, SimpleError> {
let enc_session = xlnx_create_enc_session(xma_enc_props, xlnx_enc_ctx)?;

let buffer_size = xma_enc_props.height * xma_enc_props.width * xma_enc_props.bits_per_pixel;
Expand All @@ -18,10 +21,11 @@ impl XlnxEncoder {
enc_session,
out_buffer,
flush_frame_sent: false,
encoder_ctx_lifetime: PhantomData,
})
}

/// Sends raw frames to Xilinx Encoder plugin and receives back decoded frames.
/// Sends raw frames to Xilinx Encoder plugin and receives back decoded frames.
pub fn process_frame(&mut self, enc_in_frame: *mut XmaFrame, enc_null_frame: bool, enc_out_size: &mut i32) -> Result<(), XlnxError> {
if !self.flush_frame_sent {
match self.send_frame(enc_in_frame) {
Expand Down Expand Up @@ -76,7 +80,7 @@ impl XlnxEncoder {
}
}

impl Drop for XlnxEncoder {
impl<'a> Drop for XlnxEncoder<'a> {
fn drop(&mut self) {
unsafe {
if !self.enc_session.is_null() {
Expand Down
Loading

0 comments on commit 494a05a

Please sign in to comment.