| mpp-working-config.txt | ||
| README.md | ||
| switch_mpp_orangepi5_opi2.md | ||
Rockchip MPP + FFmpeg su Orange Pi 5 Plus
Guida alla configurazione di Rockchip MPP e FFmpeg-Rockchip su Orange Pi 5 Plus / RK3588, con test di:
- decoding hardware HEVC con "hevc_rkmpp"
- encoding hardware H.264 con "h264_rkmpp"
- transcodifica HEVC → H.264
- output HLS
- segmenti MPEG-TS
- audio AAC
- video verticale con rotazione presente nei metadata MP4
- verifica finale con "ffprobe"
La configurazione riportata è quella verificata durante i test su Orange Pi 5 Plus.
- Hardware e software
Hardware utilizzato:
Orange Pi 5 Plus Rockchip RK3588 ARM64 / aarch64
La libreria Rockchip MPP supporta la famiglia RK3588.
Il progetto "ffmpeg-rockchip" è una fork di FFmpeg pensata per la pipeline hardware Rockchip MPP/RGA e include decoder ed encoder hardware. Il progetto è indirizzato in particolare a piattaforme RK3588/RK3588S.
Repository:
- MPP: https://github.com/rockchip-linux/mpp
- FFmpeg-Rockchip: https://github.com/nyanmisaka/ffmpeg-rockchip
- Wiki FFmpeg-Rockchip: https://github.com/nyanmisaka/ffmpeg-rockchip/wiki
- Controllo iniziale del sistema
Controllare l'architettura:
uname -m
Atteso:
aarch64
Controllare il kernel:
uname -a
Controllare la distribuzione:
cat /etc/os-release
- Controllo dei device Rockchip
Il supporto FFmpeg-Rockchip richiede che l'utente possa accedere ai device hardware Rockchip.
Il progetto indica, tra gli altri:
/dev/dri
/dev/dma_heap
/dev/rga
/dev/mpp_service
e, su alcune configurazioni/kernel:
/dev/iep
/dev/mpp-service
/dev/vpu_service
/dev/vpu-service
/dev/hevc_service
/dev/hevc-service
/dev/rkvdec
/dev/rkvenc
Controllare:
ls -l /dev/mpp_service
e:
ls -l /dev | grep -Ei 'mpp|rga|rkv|vpu|iep'
Controllare anche:
ls -l /dev/dri
e:
ls -l /dev/dma_heap
- Permessi utente
Aggiungere l'utente ai gruppi normalmente utilizzati per l'accesso ai device video:
sudo usermod -aG video "$USER"
Se sulla distribuzione sono presenti anche gruppi "render":
sudo usermod -aG render "$USER"
Controllare:
groups
Dopo la modifica è consigliato effettuare logout/login.
- Pacchetti necessari
Aggiornare il sistema:
sudo apt update
sudo apt upgrade -y
Installare gli strumenti di compilazione:
sudo apt install -y \
git \
build-essential \
cmake \
pkg-config \
yasm \
nasm \
libdrm-dev \
libdrm2 \
libnuma-dev \
libssl-dev \
zlib1g-dev
Per una build FFmpeg più completa possono essere necessari altri pacchetti a seconda dei codec/librerie che si desidera abilitare.
- Installazione Rockchip MPP
6.1 Directory sorgenti
Creare:
sudo mkdir -p /usr/local/src
sudo chown "$USER":"$USER" /usr/local/src
Entrare:
cd /usr/local/src
6.2 Clonare MPP
Repository ufficiale:
https://github.com/rockchip-linux/mpp
Clonare:
cd /usr/local/src
git clone https://github.com/rockchip-linux/mpp.git rockchip-mpp
Entrare nella directory:
cd /usr/local/src/rockchip-mpp
Controllare il commit:
git rev-parse HEAD
È consigliato salvare il commit utilizzato, così una futura reinstallazione può essere riprodotta.
MPP utilizza CMake e il progetto raccomanda una build out-of-source.
- Compilazione MPP
Creare la directory di build:
cd /usr/local/src/rockchip-mpp
mkdir -p build
cd build
Configurare:
cmake \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=ON \
-DBUILD_TEST=OFF \
-DCMAKE_INSTALL_PREFIX=/usr/local \
..
Compilare:
make -j"$(nproc)"
Installare:
sudo make install
- Aggiornare il linker
Aggiungere "/usr/local/lib" alla configurazione del linker:
echo '/usr/local/lib' | sudo tee /etc/ld.so.conf.d/local.conf
Aggiornare:
sudo ldconfig
Controllare:
ldconfig -p | grep -i mpp
Cercare anche direttamente:
find /usr/local -name 'librockchip_mpp.so*' -print
- Test della libreria MPP
Controllare il device:
ls -l /dev/mpp_service
Controllare la libreria:
ldconfig -p | grep -i rockchip
Se la build di MPP ha installato gli strumenti di test, possono essere disponibili utility come:
mpp_info_test mpp_buffer_test mpp_mem_test mpp_runtime_test mpp_platform_test
La documentazione ufficiale MPP descrive questi strumenti per verificare libreria e ambiente hardware.
Cercarli:
find /usr/local -type f -name 'mpp_*_test' -print
- Installazione FFmpeg-Rockchip
Per la configurazione utilizzata nei test viene utilizzato:
ffmpeg-rockchip
Repository:
https://github.com/nyanmisaka/ffmpeg-rockchip
Il progetto fornisce supporto hardware MPP/RGA direttamente nella CLI FFmpeg.
Entrare nella directory sorgenti:
cd /usr/local/src
Clonare:
git clone https://github.com/nyanmisaka/ffmpeg-rockchip.git
Entrare:
cd /usr/local/src/ffmpeg-rockchip
Controllare il commit:
git rev-parse HEAD
- Configurazione FFmpeg
Prima di compilare verificare che MPP sia visibile a "pkg-config".
pkg-config --modversion rockchip_mpp
Se non viene trovato, cercare il file:
find /usr/local -name 'rockchip_mpp.pc' -print
Impostare eventualmente:
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/usr/local/share/pkgconfig:$PKG_CONFIG_PATH
Riprovare:
pkg-config --modversion rockchip_mpp
11.1 Configure
Configurazione utilizzata:
./configure \
--prefix=/usr/local \
--enable-gpl \
--enable-version3 \
--enable-libdrm \
--enable-rkmpp \
--enable-rkrga \
--enable-shared \
--disable-static \
--extra-cflags="-I/usr/local/include" \
--extra-ldflags="-L/usr/local/lib"
"ffmpeg-rockchip" include il supporto MPP e RGA e documenta le pipeline hardware per decoder, encoder e filtri.
- Compilazione FFmpeg
Compilare:
make -j"$(nproc)"
Installare:
sudo make install
Aggiornare il linker:
sudo ldconfig
- Verificare il binario FFmpeg
Controllare:
which ffmpeg
Il binario che abbiamo utilizzato nei test è:
/usr/local/bin/ffmpeg
Controllare:
/usr/local/bin/ffmpeg -hide_banner -version
Controllare la configurazione:
/usr/local/bin/ffmpeg -hide_banner -buildconf
- Verificare i decoder RKMPP
Eseguire:
/usr/local/bin/ffmpeg \
-hide_banner \
-decoders | grep -i rkmpp
Tra quelli importanti per il nostro test deve esserci:
hevc_rkmpp
Il progetto FFmpeg-Rockchip documenta esplicitamente "hevc_rkmpp" come decoder HEVC Rockchip MPP.
Controllo diretto:
/usr/local/bin/ffmpeg \
-hide_banner \
-decoders | grep hevc_rkmpp
- Verificare gli encoder RKMPP
Eseguire:
/usr/local/bin/ffmpeg \
-hide_banner \
-encoders | grep -i rkmpp
Controllare direttamente H.264:
/usr/local/bin/ffmpeg \
-hide_banner \
-encoders | grep h264_rkmpp
Deve essere disponibile:
h264_rkmpp
- Verificare i filtri RGA
Se RGA è stato compilato:
/usr/local/bin/ffmpeg \
-hide_banner \
-filters | grep rkrga
Possibili filtri:
scale_rkrga vpp_rkrga overlay_rkrga
Il progetto documenta "scale_rkrga" per scaling/conversione formato e "vpp_rkrga" per operazioni come scaling, crop e transpose.
- Primo test: decoder HEVC
Prima di fare HLS conviene verificare il decoder.
Esempio:
/usr/local/bin/ffmpeg \
-hide_banner \
-loglevel verbose \
-c:v hevc_rkmpp \
-i input.mp4 \
-f null -
Nel log deve comparire una sequenza simile:
Created a RKMPP hardware device
e:
hevc_rkmpp
- Test HEVC → H.264
Testare contemporaneamente decoder e encoder hardware:
/usr/local/bin/ffmpeg \
-hide_banner \
-loglevel verbose \
-y \
-c:v hevc_rkmpp \
-i input.mp4 \
-map 0:v:0 \
-c:v h264_rkmpp \
-rc_mode CBR \
-b:v 5000k \
-maxrate 6000k \
-bufsize 12000k \
-r 30 \
-g 90 \
-keyint_min 90 \
output.mp4
Controllare:
/usr/local/bin/ffprobe \
-hide_banner \
output.mp4
- Test con il video Xiaomi 13T Pro
Il file utilizzato nei test:
VID_20260221_095917.mp4
Directory:
cd /home/nvme/dockerdata/prove/s120js
Il file presenta:
Video: HEVC 1920x1080 ~30 fps yuv420p
e:
Audio: AAC 48000 Hz stereo
Controllare il video:
/usr/local/bin/ffprobe \
-hide_banner \
-select_streams v:0 \
-show_entries stream=codec_name,width,height,r_frame_rate,pix_fmt \
-of default=noprint_wrappers=1 \
VID_20260221_095917.mp4
Controllare l'audio:
/usr/local/bin/ffprobe \
-hide_banner \
-select_streams a:0 \
-show_entries stream=codec_name,sample_rate,channels \
-of default=noprint_wrappers=1 \
VID_20260221_095917.mp4
- Rotazione del video Xiaomi
Il file contiene nei metadata:
Display Matrix: rotation of -90.00 degrees
Durante il test FFmpeg ha rilevato automaticamente la rotazione.
Nel log è comparso:
[transpose] w:1920 h:1080 dir:1 -> w:1080 h:1920
Quindi l'output corretto è:
1080x1920
Non è stato necessario aggiungere manualmente:
-vf transpose=...
Questo è importante.
Per il file Xiaomi testato la pipeline ha quindi fatto:
Input:
1920x1080 HEVC
rotation -90°
↓
hevc_rkmpp
↓
transpose automatico
↓
1080x1920
↓
h264_rkmpp
↓
HLS MPEG-TS
- Pipeline HLS funzionante
Questa è la pipeline che abbiamo verificato con successo.
Creare la directory:
rm -rf /tmp/hls_xiaomi
mkdir -p /tmp/hls_xiaomi
Eseguire:
/usr/local/bin/ffmpeg \
-hide_banner \
-loglevel verbose \
-y \
-probesize 5000000 \
-analyzeduration 10000000 \
-c:v hevc_rkmpp \
-i VID_20260221_095917.mp4 \
-map 0:v:0 \
-map 0:a:0? \
-c:v h264_rkmpp \
-rc_mode CBR \
-b:v 5000k \
-maxrate 6000k \
-bufsize 12000k \
-r 30 \
-g 90 \
-keyint_min 90 \
-c:a aac \
-b:a 160k \
-ac 2 \
-ar 48000 \
-f hls \
-hls_time 3 \
-hls_list_size 0 \
-hls_playlist_type vod \
-hls_segment_type mpegts \
-hls_segment_filename '/tmp/hls_xiaomi/segment_%05d.ts' \
/tmp/hls_xiaomi/master.m3u8
- Struttura corretta dell'output
Dopo l'esecuzione:
ls -lh /tmp/hls_xiaomi
Atteso:
master.m3u8
segment_00000.ts
segment_00001.ts
Nel test reale abbiamo ottenuto circa:
master.m3u8 183 bytes
segment_00000.ts ~1.9 MB
segment_00001.ts ~1.5 MB
- Playlist risultante
Controllare:
cat /tmp/hls_xiaomi/master.m3u8
Nel test è risultata:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:3.000000,
segment_00000.ts
#EXTINF:2.466667,
segment_00001.ts
#EXT-X-ENDLIST
La durata totale è circa:
5.47 secondi
- Verifica HLS con ffprobe
Eseguire:
/usr/local/bin/ffprobe \
-hide_banner \
/tmp/hls_xiaomi/master.m3u8
Il risultato del test ha mostrato:
Video: h264
1080x1920
30 fps
e:
Audio: aac
48000 Hz
stereo
Quindi:
HEVC input
↓
hevc_rkmpp
↓
h264_rkmpp
↓
HLS MPEG-TS
ha funzionato correttamente.
- Perché usare "-hls_segment_filename"
Questa opzione è importante:
-hls_segment_filename '/tmp/hls_xiaomi/segment_%05d.ts'
La playlist deve essere:
/tmp/hls_xiaomi/master.m3u8
e i segmenti:
/tmp/hls_xiaomi/segment_00000.ts
/tmp/hls_xiaomi/segment_00001.ts
La struttura corretta è:
/tmp/hls_xiaomi/
├── master.m3u8
├── segment_00000.ts
└── segment_00001.ts
Non bisogna concatenare accidentalmente il pattern dei segmenti al nome della playlist.
- Configurazione Node.js utilizzata dall'applicazione
La funzione può essere strutturata così:
function buildFfmpegArgs(inputPath, jobDir, useRkmpp) {
const master = path.join(jobDir, 'master.m3u8');
const segPattern = path.join(jobDir, 'segment_%05d.ts');
if (useRkmpp) {
return [
'-hide_banner',
'-loglevel',
'verbose',
'-y',
// Input probing
'-probesize',
'5000000',
'-analyzeduration',
'10000000',
// Rockchip HEVC hardware decoder
'-c:v',
'hevc_rkmpp',
'-i',
inputPath,
// Streams
'-map',
'0:v:0',
'-map',
'0:a:0?',
// Rockchip H.264 hardware encoder
'-c:v',
'h264_rkmpp',
'-rc_mode',
'CBR',
'-b:v',
'5000k',
'-maxrate',
'6000k',
'-bufsize',
'12000k',
// Output framerate
'-r',
'30',
// 90 frames = 3 seconds at 30 fps
'-g',
'90',
'-keyint_min',
'90',
// Audio
'-c:a',
'aac',
'-b:a',
'160k',
'-ac',
'2',
'-ar',
'48000',
// HLS
'-f',
'hls',
'-hls_time',
'3',
'-hls_list_size',
'0',
'-hls_playlist_type',
'vod',
'-hls_segment_type',
'mpegts',
'-hls_segment_filename',
segPattern,
master
];
}
}
Questa è la configurazione da mantenere come riferimento per la pipeline che abbiamo testato.
- Significato delle opzioni video
Decoder
-c:v hevc_rkmpp
Utilizza il decoder hardware Rockchip MPP per HEVC.
Encoder
-c:v h264_rkmpp
Utilizza l'encoder hardware Rockchip MPP per H.264.
Il progetto FFmpeg-Rockchip espone i codec MPP direttamente alla CLI FFmpeg.
CBR
-rc_mode CBR
Target:
-b:v 5000k
Massimo:
-maxrate 6000k
Buffer:
-bufsize 12000k
Durante il test il log MPP ha confermato:
mode cbr
bps [4687500:5000000:5312500]
- Framerate
-r 30
L'output viene forzato a:
30 fps
- GOP
-g 90
-keyint_min 90
A 30 fps:
90 / 30 = 3 secondi
Quindi il GOP è coerente con:
-hls_time 3
Questo è particolarmente utile per una segmentazione HLS regolare.
- Audio
Configurazione:
-c:a aac
-b:a 160k
-ac 2
-ar 48000
Output:
AAC
160 kbps
stereo
48000 Hz
Il punto interrogativo:
-map 0:a:0?
rende l'audio opzionale.
Se il file non contiene una traccia audio, FFmpeg continua comunque con il video.
- HLS
Configurazione:
-f hls
-hls_time 3
-hls_list_size 0
-hls_playlist_type vod
-hls_segment_type mpegts
Significato:
-hls_time 3
segmenti di circa 3 secondi.
-hls_list_size 0
mantiene tutti i segmenti nella playlist.
-hls_playlist_type vod
crea una playlist VOD.
-hls_segment_type mpegts
forza segmenti MPEG-TS.
- Test completo automatico
Dopo una reinstallazione è possibile eseguire questo controllo:
cd /home/nvme/dockerdata/prove/s120js
rm -rf /tmp/hls_test
mkdir -p /tmp/hls_test
/usr/local/bin/ffmpeg \
-hide_banner \
-loglevel verbose \
-y \
-probesize 5000000 \
-analyzeduration 10000000 \
-c:v hevc_rkmpp \
-i VID_20260221_095917.mp4 \
-map 0:v:0 \
-map 0:a:0? \
-c:v h264_rkmpp \
-rc_mode CBR \
-b:v 5000k \
-maxrate 6000k \
-bufsize 12000k \
-r 30 \
-g 90 \
-keyint_min 90 \
-c:a aac \
-b:a 160k \
-ac 2 \
-ar 48000 \
-f hls \
-hls_time 3 \
-hls_list_size 0 \
-hls_playlist_type vod \
-hls_segment_type mpegts \
-hls_segment_filename '/tmp/hls_test/segment_%05d.ts' \
/tmp/hls_test/master.m3u8
Controllare:
echo "=== FILE ==="
ls -lh /tmp/hls_test
echo
echo "=== PLAYLIST ==="
cat /tmp/hls_test/master.m3u8
echo
echo "=== SEGMENTI ==="
ls -lh /tmp/hls_test/segment_*.ts
echo
echo "=== PROBE ==="
/usr/local/bin/ffprobe \
-hide_banner \
/tmp/hls_test/master.m3u8
- Risultato considerato corretto
Il test è da considerarsi riuscito se:
ffmpeg exit code = 0
e vengono creati:
master.m3u8
segment_00000.ts
segment_00001.ts
e "ffprobe" mostra:
Video: h264
con:
1080x1920
30 fps
e:
Audio: aac
48000 Hz
stereo
Nel test reale il video è risultato senza artefatti.
- Warning MPP osservati durante i test
Durante la transcodifica sono comparsi alcuni messaggi MPP come:
mpp_platform: client 4 driver is not ready!
mpp_platform: client 12 driver is not ready!
e:
mpp_buffer: check buffer found NULL pointer from get_packet_async
oltre a:
mpp_mem_pool: mpp_mem_pool_put_f invalid mem pool ptr
Questi messaggi non hanno impedito il funzionamento della pipeline testata.
Nel test abbiamo infatti ottenuto:
Exiting with exit code 0
e:
164 frames decoded
0 decode errors
seguiti dalla corretta generazione dei segmenti HLS.
Quindi non bisogna considerare automaticamente questi warning come un fallimento, ma bisogna sempre verificare:
- exit code di FFmpeg
- presenza dei segmenti
- validità della playlist
- output di "ffprobe"
- qualità visiva del video
- Errori da evitare
35.1 Usare un path HLS errato
Non fare:
/tmp/hls_test/master.m3u8mp/hls_test/segment_...
Usare invece:
-hls_segment_filename '/tmp/hls_test/segment_%05d.ts'
e:
/tmp/hls_test/master.m3u8
35.2 Aggiungere inutilmente "-hwaccel rkmpp"
La configurazione che abbiamo testato utilizza esplicitamente:
-c:v hevc_rkmpp
per il decoder.
Quindi la configurazione applicativa non deve essere modificata aggiungendo:
-hwaccel rkmpp
solo perché si sta usando MPP.
Il progetto "ffmpeg-rockchip" documenta anche pipeline basate su "-hwaccel rkmpp", ma quella è una modalità diversa dalla pipeline esplicitamente testata qui.
35.3 Aggiungere manualmente "transpose"
Nel test Xiaomi FFmpeg ha già rilevato:
Display Matrix: rotation of -90.00 degrees
e ha applicato automaticamente:
1920x1080
→
1080x1920
Quindi non aggiungere:
-vf transpose=...
senza prima verificare il comportamento del file specifico.
- Pipeline finale
La configurazione verificata può essere riassunta così:
MP4 Xiaomi
│
│
▼
HEVC / H.265
1920x1080
~30 fps
│
▼
hevc_rkmpp
│
│
RK3588 hardware
│
▼
rotazione metadata
│
▼
1080x1920
│
▼
h264_rkmpp
│
CBR 5000 kbps
│
▼
H.264
│
┌──────────┴──────────┐
│ │
▼ ▼
Video AAC
H.264 160 kbps
│ │
└──────────┬──────────┘
│
▼
HLS
│
▼
MPEG-TS segments
│
┌──────────┴──────────┐
▼ ▼
segment_00000.ts segment_00001.ts
│ │
└──────────┬──────────┘
▼
master.m3u8
- Checklist finale
Sistema
- [ ] "uname -m" → "aarch64"
- [ ] RK3588
- [ ] "/dev/mpp_service" presente
- [ ] "/dev/dri" presente
- [ ] "/dev/dma_heap" presente
- [ ] permessi utente corretti
MPP
- [ ] repository MPP compilato
- [ ] "librockchip_mpp.so" installata
- [ ] "ldconfig" aggiornato
- [ ] eventuali test MPP funzionanti
FFmpeg
- [ ] "/usr/local/bin/ffmpeg"
- [ ] "hevc_rkmpp" disponibile
- [ ] "h264_rkmpp" disponibile
- [ ] "rkrga" disponibile, se necessario
Transcoding
- [ ] HEVC hardware decode
- [ ] H.264 hardware encode
- [ ] CBR 5000k
- [ ] 30 fps
- [ ] GOP 90
- [ ] audio AAC 160k
- [ ] 48 kHz stereo
HLS
- [ ] "master.m3u8"
- [ ] "segment_00000.ts"
- [ ] "segment_00001.ts"
- [ ] playlist VOD
- [ ] segmenti MPEG-TS
- [ ] "ffprobe" legge correttamente HLS
- [ ] nessun artefatto video
- Versioni da salvare per riproducibilità
Quando la configurazione è funzionante, salvare le versioni:
echo "=== MPP ==="
cd /usr/local/src/rockchip-mpp
git rev-parse HEAD
echo
echo "=== FFmpeg Rockchip ==="
cd /usr/local/src/ffmpeg-rockchip
git rev-parse HEAD
echo
echo "=== FFmpeg ==="
/usr/local/bin/ffmpeg -hide_banner -version | head -n 3
echo
echo "=== Kernel ==="
uname -a
È consigliato conservare questo output insieme alla guida.
In caso di futura reinstallazione, sarà così possibile capire esattamente quale combinazione di:
kernel MPP FFmpeg-Rockchip
era stata utilizzata nella configurazione funzionante.
- Riferimenti ufficiali
Rockchip MPP
Repository ufficiale:
https://github.com/rockchip-linux/mpp
Documentazione MPP:
https://github.com/rockchip-linux/mpp/blob/develop/doc/Rockchip_Developer_Guide_MPP_EN.md
MPP supporta RK3588 e fornisce API e librerie per encoding, decoding e processing hardware Rockchip.
FFmpeg-Rockchip
Repository:
https://github.com/nyanmisaka/ffmpeg-rockchip
Wiki:
https://github.com/nyanmisaka/ffmpeg-rockchip/wiki
Transcoding:
https://github.com/nyanmisaka/ffmpeg-rockchip/wiki/Video-Transcode
Il progetto documenta pipeline MPP decode + MPP encode e supporto ai decoder/encoder Rockchip.
- Configurazione di riferimento
La configurazione da considerare come baseline funzionante è:
SoC:
RK3588
Decoder:
hevc_rkmpp
Encoder:
h264_rkmpp
Video:
CBR
5000 kbps
maxrate 6000 kbps
bufsize 12000 kbps
30 fps
GOP 90
Audio:
AAC
160 kbps
48 kHz
stereo
HLS:
3 secondi
VOD
playlist completa
MPEG-TS
segment_%05d.ts
Questa è la configurazione utilizzata nei test che hanno prodotto HLS valido e video senza artefatti.