forked from External/mediamtx
parent
22414bb38c
commit
0c131a2e92
11 changed files with 71 additions and 33 deletions
|
|
@ -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) ||
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,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.
|
||||||
|
|
|
||||||
|
|
@ -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…
Add table
Add a link
Reference in a new issue