GStreamer 多媒体开发
1. 概述
1.1 功能简介
GStreamer 是 Linux 平台上最主流的开源多媒体框架,采用基于插件的流水线(Pipeline)架构,支持音视频播放、录制、转码、流媒体传输等完整多媒体处理流程。在 RK3576 平台上,GStreamer 通过 Rockchip MPP(Media Process Platform)插件实现硬件加速编解码,结合 V4L2 摄像头采集、DRM/KMS 显示输出、ALSA 音频处理等模块,构建完整的硬件加速多媒体处理链路。RK3576 的 8 核 4×Cortex-A72 + 4×Cortex-A53 处理器配合 Mali-G52 MC3 GPU 和专用 RGA 2D 加速器,能够实现 4K 视频解码、4K 视频编码等高性能多媒体应用。
1.2 应用场景
- 视频播放:本地/网络视频文件播放(H.264/H.265/VP9 硬解码)
- 视频监控:多路摄像头实时采集、预览与录像
- 视频编码录制:摄像头采集后硬件编码为 H.264/H.265 文件
- 流媒体服务:RTSP/RTMP/HLS 推流与拉流
- 视频会议:多路音视频采集、编解码、显示
- 数字标牌:多屏异显播放、视频墙
- 视频转码:格式转换、分辨率缩放、码率调整
1.3 工作原理
GStreamer 采用流水线(Pipeline)模型,多个处理单元(Element)通过数据流连接,形成完整的处理链路:
┌─────────────────────────────────────────────────────────────┐
│ GStreamer Pipeline │
│ │
│ Source ──► Decode/Filter ──► Processing ──► Sink │
│ │
│ Example: 文件播放流水线 │
│ filesrc ! decodebin ! videoconvert ! video sink │
│ audioconvert ! audio sink │
└─────────────────────────────────────────────────────────────┘
RK3576 硬件加速架构:
┌──────────────────────────────────────────────────────┐
│ GStreamer 应用层 │
│ filesrc / v4l2src / alsasrc / rtspsrc │
├──────────────────────────────────────────────────────┤
│ GStreamer 插件层 │
│ rockchipmpp (MPP 硬件编解码) │
│ v4l2 (V4L2 摄像头/视频设备) │
│ rga (RGA 2D 图形加速) │
│ drm/drmkms (DRM/KMS 显示输出) │
│ alsa (ALSA 音频) │
├──────────────────────────────────────────────────────┤
│ 硬件抽象层 (HAL) │
│ MPP (Media Process Platform) │
│ DRM/KMS (显示管理) │
│ V4L2 (视频设备) │
│ ALSA (音频设备) │
├──────────────────────────────────────────────────────┤
│ RK3576 硬件 │
│ VPU (视频编解码) / RGA (2D 加速) │
│ VOP (显示控制器) / HDMI TX │
│ I2S/TDM (音频接口) │
│ MIPI-CSI (摄像头接口) │
└──────────────────────────────────────────────────────┘RK3576 关键多媒体硬件地址(以下为 RK 平台通用结构示例,具体数值以实际发布的 RK3576 SDK 设备树为准):
| 模块 | 设备树节点 | 寄存器基地址 | 功能 |
|---|---|---|---|
| 显示控制器 | vop@... | 待确认 | 视频合成与显示输出 |
| HDMI 输出 | hdmi@... | 待确认 | HDMI 输出 |
| RGA 2D 加速 | rga@... | 待确认 | 2D 图形加速 |
| MPP VPU | rkvdec2@... | 待确认 | 视频解码器 |
| MPP VPU | rkvenc@... | 待确认 | 视频编码器 |
各多媒体控制器的寄存器基地址与设备树节点名称以实际发布的 RK3576 SDK 设备树为准(待板上确认)。
2. 硬件准备
2.1 硬件清单
| 组件 | 型号/规格 | 数量 | 备注 |
|---|---|---|---|
| 主控板 | C-3576BQ 核心板 + M4-R2 底板 | 1 | 运行 Debian 系统 |
| 调试串口线 | USB 转 TTL(3.3V) | 1 | 波特率 1500000 |
| HDMI 显示器 | 支持 1080p 或更高分辨率 | 1 | 用于视频输出验证 |
| 摄像头模块(可选) | MIPI-CSI 摄像头(IMX415/SC5235 等) | 1 | 用于摄像头采集验证 |
| 音频模块(可选) | 3.5mm 音频线或 HDMI 音频 | 1 | 用于音频输出验证 |
| 网线 | 标准 RJ45 | 1 | 用于网络和 SSH 连接 |
| USB 存储(可选) | U 盘或移动硬盘 | 1 | 存放测试视频文件 |
2.2 硬件连接
M4-R2 底板连接:
├── HDMI 输出 ──► HDMI 显示器
├── MIPI-CSI 接口 ──► 摄像头模块(可选)
├── 3.5mm 音频口 ──► 音频输出设备(可选)
├── RJ45 网口 ──► 网络交换机/路由器
├── USB 调试口 ──► PC(串口调试)
└── DC 5V 电源 ──► 电源适配器2.3 硬件确认
# 确认系统架构
uname -m
# 输出:aarch64
# 确认 GStreamer 版本
gst-inspect-1.0 --version
# 输出:GStreamer 1.18.x
# 确认 Rockchip MPP 插件是否可用
gst-inspect-1.0 | grep rockchip
# 输出:rockchipmpp: mpph264dec
# rockchipmpp: mpph265dec
# rockchipmpp: mppvp9dec
# ...
# 确认 V4L2 设备
ls /dev/video*
# 输出:/dev/video0 /dev/video1 ...
# 确认 DRM 显示设备
ls /dev/dri/
# 输出:card0 renderD1283. 软件准备
3.1 内核配置
GStreamer 多媒体开发需要以下内核模块支持:
# Rockchip MPP 硬件编解码
CONFIG_ROCKCHIP_MPP=y
CONFIG_ROCKCHIP_MPP_SERVICE=y
CONFIG_ROCKCHIP_MPP_IEP2=y
# V4L2 视频设备
CONFIG_V4L2_MEM2KM=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_CAMERA_SUPPORT=y
# DRM/KMS 显示
CONFIG_DRM_ROCKCHIP=y
CONFIG_ROCKCHIP_VOP2=y
CONFIG_ROCKCHIP_DW_HDMI=y
# ALSA 音频
CONFIG_SND_SOC_ROCKCHIP=y
CONFIG_SND_SOC_RK817=y3.2 设备树配置
摄像头 MIPI-CSI 接口设备树配置(以下为 RK 平台通用结构示例,具体数值以实际发布的 RK3576 SDK 设备树为准):
/* MIPI-CSI 摄像头接口(以 IMX415 为例) */
&csi2_dphy0 {
status = "okay";
ports {
port@0 {
reg = <0>;
csi2_dphy0_in: endpoint {
remote-endpoint = <&imx415_out>;
data-lanes = <1 2 3 4>;
};
};
};
};
&i2c3 {
status = "okay";
imx415: camera@1a {
compatible = "sony,imx415";
reg = <0x1a>;
clocks = <&cru CLK_MIPI_CAMARAOUT_M3>;
clock-frequency = <24000000>;
reset-gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_LOW>;
port {
imx415_out: endpoint {
remote-endpoint = <&csi2_dphy0_in>;
data-lanes = <1 2 3 4>;
clock-lanes = <0>;
};
};
};
};3.3 GStreamer 插件安装
# Debian 系统 GStreamer 基础包
sudo apt-get update
sudo apt-get install -y \
gstreamer1.0-tools \
gstreamer1.0-plugins-base \
gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad \
gstreamer1.0-plugins-ugly \
gstreamer1.0-libav
# Rockchip MPP GStreamer 插件(SDK 自带)
# 插件路径:/usr/lib/gstreamer-1.0/
ls /usr/lib/gstreamer-1.0/libgstrockchipmpp.so
# ALSA 音频插件
sudo apt-get install -y \
gstreamer1.0-alsa \
libasound2-dev
# Python GStreamer 绑定
sudo apt-get install -y \
python3-gi \
gir1.2-gstreamer-1.0 \
gir1.2-gst-plugins-base-1.0
# 开发头文件(编译自定义 GStreamer 应用时需要)
sudo apt-get install -y \
libgstreamer1.0-dev \
libgstreamer-plugins-base1.0-dev4. 操作步骤
4.1 GStreamer 命令行基础
# 查看所有可用插件
gst-inspect-1.0
# 查看特定插件详情
gst-inspect-1.0 rockchipmpp
# 查看元素(Element)详情
gst-inspect-1.0 mpph264dec
# 播放本地视频文件(自动选择最佳输出)
gst-launch-1.0 filesrc location=/root/test.mp4 ! decodebin ! autovideosink
# 播放带音频的视频文件
gst-launch-1.0 filesrc location=/root/test.mp4 ! decodebin name=demux \
demux. ! queue ! videoconvert ! autovideosink \
demux. ! queue ! audioconvert ! autoaudiosink4.2 视频解码流水线(H.264/H.265/VP9)
H.264 硬件解码
# 方法一:使用 decodebin 自动选择 MPP 解码器
gst-launch-1.0 filesrc location=/root/test_h264.mp4 ! decodebin ! \
videoconvert ! videoscale ! video/x-raw,width=1920,height=1080 ! \
autovideosink
# 方法二:显式指定 MPP H.264 解码器
gst-launch-1.0 filesrc location=/root/test.h264 ! h264parse ! \
mpph264dec ! videoconvert ! autovideosink
# 方法三:MP4 文件解码
gst-launch-1.0 filesrc location=/root/test.mp4 ! qtdemux ! h264parse ! \
mpph264dec ! videoconvert ! autovideosinkH.265 硬件解码
# H.265/HEVC 硬件解码
gst-launch-1.0 filesrc location=/root/test.h265 ! h265parse ! \
mpph265dec ! videoconvert ! autovideosink
# MP4 容器中的 H.265 解码
gst-launch-1.0 filesrc location=/root/test.mp4 ! qtdemux ! h265parse ! \
mpph265dec ! videoconvert ! autovideosinkVP9 硬件解码
# VP9 硬件解码
gst-launch-1.0 filesrc location=/root/test.vp9 ! vp9parse ! \
mppvp9dec ! videoconvert ! autovideosink
# WebM 容器中的 VP9 解码
gst-launch-1.0 filesrc location=/root/test.webm ! matroskademux ! \
vp9parse ! mppvp9dec ! videoconvert ! autovideosink4K 视频解码(零拷贝模式)
# 4K H.265 解码,使用 DMA-BUF 零拷贝
gst-launch-1.0 filesrc location=/root/test_4k.mp4 ! qtdemux ! h265parse ! \
mpph265dec ! videoconvert ! videoscale ! \
video/x-raw,width=3840,height=2160 ! autovideosink
# 4K H.265 解码(RK3576 支持 4K@30fps 解码)
gst-launch-1.0 filesrc location=/root/test_4k.mp4 ! qtdemux ! h265parse ! \
mpph265dec ! videoconvert ! autovideosink4.3 视频编码流水线
H.264 硬件编码
# 从文件编码 H.264
gst-launch-1.0 filesrc location=/root/raw_video.yuv ! \
video/x-raw,format=I420,width=1920,height=1080,framerate=30/1 ! \
mpph264enc ! h264parse ! mp4mux ! filesink location=/root/output.mp4
# 摄像头采集编码(见 4.4 节组合流水线)H.265 硬件编码
# H.265/HEVC 硬件编码
gst-launch-1.0 filesrc location=/root/raw_video.yuv ! \
video/x-raw,format=I420,width=3840,height=2160,framerate=30/1 ! \
mpph265enc ! h265parse ! mp4mux ! filesink location=/root/output_4k.mp44.4 摄像头采集流水线(V4L2)
摄像头预览
# V4L2 摄像头实时预览
gst-launch-1.0 v4l2src device=/dev/video0 ! \
video/x-raw,format=YUY2,width=1920,height=1080,framerate=30/1 ! \
videoconvert ! autovideosink
# MIPI-CSI 摄像头预览(YUY2 格式)
gst-launch-1.0 v4l2src device=/dev/video0 ! \
video/x-raw,format=YUY2,width=1920,height=1080,framerate=30/1 ! \
videoconvert ! videoscale ! video/x-raw,width=1280,height=720 ! \
autovideosink摄像头采集并编码保存
# 摄像头采集 + H.264 硬件编码 + MP4 封装
gst-launch-1.0 v4l2src device=/dev/video0 num-buffers=300 ! \
video/x-raw,format=YUY2,width=1920,height=1080,framerate=30/1 ! \
videoconvert ! mpph264enc ! h264parse ! mp4mux ! \
filesink location=/root/capture.mp4
# 摄像头采集 + H.265 硬件编码
gst-launch-1.0 v4l2src device=/dev/video0 num-buffers=300 ! \
video/x-raw,format=YUY2,width=1920,height=1080,framerate=30/1 ! \
videoconvert ! mpph265enc ! h265parse ! mp4mux ! \
filesink location=/root/capture_h265.mp4多路摄像头采集
# 两路摄像头同时预览(RK3576 支持多路 V4L2 设备)
gst-launch-1.0 \
v4l2src device=/dev/video0 ! video/x-raw,width=1920,height=1080 ! \
videoconvert ! autovideosink name=sink1 \
v4l2src device=/dev/video2 ! video/x-raw,width=1280,height=720 ! \
videoconvert ! autovideosink name=sink24.5 音频流水线(ALSA)
# ALSA 音频播放(WAV 文件)
gst-launch-1.0 filesrc location=/root/test.wav ! wavparse ! \
audioconvert ! autoaudiosink
# ALSA 音频录制(WAV 文件)
gst-launch-1.0 alsasrc device=hw:0,0 ! \
audio/x-raw,format=S16LE,rate=44100,channels=2 ! \
wavenc ! filesink location=/root/record.wav
# ALSA 音频播放 MP3
gst-launch-1.0 filesrc location=/root/test.mp3 ! mpegaudioparse ! \
mpg123audiodec ! audioconvert ! autoaudiosink
# 音频重采样
gst-launch-1.0 filesrc location=/root/test.wav ! wavparse ! \
audioconvert ! audio/x-raw,rate=48000 ! autoaudiosink4.6 显示输出(DRM/KMS Sink)
# DRM/KMS 直接输出到显示器(零拷贝显示)
gst-launch-1.0 filesrc location=/root/test.mp4 ! decodebin ! \
videoconvert ! video/x-raw,format=NV12 ! \
kmssink connector-id=0
# 指定显示模式和分辨率
gst-launch-1.0 filesrc location=/root/test.mp4 ! decodebin ! \
videoconvert ! video/x-raw,format=NV12 ! \
kmssink connector-id=0 driver-name=rockchip
# DRM 直接输出(通过 drmvideosink)
gst-launch-1.0 filesrc location=/root/test.mp4 ! decodebin ! \
videoconvert ! drmvideosink
# DRM/KMS 视频叠加层(Overlay)
# RK3576 VOP 支持多图层,可实现画中画
gst-launch-1.0 \
filesrc location=/root/bg.mp4 ! decodebin ! videoconvert ! \
kmssink connector-id=0 enable-overlay=true name=bg \
filesrc location=/root/pip.mp4 ! decodebin ! videoconvert ! \
kmssink connector-id=0 enable-overlay=true name=pip4.7 完整多媒体应用流水线
视频播放器(带音频同步)
# 完整的视频播放流水线
gst-launch-1.0 \
filesrc location=/root/movie.mp4 ! qtdemux name=demux \
demux. ! queue ! h264parse ! mpph264dec ! videoconvert ! \
videoscale ! video/x-raw,width=1920,height=1080 ! autovideosink \
demux. ! queue ! aacparse ! faad ! audioconvert ! \
audio/x-raw,rate=48000,channels=2 ! autoaudiosinkRTSP 流媒体接收
# 接收 RTSP 流并播放
gst-launch-1.0 rtspsrc location=rtsp://192.168.1.100/stream latency=300 ! \
rtph264depay ! h264parse ! mpph264dec ! videoconvert ! autovideosink
# 接收 RTSP 流并录制
gst-launch-1.0 rtspsrc location=rtsp://192.168.1.100/stream latency=300 ! \
rtph264depay ! h264parse ! mp4mux ! filesink location=/root/record.mp45. 代码详解
5.1 GStreamer Pipeline 架构
GStreamer 中的核心概念:
Element(元素):
├── Source Element(源元素):产生数据
│ filesrc, v4l2src, alsasrc, rtspsrc
├── Filter Element(过滤元素):处理数据
│ videoconvert, videoscale, audioconvert
├── Decoder Element(解码元素):硬件解码
│ mpph264dec, mpph265dec, mppvp9dec
├── Encoder Element(编码元素):硬件编码
│ mpph264enc, mpph265enc
└── Sink Element(输出元素):消费数据
autovideosink, autoaudiosink, kmssink, filesink
Pad(端口):
├── Src Pad(源端口):数据输出
└── Sink Pad(接收端口):数据输入
Caps(能力协商):
定义数据格式、分辨率、帧率等参数
video/x-raw,format=NV12,width=1920,height=10805.2 Rockchip MPP 插件工作原理
MPP GStreamer 插件数据流:
编码数据 (H.264/H.265/VP9 码流)
│
▼
mpph264dec / mpph265dec / mppvp9dec
│
├── 1. 解析码流头部,获取分辨率/帧率信息
├── 2. 调用 MPP API 分配解码缓冲区
│ mpp_create() → mpp_init() → mpp_open()
├── 3. 将码流数据送入 VPU 解码
│ mpp_packet_init() → mpp_dec_send()
├── 4. VPU 硬件解码完成
│ mpp_frame_get_info_change() → mpp_dec_get_frame()
├── 5. 输出 NV12/YUV420 帧数据
│ mpp_frame_get_buffer() → DMA-BUF / 内存映射
└── 6. 通过 GStreamer buffer 传递给下游元素
RK3576 VPU 硬件能力:
├── 解码:H.264 4K@30fps, H.265 4K@30fps, VP9 4K@30fps
├── 编码:H.264 4K@30fps, H.265 4K@30fps
└── 并发:支持多路同时编解码(受 VPU 通道数限制)RK3576 VPU 具体编解码能力以实际 SDK 与芯片手册为准(待板上确认)。
5.3 RGA 2D 加速
# 使用 RGA 进行图像缩放和格式转换
gst-launch-1.0 filesrc location=/root/test.mp4 ! decodebin ! \
videoconvert ! rga video/x-raw,format=NV12,width=1280,height=720 ! \
autovideosink
# RGA 支持的操作:
# ├── 图像缩放(Resize)
# ├── 色彩空间转换(Color Space Conversion)
# ├── 图像旋转(Rotation: 0/90/180/270 度)
# ├── 图像裁剪(Crop)
# └── Alpha 混合(Blending)5.4 DMA-BUF 零拷贝机制
传统数据流(多次内存拷贝):
VPU 解码 → 内存拷贝 → GStreamer Buffer → 内存拷贝 → DRM 显示
↑ ↑
└──── 至少 2 次内存拷贝 ────────────────────────────────┘
DMA-BUF 零拷贝(RK3576 优化路径):
VPU 解码 → DMA-BUF(共享内存)→ DRM 显示
↑ ↑
└──── 零拷贝,直接共享 buffer ──────┘
零拷贝实现条件:
1. MPP 解码输出使用 DMA-BUF allocator
2. DRM/KMS sink 接受 DMA-BUF import
3. 内核 IOMMU 支持 DMA-BUF 共享
4. GStreamer buffer 使用 GstDmaBufAllocator5.5 Python GStreamer 绑定
#!/usr/bin/env python3
"""RK3576 GStreamer Python 示例 — 视频播放器"""
import gi
gi.require_version('Gst', '1.0')
gi.require_version('GstVideo', '1.0')
from gi.repository import Gst, GstVideo, GLib
# 初始化 GStreamer
Gst.init(None)
def on_message(bus, message, loop):
"""处理 GStreamer 消息"""
mtype = message.type
if mtype == Gst.MessageType.EOS:
print("播放结束")
loop.quit()
elif mtype == Gst.MessageType.ERROR:
err, debug = message.parse_error()
print(f"错误: {err.message}")
if debug:
print(f"调试: {debug}")
loop.quit()
elif mtype == Gst.MessageType.STATE_CHANGED:
if message.src == pipeline:
old, new, pending = message.parse_state_changed()
print(f"状态变更: {old.value_nick} -> {new.value_nick}")
return True
def play_video(file_path):
"""播放视频文件"""
global pipeline
# 构建流水线(使用 MPP H.264 解码器)
pipeline_str = (
f'filesrc location={file_path} ! qtdemux name=demux '
f'demux. ! queue ! h264parse ! mpph264dec ! videoconvert ! '
f'autovideosink '
f'demux. ! queue ! audioconvert ! autoaudiosink'
)
print(f"流水线: {pipeline_str}")
pipeline = Gst.parse_launch(pipeline_str)
# 获取消息总线
bus = pipeline.get_bus()
bus.add_signal_watch()
# 创建主循环
loop = GLib.MainLoop()
# 连接消息处理
bus.connect("message", on_message, loop)
# 启动播放
pipeline.set_state(Gst.State.PLAYING)
print("开始播放...")
try:
loop.run()
except KeyboardInterrupt:
print("用户中断")
# 停止流水线
pipeline.set_state(Gst.State.NULL)
if __name__ == "__main__":
import sys
if len(sys.argv) < 2:
print(f"用法: {sys.argv[0]} <视频文件路径>")
sys.exit(1)
play_video(sys.argv[1])#!/usr/bin/env python3
"""RK3576 GStreamer Python 示例 — 摄像头采集"""
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GLib
Gst.init(None)
def camera_capture():
"""摄像头采集并保存为 MP4 文件"""
# 摄像头采集 + H.264 硬件编码
pipeline_str = (
'v4l2src device=/dev/video0 ! '
'video/x-raw,format=YUY2,width=1920,height=1080,framerate=30/1 ! '
'videoconvert ! mpph264enc ! h264parse ! mp4mux ! '
'filesink location=/root/capture.mp4'
)
pipeline = Gst.parse_launch(pipeline_str)
bus = pipeline.get_bus()
bus.add_signal_watch()
loop = GLib.MainLoop()
def on_message(bus, message):
mtype = message.type
if mtype == Gst.MessageType.EOS:
print("录制完成")
loop.quit()
elif mtype == Gst.MessageType.ERROR:
err, debug = message.parse_error()
print(f"错误: {err.message}")
loop.quit()
bus.connect("message", on_message)
pipeline.set_state(Gst.State.PLAYING)
print("开始录制...按 Ctrl+C 停止")
try:
loop.run()
except KeyboardInterrupt:
print("停止录制...")
pipeline.send_event(Gst.Event.new_eos())
bus.connec.loop.run()
pipeline.set_state(Gst.State.NULL)
if __name__ == "__main__":
camera_capture()#!/usr/bin/env python3
"""RK3576 GStreamer Python 示例 — 带 RGA 加速的视频处理"""
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GLib
Gst.init(None)
def process_video_with_rga(input_path, output_path):
"""使用 RGA 硬件加速进行视频缩放和格式转换"""
# 读取 → 解码 → RGA 缩放 → 编码 → 输出
pipeline_str = (
f'filesrc location={input_path} ! qtdemux ! h264parse ! '
f'mpph264dec ! videoconvert ! '
f'video/x-raw,format=NV12,width=1280,height=720 ! '
f'mpph264enc ! h264parse ! mp4mux ! '
f'filesink location={output_path}'
)
pipeline = Gst.parse_launch(pipeline_str)
bus = pipeline.get_bus()
bus.add_signal_watch()
loop = GLib.MainLoop()
def on_message(bus, message):
if message.type == Gst.MessageType.EOS:
print("处理完成")
loop.quit()
elif message.type == Gst.MessageType.ERROR:
err, _ = message.parse_error()
print(f"错误: {err.message}")
loop.quit()
elif message.type == Gst.MessageType.PROGRESS:
_, percent = message.parse_progress()
print(f"进度: {percent}%", end='\r')
bus.connect("message", on_message)
pipeline.set_state(Gst.State.PLAYING)
try:
loop.run()
except KeyboardInterrupt:
pipeline.send_event(Gst.Event.new_eos())
loop.run()
pipeline.set_state(Gst.State.NULL)
if __name__ == "__main__":
process_video_with_rga("/root/input_1080p.mp4", "/root/output_720p.mp4")5.6 内核设备节点与 GStreamer 对应关系
RK3576 多媒体设备节点映射(具体节点以实际 SDK 为准):
/dev/video0, /dev/video1 ──► v4l2src element
│
└── MIPI-CSI 摄像头接口
├── /dev/media0 (media controller)
└── /dev/v4l-subdev0 (sub-device)
/dev/dri/card0 ──► kmssink element
│
├── VOP (显示控制器)
│ ├── CRTC 0: HDMI 输出
│ └── CRTC 1: MIPI DSI 输出
└── HDMI TX
/dev/snd/ ──► alsasrc / autoaudiosink
├── pcmC0D0p (playback)
├── pcmC0D0c (capture)
└── hw:0,0 / hw:0,1 (ALSA 设备)
/dev/mpp_service ──► mpph264dec / mpph265dec / mppvp9dec / mpph264enc
│
└── MPP (Media Process Platform)
├── rkvdec2 (H.264/H.265/VP8/VP9 解码)
└── rkvenc (H.264/H.265 编码)6. 常见问题
6.1 MPP 解码插件未找到
现象: gst-inspect-1.0 rockchipmpp 无输出或报 "no element mpph264dec"
解决方案:
# 检查 MPP 插件是否存在
ls -la /usr/lib/gstreamer-1.0/libgstrockchipmpp.so
# 检查 MPP 驱动是否加载
ls /dev/mpp_service
# 检查内核模块
lsmod | grep mpp
# 手动加载 MPP 模块
sudo modprobe rockchip_mpp
# 检查 MPP 服务
sudo systemctl status mpp-daemon
# 或直接运行
sudo /usr/bin/mpp-daemon &6.2 视频播放黑屏无输出
现象: 流水线正常运行但屏幕无显示
解决方案:
# 检查 DRM 设备
ls -la /dev/dri/
# 检查显示连接器状态
cat /sys/class/drm/card0-HDMI-A-1/status
# 应输出:connected
# 检查 VOP 显示控制器
cat /sys/kernel/debug/dri/0/state | grep -A5 vop
# 使用 DRM sink 时指定 connector-id
gst-launch-1.0 filesrc location=test.mp4 ! decodebin ! \
videoconvert ! kmssink connector-id=42
# 查看可用的 connector-id
cat /sys/class/drm/card0-HDMI-A-1/status
modetest -M rockchip -c6.3 V4L2 摄像头无法打开
现象: v4l2src device=/dev/video0 报错 "Cannot identify device"
解决方案:
# 检查 V4L2 设备
ls -la /dev/video*
# 检查设备能力
v4l2-ctl --device=/dev/video0 --all
# 检查摄像头是否被占用
fuser /dev/video0
# 检查 MIPI-CSI 设备树状态
# 具体节点路径以实际 DTB 反编译结果为准
dtc -I dtb -O dts /sys/firmware/fdt | grep -A3 "csi2-dphy0"
# 应输出:status = "okay"
# 查看 media 设备拓扑
media-ctl -d /dev/media0 -p6.4 音频无声
现象: 视频正常播放但无声音输出
解决方案:
# 检查 ALSA 设备
arecord -l # 列出录音设备
aplay -l # 列出播放设备
# 测试 ALSA 直接播放
aplay /root/test.wav
# 检查音频设备节点
ls /dev/snd/
# 检查 GStreamer 音频插件
gst-inspect-1.0 | grep alsa
# 指定 ALSA 设备
gst-launch-1.0 filesrc location=test.mp3 ! mpegaudioparse ! \
mpg123audiodec ! audioconvert ! alsasink device=hw:0,06.5 编码输出文件无法播放
现象: 编码生成的文件在播放器中无法打开
解决方案:
# 检查编码输出格式
gst-launch-1.0 -v filesrc location=/root/raw.yuv ! \
video/x-raw,format=I420,width=1920,height=1080,framerate=30/1 ! \
mpph264enc ! h264parse ! mp4mux ! filesink location=/root/out.mp4
# 使用 h264parse 确保 SPS/PPS 信息正确
# 在 mpph264enc 后添加 h264parse
# 检查编码参数
gst-inspect-1.0 mpph264enc
# 确认 bitrate、key-int-max 等参数
# 用 ffprobe 检查输出文件
ffprobe /root/out.mp46.6 性能瓶颈 — CPU 占用过高
现象: 视频播放时 CPU 占用率超过 80%
解决方案:
# 使用零拷贝模式(DMA-BUF)
gst-launch-1.0 filesrc location=/root/test.mp4 ! decodebin ! \
videoconvert ! video/x-raw,format=NV12 ! \
kmssink connector-id=0
# 使用 RGA 替代 videoconvert(硬件加速色彩转换)
gst-launch-1.0 filesrc location=/root/test.mp4 ! decodebin ! \
rga video/x-raw,format=NV12,width=1920,height=1080 ! \
autovideosink
# 调整 GStreamer 线程数
export GST_DEBUG=2
export GST_PLUGIN_PATH=/usr/lib/gstreamer-1.0
# 使用 queue 元素实现流水线并行
gst-launch-1.0 filesrc location=/root/test.mp4 ! decodebin ! \
queue ! videoconvert ! autovideosink \
queue ! audioconvert ! autoaudiosink相关文档
- C/C++应用开发入门 — C/C++ 开发基础
- Python应用开发 — Python 开发基础
- Qt嵌入式开发实战 — Qt GUI 开发
- 显示框架 — 显示系统
- 视频编解码(MPP) — MPP 编解码
- 音频开发与ALSA — ALSA 音频
- RGA图像处理 — RGA 2D 加速
- 摄像头应用 — V4L2 摄像头
- 音频驱动 — ALSA 音频驱动
- 摄像头Camera驱动 — V4L2 摄像头驱动
- 显示DRM驱动 — DRM/KMS 显示驱动
- HDMI显示驱动 — HDMI 输出驱动
- 内核配置与裁剪 — 内核配置
