Skip to content

Commit

Permalink
vimba: update to Vimba X
Browse files Browse the repository at this point in the history
  • Loading branch information
astraw committed Apr 10, 2024
1 parent f7f37a2 commit 0038e5f
Show file tree
Hide file tree
Showing 11 changed files with 142 additions and 143 deletions.
6 changes: 3 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
[appropriate NVENC
hardware](https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-new),
hardware-accelerated encoding is also supported.
* Added support from Allied Vision Technologies cameras using the Vimba driver.
In the braid .toml configuration file, specify the camera with `start_backend =
"vimba"`.
* Added support from Allied Vision Technologies cameras using the Vimba X
driver. In the braid .toml configuration file, specify the camera with
`start_backend = "vimba"`.
* Braidz Viewer website at https://braidz.strawlab.org/ can be installed as a
[Progressive Web App
(PWA)](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Guides/What_is_a_progressive_web_app).
Expand Down
2 changes: 1 addition & 1 deletion ci2-vimba/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ parking_lot = "0.12.1"
lazy_static = "1"
tempfile = "3.4.0"

vimba-sys = "0.2.0"
vmbc-sys = "0.1"

ci2 = { path = "../ci2" }
basic-frame = { path = "../basic-frame" }
Expand Down
27 changes: 14 additions & 13 deletions ci2-vimba/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ struct FrameSender {
}

struct CamHandle {
inner: vimba_sys::VmbHandle_t,
inner: vmbc_sys::VmbHandle_t,
}

unsafe impl Sync for CamHandle {}
Expand All @@ -53,15 +53,15 @@ fn ve2ce(orig: vimba::Error) -> ci2::Error {
}

