Library / SDK
rgaufman/live555 avatar
rgaufman/live555

live555 enhanced fork: patches for cameras that misbehave

An unofficial fork of the live555 source code.

873 stars390 forksC++LGPL-3.0

At a glance

What is it?
rgaufman/live555 is a third-party fork of the live555 streaming media library that now evolves independently of upstream, fixing RTSP server denial-of-service edges, an uninitialised read in the OnDemand server, a CPU-spinning RTCP loop, and adding proxy flags for dead-stream detection, stream naming and downstream authentication. It is LGPL-3.0 and publishes no GitHub releases.
Who is it for?
Adopt this live555 fork if you run live555MediaServer or live555ProxyServer against real IP cameras, especially ones whose firmware deviates from the RFCs, because the changes here target exactly the behaviours that show up in production and none of them are in upstream.
Can I use it commercially?
Yes, with conditions. LGPL-3.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
Is it still maintained?
Yes. The repository last received commits 86 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A fork that stopped pretending to be a patch set

The README opens by saying what this is not: this is not the official live555 repository, but a third-party fork maintained for production use and offered without any warranty or support guarantee. The canonical distribution lives at live555.com/liveMedia, and the authoritative channel for discussion and bug reports is the live-devel mailing list, which the README links as the place where genuine issues belong.

The fork relationship is described with unusual candour. It was forked from live.2026.06.24, and the README says plainly that the fork now evolves independently, that a byte-for-byte patch against upstream is no longer maintained, that upstream releases are still tracked and worthwhile fixes are backported, and that the divergence is a difference in philosophy rather than a criticism.

The stated philosophy is worth repeating because it explains every change in the fork. The optimisation target is running reliably against the real mix of legacy and current IP cameras the maintainer has to connect to, many of which deviate from the RFCs in their own particular ways. Upstream is described as making changes it would reasonably decline, some of which would be suboptimal in a perfect world.

The other half of the arrangement is an explicit request to report upstream too. The README asks that genuine library bugs be reported upstream as well, noting that the upstream authors do not see issues filed in the fork, and that their fixes flow back to the wider userbase, which the README names as VLC, MPlayer and many embedded cameras. The fork asks for reports in both places, and offers to patch in the fork and feed the fix back upstream.

The licence is LGPL-3.0, with COPYING and COPYING.LESSER in the repository, and the primary language is C++.

Building it takes two commands and a C++20 toolchain

The build section is short because the build system is the upstream one:

bash
./genMakefiles linux
make -j4

The first command generates the makefiles for a platform, and the README says to replace linux with your platform, pointing at the config.* files. The repository carries a wide matrix of them, from config.linux and config.linux-64bit through config.macosx-bigsur, config.macosx-catalina, config.openbsd, config.freebsd, config.qnx4, config.solaris-64bit, config.raspberrypi, config.cygwin, config.iphoneos and several uClinux and embedded variants, plus win32config and the genWindowsMakefiles scripts for Windows.

One detail will bite anyone building on a current distribution. As of the live.2026.06.24 base, upstream pins -std=c++20 across its config files, because it uses std::atomic_flag::test(), and the fork keeps that on the macOS configs too. If you build with a toolchain that defaults to an older C++ standard, the README says to add -std=c++20 yourself. That is a compiler flag change in the upstream base rather than something the fork invented, but it is the kind of thing that turns into a confusing compile error rather than an obvious one.

After the build, the executables that matter are listed explicitly: testProgs/testRTSPClient and testProgs/openRTSP for talking to and from a server, proxyServer/live555ProxyServer for the proxy, and mediaServer/live555MediaServer for the server. The directory layout follows the upstream arrangement, with liveMedia/, groupsock/, BasicUsageEnvironment/, UsageEnvironment/, mediaServer/, proxyServer/, hlsProxy/ and testProgs/ at the top level.

Two megabyte packets for cameras that send oversized frames

The first enhancement is about volume rather than logic. OutPacketBuffer::maxSize is bumped from 60 KB to 2 MB, in MediaSink.cpp, and the change is retained in the per-program bumps under testProgs/ and in mediaServer/DynamicRTSPServer.cpp. StreamParser::BANK_SIZE is bumped to 600 KB.

The reason given is specific: high-bitrate streams and cameras that send oversized frames. A 60 KB packet buffer is a limit that a modern high-bitrate stream can reach in a single frame, and a stream parser bank of that size is small for the same reason.

