Browse Source

rpi: pass log level to libcamera (#2617) (#2811)

pull/2814/head
Alessandro Ros 1 year ago committed by GitHub
parent
commit
0c131a2e92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      internal/core/core.go
  2. 4
      internal/core/path.go
  3. 4
      internal/core/path_manager.go
  4. 4
      internal/core/static_source_handler.go
  5. 14
      internal/protocols/rpicamera/exe/camera.cpp
  6. 4
      internal/protocols/rpicamera/exe/parameters.c
  7. 1
      internal/protocols/rpicamera/exe/parameters.h
  8. 1
      internal/protocols/rpicamera/params.go
  9. 32
      internal/protocols/rpicamera/rpicamera.go
  10. 14
      internal/protocols/rpicamera/rpicamera_disabled.go
  11. 24
      internal/staticsources/rpicamera/source.go

2
internal/core/core.go

@ -310,6 +310,7 @@ func (p *Core) createResources(initial bool) error {
if p.pathManager == nil { if p.pathManager == nil {
p.pathManager = newPathManager( p.pathManager = newPathManager(
p.conf.LogLevel,
p.conf.ExternalAuthenticationURL, p.conf.ExternalAuthenticationURL,
p.conf.RTSPAddress, p.conf.RTSPAddress,
p.conf.AuthMethods, p.conf.AuthMethods,
@ -614,6 +615,7 @@ func (p *Core) closeResources(newConf *conf.Conf, calledByAPI bool) {
closeLogger closeLogger
closePathManager := newConf == nil || closePathManager := newConf == nil ||
newConf.LogLevel != p.conf.LogLevel ||
newConf.ExternalAuthenticationURL != p.conf.ExternalAuthenticationURL || newConf.ExternalAuthenticationURL != p.conf.ExternalAuthenticationURL ||
newConf.RTSPAddress != p.conf.RTSPAddress || newConf.RTSPAddress != p.conf.RTSPAddress ||
!reflect.DeepEqual(newConf.AuthMethods, p.conf.AuthMethods) || !reflect.DeepEqual(newConf.AuthMethods, p.conf.AuthMethods) ||

4
internal/core/path.go

@ -64,6 +64,7 @@ type pathAPIPathsGetReq struct {
} }
type path struct { type path struct {
logLevel conf.LogLevel
rtspAddress string rtspAddress string
readTimeout conf.StringDuration readTimeout conf.StringDuration
writeTimeout conf.StringDuration writeTimeout conf.StringDuration
@ -116,6 +117,7 @@ type path struct {
func newPath( func newPath(
parentCtx context.Context, parentCtx context.Context,
logLevel conf.LogLevel,
rtspAddress string, rtspAddress string,
readTimeout conf.StringDuration, readTimeout conf.StringDuration,
writeTimeout conf.StringDuration, writeTimeout conf.StringDuration,
@ -132,6 +134,7 @@ func newPath(
ctx, ctxCancel := context.WithCancel(parentCtx) ctx, ctxCancel := context.WithCancel(parentCtx)
pa := &path{ pa := &path{
logLevel: logLevel,
rtspAddress: rtspAddress, rtspAddress: rtspAddress,
readTimeout: readTimeout, readTimeout: readTimeout,
writeTimeout: writeTimeout, writeTimeout: writeTimeout,
@ -206,6 +209,7 @@ func (pa *path) run() {
pa.source = &staticSourceHandler{ pa.source = &staticSourceHandler{
conf: pa.conf, conf: pa.conf,
logLevel: pa.logLevel,
readTimeout: pa.readTimeout, readTimeout: pa.readTimeout,
writeTimeout: pa.writeTimeout, writeTimeout: pa.writeTimeout,
writeQueueSize: pa.writeQueueSize, writeQueueSize: pa.writeQueueSize,

4
internal/core/path_manager.go

@ -79,6 +79,7 @@ type pathManagerParent interface {
} }
type pathManager struct { type pathManager struct {
logLevel conf.LogLevel
externalAuthenticationURL string externalAuthenticationURL string
rtspAddress string rtspAddress string
authMethods conf.AuthMethods authMethods conf.AuthMethods
@ -112,6 +113,7 @@ type pathManager struct {
} }
func newPathManager( func newPathManager(
logLevel conf.LogLevel,
externalAuthenticationURL string, externalAuthenticationURL string,
rtspAddress string, rtspAddress string,
authMethods conf.AuthMethods, authMethods conf.AuthMethods,
@ -126,6 +128,7 @@ func newPathManager(
ctx, ctxCancel := context.WithCancel(context.Background()) ctx, ctxCancel := context.WithCancel(context.Background())
pm := &pathManager{ pm := &pathManager{
logLevel: logLevel,
externalAuthenticationURL: externalAuthenticationURL, externalAuthenticationURL: externalAuthenticationURL,
rtspAddress: rtspAddress, rtspAddress: rtspAddress,
authMethods: authMethods, authMethods: authMethods,
@ -400,6 +403,7 @@ func (pm *pathManager) createPath(
) { ) {
pa := newPath( pa := newPath(
pm.ctx, pm.ctx,
pm.logLevel,
pm.rtspAddress, pm.rtspAddress,
pm.readTimeout, pm.readTimeout,
pm.writeTimeout, pm.writeTimeout,

4
internal/core/static_source_handler.go

@ -31,6 +31,7 @@ type staticSourceHandlerParent interface {
// staticSourceHandler is a static source handler. // staticSourceHandler is a static source handler.
type staticSourceHandler struct { type staticSourceHandler struct {
conf *conf.Path conf *conf.Path
logLevel conf.LogLevel
readTimeout conf.StringDuration readTimeout conf.StringDuration
writeTimeout conf.StringDuration writeTimeout conf.StringDuration
writeQueueSize int writeQueueSize int
@ -108,7 +109,8 @@ func (s *staticSourceHandler) initialize() {
case s.resolvedSource == "rpiCamera": case s.resolvedSource == "rpiCamera":
s.instance = &rpicamerasource.Source{ s.instance = &rpicamerasource.Source{
Parent: s, LogLevel: s.logLevel,
Parent: s,
} }
} }
} }

14
internal/protocols/rpicamera/exe/camera.cpp

@ -126,13 +126,23 @@ static void set_hdr(bool hdr) {
} }
bool camera_create(const parameters_t *params, camera_frame_cb frame_cb, camera_t **cam) { bool camera_create(const parameters_t *params, camera_frame_cb frame_cb, camera_t **cam) {
std::unique_ptr<CameraPriv> camp = std::make_unique<CameraPriv>();
set_hdr(params->hdr); set_hdr(params->hdr);
if (strcmp(params->log_level, "debug") == 0) {
setenv("LIBCAMERA_LOG_LEVELS", "*:DEBUG", 1);
} else if (strcmp(params->log_level, "info") == 0) {
setenv("LIBCAMERA_LOG_LEVELS", "*:INFO", 1);
} else if (strcmp(params->log_level, "warn") == 0) {
setenv("LIBCAMERA_LOG_LEVELS", "*:WARN", 1);
} else { // error
setenv("LIBCAMERA_LOG_LEVELS", "*:ERROR", 1);
}
// We make sure to set the environment variable before libcamera init // We make sure to set the environment variable before libcamera init
setenv("LIBCAMERA_RPI_TUNING_FILE", params->tuning_file, 1); setenv("LIBCAMERA_RPI_TUNING_FILE", params->tuning_file, 1);
std::unique_ptr<CameraPriv> camp = std::make_unique<CameraPriv>();
camp->camera_manager = std::make_unique<CameraManager>(); camp->camera_manager = std::make_unique<CameraManager>();
int ret = camp->camera_manager->start(); int ret = camp->camera_manager->start();
if (ret != 0) { if (ret != 0) {

4
internal/protocols/rpicamera/exe/parameters.c

@ -37,7 +37,9 @@ bool parameters_unserialize(parameters_t *params, const uint8_t *buf, size_t buf
char *key = strsep(&entry, ":"); char *key = strsep(&entry, ":");
char *val = strsep(&entry, ":"); char *val = strsep(&entry, ":");
if (strcmp(key, "CameraID") == 0) { if (strcmp(key, "LogLevel") == 0) {
params->log_level = base64_decode(val);
} else if (strcmp(key, "CameraID") == 0) {
params->camera_id = atoi(val); params->camera_id = atoi(val);
} else if (strcmp(key, "Width") == 0) { } else if (strcmp(key, "Width") == 0) {
params->width = atoi(val); params->width = atoi(val);

1
internal/protocols/rpicamera/exe/parameters.h

@ -8,6 +8,7 @@
#include "sensor_mode.h" #include "sensor_mode.h"
typedef struct { typedef struct {
char *log_level;
unsigned int camera_id; unsigned int camera_id;
unsigned int width; unsigned int width;
unsigned int height; unsigned int height;

1
internal/protocols/rpicamera/params.go

@ -9,6 +9,7 @@ import (
// Params is a set of camera parameters. // Params is a set of camera parameters.
type Params struct { type Params struct {
LogLevel string
CameraID int CameraID int
Width int Width int
Height int Height int

32
internal/protocols/rpicamera/rpicamera.go

@ -111,8 +111,10 @@ func checkLibraries64Bit() error {
return nil return nil
} }
// RPICamera is a RPI Camera reader.
type RPICamera struct { type RPICamera struct {
onData func(time.Duration, [][]byte) Params Params
OnData func(time.Duration, [][]byte)
cmd *exec.Cmd cmd *exec.Cmd
pipeConf *pipe pipeConf *pipe
@ -122,31 +124,25 @@ type RPICamera struct {
readerDone chan error readerDone chan error
} }
func New( // Initialize initializes a RPICamera.
params Params, func (c *RPICamera) Initialize() error {
onData func(time.Duration, [][]byte),
) (*RPICamera, error) {
if runtime.GOARCH == "arm" { if runtime.GOARCH == "arm" {
err := checkLibraries64Bit() err := checkLibraries64Bit()
if err != nil { if err != nil {
return nil, err return err
} }
} }
c := &RPICamera{
onData: onData,
}
var err error var err error
c.pipeConf, err = newPipe() c.pipeConf, err = newPipe()
if err != nil { if err != nil {
return nil, err return err
} }
c.pipeVideo, err = newPipe() c.pipeVideo, err = newPipe()
if err != nil { if err != nil {
c.pipeConf.close() c.pipeConf.close()
return nil, err return err
} }
env := []string{ env := []string{
@ -158,10 +154,10 @@ func New(
if err != nil { if err != nil {
c.pipeConf.close() c.pipeConf.close()
c.pipeVideo.close() c.pipeVideo.close()
return nil, err return err
} }
c.pipeConf.write(append([]byte{'c'}, params.serialize()...)) c.pipeConf.write(append([]byte{'c'}, c.Params.serialize()...))
c.waitDone = make(chan error) c.waitDone = make(chan error)
go func() { go func() {
@ -178,7 +174,7 @@ func New(
c.pipeConf.close() c.pipeConf.close()
c.pipeVideo.close() c.pipeVideo.close()
<-c.readerDone <-c.readerDone
return nil, fmt.Errorf("process exited unexpectedly") return fmt.Errorf("process exited unexpectedly")
case err := <-c.readerDone: case err := <-c.readerDone:
if err != nil { if err != nil {
@ -186,7 +182,7 @@ func New(
<-c.waitDone <-c.waitDone
c.pipeConf.close() c.pipeConf.close()
c.pipeVideo.close() c.pipeVideo.close()
return nil, err return err
} }
} }
@ -195,7 +191,7 @@ func New(
c.readerDone <- c.readData() c.readerDone <- c.readData()
}() }()
return c, nil return nil
} }
func (c *RPICamera) Close() { func (c *RPICamera) Close() {
@ -248,6 +244,6 @@ func (c *RPICamera) readData() error {
return err return err
} }
c.onData(dts, nalus) c.OnData(dts, nalus)
} }
} }

14
internal/protocols/rpicamera/rpicamera_disabled.go

@ -14,14 +14,14 @@ func Cleanup() {
} }
// RPICamera is a RPI Camera reader. // RPICamera is a RPI Camera reader.
type RPICamera struct{} type RPICamera struct {
Params Params
OnData func(time.Duration, [][]byte)
}
// New allocates a RPICamera. // Initialize initializes a RPICamera.
func New( func (c *RPICamera) Initialize() error {
_ Params, return fmt.Errorf("server was compiled without support for the Raspberry Pi Camera")
_ func(time.Duration, [][]byte),
) (*RPICamera, error) {
return nil, fmt.Errorf("server was compiled without support for the Raspberry Pi Camera")
} }
// Close closes a RPICamera. // Close closes a RPICamera.

24
internal/staticsources/rpicamera/source.go

@ -15,8 +15,19 @@ import (
"github.com/bluenviron/mediamtx/internal/unit" "github.com/bluenviron/mediamtx/internal/unit"
) )
func paramsFromConf(cnf *conf.Path) rpicamera.Params { func paramsFromConf(logLevel conf.LogLevel, cnf *conf.Path) rpicamera.Params {
return rpicamera.Params{ return rpicamera.Params{
LogLevel: func() string {
switch logLevel {
case conf.LogLevel(logger.Debug):
return "debug"
case conf.LogLevel(logger.Info):
return "info"
case conf.LogLevel(logger.Warn):
return "warn"
}
return "error"
}(),
CameraID: cnf.RPICameraCamID, CameraID: cnf.RPICameraCamID,
Width: cnf.RPICameraWidth, Width: cnf.RPICameraWidth,
Height: cnf.RPICameraHeight, Height: cnf.RPICameraHeight,
@ -54,7 +65,8 @@ func paramsFromConf(cnf *conf.Path) rpicamera.Params {
// Source is a Raspberry Pi Camera static source. // Source is a Raspberry Pi Camera static source.
type Source struct { type Source struct {
Parent defs.StaticSourceParent LogLevel conf.LogLevel
Parent defs.StaticSourceParent
} }
// Log implements logger.Writer. // Log implements logger.Writer.
@ -96,7 +108,11 @@ func (s *Source) Run(params defs.StaticSourceRunParams) error {
}) })
} }
cam, err := rpicamera.New(paramsFromConf(params.Conf), onData) cam := &rpicamera.RPICamera{
Params: paramsFromConf(s.LogLevel, params.Conf),
OnData: onData,
}
err := cam.Initialize()
if err != nil { if err != nil {
return err return err
} }
@ -111,7 +127,7 @@ func (s *Source) Run(params defs.StaticSourceRunParams) error {
for { for {
select { select {
case cnf := <-params.ReloadConf: case cnf := <-params.ReloadConf:
cam.ReloadParams(paramsFromConf(cnf)) cam.ReloadParams(paramsFromConf(s.LogLevel, cnf))
case <-params.Context.Done(): case <-params.Context.Done():
return nil return nil

Loading…
Cancel
Save