Skip to main content

Rockchip Video Codec Examples

Download video codec examples

Example files

The archive contains prepare-video.sh; extract and run it in section 3. Video is not bundled: the script downloads Sintel from Blender’s official website and prepares the clip used in the examples. Codec commands remain in the individual examples.

1. Introduction to video codecs​

This guide covers three ways to work with H.264 and H.265 on ArmSoM boards. First, use GStreamer and Rockchip MPP to hardware-transcode a 1080p H.264 clip to MP4 and play it over HDMI. Next, try H.265 software encoding and decoding with FFmpeg, then verify the GStreamer hardware path. Finally, use the MPP command-line tools to test both codecs with elementary streams and raw NV12 frames.

H.264 (AVC) and H.265 (HEVC) are video coding formats. Decoding reconstructs pictures from a compressed bitstream, and encoding compresses pictures into a bitstream. MP4 is a container that stores streams and timing information. The third example also works with two intermediate files: an elementary bitstream without an MP4 container and uncompressed NV12 frames. NV12 stores luma and interleaved chroma in separate planes.

TechnologyRole in this guideExamples
GStreamerConnects demuxing, parsing, codec, muxing, and display elements in a pipeline. This guide uses mppvideodec for hardware decoding and mpph264enc or mpph265enc for hardware encoding.Examples 1 and 2
FFmpegPrepares clips and extracts streams, with ffprobe to inspect outputs. Example 2 uses the board's system FFmpeg for H.265 software encoding and decoding, then plays the output with GStreamer and MPP.Example 2 and file checks elsewhere
Rockchip MPPGives applications access to Rockchip video codec hardware. Example 3 uses mpi_dec_test and mpi_enc_test to verify decoding and encoding separately and inspect NV12 data and elementary streams.Example 3 and the underlying library for the Rockchip GStreamer plugin

Start with example 1 to produce a playable MP4. Use example 2 to compare H.265 software and hardware workflows. Use example 3 to investigate elementary streams, pixel formats, or frame strides.

1.1 How data moves through the pipeline​

An MP4 file first goes through a demuxer to extract its video stream. A parser prepares the compressed stream for the decoder, which produces raw frames. From there, the pipeline can display those frames or pass them to an encoder and mux the new bitstream into MP4.

StageElements in this guideWhat to check
Read and parsefilesrc, qtdemux, h264parse or h265parseMatch the parser to the input codec. An Annex B elementary stream skips the MP4 demuxer.
DecodemppvideodecA run ending in EOS with fakesink verifies that the pipeline reached the end without displaying frames.
Encode and savempph264enc or mpph265enc, parser, mp4muxLet the muxer finish at EOS, then check codec, dimensions, frame rate, and frame count with ffprobe.
DisplayxvimagesinkCheck the display session separately. A valid MP4 can still fail to play if the display sink cannot accept the decoded format.
tip

The MPP tools expose raw NV12 frames. For a tightly packed 8-bit NV12 frame with even dimensions, the Y plane takes width × height bytes, and the interleaved UV plane takes half as much. Hardware buffers can have padding, so use the actual row and vertical strides when reading them.

2. Tested setup and prerequisites​

2.1 Supported board and image configurations​

The ArmSoM SDK includes these ARM64 board and OS configurations for Debian 12 and Ubuntu 22.04:

SoCBoardsSDK image families
RK3528Sige1Debian 12
RK3576AIM5, CM5 (CM5-IO and CM4 Nano B IO), Sige5Debian 12, Ubuntu 22.04
RK3588 / RK3588SAIM7, CM7S, LM7, Sige7, Sige7SDebian 12, Ubuntu 22.04

Both SDK rootfs trees include Rockchip MPP and the GStreamer Rockchip plugin. On another board, use its matching official image and run the element checks in section 2.3. Then verify that decoding reaches EOS and that the encoded MP4 passes the file checks in section 4. An SDK image configuration alone does not establish runtime support for every codec or display path.

