Tech Notes · Display & MPP

RTSP Streaming on Rockchip with live555 + MPP

Push an H.264 RTSP stream from a USB camera on RK3399Pro — using the live555 server framework plus the Rockchip MPP hardware encoder and RGA. Translated and annotated from hisping, Rockchip / Toybrick community, including the common RGA/MPP version-mismatch pitfall and how to fix it.

Attribution & source
Original author: hisping · Published on the Rockchip / Toybrick community forum (t.rock-chips.com/forum.php?mod=viewthread&tid=895), originally titled "RK3399Pro Getting-Started Tutorial (10): RTSP Push-Streaming Introduction", posted 2019-09-29.
Translated into English and annotated by Bestom. Code and commands are reproduced from the original; logic and identifiers are unchanged. Bestom presents this as a reference walkthrough for engineers building camera / streaming products on Rockchip SoCs — it is a teaching example, and production use needs your own hardening and tuning.

What this walkthrough does

The original tutorial builds a small RTSP server on the TB-RK3399ProD board that captures frames from a USB camera, hardware-encodes them to H.264 with Rockchip MPP, and serves the stream over RTSP so a remote player (VLC) can display it. The key idea — and the part worth stealing — is that the video encode runs on the Rockchip hardware encoder through MPP, not on the CPU. The thread notes a 3-hour soak test ran clean on the demo; for commercial products you should still do your own optimization. You can also swap live555 for another RTSP framework and keep the same MPP encode path.

USB camera (UVC) RK3399Pro board Network / VLC ┌──────────────┐ ┌──────────────────────────┐ ┌──────────────┐ │ YUYV frames │ V4L2 │ V4L2.cpp │ │ rtsp://… │ │ (UVC) │ ─────▶ │ grab one frame │ │ h264ES… │ └──────────────┘ │ → RGA convert to NV12 │ │ │ │ StreamEncoder.cpp │ ───▶ │ VLC play │ │ MPP H.264 encode │ │ │ │ live555 RTSP server │ └──────────────┘ └──────────────────────────┘
Bestom note: This exact pipeline — capture → RGA color-space convert → MPP hardware H.264 encode → RTSP — is the foundation of most Rockchip camera products, and it carries forward unchanged to RK3588 / RK3576, which expose the same MPP encoder (now H.264/H.265) and RGA2 for format conversion. On those parts you can also use the rockchip-mpp GStreamer plugins or rkmpp directly. Bestom builds RK3588/RK3576 SoM and reference designs and can help you stand up a camera + streaming path — see Solutions → Smart Vision.

1. Install the environment

The tutorial was verified on Fedora 28 (firmware v1.5) and also on Debian 10. Install the live555, FFmpeg, and Rockchip MPP/RGA development packages.

1.1 Fedora 28

sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm
sudo dnf install live555-devel
sudo dnf install ffmpeg-devel
sudo dnf install librockchip_mpp-devel
sudo dnf install librockchip_rga-devel

1.2 Debian 10

First refresh the package indexes (the first update pulls in the Toybrick apt source):

# 1. refresh sources
sudo apt update --fix-missing
# 2. upgrade packages
#    NOTE: during the upgrade you will be asked whether to keep
#    /etc/apt/sources.list.d/toybrick.list — answer "Y"
sudo apt -y upgrade
# 3. refresh sources again
sudo apt update

For later updates, a plain sudo apt update && sudo apt upgrade is enough. Then install the dependencies:

sudo apt install liblivemedia-dev
sudo apt install livemedia-utils
sudo apt install ffmpeg
sudo apt install libavcodec-dev
sudo apt install libswscale-dev
sudo apt install libavformat-dev
sudo apt install vlc
sudo apt install rockchip-mpp-dev
sudo apt install rockchip-rga-dev
Bestom note: Keep the MPP and RGA packages matched to your BSP. As the troubleshooting below shows, a stray apt/dnf upgrade can pull a newer mpp/rga/drm than your kernel BSP expects and break the encoder. Pin or vendor the exact versions your SoM firmware was built against — Bestom ships MPP/RGA versions aligned to each RK3588/RK3576 BSP release for this reason.

2. Get the demo source and build

Download and extract the attachment for your distro (Fedora or Debian), then build inside the IPCamera/ directory:

