Skip to content

Commit

Permalink
rpicamera: support two CSI cameras at once (#1573) (#1574)
Browse files Browse the repository at this point in the history
  • Loading branch information
aler9 committed Mar 19, 2023
1 parent c1bcd0c commit 32d6cb4
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 48 deletions.
2 changes: 1 addition & 1 deletion internal/conf/conf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ func TestConfErrors(t *testing.T) {
" source: rpiCamera\n" +
" cam2:\n" +
" source: rpiCamera\n",
"'rpiCamera' is used as source in two paths ('cam1' and 'cam2')",
"'rpiCamera' with same camera ID 0 is used as source in two paths, 'cam1' and 'cam2'",
},
} {
t.Run(ca.name, func(t *testing.T) {
Expand Down
6 changes: 4 additions & 2 deletions internal/conf/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,10 @@ func (pconf *PathConf) checkAndFillMissing(conf *Conf, name string) error {
}

for otherName, otherPath := range conf.Paths {
if otherPath != pconf && otherPath != nil && otherPath.Source == "rpiCamera" {
return fmt.Errorf("'rpiCamera' is used as source in two paths ('%s' and '%s')", name, otherName)
if otherPath != pconf && otherPath != nil &&
otherPath.Source == "rpiCamera" && otherPath.RPICameraCamID == pconf.RPICameraCamID {
return fmt.Errorf("'rpiCamera' with same camera ID %d is used as source in two paths, '%s' and '%s'",
pconf.RPICameraCamID, name, otherName)
}
}

Expand Down
5 changes: 5 additions & 0 deletions internal/core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/aler9/rtsp-simple-server/internal/externalcmd"
"github.com/aler9/rtsp-simple-server/internal/logger"
"github.com/aler9/rtsp-simple-server/internal/rlimit"
"github.com/aler9/rtsp-simple-server/internal/rpicamera"
)

var version = "v0.0.0"
Expand Down Expand Up @@ -84,6 +85,8 @@ func New(args []string) (*Core, bool) {
// do not check for errors
rlimit.Raise()

rpicamera.LibcameraSetup()

gin.SetMode(gin.ReleaseMode)

ctx, ctxCancel := context.WithCancel(context.Background())
Expand Down Expand Up @@ -186,6 +189,8 @@ outer:
p.ctxCancel()

p.closeResources(nil, false)

rpicamera.LibcameraCleanup()
}

func (p *Core) createResources(initial bool) error {
Expand Down
47 changes: 47 additions & 0 deletions internal/rpicamera/libcamera.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//go:build rpicamera
// +build rpicamera

package rpicamera

import (
"fmt"
"os"
"os/exec"
"strings"
)

func findLibrary(name string) (string, error) {
byts, err := exec.Command("ldconfig", "-p").Output()
if err == nil {
for _, line := range strings.Split(string(byts), "\n") {
f := strings.Split(line, " => ")
if len(f) == 2 && strings.Contains(f[1], name+".so") {
return f[1], nil
}
}
}

return "", fmt.Errorf("library '%s' not found", name)
}

func setupSymlink(name string) error {
lib, err := findLibrary(name)
if err != nil {
return err
}

os.Remove("/dev/shm/" + name + ".so.x.x.x")
return os.Symlink(lib, "/dev/shm/"+name+".so.x.x.x")
}

// LibcameraSetup creates libcamera simlinks that are version agnostic.
func LibcameraSetup() {
setupSymlink("libcamera")
setupSymlink("libcamera-base")
}

// LibcameraCleanup removes files created by LibcameraSetup.
func LibcameraCleanup() {
os.Remove("/dev/shm/libcamera-base.so.x.x.x")
os.Remove("/dev/shm/libcamera.so.x.x.x")
}
12 changes: 12 additions & 0 deletions internal/rpicamera/libcamera_disabled.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//go:build !rpicamera
// +build !rpicamera

package rpicamera

// LibcameraSetup creates libcamera simlinks that are version agnostic.
func LibcameraSetup() {
}

// LibcameraCleanup removes files created by LibcameraSetup.
func LibcameraCleanup() {
}
45 changes: 0 additions & 45 deletions internal/rpicamera/rpicamera.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,45 +53,6 @@ func checkArch() error {
return nil
}

func findLibrary(name string) (string, error) {
byts, err := exec.Command("ldconfig", "-p").Output()
if err == nil {
for _, line := range strings.Split(string(byts), "\n") {
f := strings.Split(line, " => ")
if len(f) == 2 && strings.Contains(f[1], name+".so") {
return f[1], nil
}
}
}

return "", fmt.Errorf("library '%s' not found", name)
}

func setupSymlink(name string) error {
lib, err := findLibrary(name)
if err != nil {
return err
}

os.Remove("/dev/shm/" + name + ".so.x.x.x")
return os.Symlink(lib, "/dev/shm/"+name+".so.x.x.x")
}

// create libcamera simlinks that are version agnostic.
func setupSymlinks() error {
err := setupSymlink("libcamera")
if err != nil {
return err
}

return setupSymlink("libcamera-base")
}

func removeSymlinks() {
os.Remove("/dev/shm/libcamera-base.so.x.x.x")
os.Remove("/dev/shm/libcamera.so.x.x.x")
}

func startEmbeddedExe(content []byte, env []string) (*exec.Cmd, error) {
tempPath := tempPathPrefix + strconv.FormatInt(time.Now().UnixNano(), 10)

Expand Down Expand Up @@ -172,12 +133,6 @@ func New(
return nil, err
}

err = setupSymlinks()
if err != nil {
return nil, err
}
defer removeSymlinks()

c := &RPICamera{
onData: onData,
}
Expand Down

0 comments on commit 32d6cb4

Please sign in to comment.