This is a change with a memory cost rather than a behaviour change. A 2 MB buffer per output stream is not free on a device with a handful of megabytes of RAM, and the fork is aimed at embedded cameras, so the trade is deliberate: reliability against odd cameras at the cost of memory that upstream would rather not spend on every possible deployment. The size is a compile-time constant in the source, so a deployment that needs the old behaviour has to patch it back rather than configure it.

The same section of the README covers a smaller change with a sharp edge. config.linux sets -DALLOW_RTSP_SERVER_PORT_REUSE=1 so service restarts do not wait on TIME_WAIT, and the README attaches a warning in the same line: never run two instances on the same port. That is a compile-time switch rather than a runtime option, and it converts a slow restart into a silent port conflict if the second instance does come up.

The RTSP server now rejects what it cannot honour

Two server-side changes in RTSPServer.cpp are the kind of hardening that upstream tends to defer, and both are visible in the fork's own description.

The first is a Content-Length slow-read cap. The server now rejects a request whose Content-Length is greater than or equal to REQUEST_BUFFER_SIZE, which is 20000, with 400 Bad Request, instead of holding the connection open while it waits for body bytes that could never fit in the fixed request buffer. The README describes the old behaviour as a low-effort slow-read denial of service, where a client declares a huge body and then stalls. It also notes that the only prior guard, a pointer wraparound check, is a no-op on 64-bit, so a declared length such as 999999999 hung the connection until the buffer filled.

The second change is about honesty in the protocol. The server implements no server-side RTSP option-tags, so any Require: or Proxy-Require: header names an option the server cannot honour. The fork now rejects such requests with 551 Option not supported and echoes the offending tags in an Unsupported: header, rather than silently processing the request as though the requirement had been met. The reference is RFC 2326 section 12.32, and both single tags and comma-separated multi-token headers are handled.

Both are cases where the previous behaviour was not wrong so much as accommodating. Silently ignoring a Require: header means a client that asked for an option got a response that did not honour it, which is the kind of thing that produces a bug report in a different place entirely. Rejecting with the documented status code turns that into a clear failure.

An uninitialised read and a CPU-spinning RTCP loop

The OnDemand fix is the most interesting piece of the fork, because it is a memory bug found with a tool rather than a policy change.

OnDemandServerMediaSubsession::getStreamParameters has a local streamBitrate out-parameter. Several subclass overrides of createNewStreamSource(), the Matroska and Ogg ones among them, return NULL on a demuxer track lookup failure without writing that out-parameter, which leaves the caller multiplying an uninitialised value into an increaseSendBufferTo() call. The fork adds defensive initialisation. The report was filed against the fork as issue 65 with a valgrind trace, and the README says the same bug is present in upstream live.2026.04.01 and should be reported to the live-devel list.

That is a textbook shape for a fork: a defect that upstream may not reproduce because their configuration never hits the failing demuxer path, and a fix that is safe to take in either place.

The RTCP fix addresses a different kind of problem, one that shows up as an operational symptom rather than a crash. Some buggy RTP and RTCP over TCP implementations, certain Hikvision firmware according to the README, can pin a CPU to 100 percent by emitting oversized RTCP reports faster than the handler can drain them. The fix resets the buffer and returns instead of looping, and it rate-limits the packet overflow warning to one line per five seconds per instance, with a count of suppressed events so that the log still shows how much was dropped.

The rate limiting is the detail worth copying. Without it, the warning rate is itself the denial of service, since the whole point is that the peer is emitting faster than the log can absorb.

Three new proxy flags: -D, -e and -C

The proxy gains the most user-visible changes, and all three are documented with runnable examples.

The first is dead-stream detection. live555ProxyServer now takes a -D flag in seconds, defaulting to 10, that resets the upstream connection if no packets are received for that long. The README is precise about the accuracy: detection latency is one to two times the configured value, because the check samples cumulative packet counts at that interval, and -D 0 disables the behaviour.

bash
./proxyServer/live555ProxyServer rtsp://camera.example.com/stream        # default 10s
./proxyServer/live555ProxyServer -D 30 rtsp://camera.example.com/stream  # custom 30s
./proxyServer/live555ProxyServer -D 0 rtsp://camera.example.com/stream   # disabled

The second is a custom downstream name. By default the proxy publishes proxied streams as rtsp://<proxy>/proxyStream for a single URL, or proxyStream-1 through proxyStream-N for several, and the -e flag substitutes a prefix of your own, up to 50 characters and not empty.

