Skip to content

Commit

Permalink
device: some v4l2 cameras do not accept parameters unless streaming
Browse files Browse the repository at this point in the history
This fixes 3DO camera not accepting `--camera-options=focus_absolute=100`
and `--camera-options=focus_automatic_continuous=0`, and not properly
configuring the sensor.

The settings are applied twice (if failed) to ignore ordering problems
related to auto-focus and focus-absolute value command line order.
  • Loading branch information
ayufan committed Nov 20, 2023
1 parent 82dea91 commit 3c116f2
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 5 deletions.
10 changes: 9 additions & 1 deletion device/camera/camera.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,15 @@ void camera_capture_add_callbacks(camera_t *camera, buffer_list_t *capture, link
int camera_set_params(camera_t *camera)
{
device_set_fps(camera->camera, camera->options.fps);
device_set_option_list(camera->camera, camera->options.options);

// HACK:
// Some cameras require to be in streaming to apply settings
// This applies twice to avoid ordering issues (auto-focus vs focus value)
if (camera->camera->n_capture_list > 0)
buffer_list_set_stream(camera->camera->capture_lists[0], true);
if (device_set_option_list(camera->camera, camera->options.options) < 0)
device_set_option_list(camera->camera, camera->options.options);

device_set_option_list(camera->isp, camera->options.isp.options);

if (camera->options.auto_focus) {
Expand Down
14 changes: 11 additions & 3 deletions device/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,32 +250,40 @@ int device_set_option_string(device_t *dev, const char *key, const char *value)
return -1;
}

void device_set_option_list(device_t *dev, const char *option_list)
int device_set_option_list(device_t *dev, const char *option_list)
{
if (!dev || !option_list || !option_list[0]) {
return;
return 0;
}

char *start = strdup(option_list);
char *string = start;
char *option;
bool err = false;
int count = 0;

while ((option = strsep(&string, OPTION_VALUE_LIST_SEP)) != NULL) {
char *value = option;
char *key = strsep(&value, "=");

if (value) {
device_set_option_string(dev, key, value);
if (device_set_option_string(dev, key, value) < 0) {
err = true;
}
} else {
LOG_INFO(dev, "Missing 'key=value' for '%s'", option);
continue;
}

// consume all separators
while (strsep(&value, "="));

count++;
}

free(start);

return err ? -count : count;
}

int device_output_enqueued(device_t *dev)
Expand Down
2 changes: 1 addition & 1 deletion device/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ int device_dump_options2(device_t *dev, device_option_fn fn, void *opaque);
int device_set_fps(device_t *dev, int desired_fps);
int device_set_rotation(device_t *dev, bool vflip, bool hflip);
int device_set_option_string(device_t *dev, const char *option, const char *value);
void device_set_option_list(device_t *dev, const char *option_list);
int device_set_option_list(device_t *dev, const char *option_list);

int device_output_enqueued(device_t *dev);
int device_capture_enqueued(device_t *dev, int *max);
Expand Down

0 comments on commit 3c116f2

Please sign in to comment.