cd IPCamera/
make clean
make
./RTSPServer

On startup the server prints the RTSP URL — the IP is whatever the board got, so use the printed value. In the original run it was:

rtsp://172.16.9.3:8554/h264ESVideoTest

Keep this URL; the player uses it in the next step.


3. Play the stream with VLC

The tutorial installs VLC right on the board, but you can also play from a PC on the same network:

sudo dnf install vlc
vlc

In VLC: Media → Open Network Stream → paste rtsp://172.16.9.3:8554/h264ESVideoTestPlay.


4. How the code works (two key files)

4.1 V4L2.cpp — grab a frame, convert to NV12

V4L2FramedSource::doGetNextFrame() pulls one frame from the USB camera (UVC) and converts it to NV12 for the encoder:

void V4L2FramedSource::doGetNextFrame() {
    long bigin = get_time();
    registerOutputInterest();
    while(fTotOfFrameToSend < fMaxOfFrameToSend) {
        convernt_to_OutputBuffer();
    }
    long end = get_time();
    printf("V4L2FramedSource::doGetNextFrame use %d \n", end - bigin);
    // record the returned info
    fFrameSize = fNumValidDataBytes;  // one frame per call
    fNumTruncatedBytes = 0;
    reset();
    afterGetting(this);
}

4.2 StreamEncoder.cpp — MPP H.264 encode

StreamEncoder::continueReadProcessing1() calls the Rockchip MPP library to encode the NV12 frame to H.264:

void StreamEncoder::continueReadProcessing1(unsigned frameSize, unsigned numTruncatedBytes,
                                            struct timeval presentationTime,
                                            unsigned durationInMicroseconds) {
    fNumTruncatedBytes = numTruncatedBytes;
    fPresentationTime = presentationTime;
    fDurationInMicroseconds = durationInMicroseconds;
    encoder_to_h264();
    if (fNumValidDataBytes + dstsize < fOutputBufferSize && fTotOfFrameToSend < fMaxOfFrameToSend) {
        copy_to_outputbuffer();
    }
    fFrameSize = fNumValidDataBytes;
    gettimeofday(&fPresentationTime, NULL);
    reset();
    FramedSource::afterGetting(this);
}
Bestom note: The two-stage split — capture/convert in V4L2.cpp, encode in StreamEncoder.cpp — is a clean pattern to port. On RK3588/RK3576 the MPP API is the same family, and RGA2 does the YUYV→NV12 (or other) conversion. If your camera already outputs NV12 or MJPEG you can skip the RGA step and feed MPP directly, saving a copy. Bestom's camera reference designs use exactly this MPP encode path and can hand you a working StreamEncoder for your sensor.

5. Common pitfall: RGA / MPP version mismatch

The thread's replies contain a genuinely useful debugging record. Two failure modes came up repeatedly:

SymptomCauseFix (from the thread)
Open file(/boot/toybrick-release) failed then rgaCreate error! on startupThe system rga package (installed via apt/dnf) is incompatible with the board's BSPBuild RGA from the "RK3399Pro Tutorial (5): Using the RGA graphics-acceleration engine" source: copy that project's rockchip_rga/ folder into the RTSP project root, put its headers into include/, add the generated .o files to the Makefile, and remove the rockchip/ path prefix from #include <rockchip/rockchip_rga.h>.
Same RGA error after a routine dnf updatempp, rga, and drm libraries were upgraded to versions newer than the BSPDowngrade mpp, rga, and drm back to the versions that shipped with the firmware.
Stream stutters / freezes when viewed over the LAN from a PC (e.g. via OpenCV)Demo-level pipeline; not tuned for high-load network playbackTreat as a teaching example; for production, tune the RTSP server, buffer, and bitrate, or move to a maintained server (e.g. rkmpp + a lightweight RTSP server).
Bestom note: This is the single most common "it worked on the eval image, broke after I ran apt" problem on Rockchip camera builds. The lesson generalizes to RK3588 / RK3576: always lock MPP, RGA, and DRM to the BSP-tagged versions. Bestom's RK3588/RK3576 BSP releases ship a matched MPP/RGA set and a known-good camera pipeline so you don't rediscover this the hard way — see Contact.

Recap