bash
# Single URL → rtsp://<proxy>/frontdoor
./proxyServer/live555ProxyServer -e frontdoor rtsp://camera.example.com/stream

# Multiple URLs → rtsp://<proxy>/camera-1, camera-2, camera-3
./proxyServer/live555ProxyServer -e camera \
    rtsp://cam1.example.com/stream \
    rtsp://cam2.example.com/stream \
    rtsp://cam3.example.com/stream

The third is downstream authentication. The -C flag takes a username and a password and requires downstream RTSP clients to authenticate with digest auth before they can pull the proxied stream. It is distinct from -u, which supplies the credentials the proxy itself uses to connect to the upstream camera, and internally it populates the same UserAuthenticationDatabase that RTSPServer already consults for every request.

bash
# Proxy requires "viewer"/"secret" from its RTSP clients,
# and uses "admin"/"hunter2" to connect to the camera upstream:
./proxyServer/live555ProxyServer \
    -C viewer secret \
    -u admin hunter2 \
    rtsp://camera.example.com/stream

That separation of upstream and downstream credentials is the feature that matters for a camera in someone else's building. The README also states that -C combines with -e, -D, -U and -R without interaction.

No releases, a mailing list, and a build you maintain yourself

Three practical points about operating this fork.

First, there are no GitHub releases. The repository has no release artefacts, so a deployment either builds from a commit or tracks the source tree itself. The last push was on 2026-07-29, and the repository is not archived, so the source is moving, but there is no tag to pin to and no changelog of released versions to compare against. The upstream numbering is the reference point, since the README states which upstream release the current base was forked from.

Second, the support story points outward. The README directs bug reports to the live-devel mailing list, says the fork is offered without any warranty or support guarantee, and has a security reports section with its own recommended disclosure workflow. There is a CLAUDE.md at the root of the repository alongside the README, and a .vscode/ directory, which suggests the fork is maintained with the same tooling habits as a working project rather than as a patch pile.

Third, the divergence cuts both ways. Because the fork no longer maintains a byte-for-byte patch against upstream, backporting a new upstream release is a merge exercise rather than a rebase, and the README says outright that some changes here are ones upstream would reasonably decline. If your policy requires staying close to the canonical library, that is the cost, and the README states it rather than hiding it.

The LGPL-3.0 licence is the last operational consideration. The licence files are in the tree, and the fork's own README asks for upstream reporting and credit, which is consistent with a project that wants to be a good citizen of the upstream community rather than a replacement for it.

Editorial conclusion

Adopt this live555 fork if you run live555MediaServer or live555ProxyServer against real IP cameras, especially ones whose firmware deviates from the RFCs, because the changes here target exactly the behaviours that show up in production and none of them are in upstream. Do not adopt it if you need a drop-in replacement that stays byte-for-byte compatible with upstream, since the fork states it no longer maintains a patch against upstream and has diverged in philosophy, and expect to track releases yourself because the repository publishes no GitHub releases. Before you deploy a build, read the C++20 requirement in the config files, keep the two server instances off the same RTSP port because port reuse is enabled, and report any genuine library bug to the live-devel mailing list as well, since the upstream authors do not see issues filed in the fork.

Frequently asked questions

How do I build this live555 fork?

Run ./genMakefiles with your platform, for example linux, and then make -j4. The README notes that the config files pin -std=c++20 as of the live.2026.06.24 base, so a toolchain defaulting to an older standard needs that flag added.

What does the -D flag do in live555ProxyServer?

It sets the inter-packet gap in seconds, defaulting to 10, and resets the upstream connection when no packets arrive for that long. The README notes that detection latency is one to two times the configured value, and that -D 0 disables the behaviour.

How is downstream authentication different from the upstream credentials?

The -C flag takes a username and password and requires downstream RTSP clients to authenticate with digest auth before pulling the proxied stream, while -u supplies the credentials the proxy itself uses to connect to the upstream camera. Internally, -C populates the same UserAuthenticationDatabase that RTSPServer consults for every request.

Where should I report a bug in this live555 fork?

The README asks that genuine library bugs be reported to the live-devel mailing list as well as in the fork, because the upstream authors do not see issues filed here and their fixes reach the wider userbase. The fork also describes a separate security reports workflow.

Official sources

  1. Issues
  2. License: LGPL-3.0
  3. README
  4. rgaufman/live555 on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/rgaufman-live555.svg)](https://hysenlabs.com/projects/rgaufman-live555)

Was this useful?