Skip to content

Add native Reolink/Baichuan support - #2413

Open
ucbmckee wants to merge 1 commit into
AlexxIT:masterfrom
ucbmckee:topic/reolink-baichuan
Open

Add native Reolink/Baichuan support#2413
ucbmckee wants to merge 1 commit into
AlexxIT:masterfrom
ucbmckee:topic/reolink-baichuan

Conversation

@ucbmckee

Copy link
Copy Markdown

** This was generated by a mix of AI suggestions and human editing **

This PR adds a native reolink:// source using Reolink's Baichuan protocol over direct LAN TCP or local UID-discovered LAN-P2P. It carries video, audio, and two-way audio directly from the camera, without using RTSP, RTMP, HTTP-FLV, or FFmpeg as the camera input.

One configured source can feed recording, live view, and other go2rtc consumers through the normal fanout. Users configure the camera once, then choose its streams, lenses, audio, and talkback as native features.

Why it exists

Without a native source, this camera setup needed a continuously running FFmpeg process for each configured input to bridge Reolink's HTTP-FLV feed into go2rtc. Direct Baichuan input removes those processes, reduces CPU use, and makes Reolink streams and talkback part of go2rtc's normal source model.

It also addresses the failures that motivated this work: malformed or incomplete keyframes, timing discontinuities, and downstream decoder/FFmpeg crashes when using full-resolution streams. The adapter validates access units and codec parameter sets, suppresses invalid video, resumes only on a valid keyframe with established parameter sets, and keeps RTP timestamps moving forward across reconnects. In final testing, 4K HEVC segments had the expected frame and keyframe cadence, complete PTS/DTS, no DTS regressions or non-positive video durations, and clean FFmpeg 8.1 strict decoding. FFmpeg 8.1 was used only to validate the output; the source does not invoke FFmpeg or require a particular FFmpeg version. The observed keyframe, timing, and transport-related crash symptoms did not recur in the tested production workload.

Performance

The prior non-Baichuan setup used go2rtc's generic HTTP-FLV support through one source-side FFmpeg process per configured source, then loopback RTSP. Native Baichuan removes that process. Matched tests on the same cameras and Intel Core i7-12700H host preserved codec, resolution, frame rate, keyframe cadence, and strict-decode results:

Camera workload Prior HTTP-FLV/FFmpeg path Native Baichuan Attributable change
H.264 sub, 640x360/10 2.4 CPU points 1.8 25% lower
H.264 extern, 896x512/20 3.8 CPU points 2.9 25% lower
HEVC main, 3840x2160/20 2.4 CPU points 1.0 56% lower

CPU points are Frigate-reported process CPU attributable to one source path, not whole-host percentages. Results may differ elsewhere, but every matched profile used less CPU.

Validation

Hardware testing covers E1 Zoom/E340 cameras and both lenses of dual-lens TrackFlex cameras: main and sub streams, TCP and same-LAN UID/LAN-P2P connections, H.264, H.265, AAC, camera ADPCM, and repeated talkback setup and teardown. A production system has exercised 16 profiles from six cameras.

Verification includes focused normal and race tests, malformed-input tests, nine fuzz targets with about 12 million final executions, vet, strict FFmpeg decode and timestamp checks, and Linux, Windows, macOS, and FreeBSD builds.

This implementation versus fzurita

The fzurita branch showed that native Baichuan support in go2rtc is practical. This PR covers the same core streaming and talkback use case while keeping Reolink work isolated from the rest of go2rtc. It also adds stricter safeguards and recovery behavior. The implementations differ at the protocol, lifecycle, and shared-code boundaries, so this is submitted as an independent alternative rather than a patch stack.

The implementation lives in three new packages:

  • protocol-only pkg/baichuan
  • the go2rtc adapter in pkg/reolink
  • registration in internal/reolink

Outside those packages, existing files change only to register and document the source. Shared H.264, H.265, RTP, WebRTC, and stream-lifecycle code is untouched; the pinned fzurita branch changes several of those shared paths. That limits the blast radius: Reolink protocol and recovery changes stay on Reolink camera paths. Configuration, camera sharing, media conversion, talkback, lifecycle, and health checks are separated for review and maintenance. This follows go2rtc's usual thin internal registration plus protocol/adapter package split.