Decode and encode can run without a desktop. The HDMI commands in section 4.1 require an active X11 session and a working xvimagesink; the presence of the element alone does not verify XVideo support. The complete workflow in this guide was tested on CM7S with Debian 12 XFCE/X11. Other listed board and image combinations, including Ubuntu 22.04, are candidates for the same verification steps.

2.2 Tested setup​

The test used ArmSoM CM7S (RK3588S) with Debian 12 arm64 XFCE/X11 and kernel 6.1.118-rk3588. HDMI was set to 1920×1080 at 60 Hz. The installed GStreamer tools, Rockchip GStreamer plugin, and MPP library packages were 1.22.9-1, 1.14-4, and 1.5.0-1, respectively.

2.3 Install and check dependencies​

tip

On a fresh image, check the board clock before downloading the sample or using APT. If the time is wrong, set the current date and time in the desktop settings. Retry the download after correcting the clock if HTTPS reports that the certificate is not yet valid.

date -Is

Connect HDMI and log in. If the tools are missing, connect to the internet and install them on the board.

tip

The tested image already includes these tools. As root, omit sudo.

Before refreshing the index, check the system clock and repositories in Update the APT package source list.

sudo apt update
sudo apt install gstreamer1.0-tools ffmpeg curl

Then check the GStreamer elements. If the MPP codecs are missing, check the official desktop image and Rockchip plugin package for your board.

mkdir -p ~/rockchip-video
cd ~/rockchip-video
for element in qtdemux h264parse mppvideodec mpph264enc mp4mux fpsdisplaysink xvimagesink; do
gst-inspect-1.0 "$element" >/dev/null || break
printf '%s OK\n' "$element"
done

The example uses system FFmpeg to prepare and inspect media. For FFmpeg's Rockchip codecs and RGA filters, see the FFmpeg installation guide.

3. Prepare a 1080p H.264 clip​

Generate a five-second, 30 fps test pattern without network access. Select it as the input for the following steps.

ffmpeg -nostdin -n -f lavfi -i testsrc2=size=1920x1080:rate=30 -frames:v 150 -c:v libx264 -preset ultrafast -pix_fmt yuv420p input-1080p.mp4
INPUT=input-1080p.mp4
OUTPUT=output-mpp.mp4

With internet access, you can instead download the official Sintel 1080p trailer. Use prepare-video.sh from the archive to take eight seconds starting at 12 seconds, drop audio, and normalize the clip to 1080p30. Footage © Blender Foundation | durian.blender.org, CC BY 3.0.

cd ~/rockchip-video
curl -fL https://docs.armsom.org/downloads/rockchip-video/rockchip-video-examples.tar.gz -o rockchip-video-examples.tar.gz
tar -xzf rockchip-video-examples.tar.gz
bash prepare-video.sh

The source is saved to ~/rockchip-video/sintel-source.mp4, and the test clip to ~/rockchip-video/sintel-1080p.mp4. The script reuses an existing source. If the clip already exists, use it directly or rename it before rerunning.

INPUT=sintel-1080p.mp4
OUTPUT=sintel-output-mpp.mp4

Run section 3 with the Sintel sample before continuing to examples 2 and 3. Keep the same terminal so INPUT and OUTPUT remain set.

4. Example 1: H.264 hardware decode and encode to MP4​

Verify decoding with mppvideodec. This test opens no window, and sync=false lets the pipeline process input as fast as it can.

time gst-launch-1.0 filesrc location="$INPUT" ! qtdemux ! h264parse ! mppvideodec ! fakesink sync=false

Encode at a target 6 Mbps with mpph264enc, then mux with mp4mux.

caution

Choose a new output name if the file exists. Wait for EOS so mp4mux can finish the file.

time gst-launch-1.0 -e filesrc location="$INPUT" ! qtdemux ! h264parse ! mppvideodec ! mpph264enc bps=6000000 ! h264parse ! mp4mux ! filesink location="$OUTPUT"

Go to the working directory, then list the output file. The test pattern produces output-mpp.mp4; Sintel produces sintel-output-mpp.mp4. If you opened a new terminal, set OUTPUT to the corresponding filename first.

cd ~/rockchip-video
ls -lh -- "$OUTPUT"
ffprobe -v error -select_streams v:0 -show_entries stream=codec_name,width,height,avg_frame_rate,nb_frames:format=duration -of default=nw=1 "$OUTPUT"

4.1 HDMI playback and board results​

Play on XFCE/X11. Statistics go to ~/rockchip-video/playback-xv.log.

tip

In a desktop terminal, use its existing DISPLAY. Over serial, replace :0 with the active display number.

DISPLAY=:0 gst-launch-1.0 -v filesrc location="$OUTPUT" ! qtdemux ! h264parse ! mppvideodec ! fpsdisplaysink video-sink=xvimagesink text-overlay=false sync=true > playback-xv.log 2>&1
echo "PLAY_EXIT=$?"
grep -E 'rendered:|Got EOS' playback-xv.log | tail -4
CM7S test with the generated clipResult
Input and outputH.264, 1920×1080, 30 fps, 150 frames, 5 seconds
Hardware decode alone0.231 s
Hardware decode, encode, and mux0.676 s
Output fileoutput-mpp.mp4, about 3.5 MiB
HDMI playbackReached EOS and exited with code 0. Last periodic sample showed 140 frames rendered, 0 dropped, and 30.12 fps average.
tip

Times are from single runs. Playback statistics were sampled before EOS and measure sink output, not monitor refresh.

caution

On this image, direct ximagesink playback failed format negotiation. With videoconvert, it dropped frames. Use xvimagesink for this example.

4.2 Sintel trailer results​

The public clip also passed on CM7S. The output retained H.264, 1920×1080, 30 fps, and all 240 frames (8 seconds). Decode took 0.322 s, and hardware decode, encode, and mux took 1.310 s. The output was 5,355,119 bytes. HDMI playback reached EOS and exited with code 0. The last periodic sample reported 236 frames rendered, 0 dropped, and 30.23 fps average.

CM7S XFCE desktop playing the hardware-transcoded Sintel clip

Sintel © Blender Foundation | durian.blender.org · CC BY 3.0

5. Example 2: H.265 with FFmpeg and GStreamer​

5.1 Software encoding and decoding with FFmpeg​

The system FFmpeg on the tested image did not list RKMPP codecs. This example encodes a different four-second Sintel excerpt on the CPU using libx265, verifies it by software decoding, then plays the output with MPP. FFmpeg encoded 120 frames in 23.25 seconds (5.16 fps); the software decode check exited with code 0. The screenshot shows MPP playback of the FFmpeg output.

mkdir -p ~/rockchip-video/advanced
cd ~/rockchip-video/advanced
ffmpeg -nostdin -n -ss 19 -i ../sintel-source.mp4 -t 4 -an -r 30 -c:v libx265 -preset ultrafast -x265-params pools=2 -pix_fmt yuv420p sintel-ffmpeg-hevc.mp4
ffmpeg -nostdin -v error -xerror -i sintel-ffmpeg-hevc.mp4 -f null -
DISPLAY=:0 gst-launch-1.0 filesrc location=sintel-ffmpeg-hevc.mp4 ! qtdemux ! h265parse ! mppvideodec ! xvimagesink

CM7S FFmpeg HEVC output playback

5.2 Hardware alternative with GStreamer​

Use sintel-1080p.mp4 from section 3 to encode HEVC and verify it with MPP. Output: ~/rockchip-video/advanced/output-hevc.mp4.

caution

Choose a new output name if this file already exists.

  1. Check the H.265 hardware encoder and bitstream parser.

    gst-inspect-1.0 mpph265enc
    gst-inspect-1.0 h265parse
  2. Create and enter the working directory.

    mkdir -p ~/rockchip-video/advanced
    cd ~/rockchip-video/advanced
  3. Hardware-transcode to H.265 MP4 and wait for muxing to finish.

    gst-launch-1.0 -e filesrc location=../sintel-1080p.mp4 ! qtdemux ! h264parse ! mppvideodec ! mpph265enc bps=6000000 ! h265parse ! mp4mux ! filesink location=output-hevc.mp4
  4. Verify hardware decoding of the output. Got EOS means the pipeline reached the end of the file. fakesink does not display video.

    gst-launch-1.0 filesrc location=output-hevc.mp4 ! qtdemux ! h265parse ! mppvideodec ! fakesink sync=false
  5. Inspect the output file separately. Expect hevc, 1920×1080, 30 fps, and 240 frames.

    ffprobe -v error -select_streams v:0 -show_entries stream=codec_name,width,height,avg_frame_rate,nb_frames -of default=nw=1 output-hevc.mp4

Both GStreamer pipelines exited successfully on CM7S. The output contained 240 HEVC frames at 1920×1080 and 30 fps. This test covers file transcoding and decode without a window. The HDMI screenshot above shows the H.264 output.

6. Example 3: Direct H.264 and H.265 tests with MPP tools​

The tested rockchip-mpp-demos package (1.5.0-1) provides both tools. Use the H.264 clip from section 3 and the HEVC MP4 from section 5.2.

caution

Allow at least 400 MiB of free space and preserve any existing files with the same output names.

command -v mpi_dec_test mpi_enc_test
cd ~/rockchip-video/advanced

Extract the H.264 stream, then decode and encode 60 frames.

ffmpeg -nostdin -n -i ../sintel-1080p.mp4 -an -c:v copy -bsf:v h264_mp4toannexb input.h264
mpi_dec_test -i input.h264 -t 7 -n 60 -f 0 -o decoded.nv12
mpi_enc_test -i decoded.nv12 -w 1920 -h 1080 -hstride 1920 -vstride 1080 -f 0 -t 7 -n 60 -fps 30 -bps 6000000 -o encoded.h264

Repeat with the H.265 output from section 5.2.

ffmpeg -nostdin -n -i output-hevc.mp4 -an -c:v copy -bsf:v hevc_mp4toannexb input.hevc
mpi_dec_test -i input.hevc -t 16777220 -n 60 -f 0 -o decoded-hevc.nv12
mpi_enc_test -i decoded-hevc.nv12 -w 1920 -h 1080 -hstride 1920 -vstride 1080 -f 0 -t 16777220 -n 60 -fps 30 -bps 6000000 -o encoded.hevc

Check that each encoded stream contains 60 frames.

for file in encoded.h264 encoded.hevc; do
ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=codec_name,width,height,nb_read_frames -of default=nw=1 "$file"
done

FFmpeg extracts the streams without re-encoding. The bitstream filters convert the MP4 streams to Annex B. In these MPP tools, -t 7 selects H.264, -t 16777220 selects H.265, and -f 0 selects NV12. Each run processes 60 frames and writes its files to ~/rockchip-video/advanced/.

InputDecoded fileHardware-encoded fileBoard verification
H.264decoded.nv12encoded.h264H.264, 1920×1080, 60 frames
H.265decoded-hevc.nv12encoded.hevcHEVC, 1920×1080, 60 frames
caution

Each NV12 dump was 186,624,000 bytes in the packed layout exported by the test tool. When reading hardware buffers, take the row and vertical strides from frame metadata.

tip

For C/C++, start with the SDK's MPP development package and demos. Initialize the context, submit input, collect output, drain at EOS, and release resources. If frame dimensions or layout change, prepare buffers from the new frame information.

6.1 Play the MPP output​

Play the raw HEVC stream produced by mpi_enc_test. It has no MP4 container, so the playback pipeline starts at h265parse without qtdemux.

cd ~/rockchip-video/advanced
DISPLAY=:0 gst-launch-1.0 filesrc location=encoded.hevc ! h265parse ! mppvideodec ! xvimagesink

CM7S MPP HEVC elementary stream playback

Sintel © Blender Foundation | durian.blender.org · CC BY 3.0

Contact us