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 { @@ -73,6 +73,11 @@ type PathConf struct {
RPICameraBitrate int `json:"rpiCameraBitrate"`
RPICameraProfile string `json:"rpiCameraProfile"`
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
PublishUser Credential `json:"publishUser"`

53
internal/core/source_static.go

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

6
internal/rpicamera/exe/Makefile

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

65
internal/rpicamera/exe/camera.cpp

@ -334,6 +334,71 @@ bool camera_start(camera_t *cam) { @@ -334,6 +334,71 @@ bool camera_start(camera_t *cam) {
int64_t frame_time = 1000000 / camp->params->fps;
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);
if (res != 0) {
set_error("Camera.start() failed");

17
internal/rpicamera/exe/parameters.c

@ -39,7 +39,7 @@ bool parameters_load(parameters_t *params) { @@ -39,7 +39,7 @@ bool parameters_load(parameters_t *params) {
params->ev = atof(getenv("EV"));
if (strlen(getenv("ROI")) != 0) {
bool ok = roi_load(getenv("ROI"), &params->roi);
bool ok = window_load(getenv("ROI"), &params->roi);
if (!ok) {
set_error("invalid ROI");
return false;
@ -85,5 +85,20 @@ bool parameters_load(parameters_t *params) { @@ -85,5 +85,20 @@ bool parameters_load(parameters_t *params) {
params->buffer_count = 6;
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;
}

9
internal/rpicamera/exe/parameters.h

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

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

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

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

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
#ifndef __ROI_H__
#define __ROI_H__
#ifndef __WINDOW_H__
#define __WINDOW_H__
#include <stdbool.h>
@ -8,8 +8,8 @@ typedef struct { @@ -8,8 +8,8 @@ typedef struct {
float y;
float width;
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

53
internal/rpicamera/params.go

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

5
internal/rpicamera/rpicamera.go

@ -145,6 +145,11 @@ func New( @@ -145,6 +145,11 @@ func New(
"BITRATE=" + strconv.FormatInt(int64(params.Bitrate), 10),
"PROFILE=" + params.Profile,
"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)

18
rtsp-simple-server.yml

@ -327,6 +327,24 @@ paths: @@ -327,6 +327,24 @@ paths:
rpiCameraProfile: main
# H264 level
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.
# SHA256-hashed values can be inserted with the "sha256:" prefix.

Loading…
Cancel
Save