This PR also adds safeguards that are absent from the current fzurita branch. The protocol safeguards do not restrict supported resolutions, bitrates, codecs, or normal go2rtc fanout.

Area This PR fzurita at fcbd6109 Why it matters
Camera data Validates camera-supplied sizes before allocating memory Allocates camera-declared message sizes; parser memory may grow indefinitely Bounds memory exposure from malformed or corrupt size fields
Network I/O Tracks requests safely; completes writes with deadlines; reports corruption Requests may collide; one write without a deadline; drops or resets bad data Bounds hangs, completes commands, and makes stream damage visible
Stream routing Routes by channel and stream before parsing Sends each message to every preview before filtering by stream Reduces extra work and cross-stream interference
Credentials Keeps credentials private and redacted; discards the raw source URL Public credential fields; retains the parsed source URL Reduces accidental credential exposure
Source lifecycle Keeps configured sources independent, leaves capacity decisions to the camera, isolates talkback, and waits for cleanup No cross-source coordination; talkback shares the preview connection Avoids guessed model limits and cross-source teardown interference

Performance versus fzurita

For a direct Baichuan comparison, both implementations were built with Go 1.24 and identical Linux build flags, then tested against the same 3840x2160/20 HEVC camera. Each ran alone in a Debian 13 Proxmox LXC with 8 assigned cores and 16 GiB RAM on the same host.

180-second workload This PR fzurita
One RTSP-copy viewer 1.1% CPU; 23.8 MiB RSS 1.0% CPU; 26.3 MiB RSS
Two RTSP-copy viewers 1.1% CPU; 26.8 MiB RSS 1.2% CPU; 28.3 MiB RSS

CPU use was close enough to treat as equivalent at this load. This PR used 2.6 MiB less memory with one viewer and 1.4 MiB less with two. Both produced matched recordings with complete, forward-moving timestamps and no strict-decode errors. These are short, single-camera measurements rather than fleet-wide performance claims.

The feature and engineering differences—not a claimed universal speed advantage—are the main reasons for this implementation.

Implemented feature coverage

The comparison below uses the current fzurita/reolink_protocol@fcbd6109. This PR remains experimental; checks indicate implemented behavior, not universal camera or firmware support.

Feature This PR fzurita
Connect directly by camera IP over LAN TCP
Connect by Reolink UID using LAN-P2P over reliable UDP
Choose the network interface and broadcast address for UID discovery
main, sub, and extern camera streams
Select NVR channels or individual lenses
Detect H.264 or H.265 from the selected stream
Receive AAC or camera ADPCM audio
Two-way audio using common go2rtc audio formats
Turn video or incoming audio off for one source
Create a talkback-only source
Combine main and lower-resolution sources for browser codec fallback
Share one configured source across recording and live viewers
Use a separate camera connection for talkback
Show model, firmware, observed channels, and query status in diagnostics
Suppress invalid video and resume on the next valid keyframe
Reconnect when only one advertised audio or video track stalls
Reconnect when audio remains far below its advertised rate

Unsupported (so far)

  • WAN or cloud P2P, relay, NAT traversal, and UPnP; UID/LAN-P2P is local only
  • Battery-camera wake and cloud lifecycles
  • PTZ, presets, lights, sirens, camera settings, and event APIs
  • Automatic RTSP, RTMP, HTTP-FLV, or FFmpeg fallback

Baichuan should be used only on a trusted local network.

AI disclosure

This implementation was developed with assistance from OpenAI Codex and Anthropic Claude. Its architecture, acceptance criteria, and engineering standards were human-directed. The final branch was reviewed, tested, benchmarked, and exercised on physical cameras. The code was repeatedly reduced and reorganized for reviewability without removing the protocol, safety, lifecycle, or test coverage described above.

@quenthal

Copy link
Copy Markdown

"Use a separate camera connection for talkback"

Maybe I misintrepet this, but is this beneficial? Less simultaneous connections equals more stable Reolink camera.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants