Browse Source

rpicamera: support libcamera 0.0.2

pull/1301/head
aler9 2 years ago
parent
commit
3f5c550baf
  1. 2
      .dockerignore
  2. 4
      README.md
  3. 38
      internal/rpicamera/embeddedexe.go
  4. 4
      internal/rpicamera/exe/Makefile
  5. 70
      internal/rpicamera/rpicamera.go
  6. 4
      scripts/binaries.mk

2
.dockerignore

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
# do not add .git, since it is needed to extract the tag
/tmp
/binaries
/coverage*.txt
/apidocs/*.html

4
README.md

@ -534,11 +534,11 @@ After starting the server, the webcam can be reached on `rtsp://localhost:8554/c @@ -534,11 +534,11 @@ After starting the server, the webcam can be reached on `rtsp://localhost:8554/c
_rtsp-simple-server_ natively support the Raspberry Pi Camera, enabling high-quality and low-latency video streaming from the camera to any user. There are a couple of requisites:
1. The server must run on a Raspberry Pi, with Raspberry Pi OS bullseye or newer as operative system.
1. The server must run on a Raspberry Pi, with Raspberry Pi OS bullseye or newer as operative system. Both 32 bit and 64 bit operative systems are supported.
2. Make sure that the legacy camera stack is disabled. Type `sudo raspi-config`, then go to `Interfacing options`, `enable/disable legacy camera support`, choose `no`. Reboot the system.
3. Make sure that the `libcamera` version is at least `0.0.1`, otherwise upgrade it with `sudo apt upgrade`.
3. Make sure that the `libcamera0` package version is at least `0.0.2`, otherwise upgrade it with `sudo apt update && sudo apt upgrade`.
If you want to run the standard (non-dockerized) version of the server, just download the server executable and make sure to pick the `arm64` variant if you're using the 64-bit version of the operative system. Then edit `rtsp-simple-server.yml` and replace everything inside section `paths` with the following content:

38
internal/rpicamera/embeddedexe.go

@ -4,10 +4,8 @@ @@ -4,10 +4,8 @@
package rpicamera
import (
"fmt"
"os"
"os/exec"
"runtime"
"strconv"
"time"
)
@ -16,48 +14,14 @@ const ( @@ -16,48 +14,14 @@ const (
tempPathPrefix = "/dev/shm/rtspss-embeddedexe-"
)
func getKernelArch() (string, error) {
cmd := exec.Command("uname", "-m")
byts, err := cmd.Output()
if err != nil {
return "", err
}
return string(byts[:len(byts)-1]), nil
}
// 32-bit embedded executables can't run on 64-bit.
func checkArch() error {
if runtime.GOARCH != "arm" {
return nil
}
arch, err := getKernelArch()
if err != nil {
return err
}
if arch == "aarch64" {
return fmt.Errorf("OS is 64-bit, you need the arm64 server version")
}
return nil
}
type embeddedExe struct {
cmd *exec.Cmd
}
func newEmbeddedExe(content []byte, env []string) (*embeddedExe, error) {
err := checkArch()
if err != nil {
return nil, err
}
tempPath := tempPathPrefix + strconv.FormatInt(time.Now().UnixNano(), 10)
err = os.WriteFile(tempPath, content, 0o755)
err := os.WriteFile(tempPath, content, 0o755)
if err != nil {
return nil, err
}

4
internal/rpicamera/exe/Makefile

@ -36,4 +36,6 @@ all: exe @@ -36,4 +36,6 @@ all: exe
$(CXX) $(CXXFLAGS) -c $< -o $@
exe: $(OBJS)
$(CXX) -o $@ $^ $(LDFLAGS)
$(CXX) $^ $(LDFLAGS) -o $@
patchelf --replace-needed libcamera.so.0.0.2 libcamera.so.x.x.x $@
patchelf --replace-needed libcamera-base.so.0.0.2 libcamera-base.so.x.x.x $@

70
internal/rpicamera/rpicamera.go

@ -6,7 +6,11 @@ package rpicamera @@ -6,7 +6,11 @@ package rpicamera
import (
_ "embed"
"fmt"
"os"
"os/exec"
"runtime"
"strconv"
"strings"
"time"
"github.com/aler9/gortsplib/pkg/h264"
@ -22,6 +26,61 @@ func bool2env(v bool) string { @@ -22,6 +26,61 @@ func bool2env(v bool) string {
return "0"
}
func getKernelArch() (string, error) {
cmd := exec.Command("uname", "-m")
byts, err := cmd.Output()
if err != nil {
return "", err
}
return string(byts[:len(byts)-1]), nil
}
// 32-bit embedded executables can't run on 64-bit.
func checkArch() error {
if runtime.GOARCH != "arm" {
return nil
}
arch, err := getKernelArch()
if err != nil {
return err
}
if arch == "aarch64" {
return fmt.Errorf("OS is 64-bit, you need the arm64 server version")
}
return nil
}
func setupSymlink(name string) error {
cmd := exec.Command("sh", "-c", "ldconfig -p | grep "+name+".so | awk '{ print $4 }'")
byts, err := cmd.Output()
if err != nil {
return err
}
lib := strings.TrimSpace(string(byts))
if lib == "" {
return fmt.Errorf(name + " not found")
}
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")
}
type RPICamera struct {
onData func(time.Duration, [][]byte)
@ -36,12 +95,23 @@ func New( @@ -36,12 +95,23 @@ func New(
params Params,
onData func(time.Duration, [][]byte),
) (*RPICamera, error) {
err := checkArch()
if err != nil {
return nil, err
}
err = setupSymlinks()
if err != nil {
return nil, err
}
pipe, err := newPipe()
if err != nil {
return nil, err
}
env := []string{
"LD_LIBRARY_PATH=/dev/shm",
"PIPE_FD=" + strconv.FormatInt(int64(pipe.writeFD), 10),
"CAMERA_ID=" + strconv.FormatInt(int64(params.CameraID), 10),
"WIDTH=" + strconv.FormatInt(int64(params.Width), 10),

4
scripts/binaries.mk

@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
define DOCKERFILE_BINARIES
FROM $(RPI32_IMAGE) AS rpicamera32
RUN ["cross-build-start"]
RUN apt update && apt install -y --no-install-recommends g++ pkg-config make libcamera-dev
RUN apt update && apt install -y --no-install-recommends g++ pkg-config make libcamera-dev patchelf
WORKDIR /s/internal/rpicamera
COPY internal/rpicamera .
RUN cd exe && make -j$$(nproc)
FROM $(RPI64_IMAGE) AS rpicamera64
RUN ["cross-build-start"]
RUN apt update && apt install -y --no-install-recommends g++ pkg-config make libcamera-dev
RUN apt update && apt install -y --no-install-recommends g++ pkg-config make libcamera-dev patchelf
WORKDIR /s/internal/rpicamera
COPY internal/rpicamera .
RUN cd exe && make -j$$(nproc)

Loading…
Cancel
Save