Skip to content

Commit

Permalink
fixed issue with ControlInfo.values() not properly decoding into Rust…
Browse files Browse the repository at this point in the history
… Vec
  • Loading branch information
SoZ0 committed Dec 8, 2024
1 parent ad95922 commit c052b1d
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 14 deletions.
4 changes: 4 additions & 0 deletions libcamera-sys/c_api/controls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ void libcamera_control_value_set(libcamera_control_value_t *val, enum libcamera_
memcpy(storage.data(), data, storage.size());
}

size_t libcamera_control_value_size() {
return sizeof(libcamera::ControlValue);
}

const libcamera_control_value_t *libcamera_control_info_max(libcamera_control_info_t *val){
return &val->max();
}
Expand Down
3 changes: 1 addition & 2 deletions libcamera-sys/c_api/controls.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,12 @@ bool libcamera_control_value_is_array(const libcamera_control_value_t *val);
size_t libcamera_control_value_num_elements(const libcamera_control_value_t *val);
const void *libcamera_control_value_get(const libcamera_control_value_t *val);
void libcamera_control_value_set(libcamera_control_value_t *val, enum libcamera_control_type type, const void *data, bool is_array, size_t num_elements);

size_t libcamera_control_value_size();
// --- libcamera_control_info_t ---
const libcamera_control_value_t *libcamera_control_info_max(libcamera_control_info_t *val);
const libcamera_control_value_t *libcamera_control_info_min(libcamera_control_info_t *val);
const libcamera_control_value_t *libcamera_control_info_def(libcamera_control_info_t *val);
const libcamera_control_value_t* libcamera_control_info_values(const libcamera_control_info_t* info, size_t* size);

// --- libcamera_control_id_map ---
bool libcamera_control_id_map_add(libcamera_control_id_map_t *idmap, unsigned int key, const libcamera_control_id_t *control_id);
const libcamera_control_id_t *libcamera_control_id_map_get(libcamera_control_id_map_t *idmap, unsigned int key);
Expand Down
36 changes: 24 additions & 12 deletions libcamera/src/control.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{marker::PhantomData, ptr::NonNull, slice};
use std::{marker::PhantomData, ptr::NonNull};

use libcamera_sys::*;
use thiserror::Error;
Expand Down Expand Up @@ -82,26 +82,38 @@ impl ControlInfo {
unsafe {
let mut size: usize = 0;
let values_ptr = libcamera_control_info_values(self.ptr(), &mut size as *mut usize);

if values_ptr.is_null() || size == 0 {
return Vec::new();
}

let raw_slice = slice::from_raw_parts(values_ptr, size);


// Determine the size of libcamera_control_value_t
let control_value_size = libcamera_control_value_size();
println!("libcamera::ControlValue size: {}", control_value_size);

// Cast the pointer to *const u8 for byte-wise pointer arithmetic
let base_ptr = values_ptr as *const u8;

let mut control_values = Vec::with_capacity(size);
for raw_val in raw_slice {
let val_ptr = NonNull::new(raw_val as *const libcamera_control_value_t as *mut libcamera_control_value_t)
.expect("Received a null pointer in raw_slice");

match ControlValue::read(val_ptr) {
for i in 0..size {
// Calculate the pointer to the i-th ControlValue
let offset = i * control_value_size;
let val_ptr = base_ptr.add(offset) as *const libcamera_control_value_t;

if val_ptr.is_null() {
eprintln!("ControlValue at index {} is null", i);
continue;
}

// Read and convert the ControlValue
match ControlValue::read(NonNull::new(val_ptr.cast_mut()).unwrap()) {
Ok(control_val) => control_values.push(control_val),
Err(e) => {
eprintln!("Failed to read ControlValue: {:?}", e);
eprintln!("Failed to read ControlValue at index {}: {:?}", i, e);
}
}
}

control_values
}
}
Expand Down

0 comments on commit c052b1d

Please sign in to comment.