Skip to content

Commit

Permalink
rpicamera: support libcamera 0.0.2
Browse files Browse the repository at this point in the history
  • Loading branch information
aler9 committed Dec 8, 2022
1 parent 7fef550 commit 3f5c550
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 43 deletions.
2 changes: 1 addition & 1 deletion .dockerignore
@@ -1,5 +1,5 @@
# do not add .git, since it is needed to extract the tag

/tmp
/binaries
/coverage*.txt
/apidocs/*.html
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -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:

Expand Down
38 changes: 1 addition & 37 deletions internal/rpicamera/embeddedexe.go
Expand Up @@ -4,10 +4,8 @@
package rpicamera

import (
"fmt"
"os"
"os/exec"
"runtime"
"strconv"
"time"
)
Expand All @@ -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
}
Expand Down
4 changes: 3 additions & 1 deletion internal/rpicamera/exe/Makefile
Expand Up @@ -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 changes: 70 additions & 0 deletions internal/rpicamera/rpicamera.go
Expand Up @@ -6,7 +6,11 @@ package rpicamera
import (
_ "embed"
"fmt"
"os"
"os/exec"
"runtime"
"strconv"
"strings"
"time"

"github.com/aler9/gortsplib/pkg/h264"
Expand All @@ -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)

Expand All @@ -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),
Expand Down
4 changes: 2 additions & 2 deletions scripts/binaries.mk
@@ -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)
Expand Down

0 comments on commit 3f5c550

Please sign in to comment.