Skip to content

Commit

Permalink
Merge branch 'main' into 31-support-configurable-append-dimension-in-…
Browse files Browse the repository at this point in the history
…storageproperties
  • Loading branch information
aliddell committed Jan 23, 2024
2 parents 6a47b35 + 753b26b commit 1dd15f2
Show file tree
Hide file tree
Showing 8 changed files with 235 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -402,3 +402,22 @@ device_manager_select(const struct DeviceManager* self,
}
return Device_Err;
}

enum DeviceStatusCode
device_manager_select_default(const struct DeviceManager* self,
enum DeviceKind kind,
struct DeviceIdentifier* out)
{
switch (kind) {
case DeviceKind_Camera:
return device_manager_select_inner_(
self, kind, ".*random.*", sizeof(".*random.*") - 1, out);
case DeviceKind_Storage:
return device_manager_select_inner_(
self, kind, "trash", sizeof("trash") - 1, out);
default:
LOGE("Invalid parameter `kind`. Got: %s",
device_kind_as_string(kind));
return Device_Err;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ extern "C"
size_t bytes_of_name,
struct DeviceIdentifier* out);

/// Query for the default device with a matching `kind`.
///
/// @param self The deviceManager context to query.
/// @param kind The kind of device to select.
/// @param out The id of the default device discovered that matches the
/// `kind`.
enum DeviceStatusCode device_manager_select_default(
const struct DeviceManager* self,
enum DeviceKind kind,
struct DeviceIdentifier* out);

struct Driver* device_manager_get_driver(
const struct DeviceManager* self,
const struct DeviceIdentifier* identifier);
Expand Down
3 changes: 2 additions & 1 deletion acquire-core-libs/src/acquire-device-kit/device/kit/camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ extern "C"
/// @details This instructs the camera to stop and may block until it
/// actually has stopped acquiring frames.
/// The camera should also be restartable after calling this
/// (i.e. one call of start after one call of stop should succeed).
/// (i.e. one call of start after one call of stop should
/// succeed).
enum DeviceStatusCode (*stop)(struct Camera*);

/// @brief Execute the software trigger.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@ extern "C"

/// @brief Stores the properties of a camera.
/// @details Can be populated with values from a camera or
/// can be filled out to define new values that a camera should adopt.
/// can be filled out to define new values that a camera should
/// adopt.
struct CameraProperties
{
/// @brief Exposure time of a frame in microseconds.
/// @details Acquire assumes that exposure is always manually specified by this period of time.
/// It does not currently support auto-exposure or durations defined by trigger widths.
/// @details Acquire assumes that exposure is always manually specified
/// by this period of time.
/// It does not currently support auto-exposure or durations
/// defined by trigger widths.
float exposure_time_us;

float line_interval_us;
Expand All @@ -27,14 +30,15 @@ extern "C"
/// @brief Binning or downsample factor.
/// @details Determines how many pixels in each spatial dimension on the
/// sensor are aggregated to form pixels in an image.
/// For example, if we have a sensor of size 1920x1200 and a binning
/// factor of 2, one image should be 960x600.
/// For example, if we have a sensor of size 1920x1200 and a
/// binning factor of 2, one image should be 960x600.
uint8_t binning;

/// @brief Type of each image pixel or sample.
enum SampleType pixel_type;

/// @brief Offset of the region of interest on the sensor from its top-left corner.
/// @brief Offset of the region of interest on the sensor from its
/// top-left corner.
/// @details Each value represents a number of aggregated pixels in the
/// frame after binning has been applied.
struct camera_properties_offset_s
Expand Down Expand Up @@ -87,21 +91,25 @@ extern "C"

struct CameraPropertyMetadataDigitalLineMetadata
{
/// @brief The number of supported digital IO lines. Must be less than 8.
/// @brief The number of supported digital IO lines. Must be less
/// than 8.
uint8_t line_count;

/// @brief Support describing up to 8 names for use with triggering.
/// @details name[i] is a short, null terminated string naming line i.
/// @details name[i] is a short, null terminated string naming line
/// i.
char names[8][64];
} digital_lines;

struct CameraPropertiesTriggerMetadata
{
struct camera_properties_metadata_trigger_capabilities_s
{
/// @brief Bit i is set if line i can be used as a trigger input.
/// @brief Bit i is set if line i can be used as a trigger
/// input.
uint8_t input;
/// @brief Bit i is set if line i can be used as a trigger output.
/// @brief Bit i is set if line i can be used as a trigger
/// output.
uint8_t output;
} acquisition_start, exposure, frame_start;
} triggers;
Expand Down
47 changes: 32 additions & 15 deletions acquire-video-runtime/src/acquire.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "acquire.h"

#include "device/hal/camera.h"
#include "device/props/device.h"
#include "logger.h"
#include "platform.h"
#include "runtime/channel.h"
Expand All @@ -11,6 +12,8 @@
#include <stdio.h>
#include <string.h>

#define max(a, b) ((a) < (b) ? (b) : (a))

#define containerof(ptr, T, V) ((T*)(((char*)(ptr)) - offsetof(T, V)))
#define countof(e) (sizeof(e) / sizeof(*(e)))

Expand Down Expand Up @@ -258,20 +261,30 @@ configure_video_stream(struct video_s* const video,
struct aq_properties_storage_s* const pstorage = &pvideo->storage;

int is_ok = 1;
is_ok &= (video_source_configure(&video->source,
device_manager,
&pcamera->identifier,
&pcamera->settings,
pvideo->max_frame_count,
pvideo->frame_average_count > 1) == Device_Ok);
if (pcamera->identifier.kind == DeviceKind_None) {
is_ok &= (Device_Ok == device_manager_select_default(
device_manager, DeviceKind_Camera, &pcamera->identifier));
}

is_ok &=
(video_source_configure(&video->source,
device_manager,
&pcamera->identifier,
&pcamera->settings,
pvideo->max_frame_count,
pvideo->frame_average_count > 1) == Device_Ok);
is_ok &= (video_filter_configure(&video->filter,
pvideo->frame_average_count) == Device_Ok);
is_ok &=
(video_sink_configure(&video->sink,
device_manager,
&pstorage->identifier,
&pstorage->settings,
pstorage->write_delay_ms) == Device_Ok);

if (pstorage->identifier.kind == DeviceKind_None) {
is_ok &= (Device_Ok == device_manager_select_default(
device_manager, DeviceKind_Storage, &pstorage->identifier));
}
is_ok &= (video_sink_configure(&video->sink,
device_manager,
&pstorage->identifier,
&pstorage->settings,
pstorage->write_delay_ms) == Device_Ok);
is_ok &= reserve_image_shape(video);

EXPECT(is_ok, "Failed to configure video stream.");
Expand Down Expand Up @@ -322,9 +335,13 @@ acquire_configure(struct AcquireRuntime* self_,
}
}
TRACE("Valid video streams: code %#04x", self->valid_video_streams);
self->state = self->valid_video_streams > 0
? DeviceState_Armed
: DeviceState_AwaitingConfiguration;
if (self->valid_video_streams == 0) {
acquire_abort(self_); // aborts, moves to an Armed state
self->state = DeviceState_AwaitingConfiguration;
} else {
// success, moved to armed state or leave running
self->state = max(self->state, DeviceState_Armed);
}
return AcquireStatus_Ok;
Error:
if (self_)
Expand Down
12 changes: 8 additions & 4 deletions acquire-video-runtime/src/runtime/channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,16 @@ extern "C"
/// Position in the channel where the next write operation will occur.
size_t head;

/// Highest position in the channel that has been written to in the current cycle.
/// Highest position in the channel that has been written to in the
/// current cycle.
size_t high;

/// Number of times the buffer has been filled and wrapped around to the start.
/// Number of times the buffer has been filled and wrapped around to the
/// start.
size_t cycle;

/// Pointer to the end position of the reserved region of a mapped write.
/// Pointer to the end position of the reserved region of a mapped
/// write.
size_t mapped;

/// Whether or not the channel is accepting writes.
Expand All @@ -44,7 +47,8 @@ extern "C"
{
size_t pos[8];
size_t cycles[8];
unsigned n; /// Number of readers currently reading from the channel.
unsigned
n; /// Number of readers currently reading from the channel.
} holds;
};

Expand Down
1 change: 1 addition & 0 deletions acquire-video-runtime/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ else ()
change-file-name
client-queue-is-flushed-after-abort
configure-after-shutdown-and-reinitialize
default-devices
device-selection
no-abort-on-dropped-frames
one-video-stream
Expand Down
144 changes: 144 additions & 0 deletions acquire-video-runtime/tests/default-devices.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/// @file default-devices.cpp
/// Test that setting DeviceKind_None for the camera or storage devices selects
/// random and trash devices, respectively, if and only if the other device is
/// not set to DeviceKind_None.

#include "acquire.h"
#include "device/hal/device.manager.h"
#include "logger.h"

#include <cstdio>
#include <cstring>
#include <stdexcept>

void
reporter(int is_error,
const char* file,
int line,
const char* function,
const char* msg)
{
fprintf(is_error ? stderr : stdout,
"%s%s(%d) - %s: %s\n",
is_error ? "ERROR " : "",
file,
line,
function,
msg);
}

/// Helper for passing size static strings as function args.
/// For a function: `f(char*,size_t)` use `f(SIZED("hello"))`.
/// Expands to `f("hello",5)`.
#define SIZED(str) str, sizeof(str)

#define L (aq_logger)
#define LOG(...) L(0, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
#define ERR(...) L(1, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
#define EXPECT(e, ...) \
do { \
if (!(e)) { \
char buf[1 << 8] = { 0 }; \
ERR(__VA_ARGS__); \
snprintf(buf, sizeof(buf) - 1, __VA_ARGS__); \
throw std::runtime_error(buf); \
} \
} while (0)
#define CHECK(e) EXPECT(e, "Expression evaluated as false: %s", #e)
#define DEVOK(e) CHECK(Device_Ok == (e))
#define OK(e) CHECK(AcquireStatus_Ok == (e))

void
select_camera(AcquireRuntime* runtime)
{
CHECK(runtime);

auto* dm = acquire_device_manager(runtime);
CHECK(dm);

AcquireProperties props = {};
OK(acquire_get_configuration(runtime, &props));
props.video[0].camera.identifier = { 0 };
CHECK(props.video[0].camera.identifier.kind == DeviceKind_None);
CHECK(strlen(props.video[0].camera.identifier.name) == 0);

DEVOK(device_manager_select(dm,
DeviceKind_Storage,
SIZED("Trash") - 1,
&props.video[0].storage.identifier));

OK(acquire_configure(runtime, &props));

CHECK(props.video[0].camera.identifier.kind == DeviceKind_Camera);
CHECK(strcmp(props.video[0].camera.identifier.name,
"simulated: uniform random") == 0);
}

void
select_storage(AcquireRuntime* runtime)
{
CHECK(runtime);

auto* dm = acquire_device_manager(runtime);
CHECK(dm);

AcquireProperties props = {};
OK(acquire_get_configuration(runtime, &props));
props.video[0].storage.identifier = { 0 };
CHECK(props.video[0].storage.identifier.kind == DeviceKind_None);
CHECK(strlen(props.video[0].storage.identifier.name) == 0);

DEVOK(device_manager_select(dm,
DeviceKind_Camera,
SIZED(".*empty.*") - 1,
&props.video[0].camera.identifier));

OK(acquire_configure(runtime, &props));

CHECK(props.video[0].storage.identifier.kind == DeviceKind_Storage);
CHECK(strcmp(props.video[0].storage.identifier.name, "trash") == 0);
}

void
select_neither(AcquireRuntime* runtime)
{
CHECK(runtime);

auto* dm = acquire_device_manager(runtime);
CHECK(dm);

AcquireProperties props = {};
OK(acquire_get_configuration(runtime, &props));
props.video[0].camera.identifier = { 0 };
CHECK(props.video[0].camera.identifier.kind == DeviceKind_None);
CHECK(strlen(props.video[0].camera.identifier.name) == 0);

props.video[0].storage.identifier = { 0 };
CHECK(props.video[0].storage.identifier.kind == DeviceKind_None);
CHECK(strlen(props.video[0].storage.identifier.name) == 0);

OK(acquire_configure(runtime, &props));

CHECK(props.video[0].camera.identifier.kind == DeviceKind_None);
CHECK(strlen(props.video[0].camera.identifier.name) == 0);

CHECK(props.video[0].storage.identifier.kind == DeviceKind_None);
CHECK(strlen(props.video[0].storage.identifier.name) == 0);
}

int
main()
{
auto runtime = acquire_init(reporter);

try {
select_camera(runtime);
select_storage(runtime);
select_neither(runtime);
} catch (const std::exception& e) {
ERR("ERROR: %s\n", e.what());
return 1;
}

return 0;
}

0 comments on commit 1dd15f2

Please sign in to comment.