Browse Source

Add support for libcamera Autofocus parameters (#1417)

* [DEV #1416] Add support for libcamera Autofocus parameters

* [DEVMINOR] Fix Go formatting

* [DEV] Support AF window parameter for rpiCamera

* [DEV] Update default .yml file to add rpiCameraAfWindow parameter
pull/970/head
Azsde 3 years ago committed by GitHub
parent
commit
4841189456
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      internal/conf/path.go
  2. 53
      internal/core/source_static.go
  3. 6
      internal/rpicamera/exe/Makefile
  4. 65
      internal/rpicamera/exe/camera.cpp
  5. 17
      internal/rpicamera/exe/parameters.c
  6. 9
      internal/rpicamera/exe/parameters.h
  7. 6
      internal/rpicamera/exe/window.c
  8. 8
      internal/rpicamera/exe/window.h
  9. 53
      internal/rpicamera/params.go
  10. 5
      internal/rpicamera/rpicamera.go
  11. 18
      rtsp-simple-server.yml

5
internal/conf/path.go

@ -73,6 +73,11 @@ type PathConf struct {
RPICameraBitrate int `json:"rpiCameraBitrate"` RPICameraBitrate int `json:"rpiCameraBitrate"`
RPICameraProfile string `json:"rpiCameraProfile"` RPICameraProfile string `json:"rpiCameraProfile"`
RPICameraLevel string `json:"rpiCameraLevel"` RPICameraLevel string `json:"rpiCameraLevel"`
RPICameraAfMode string `json:"rpiCameraAfMode"`
RPICameraAfRange string `json:"rpiCameraAfRange"`
RPICameraAfSpeed string `json:"rpiCameraAfSpeed"`
RPICameraLensPosition float64 `json:"rpiCameraLensPosition"`
RPICameraAfWindow string `json:"rpiCameraAfWindow"`
// authentication // authentication
PublishUser Credential `json:"publishUser"` PublishUser Credential `json:"publishUser"`

53
internal/core/source_static.go

@ -86,30 +86,35 @@ func newSourceStatic(
case conf.Source == "rpiCamera": case conf.Source == "rpiCamera":
s.impl = newRPICameraSource( s.impl = newRPICameraSource(
rpicamera.Params{ rpicamera.Params{
CameraID: conf.RPICameraCamID, CameraID: conf.RPICameraCamID,
Width: conf.RPICameraWidth, Width: conf.RPICameraWidth,
Height: conf.RPICameraHeight, Height: conf.RPICameraHeight,
HFlip: conf.RPICameraHFlip, HFlip: conf.RPICameraHFlip,
VFlip: conf.RPICameraVFlip, VFlip: conf.RPICameraVFlip,
Brightness: conf.RPICameraBrightness, Brightness: conf.RPICameraBrightness,
Contrast: conf.RPICameraContrast, Contrast: conf.RPICameraContrast,
Saturation: conf.RPICameraSaturation, Saturation: conf.RPICameraSaturation,
Sharpness: conf.RPICameraSharpness, Sharpness: conf.RPICameraSharpness,
Exposure: conf.RPICameraExposure, Exposure: conf.RPICameraExposure,
AWB: conf.RPICameraAWB, AWB: conf.RPICameraAWB,
Denoise: conf.RPICameraDenoise, Denoise: conf.RPICameraDenoise,
Shutter: conf.RPICameraShutter, Shutter: conf.RPICameraShutter,
Metering: conf.RPICameraMetering, Metering: conf.RPICameraMetering,
Gain: conf.RPICameraGain, Gain: conf.RPICameraGain,
EV: conf.RPICameraEV, EV: conf.RPICameraEV,
ROI: conf.RPICameraROI, ROI: conf.RPICameraROI,
TuningFile: conf.RPICameraTuningFile, TuningFile: conf.RPICameraTuningFile,
Mode: conf.RPICameraMode, Mode: conf.RPICameraMode,
FPS: conf.RPICameraFPS, FPS: conf.RPICameraFPS,
IDRPeriod: conf.RPICameraIDRPeriod, IDRPeriod: conf.RPICameraIDRPeriod,
Bitrate: conf.RPICameraBitrate, Bitrate: conf.RPICameraBitrate,
Profile: conf.RPICameraProfile, Profile: conf.RPICameraProfile,
Level: conf.RPICameraLevel, Level: conf.RPICameraLevel,
AfMode: conf.RPICameraAfMode,
AfRange: conf.RPICameraAfRange,
AfSpeed: conf.RPICameraAfSpeed,
LensPosition: conf.RPICameraLensPosition,
AfWindow: conf.RPICameraAfWindow,
}, },
s) s)
} }

6
internal/rpicamera/exe/Makefile

@ -3,7 +3,8 @@ CFLAGS = \
-Werror \ -Werror \
-Wall \ -Wall \
-Wextra \ -Wextra \
-Wno-unused-parameter -Wno-unused-parameter \
-Wno-unused-result
CXXFLAGS = \ CXXFLAGS = \
-Ofast \ -Ofast \
@ -11,6 +12,7 @@ CXXFLAGS = \
-Wall \ -Wall \
-Wextra \ -Wextra \
-Wno-unused-parameter \ -Wno-unused-parameter \
-Wno-unused-result \
-std=c++17 \ -std=c++17 \
$$(pkg-config --cflags libcamera) $$(pkg-config --cflags libcamera)
@ -24,7 +26,7 @@ OBJS = \
encoder.o \ encoder.o \
main.o \ main.o \
parameters.o \ parameters.o \
roi.o \ window.o \
sensor_mode.o sensor_mode.o
all: exe all: exe

65
internal/rpicamera/exe/camera.cpp

@ -334,6 +334,71 @@ bool camera_start(camera_t *cam) {
int64_t frame_time = 1000000 / camp->params->fps; int64_t frame_time = 1000000 / camp->params->fps;
ctrls.set(controls::FrameDurationLimits, Span<const int64_t, 2>({ frame_time, frame_time })); ctrls.set(controls::FrameDurationLimits, Span<const int64_t, 2>({ frame_time, frame_time }));
int af_mode;
if (strcmp(camp->params->af_mode, "manual") == 0) {
af_mode = controls::AfModeManual;
} else if (strcmp(camp->params->af_mode, "auto") == 0) {
af_mode = controls::AfModeAuto;
} else if (strcmp(camp->params->af_mode, "continuous") == 0) {
af_mode = controls::AfModeContinuous;
} else {
af_mode = controls::AfModeManual;
}
ctrls.set(controls::AfMode, af_mode);
int af_range;
if (strcmp(camp->params->af_range, "normal") == 0) {
af_range = controls::AfRangeNormal;
} else if (strcmp(camp->params->af_range, "macro") == 0) {
af_range = controls::AfRangeMacro;
} else if (strcmp(camp->params->af_range, "full") == 0) {
af_range = controls::AfRangeFull;
} else {
af_range = controls::AfRangeNormal;
}
ctrls.set(controls::AfRange, af_range);
int af_speed;
if (strcmp(camp->params->af_range, "normal") == 0) {
af_speed = controls::AfSpeedNormal;
} else if (strcmp(camp->params->af_range, "fast") == 0) {
af_speed = controls::AfSpeedFast;
} else {
af_speed = controls::AfSpeedNormal;
}
ctrls.set(controls::AfSpeed, af_speed);
// Lens Position
ctrls.set(controls::LensPosition, camp->params->lens_position);
// Af Window
if (camp->params->af_window != NULL) {
std::optional<Rectangle> opt = camp->camera->properties().get(properties::ScalerCropMaximum);
Rectangle sensor_area;
try {
sensor_area = opt.value();
} catch(const std::bad_optional_access& exc) {
set_error("get(ScalerCropMaximum) failed");
return false;
}
Rectangle afwindows_rectangle[1];
afwindows_rectangle[0] = Rectangle (
camp->params->af_window->x * sensor_area.width,
camp->params->af_window->y * sensor_area.height,
camp->params->af_window->width * sensor_area.width,
camp->params->af_window->height * sensor_area.height);
afwindows_rectangle[0].translateBy(sensor_area.topLeft());
//activate the AfMeteringWindows
ctrls.set(controls::AfMetering, controls::AfMeteringWindows);
//set window
ctrls.set(controls::AfWindows, afwindows_rectangle);
}
int res = camp->camera->start(&ctrls); int res = camp->camera->start(&ctrls);
if (res != 0) { if (res != 0) {
set_error("Camera.start() failed"); set_error("Camera.start() failed");

17
internal/rpicamera/exe/parameters.c

@ -39,7 +39,7 @@ bool parameters_load(parameters_t *params) {
params->ev = atof(getenv("EV")); params->ev = atof(getenv("EV"));
if (strlen(getenv("ROI")) != 0) { if (strlen(getenv("ROI")) != 0) {
bool ok = roi_load(getenv("ROI"), &params->roi); bool ok = window_load(getenv("ROI"), &params->roi);
if (!ok) { if (!ok) {
set_error("invalid ROI"); set_error("invalid ROI");
return false; return false;
@ -85,5 +85,20 @@ bool parameters_load(parameters_t *params) {
params->buffer_count = 6; params->buffer_count = 6;
params->capture_buffer_count = params->buffer_count * 2; params->capture_buffer_count = params->buffer_count * 2;
params->af_mode = getenv("AF_MODE");
params->af_range = getenv("AF_RANGE");
params->af_speed = getenv("AF_SPEED");
params->lens_position = atof(getenv("LENS_POSITION"));
if (strlen(getenv("AF_WINDOW")) != 0) {
bool ok = window_load(getenv("AF_WINDOW"), &params->af_window);
if (!ok) {
set_error("invalid AF_WINDOW");
return false;
}
} else {
params->af_window = NULL;
}
return true; return true;
} }

9
internal/rpicamera/exe/parameters.h

@ -3,7 +3,7 @@
#include <stdbool.h> #include <stdbool.h>
#include "roi.h" #include "window.h"
#include "sensor_mode.h" #include "sensor_mode.h"
typedef struct { typedef struct {
@ -23,7 +23,7 @@ typedef struct {
const char *metering; const char *metering;
float gain; float gain;
float ev; float ev;
roi_t *roi; window_t *roi;
const char *tuning_file; const char *tuning_file;
sensor_mode_t *mode; sensor_mode_t *mode;
unsigned int fps; unsigned int fps;
@ -31,6 +31,11 @@ typedef struct {
unsigned int bitrate; unsigned int bitrate;
unsigned int profile; unsigned int profile;
unsigned int level; unsigned int level;
const char *af_mode;
const char *af_range;
const char *af_speed;
float lens_position;
window_t *af_window;
// private // private
unsigned int buffer_count; unsigned int buffer_count;

6
internal/rpicamera/exe/roi.c → internal/rpicamera/exe/window.c

@ -1,9 +1,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "roi.h" #include "window.h"
bool roi_load(const char *encoded, roi_t **mode) { bool window_load(const char *encoded, window_t **mode) {
float vals[4]; float vals[4];
int i = 0; int i = 0;
char *token = strtok((char *)encoded, ","); char *token = strtok((char *)encoded, ",");
@ -21,7 +21,7 @@ bool roi_load(const char *encoded, roi_t **mode) {
return false; return false;
} }
*mode = malloc(sizeof(roi_t)); *mode = malloc(sizeof(window_t));
(*mode)->x = vals[0]; (*mode)->x = vals[0];
(*mode)->y = vals[1]; (*mode)->y = vals[1];
(*mode)->width = vals[2]; (*mode)->width = vals[2];

8
internal/rpicamera/exe/roi.h → internal/rpicamera/exe/window.h

@ -1,5 +1,5 @@
#ifndef __ROI_H__ #ifndef __WINDOW_H__
#define __ROI_H__ #define __WINDOW_H__
#include <stdbool.h> #include <stdbool.h>
@ -8,8 +8,8 @@ typedef struct {
float y; float y;
float width; float width;
float height; float height;
} roi_t; } window_t;
bool roi_load(const char *encoded, roi_t **mode); bool window_load(const char *encoded, window_t **mode);
#endif #endif

53
internal/rpicamera/params.go

@ -2,28 +2,33 @@ package rpicamera
// Params is a set of camera parameters. // Params is a set of camera parameters.
type Params struct { type Params struct {
CameraID int CameraID int
Width int Width int
Height int Height int
HFlip bool HFlip bool
VFlip bool VFlip bool
Brightness float64 Brightness float64
Contrast float64 Contrast float64
Saturation float64 Saturation float64
Sharpness float64 Sharpness float64
Exposure string Exposure string
AWB string AWB string
Denoise string Denoise string
Shutter int Shutter int
Metering string Metering string
Gain float64 Gain float64
EV float64 EV float64
ROI string ROI string
TuningFile string TuningFile string
Mode string Mode string
FPS int FPS int
IDRPeriod int IDRPeriod int
Bitrate int Bitrate int
Profile string Profile string
Level string Level string
AfMode string
AfRange string
AfSpeed string
LensPosition float64
AfWindow string
} }

5
internal/rpicamera/rpicamera.go

@ -145,6 +145,11 @@ func New(
"BITRATE=" + strconv.FormatInt(int64(params.Bitrate), 10), "BITRATE=" + strconv.FormatInt(int64(params.Bitrate), 10),
"PROFILE=" + params.Profile, "PROFILE=" + params.Profile,
"LEVEL=" + params.Level, "LEVEL=" + params.Level,
"AF_MODE=" + params.AfMode,
"AF_RANGE=" + params.AfRange,
"AF_SPEED=" + params.AfSpeed,
"LENS_POSITION=" + strconv.FormatFloat(params.LensPosition, 'f', -1, 64),
"AF_WINDOW=" + params.AfWindow,
} }
exe, err := newEmbeddedExe(exeContent, env) exe, err := newEmbeddedExe(exeContent, env)

18
rtsp-simple-server.yml

@ -327,6 +327,24 @@ paths:
rpiCameraProfile: main rpiCameraProfile: main
# H264 level # H264 level
rpiCameraLevel: '4.1' rpiCameraLevel: '4.1'
# Autofocus mode
# values: manual, auto, continuous
rpiCameraAfMode: continuous
# Autofocus range
# values: normal, macro, full
rpiCameraAfRange: normal
# Autofocus speed
# values: normal, fast
rpiCameraAfSpeed: normal
# Lens position (for manual autofocus only), will be set to focus to a specific distance
# calculated by the following formula: d = 1 / value
# Examples: 0 moves the lens to infinity.
# 0.5 moves the lens to focus on objects 2m away.
# 2 moves the lens to focus on objects 50cm away.
rpiCameraLensPosition: 0.0
# Specifies the autofocus window, in the form x,y,width,height where the coordinates
# are given as a proportion of the entire image.
rpiCameraAfWindow:
# Username required to publish. # Username required to publish.
# SHA256-hashed values can be inserted with the "sha256:" prefix. # SHA256-hashed values can be inserted with the "sha256:" prefix.

Loading…
Cancel
Save