Skip to content

Commit

Permalink
Merge pull request #913 from robvanoostenrijk/master
Browse files Browse the repository at this point in the history
Added FreeBSD binaries
  • Loading branch information
AlexxIT committed Apr 29, 2024
2 parents cf4f646 + f73ee41 commit 070ea38
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 0 deletions.
14 changes: 14 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,20 @@ jobs:
uses: actions/upload-artifact@v4
with: { name: go2rtc_mac_arm64, path: go2rtc }

- name: Build go2rtc_freebsd_amd64
env: { GOOS: freebsd, GOARCH: amd64 }
run: go build -ldflags "-s -w" -trimpath
- name: Upload go2rtc_freebsd_amd64
uses: actions/upload-artifact@v3
with: { name: go2rtc_freebsd_amd64, path: go2rtc }

- name: Build go2rtc_freebsd_arm64
env: { GOOS: freebsd, GOARCH: arm64 }
run: go build -ldflags "-s -w" -trimpath
- name: Upload go2rtc_freebsd_arm64
uses: actions/upload-artifact@v3
with: { name: go2rtc_freebsd_arm64, path: go2rtc }

docker-master:
name: Build docker master
runs-on: ubuntu-latest
Expand Down
97 changes: 97 additions & 0 deletions internal/ffmpeg/device/device_freebsd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package device

import (
"net/url"
"os"
"os/exec"
"regexp"
"strings"

"github.com/AlexxIT/go2rtc/internal/api"
"github.com/AlexxIT/go2rtc/pkg/core"
)

func queryToInput(query url.Values) string {
if video := query.Get("video"); video != "" {
// https://ffmpeg.org/ffmpeg-devices.html#video4linux2_002c-v4l2
input := "-f v4l2"

for key, value := range query {
switch key {
case "resolution":
input += " -video_size " + value[0]
case "video_size", "pixel_format", "input_format", "framerate", "use_libv4l2":
input += " -" + key + " " + value[0]
}
}

return input + " -i " + indexToItem(videos, video)
}

if audio := query.Get("audio"); audio != "" {
input := "-f oss"

for key, value := range query {
switch key {
case "channels", "sample_rate":
input += " -" + key + " " + value[0]
}
}

return input + " -i " + indexToItem(audios, audio)
}

return ""
}

func initDevices() {
files, err := os.ReadDir("/dev")
if err != nil {
return
}

for _, file := range files {
if !strings.HasPrefix(file.Name(), core.KindVideo) {
continue
}

name := "/dev/" + file.Name()

cmd := exec.Command(
Bin, "-hide_banner", "-f", "v4l2", "-list_formats", "all", "-i", name,
)
b, _ := cmd.CombinedOutput()

// [video4linux2,v4l2 @ 0x860b92280] Raw : yuyv422 : YUYV 4:2:2 : 640x480 160x120 176x144 320x176 320x240 352x288 432x240 544x288 640x360 752x416 800x448 800x600 864x480 960x544 960x720 1024x576 1184x656 1280x720 1280x960
// [video4linux2,v4l2 @ 0x860b92280] Compressed: mjpeg : Motion-JPEG : 640x480 160x120 176x144 320x176 320x240 352x288 432x240 544x288 640x360 752x416 800x448 800x600 864x480 960x544 960x720 1024x576 1184x656 1280x720 1280x960
re := regexp.MustCompile("(Raw *|Compressed): +(.+?) : +(.+?) : (.+)")
m := re.FindAllStringSubmatch(string(b), -1)
for _, i := range m {
size, _, _ := strings.Cut(i[4], " ")
stream := &api.Source{
Name: i[3],
Info: i[4],
URL: "ffmpeg:device?video=" + name + "&input_format=" + i[2] + "&video_size=" + size,
}

if i[1] != "Compressed" {
stream.URL += "#video=h264#hardware"
}

videos = append(videos, name)
streams = append(streams, stream)
}
}

err = exec.Command(Bin, "-f", "oss", "-i", "/dev/dsp", "-t", "1", "-f", "null", "-").Run()
if err == nil {
stream := &api.Source{
Name: "OSS default",
Info: " ",
URL: "ffmpeg:device?audio=default&channels=1&sample_rate=16000&#audio=opus",
}

audios = append(audios, "default")
streams = append(streams, stream)
}
}
60 changes: 60 additions & 0 deletions internal/ffmpeg/hardware/hardware_freebsd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package hardware

import (
"runtime"

"github.com/AlexxIT/go2rtc/internal/api"
)

const (
ProbeV4L2M2MH264 = "-f lavfi -i testsrc2 -t 1 -c h264_v4l2m2m -f null -"
ProbeV4L2M2MH265 = "-f lavfi -i testsrc2 -t 1 -c hevc_v4l2m2m -f null -"
ProbeRKMPPH264 = "-f lavfi -i testsrc2 -t 1 -c h264_rkmpp_encoder -f null -"
ProbeRKMPPH265 = "-f lavfi -i testsrc2 -t 1 -c hevc_rkmpp_encoder -f null -"
)

func ProbeAll(bin string) []*api.Source {
return []*api.Source{
{
Name: runToString(bin, ProbeV4L2M2MH264),
URL: "ffmpeg:...#video=h264#hardware=" + EngineV4L2M2M,
},
{
Name: runToString(bin, ProbeV4L2M2MH265),
URL: "ffmpeg:...#video=h265#hardware=" + EngineV4L2M2M,
},
{
Name: runToString(bin, ProbeRKMPPH264),
URL: "ffmpeg:...#video=h264#hardware=" + EngineRKMPP,
},
{
Name: runToString(bin, ProbeRKMPPH265),
URL: "ffmpeg:...#video=h265#hardware=" + EngineRKMPP,
},
}
}

func ProbeHardware(bin, name string) string {
if runtime.GOARCH == "arm64" || runtime.GOARCH == "arm" {
switch name {
case "h264":
if run(bin, ProbeV4L2M2MH264) {
return EngineV4L2M2M
}
if run(bin, ProbeRKMPPH264) {
return EngineRKMPP
}
case "h265":
if run(bin, ProbeV4L2M2MH265) {
return EngineV4L2M2M
}
if run(bin, ProbeRKMPPH265) {
return EngineRKMPP
}
}

return EngineSoftware
}

return EngineSoftware
}
24 changes: 24 additions & 0 deletions pkg/mdns/syscall_freebsd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package mdns

import (
"syscall"
)

func SetsockoptInt(fd uintptr, level, opt int, value int) (err error) {
// change SO_REUSEADDR and REUSEPORT flags simultaneously for BSD-like OS
// https://github.com/AlexxIT/go2rtc/issues/626
// https://stackoverflow.com/questions/14388706/how-do-so-reuseaddr-and-so-reuseport-differ/14388707
if opt == syscall.SO_REUSEADDR {
if err = syscall.SetsockoptInt(int(fd), level, opt, value); err != nil {
return
}

opt = syscall.SO_REUSEPORT
}

return syscall.SetsockoptInt(int(fd), level, opt, value)
}

func SetsockoptIPMreq(fd uintptr, level, opt int, mreq *syscall.IPMreq) (err error) {
return syscall.SetsockoptIPMreq(int(fd), level, opt, mreq)
}

0 comments on commit 070ea38

Please sign in to comment.