fn callback_rust(
camera_handle: vimba_sys::VmbHandle_t,
frame: *mut vimba_sys::VmbFrame_t,
camera_handle: vmbc_sys::VmbHandle_t,
frame: *mut vmbc_sys::VmbFrame_t,
) -> ci2::Result<()> {
let now = chrono::Utc::now(); // earliest possible timestamp
let frame_status = unsafe { (*frame).receiveStatus };
if !IS_DONE.load(Ordering::Relaxed) {
// Copy all data from Vimba.

let msg = if frame_status == vimba_sys::VmbFrameStatusType::VmbFrameStatusComplete {
let msg = if frame_status == vmbc_sys::VmbFrameStatusType::VmbFrameStatusComplete {
// Make reference to image buffer.
let buf_ref = unsafe {
let buf_ref1 = (*frame).buffer;
Expand All @@ -76,15 +76,15 @@ fn callback_rust(

let flags = unsafe { (*frame).receiveFlags };
let frame_id =
if flags & vimba_sys::VmbFrameFlagsType::VmbFrameFlagsFrameID.0 as u32 != 0 {
if flags & vmbc_sys::VmbFrameFlagsType::VmbFrameFlagsFrameID.0 as u32 != 0 {
unsafe { (*frame).frameID }
} else {
eprintln!("no frame number data in frame");
0
};

let device_timestamp =
if flags & vimba_sys::VmbFrameFlagsType::VmbFrameFlagsTimestamp.0 as u32 != 0 {
if flags & vmbc_sys::VmbFrameFlagsType::VmbFrameFlagsTimestamp.0 as u32 != 0 {
unsafe { (*frame).timestamp }
} else {
eprintln!("no timestamp data in frame");
Expand Down Expand Up @@ -118,13 +118,13 @@ fn callback_rust(
}
} else {
let str_msg = match frame_status {
vimba_sys::VmbFrameStatusType::VmbFrameStatusIncomplete => {
vmbc_sys::VmbFrameStatusType::VmbFrameStatusIncomplete => {
"Frame could not be filled to the end"
}
vimba_sys::VmbFrameStatusType::VmbFrameStatusTooSmall => {
vmbc_sys::VmbFrameStatusType::VmbFrameStatusTooSmall => {
"Frame buffer was too small"
}
vimba_sys::VmbFrameStatusType::VmbFrameStatusInvalid => "Frame buffer was invalid",
vmbc_sys::VmbFrameStatusType::VmbFrameStatusInvalid => "Frame buffer was invalid",
other => {
if other == -4 {
eprintln!("undocumented frame status -4: was VmbShutdown() called?");
Expand All @@ -144,7 +144,7 @@ fn callback_rust(
}
};

if err_code != vimba_sys::VmbErrorType::VmbErrorSuccess {
if err_code != vmbc_sys::VmbErrorType::VmbErrorSuccess {
let e = vimba::Error::from(vimba::VimbaError::from(err_code));
return Err(ve2ce(e));
}
Expand Down Expand Up @@ -184,8 +184,9 @@ fn callback_rust(
/// callbacks.
#[no_mangle]
pub unsafe extern "C" fn callback_c(
camera_handle: vimba_sys::VmbHandle_t,
frame: *mut vimba_sys::VmbFrame_t,
camera_handle: vmbc_sys::VmbHandle_t,
_stream_handle: vmbc_sys::VmbHandle_t,
frame: *mut vmbc_sys::VmbFrame_t,
) {
match std::panic::catch_unwind(|| {
callback_rust(camera_handle, frame).unwrap();
Expand Down Expand Up @@ -257,7 +258,7 @@ impl Drop for VimbaTerminateGuard {
}

pub fn make_singleton_guard<'a>(
_pylon_module: &dyn ci2::CameraModule<
_vimba_module: &dyn ci2::CameraModule<
CameraType = WrappedCamera<'a>,
Guard = VimbaTerminateGuard,
>,
Expand Down
4 changes: 2 additions & 2 deletions vimba/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ edition = "2021"
rust-version = "1.76"

[dependencies]
vimba-sys = "0.2.0"
libloading = "0.7.3"
vmbc-sys = "0.1"
libloading = "0.8.3"
thiserror = "1.0.33"
machine-vision-formats = "0.1"
log = "0.4"
Expand Down
65 changes: 28 additions & 37 deletions vimba/examples/async-std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ const N_BUFFER_FRAMES: usize = 3;
const N_CHANNEL_FRAMES: usize = 10;

lazy_static! {
// Prevent multiple concurrent access to structures and functions in Vimba
// which are not threadsafe.
static ref VIMBA_MUTEX: Mutex<()> = Mutex::new(());
static ref VIMBA: vimba::VimbaLibrary = vimba::VimbaLibrary::new().unwrap();
static ref IS_DONE: AtomicBool = AtomicBool::new(false);
static ref SENDER: Mutex<Option<Sender<Frame>>> = Mutex::new(None);
}
Expand All @@ -26,17 +24,17 @@ struct Frame {

#[no_mangle]
pub unsafe extern "C" fn callback_c(
camera_handle: vimba_sys::VmbHandle_t,
frame: *mut vimba_sys::VmbFrame_t,
camera_handle: vmbc_sys::VmbHandle_t,
_stream_handle: vmbc_sys::VmbHandle_t,
frame: *mut vmbc_sys::VmbFrame_t,
) {
match std::panic::catch_unwind(|| {
if !IS_DONE.load(Ordering::Relaxed) {
let err = {
let _guard = VIMBA_MUTEX.lock().unwrap();
vimba_sys::VmbCaptureFrameQueue(camera_handle, frame, Some(callback_c))
};
let err = VIMBA
.vimba_lib
.VmbCaptureFrameQueue(camera_handle, frame, Some(callback_c));

if err != vimba_sys::VmbErrorType::VmbErrorSuccess {
if err != vmbc_sys::VmbErrorType::VmbErrorSuccess {
eprintln!("CB: capture error: {}", err);
} else {
// no error
Expand Down Expand Up @@ -84,26 +82,26 @@ pub unsafe extern "C" fn callback_c(
fn main() -> anyhow::Result<()> {
env_logger::init();

let version_info = vimba::VersionInfo::new(&VIMBA.vimba_lib)?;
println!(
"Vimba X API Version {}.{}.{}",
version_info.major, version_info.minor, version_info.patch
);

let (tx, rx) = channellib::bounded(N_CHANNEL_FRAMES);
{
let mut sender_ref = SENDER.lock().unwrap();
*sender_ref = Some(tx);
}
let version_info = vimba::VersionInfo::new()?;
println!(
"Vimba API Version {}.{}.{}",
version_info.major, version_info.minor, version_info.patch
);
let lib = vimba::VimbaLibrary::new()?;
let n_cams = lib.n_cameras()?;
let n_cams = VIMBA.n_cameras()?;
println!("{} cameras found", n_cams);
let camera_infos = lib.camera_info(n_cams)?;
let camera_infos = VIMBA.camera_info(n_cams)?;
if !camera_infos.is_empty() {
let cam_id = camera_infos[0].camera_id_string.as_str();
println!("Opening camera {}", cam_id);
println!(" {:?}", camera_infos[0]);

let camera = vimba::Camera::open(cam_id, vimba::access_mode::FULL)?;
let camera = vimba::Camera::open(cam_id, vimba::access_mode::FULL, &VIMBA.vimba_lib)?;
let pixel_format = camera.pixel_format()?;
println!(" pixel_format: {:?}", pixel_format);

Expand All @@ -115,18 +113,14 @@ fn main() -> anyhow::Result<()> {
frames.push(frame);
}

{
let _guard = VIMBA_MUTEX.lock().unwrap();

camera.capture_start()?;

for mut frame in frames.iter_mut() {
camera.capture_frame_queue_with_callback(&mut frame, Some(callback_c))?;
}
camera.capture_start()?;

camera.command_run("AcquisitionStart")?;
for mut frame in frames.iter_mut() {
camera.capture_frame_queue_with_callback(&mut frame, Some(callback_c))?;
}

camera.command_run("AcquisitionStart")?;

println!("acquiring frames for 10 seconds");

let start = std::time::Instant::now();
Expand All @@ -145,17 +139,14 @@ fn main() -> anyhow::Result<()> {
IS_DONE.store(true, Ordering::Relaxed); // indicate we are done

println!("done acquiring frames");
{
let mut _guard = VIMBA_MUTEX.lock().unwrap();
camera.command_run("AcquisitionStop")?;
camera.capture_end()?;
camera.capture_queue_flush()?;
for mut frame in frames.into_iter() {
camera.frame_revoke(&mut frame)?;
}
camera.command_run("AcquisitionStop")?;
camera.capture_end()?;
camera.capture_queue_flush()?;
for mut frame in frames.into_iter() {
camera.frame_revoke(&mut frame)?;
}
camera.close()?;
}
// When `lib` is dropped, `VmbShutdown` will automatically be called.
unsafe { VIMBA.shutdown() };
Ok(())
}
61 changes: 29 additions & 32 deletions vimba/examples/async-tokio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ const N_BUFFER_FRAMES: usize = 3;
const N_CHANNEL_FRAMES: usize = 10;

lazy_static! {
// Prevent multiple concurrent access to structures and functions in Vimba
// which are not threadsafe.
static ref VIMBA_MUTEX: Mutex<()> = Mutex::new(());
static ref VIMBA: vimba::VimbaLibrary = vimba::VimbaLibrary::new().unwrap();
static ref IS_DONE: AtomicBool = AtomicBool::new(false);
static ref SENDER: Mutex<Option<Sender<Frame>>> = Mutex::new(None);
}
Expand All @@ -27,17 +25,19 @@ struct Frame {

#[no_mangle]
pub unsafe extern "C" fn callback_c(
camera_handle: vimba_sys::VmbHandle_t,
frame: *mut vimba_sys::VmbFrame_t,
camera_handle: vmbc_sys::VmbHandle_t,
_stream_handle: vmbc_sys::VmbHandle_t,
frame: *mut vmbc_sys::VmbFrame_t,
) {
match std::panic::catch_unwind(|| {
if !IS_DONE.load(Ordering::Relaxed) {
let err = {
let _guard = VIMBA_MUTEX.lock().unwrap();
vimba_sys::VmbCaptureFrameQueue(camera_handle, frame, Some(callback_c))
VIMBA
.vimba_lib
.VmbCaptureFrameQueue(camera_handle, frame, Some(callback_c))
};

if err != vimba_sys::VmbErrorType::VmbErrorSuccess {
if err != vmbc_sys::VmbErrorType::VmbErrorSuccess {
eprintln!("CB: capture error: {}", err);
} else {
// no error
Expand Down Expand Up @@ -103,21 +103,23 @@ async fn main() -> anyhow::Result<()> {
let mut sender_ref = SENDER.lock().unwrap();
*sender_ref = Some(tx);
}
let version_info = vimba::VersionInfo::new()?;

let version_info = vimba::VersionInfo::new(&VIMBA.vimba_lib)?;
println!(
"Vimba API Version {}.{}.{}",
"Vimba X API Version {}.{}.{}",
version_info.major, version_info.minor, version_info.patch
);
let lib = vimba::VimbaLibrary::new()?;
let n_cams = lib.n_cameras()?;

let n_cams = VIMBA.n_cameras()?;
println!("{} cameras found", n_cams);
let camera_infos = lib.camera_info(n_cams)?;
let camera_infos = VIMBA.camera_info(n_cams)?;

if !camera_infos.is_empty() {
let cam_id = camera_infos[0].camera_id_string.as_str();
println!("Opening camera {}", cam_id);
println!(" {:?}", camera_infos[0]);

let camera = vimba::Camera::open(cam_id, vimba::access_mode::FULL)?;
let camera = vimba::Camera::open(cam_id, vimba::access_mode::FULL, &VIMBA.vimba_lib)?;
let pixel_format = camera.pixel_format()?;
println!(" pixel_format: {:?}", pixel_format);

Expand All @@ -129,34 +131,29 @@ async fn main() -> anyhow::Result<()> {
frames.push(frame);
}

{
let _guard = VIMBA_MUTEX.lock().unwrap();

camera.capture_start()?;

for mut frame in frames.iter_mut() {
camera.capture_frame_queue_with_callback(&mut frame, Some(callback_c))?;
}
camera.capture_start()?;

camera.command_run("AcquisitionStart")?;
for mut frame in frames.iter_mut() {
camera.capture_frame_queue_with_callback(&mut frame, Some(callback_c))?;
}

camera.command_run("AcquisitionStart")?;

println!("acquiring frames for 1 second");
let frames_future = handle_frames(rx);
let _ = tokio::time::timeout(std::time::Duration::from_secs(1), frames_future).await;
IS_DONE.store(true, Ordering::Relaxed); // indicate we are done
println!("done acquiring frames");
{
let mut _guard = VIMBA_MUTEX.lock().unwrap();
camera.command_run("AcquisitionStop")?;
camera.capture_end()?;
camera.capture_queue_flush()?;
for mut frame in frames.into_iter() {
camera.frame_revoke(&mut frame)?;
}

camera.command_run("AcquisitionStop")?;
camera.capture_end()?;
camera.capture_queue_flush()?;
for mut frame in frames.into_iter() {
camera.frame_revoke(&mut frame)?;
}

camera.close()?;
}
// When `lib` is dropped, `VmbShutdown` will automatically be called.
unsafe { VIMBA.shutdown() };
Ok(())
}
Loading

0 comments on commit 0038e5f

Please sign in to comment.