Browse Source

rpicamera: add rpiCameraMode parameter (#1111)

pull/1219/head
aler9 4 years ago
parent
commit
7013b75daf
  1. 1
      internal/conf/path.go
  2. 1
      internal/core/source_static.go
  3. 4
      internal/rpicamera/exe/Makefile
  4. 84
      internal/rpicamera/exe/camera.cpp
  5. 9
      internal/rpicamera/exe/camera.h
  6. 12
      internal/rpicamera/exe/encoder.c
  7. 5
      internal/rpicamera/exe/encoder.h
  8. 12
      internal/rpicamera/exe/main.c
  9. 41
      internal/rpicamera/exe/parameters.c
  10. 16
      internal/rpicamera/exe/parameters.h
  11. 30
      internal/rpicamera/exe/roi.c
  12. 15
      internal/rpicamera/exe/roi.h
  13. 30
      internal/rpicamera/exe/sensor_mode.c
  14. 15
      internal/rpicamera/exe/sensor_mode.h
  15. 1
      internal/rpicamera/params.go
  16. 1
      internal/rpicamera/rpicamera.go
  17. 5
      rtsp-simple-server.yml

1
internal/conf/path.go

@ -67,6 +67,7 @@ type PathConf struct {
RPICameraEV float64 `json:"rpiCameraEV"` RPICameraEV float64 `json:"rpiCameraEV"`
RPICameraROI string `json:"rpiCameraROI"` RPICameraROI string `json:"rpiCameraROI"`
RPICameraTuningFile string `json:"rpiCameraTuningFile"` RPICameraTuningFile string `json:"rpiCameraTuningFile"`
RPICameraMode string `json:"rpiCameraMode"`
RPICameraFPS int `json:"rpiCameraFPS"` RPICameraFPS int `json:"rpiCameraFPS"`
RPICameraIDRPeriod int `json:"rpiCameraIDRPeriod"` RPICameraIDRPeriod int `json:"rpiCameraIDRPeriod"`
RPICameraBitrate int `json:"rpiCameraBitrate"` RPICameraBitrate int `json:"rpiCameraBitrate"`

1
internal/core/source_static.go

@ -104,6 +104,7 @@ func newSourceStatic(
EV: conf.RPICameraEV, EV: conf.RPICameraEV,
ROI: conf.RPICameraROI, ROI: conf.RPICameraROI,
TuningFile: conf.RPICameraTuningFile, TuningFile: conf.RPICameraTuningFile,
Mode: conf.RPICameraMode,
FPS: conf.RPICameraFPS, FPS: conf.RPICameraFPS,
IDRPeriod: conf.RPICameraIDRPeriod, IDRPeriod: conf.RPICameraIDRPeriod,
Bitrate: conf.RPICameraBitrate, Bitrate: conf.RPICameraBitrate,

4
internal/rpicamera/exe/Makefile

@ -26,7 +26,9 @@ OBJS = \
camera.o \ camera.o \
encoder.o \ encoder.o \
main.o \ main.o \
parameters.o parameters.o \
roi.o \
sensor_mode.o
all: exe all: exe

84
internal/rpicamera/exe/camera.cpp

@ -46,11 +46,32 @@ const char *camera_get_error() {
return errbuf; return errbuf;
} }
// https://github.com/raspberrypi/libcamera-apps/blob/dd97618a25523c2c4aa58f87af5f23e49aa6069c/core/libcamera_app.cpp#L42
static libcamera::PixelFormat mode_to_pixel_format(sensor_mode_t *mode) {
static std::vector<std::pair<std::pair<int, bool>, libcamera::PixelFormat>> table = {
{ {8, false}, libcamera::formats::SBGGR8 },
{ {8, true}, libcamera::formats::SBGGR8 },
{ {10, false}, libcamera::formats::SBGGR10 },
{ {10, true}, libcamera::formats::SBGGR10_CSI2P },
{ {12, false}, libcamera::formats::SBGGR12 },
{ {12, true}, libcamera::formats::SBGGR12_CSI2P },
};
auto it = std::find_if(table.begin(), table.end(), [&mode] (auto &m) {
return mode->bit_depth == m.first.first && mode->packed == m.first.second; });
if (it != table.end()) {
return it->second;
}
return libcamera::formats::SBGGR12_CSI2P;
}
struct CameraPriv { struct CameraPriv {
parameters_t *params; parameters_t *params;
camera_frame_cb frame_cb; camera_frame_cb frame_cb;
std::unique_ptr<CameraManager> camera_manager; std::unique_ptr<CameraManager> camera_manager;
std::shared_ptr<Camera> camera; std::shared_ptr<Camera> camera;
Stream *video_stream;
std::unique_ptr<FrameBufferAllocator> allocator; std::unique_ptr<FrameBufferAllocator> allocator;
std::vector<std::unique_ptr<Request>> requests; std::vector<std::unique_ptr<Request>> requests;
}; };
@ -87,6 +108,8 @@ bool camera_create(parameters_t *params, camera_frame_cb frame_cb, camera_t **ca
return false; return false;
} }
setenv("LIBCAMERA_RPI_TUNING_FILE", params->tuning_file, 1);
ret = camp->camera->acquire(); ret = camp->camera->acquire();
if (ret != 0) { if (ret != 0) {
set_error("Camera.acquire() failed"); set_error("Camera.acquire() failed");
@ -94,21 +117,32 @@ bool camera_create(parameters_t *params, camera_frame_cb frame_cb, camera_t **ca
} }
StreamRoles stream_roles = { StreamRole::VideoRecording }; StreamRoles stream_roles = { StreamRole::VideoRecording };
if (params->mode != NULL) {
stream_roles.push_back(StreamRole::Raw);
}
std::unique_ptr<CameraConfiguration> conf = camp->camera->generateConfiguration(stream_roles); std::unique_ptr<CameraConfiguration> conf = camp->camera->generateConfiguration(stream_roles);
if (conf == NULL) { if (conf == NULL) {
set_error("Camera.generateConfiguration() failed"); set_error("Camera.generateConfiguration() failed");
return false; return false;
} }
StreamConfiguration &stream_conf = conf->at(0); StreamConfiguration &video_stream_conf = conf->at(0);
stream_conf.pixelFormat = formats::YUV420; video_stream_conf.pixelFormat = formats::YUV420;
stream_conf.bufferCount = params->buffer_count; video_stream_conf.bufferCount = params->buffer_count;
stream_conf.size.width = params->width; video_stream_conf.size.width = params->width;
stream_conf.size.height = params->height; video_stream_conf.size.height = params->height;
if (params->width >= 1280 || params->height >= 720) { if (params->width >= 1280 || params->height >= 720) {
stream_conf.colorSpace = libcamera::ColorSpace::Rec709; video_stream_conf.colorSpace = libcamera::ColorSpace::Rec709;
} else { } else {
stream_conf.colorSpace = libcamera::ColorSpace::Smpte170m; video_stream_conf.colorSpace = libcamera::ColorSpace::Smpte170m;
}
if (params->mode != NULL) {
StreamConfiguration &raw_stream_conf = conf->at(1);
raw_stream_conf.size = libcamera::Size(params->mode->width, params->mode->height);
raw_stream_conf.pixelFormat = mode_to_pixel_format(params->mode);
raw_stream_conf.bufferCount = video_stream_conf.bufferCount;
} }
conf->transform = Transform::Identity; conf->transform = Transform::Identity;
@ -119,8 +153,6 @@ bool camera_create(parameters_t *params, camera_frame_cb frame_cb, camera_t **ca
conf->transform = Transform::VFlip * conf->transform; conf->transform = Transform::VFlip * conf->transform;
} }
setenv("LIBCAMERA_RPI_TUNING_FILE", params->tuning_file, 1);
CameraConfiguration::Status vstatus = conf->validate(); CameraConfiguration::Status vstatus = conf->validate();
if (vstatus == CameraConfiguration::Invalid) { if (vstatus == CameraConfiguration::Invalid) {
set_error("StreamConfiguration.validate() failed"); set_error("StreamConfiguration.validate() failed");
@ -133,23 +165,23 @@ bool camera_create(parameters_t *params, camera_frame_cb frame_cb, camera_t **ca
return false; return false;
} }
Stream *stream = stream_conf.stream(); camp->video_stream = video_stream_conf.stream();
camp->allocator = std::make_unique<FrameBufferAllocator>(camp->camera); camp->allocator = std::make_unique<FrameBufferAllocator>(camp->camera);
res = camp->allocator->allocate(stream); res = camp->allocator->allocate(camp->video_stream);
if (res < 0) { if (res < 0) {
set_error("allocate() failed"); set_error("allocate() failed");
return false; return false;
} }
for (const std::unique_ptr<FrameBuffer> &buffer : camp->allocator->buffers(stream)) { for (const std::unique_ptr<FrameBuffer> &buffer : camp->allocator->buffers(camp->video_stream)) {
std::unique_ptr<Request> request = camp->camera->createRequest((uint64_t)camp.get()); std::unique_ptr<Request> request = camp->camera->createRequest((uint64_t)camp.get());
if (request == NULL) { if (request == NULL) {
set_error("createRequest() failed"); set_error("createRequest() failed");
return false; return false;
} }
int res = request->addBuffer(stream, buffer.get()); int res = request->addBuffer(camp->video_stream, buffer.get());
if (res != 0) { if (res != 0) {
set_error("addBuffer() failed"); set_error("addBuffer() failed");
return false; return false;
@ -185,14 +217,14 @@ static void on_request_complete(Request *request) {
camp->camera->queueRequest(request); camp->camera->queueRequest(request);
} }
int camera_get_stride(camera_t *cam) { int camera_get_mode_stride(camera_t *cam) {
CameraPriv *camp = (CameraPriv *)cam; CameraPriv *camp = (CameraPriv *)cam;
return (*camp->camera->streams().begin())->configuration().stride; return camp->video_stream->configuration().stride;
} }
int camera_get_colorspace(camera_t *cam) { int camera_get_mode_colorspace(camera_t *cam) {
CameraPriv *camp = (CameraPriv *)cam; CameraPriv *camp = (CameraPriv *)cam;
return get_v4l2_colorspace((*camp->camera->streams().begin())->configuration().colorSpace); return get_v4l2_colorspace(camp->video_stream->configuration().colorSpace);
} }
bool camera_start(camera_t *cam) { bool camera_start(camera_t *cam) {
@ -271,21 +303,13 @@ bool camera_start(camera_t *cam) {
ctrls.set(controls::ExposureValue, camp->params->ev); ctrls.set(controls::ExposureValue, camp->params->ev);
if (strlen(camp->params->roi) != 0) { if (camp->params->roi != NULL) {
float vals[4];
int i = 0;
char *token = strtok((char *)camp->params->roi, ",");
while (token != NULL) {
vals[i++] = atof(token);
token = strtok(NULL, ",");
}
Rectangle sensor_area = camp->camera->properties().get(libcamera::properties::ScalerCropMaximum); Rectangle sensor_area = camp->camera->properties().get(libcamera::properties::ScalerCropMaximum);
Rectangle crop( Rectangle crop(
vals[0] * sensor_area.width, camp->params->roi->x * sensor_area.width,
vals[1] * sensor_area.height, camp->params->roi->y * sensor_area.height,
vals[2] * sensor_area.width, camp->params->roi->width * sensor_area.width,
vals[3] * sensor_area.height); camp->params->roi->height * sensor_area.height);
crop.translateBy(sensor_area.topLeft()); crop.translateBy(sensor_area.topLeft());
ctrls.set(controls::ScalerCrop, crop); ctrls.set(controls::ScalerCrop, crop);
} }

9
internal/rpicamera/exe/camera.h

@ -1,3 +1,6 @@
#ifndef __CAMERA_H__
#define __CAMERA_H__
typedef void camera_t; typedef void camera_t;
typedef void (*camera_frame_cb)(int buffer_fd, uint64_t size, uint64_t timestamp); typedef void (*camera_frame_cb)(int buffer_fd, uint64_t size, uint64_t timestamp);
@ -8,10 +11,12 @@ extern "C" {
const char *camera_get_error(); const char *camera_get_error();
bool camera_create(parameters_t *params, camera_frame_cb frame_cb, camera_t **cam); bool camera_create(parameters_t *params, camera_frame_cb frame_cb, camera_t **cam);
int camera_get_stride(camera_t *cam); int camera_get_mode_stride(camera_t *cam);
int camera_get_colorspace(camera_t *cam); int camera_get_mode_colorspace(camera_t *cam);
bool camera_start(camera_t *cam); bool camera_start(camera_t *cam);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif

12
internal/rpicamera/exe/encoder.c

@ -17,6 +17,8 @@
#include "parameters.h" #include "parameters.h"
#include "encoder.h" #include "encoder.h"
#define DEVICE "/dev/video11"
char errbuf[256]; char errbuf[256];
static void set_error(const char *format, ...) { static void set_error(const char *format, ...) {
@ -58,7 +60,7 @@ static void *output_thread(void *userdata) {
buf.m.planes = planes; buf.m.planes = planes;
int res = ioctl(encp->fd, VIDIOC_DQBUF, &buf); int res = ioctl(encp->fd, VIDIOC_DQBUF, &buf);
if (res != 0) { if (res != 0) {
fprintf(stderr, "output_thread(): ioctl() failed\n"); fprintf(stderr, "output_thread(): ioctl(VIDIOC_DQBUF) failed\n");
exit(1); exit(1);
} }
@ -88,7 +90,7 @@ static void *output_thread(void *userdata) {
buf.m.planes[0].length = length; buf.m.planes[0].length = length;
int res = ioctl(encp->fd, VIDIOC_QBUF, &buf); int res = ioctl(encp->fd, VIDIOC_QBUF, &buf);
if (res < 0) { if (res < 0) {
fprintf(stderr, "output_thread(): ioctl() failed\n"); fprintf(stderr, "output_thread(): ioctl(VIDIOC_QBUF) failed\n");
exit(1); exit(1);
} }
} }
@ -102,7 +104,7 @@ bool encoder_create(parameters_t *params, int stride, int colorspace, encoder_ou
*enc = malloc(sizeof(encoder_priv_t)); *enc = malloc(sizeof(encoder_priv_t));
encoder_priv_t *encp = (encoder_priv_t *)(*enc); encoder_priv_t *encp = (encoder_priv_t *)(*enc);
encp->fd = open("/dev/video11", O_RDWR, 0); encp->fd = open(DEVICE, O_RDWR, 0);
if (encp->fd < 0) { if (encp->fd < 0) {
set_error("unable to open device"); set_error("unable to open device");
return false; return false;
@ -254,7 +256,7 @@ bool encoder_create(parameters_t *params, int stride, int colorspace, encoder_ou
res = ioctl(encp->fd, VIDIOC_QBUF, &buffer); res = ioctl(encp->fd, VIDIOC_QBUF, &buffer);
if (res != 0) { if (res != 0) {
set_error("ioctl() failed"); set_error("ioctl(VIDIOC_QBUF) failed");
free(encp->capture_buffers); free(encp->capture_buffers);
close(encp->fd); close(encp->fd);
return false; return false;
@ -309,7 +311,7 @@ void encoder_encode(encoder_t *enc, int buffer_fd, size_t size, int64_t timestam
buf.m.planes[0].length = size; buf.m.planes[0].length = size;
int res = ioctl(encp->fd, VIDIOC_QBUF, &buf); int res = ioctl(encp->fd, VIDIOC_QBUF, &buf);
if (res != 0) { if (res != 0) {
fprintf(stderr, "encoder_encode(): ioctl() failed\n"); fprintf(stderr, "encoder_encode(): ioctl(VIDIOC_QBUF) failed\n");
exit(1); exit(1);
} }
} }

5
internal/rpicamera/exe/encoder.h

@ -1,3 +1,6 @@
#ifndef __ENCODER_H__
#define __ENCODER_H__
typedef void encoder_t; typedef void encoder_t;
typedef void (*encoder_output_cb)(const uint8_t *buf, uint64_t size); typedef void (*encoder_output_cb)(const uint8_t *buf, uint64_t size);
@ -5,3 +8,5 @@ typedef void (*encoder_output_cb)(const uint8_t *buf, uint64_t size);
const char *encoder_get_error(); const char *encoder_get_error();
bool encoder_create(parameters_t *params, int stride, int colorspace, encoder_output_cb output_cb, encoder_t **enc); bool encoder_create(parameters_t *params, int stride, int colorspace, encoder_output_cb output_cb, encoder_t **enc);
void encoder_encode(encoder_t *enc, int buffer_fd, size_t size, int64_t timestamp_us); void encoder_encode(encoder_t *enc, int buffer_fd, size_t size, int64_t timestamp_us);
#endif

12
internal/rpicamera/exe/main.c

@ -72,9 +72,13 @@ int main() {
pthread_mutex_init(&pipe_mutex, NULL); pthread_mutex_init(&pipe_mutex, NULL);
pthread_mutex_lock(&pipe_mutex); pthread_mutex_lock(&pipe_mutex);
parameters_load(&params); bool ok = parameters_load(&params);
if (!ok) {
pipe_write_error(pipe_fd, "parameters_load(): %s", parameters_get_error());
return 5;
}
bool ok = camera_create( ok = camera_create(
&params, &params,
on_frame, on_frame,
&cam); &cam);
@ -85,8 +89,8 @@ int main() {
ok = encoder_create( ok = encoder_create(
&params, &params,
camera_get_stride(cam), camera_get_mode_stride(cam),
camera_get_colorspace(cam), camera_get_mode_colorspace(cam),
on_encoder_output, on_encoder_output,
&enc); &enc);
if (!ok) { if (!ok) {

41
internal/rpicamera/exe/parameters.c

@ -1,12 +1,26 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdarg.h>
#include <stdio.h>
#include <linux/videodev2.h> #include <linux/videodev2.h>
#include "parameters.h" #include "parameters.h"
void parameters_load(parameters_t *params) { char errbuf[256];
static void set_error(const char *format, ...) {
va_list args;
va_start(args, format);
vsnprintf(errbuf, 256, format, args);
}
const char *parameters_get_error() {
return errbuf;
}
bool parameters_load(parameters_t *params) {
params->camera_id = atoi(getenv("CAMERA_ID")); params->camera_id = atoi(getenv("CAMERA_ID"));
params->width = atoi(getenv("WIDTH")); params->width = atoi(getenv("WIDTH"));
params->height = atoi(getenv("HEIGHT")); params->height = atoi(getenv("HEIGHT"));
@ -23,8 +37,29 @@ void parameters_load(parameters_t *params) {
params->metering = getenv("METERING"); params->metering = getenv("METERING");
params->gain = atof(getenv("GAIN")); params->gain = atof(getenv("GAIN"));
params->ev = atof(getenv("EV")); params->ev = atof(getenv("EV"));
params->roi = getenv("ROI");
if (strlen(getenv("ROI")) != 0) {
bool ok = roi_load(getenv("ROI"), &params->roi);
if (!ok) {
set_error("invalid ROI");
return false;
}
} else {
params->roi = NULL;
}
params->tuning_file = getenv("TUNING_FILE"); params->tuning_file = getenv("TUNING_FILE");
if (strlen(getenv("MODE")) != 0) {
bool ok = sensor_mode_load(getenv("MODE"), &params->mode);
if (!ok) {
set_error("invalid sensor mode");
return false;
}
} else {
params->mode = NULL;
}
params->fps = atoi(getenv("FPS")); params->fps = atoi(getenv("FPS"));
params->idr_period = atoi(getenv("IDR_PERIOD")); params->idr_period = atoi(getenv("IDR_PERIOD"));
params->bitrate = atoi(getenv("BITRATE")); params->bitrate = atoi(getenv("BITRATE"));
@ -49,4 +84,6 @@ void parameters_load(parameters_t *params) {
params->buffer_count = 3; params->buffer_count = 3;
params->capture_buffer_count = params->buffer_count * 2; params->capture_buffer_count = params->buffer_count * 2;
return true;
} }

16
internal/rpicamera/exe/parameters.h

@ -1,3 +1,11 @@
#ifndef __PARAMETERS_H__
#define __PARAMETERS_H__
#include <stdbool.h>
#include "roi.h"
#include "sensor_mode.h"
typedef struct { typedef struct {
unsigned int camera_id; unsigned int camera_id;
unsigned int width; unsigned int width;
@ -15,8 +23,9 @@ typedef struct {
const char *metering; const char *metering;
float gain; float gain;
float ev; float ev;
const char *roi; roi_t *roi;
const char *tuning_file; const char *tuning_file;
sensor_mode_t *mode;
unsigned int fps; unsigned int fps;
unsigned int idr_period; unsigned int idr_period;
unsigned int bitrate; unsigned int bitrate;
@ -32,8 +41,11 @@ typedef struct {
extern "C" { extern "C" {
#endif #endif
void parameters_load(parameters_t *params); const char *parameters_get_error();
bool parameters_load(parameters_t *params);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif

30
internal/rpicamera/exe/roi.c

@ -0,0 +1,30 @@
#include <stdlib.h>
#include <string.h>
#include "roi.h"
bool roi_load(const char *encoded, roi_t **mode) {
float vals[4];
int i = 0;
char *token = strtok((char *)encoded, ",");
while (token != NULL) {
vals[i] = atof(token);
if (vals[i] < 0 || vals[i] > 1) {
return false;
}
i++;
token = strtok(NULL, ",");
}
if (i != 4) {
return false;
}
*mode = malloc(sizeof(roi_t));
(*mode)->x = vals[0];
(*mode)->y = vals[1];
(*mode)->width = vals[2];
(*mode)->height = vals[3];
return true;
}

15
internal/rpicamera/exe/roi.h

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

30
internal/rpicamera/exe/sensor_mode.c

@ -0,0 +1,30 @@
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include "sensor_mode.h"
bool sensor_mode_load(const char *encoded, sensor_mode_t **mode) {
*mode = malloc(sizeof(sensor_mode_t));
char p;
int n = sscanf(encoded, "%u:%u:%u:%c", &((*mode)->width), &((*mode)->height), &((*mode)->bit_depth), &p);
if (n < 2) {
free(*mode);
return false;
}
if (n < 4) {
(*mode)->packed = true;
} else if (toupper(p) == 'P') {
(*mode)->packed = true;
} else if (toupper(p) == 'U') {
(*mode)->packed = false;
}
if (n < 3) {
(*mode)->bit_depth = 12;
}
return true;
}

15
internal/rpicamera/exe/sensor_mode.h

@ -0,0 +1,15 @@
#ifndef __SENSOR_MODE_H__
#define __SENSOR_MODE_H__
#include <stdbool.h>
typedef struct {
int width;
int height;
int bit_depth;
bool packed;
} sensor_mode_t;
bool sensor_mode_load(const char *encoded, sensor_mode_t **mode);
#endif

1
internal/rpicamera/params.go

@ -20,6 +20,7 @@ type Params struct {
EV float64 EV float64
ROI string ROI string
TuningFile string TuningFile string
Mode string
FPS int FPS int
IDRPeriod int IDRPeriod int
Bitrate int Bitrate int

1
internal/rpicamera/rpicamera.go

@ -60,6 +60,7 @@ func New(
"EV=" + strconv.FormatFloat(params.EV, 'f', -1, 64), "EV=" + strconv.FormatFloat(params.EV, 'f', -1, 64),
"ROI=" + params.ROI, "ROI=" + params.ROI,
"TUNING_FILE=" + params.TuningFile, "TUNING_FILE=" + params.TuningFile,
"MODE=" + params.Mode,
"FPS=" + strconv.FormatInt(int64(params.FPS), 10), "FPS=" + strconv.FormatInt(int64(params.FPS), 10),
"IDR_PERIOD=" + strconv.FormatInt(int64(params.IDRPeriod), 10), "IDR_PERIOD=" + strconv.FormatInt(int64(params.IDRPeriod), 10),
"BITRATE=" + strconv.FormatInt(int64(params.Bitrate), 10), "BITRATE=" + strconv.FormatInt(int64(params.Bitrate), 10),

5
rtsp-simple-server.yml

@ -264,10 +264,13 @@ paths:
rpiCameraGain: 0 rpiCameraGain: 0
# EV compensation of the image [-10, 10] # EV compensation of the image [-10, 10]
rpiCameraEV: 0 rpiCameraEV: 0
# Region of interst in format x,y,width,height # Region of interest, in format x,y,width,height
rpiCameraROI: rpiCameraROI:
# tuning file # tuning file
rpiCameraTuningFile: rpiCameraTuningFile:
# sensor mode, in format [width]:[height]:[bit-depth]:[packing]
# bit-depth and packing are optional.
rpiCameraMode:
# frames per second # frames per second
rpiCameraFPS: 30 rpiCameraFPS: 30
# period between IDR frames # period between IDR frames

Loading…
Cancel
Save