DshanPI-A1 RK3576 gstreamer播放16路视频与硬件加速

news/2025/10/13 0:17:14/文章来源:https://www.cnblogs.com/yijunchenhui/p/19137536

演示视频

一、实验环境

类别 具体配置
板卡 DshanPI-A1
主控芯片 RK3576
操作系统 Armbian
桌面系统 GNOME
窗口系统 Wayland
GPU 驱动 Panfrost

核心硬件加速单元说明

RK3576 芯片集成三类关键硬件加速单元,分别负责不同环节的视频处理:

  • VPU(视频处理单元):负责视频解码(如 H.264 硬解),核心元件 mppvideodec 调用此单元;

  • RGA(图像加速单元):负责图像缩放、格式转换(如 NV12→RGBA),可通过 mppvideodec 参数启用;

  • GPU(图形处理单元):负责视频渲染、多画面拼接(如 glvideomixer 拼接画面),由 Panfrost 驱动管理。

二、GStreamer 工具与插件安装

执行以下命令安装全套 GStreamer 工具及 RK3576 硬件加速插件:

# 基础工具(gst-launch-1.0 等)
sudo apt install -y gstreamer1.0-tools# 基础插件集(音频/视频基础功能)
sudo apt install -y gstreamer1.0-plugins-base
sudo apt install -y gstreamer1.0-plugins-good
sudo apt install -y gstreamer1.0-plugins-bad# FFmpeg 集成插件(软解 fallback)
sudo apt install -y gstreamer1.0-libav# RK3576 硬件加速插件(VPU/RGA 支持)
sudo apt install -y gstreamer1.0-rockchip1# GPU 渲染依赖(glvideomixer 等)
sudo apt install -y libgstreamer-gl1.0-0

三、基础硬解码播放实践

1. 最简硬解码命令

gst-launch-1.0 filesrc location=/root/bad_apple.mp4 ! qtdemux ! h264parse ! mppvideodec ! waylandsink

命令链路解析

元件 功能说明
filesrc 读取本地视频文件(需替换为实际路径,如 /root/bad_apple.mp4
qtdemux 解封装 MP4 文件,分离视频流与音频流(MP4 属于 QuickTime 容器格式)
h264parse 解析 H.264 码流,将 MP4 中的 AVCC 格式转为解码器支持的 Annex B 裸流
mppvideodec 调用 RK3576 VPU 硬解码,输出 NV12 格式图像(硬件解码默认格式)
waylandsink 调用 GPU 渲染,在 Wayland 窗口显示视频(自动将 NV12 转为 RGB 格式)

2. 关键环节补充说明

(1)解封装与码流解析

  • MP4 文件是「容器」,需通过 qtdemux 分离出内部的视频流(H.264)和音频流;

  • H.264 流有两种格式:MP4 中默认是 AVCC 格式,而硬件解码器仅支持 Annex B 裸流,因此必须通过 h264parse 转换。

(2)解码

  • h264解码得到nv12图像;
    在没有硬解码的系统中,可以使用元件 avdec_h264 代替 ;
    avdec_h264 就是调用ffmpeg的软件解码器;
    也可以用来对比硬解软解的性能差距。

(3)渲染(Wayland vs X11)

  • wayland窗口系统中,可以直接传入nv12图像,自动调用gpu转成rgb渲染显示出来;
    x11窗口系统中,需要额外元件将nv12图像转成rgb才能渲染;
    这里因为用的wayland窗口系统,所以渲染元件是waylandsink;
    如果是x11 则要用xvimagesink或者glimagesink。
窗口系统 渲染元件 支持输入格式 额外说明
Wayland waylandsink NV12、RGBA/BGRA 自动用 GPU 转 NV12→RGB 渲染
X11 xvimagesink RGB/RGBA(不支持 NV12) 需用 RGA/GPU 提前转格式
X11 glimagesink RGB/RGBA(不支持 NV12) 依赖 GPU 转格式,性能优于 XV

3. 硬件负载查看命令

通过以下命令实时监控 VPU/RGA/GPU 占用率(建议用 tmux 分屏同时查看):

(1)查看 RGA 占用率

watch -n 1 cat /sys/kernel/debug/rkrga/load

(2)查看 GPU 占用率(Panfrost 驱动)

watch -n 1 cat /sys/class/devfreq/27800000.gpu/load

(3)查看 GPU 占用率(Mali 官方驱动,可选)

watch -n 1 cat /sys/devices/platform/fb000000.gpu/utilisation

四、RGA 硬件加速的应用场景

RGA 主要用于图像缩放格式转换,可减轻 GPU 负载,尤其适合多视频播放场景。

1. RGA 实现视频缩放(全屏播放)

若视频分辨率为 720P,需全屏适配 1080P 屏幕,通过 mppvideodecwidth/height 参数调用 RGA 缩放:

gst-launch-1.0 filesrc location=/root/bad_apple.mp4 ! qtdemux ! h264parse ! mppvideodec width=1920 height=1080 ! waylandsink

对比:GPU 缩放方案

若不启用 RGA,仅通过 waylandsinkfullscreen=true 让 GPU 缩放,可对比两者负载差异:

gst-launch-1.0 filesrc location=/root/bad_apple.mp4 ! qtdemux ! h264parse ! mppvideodec ! waylandsink fullscreen=true

2. RGA 实现图像格式转换

Wayland 中 waylandsink 不支持 RGB/BGR 格式,仅支持 RGBA/BGRA(带透明度);X11 中 xvimagesink 不支持 NV12,需转 RGB 格式。通过 mppvideodecformat 参数调用 RGA 转格式:

# Wayland 场景:NV12→RGBA(减轻 GPU 转格式负载)
gst-launch-1.0 filesrc location=/root/bad_apple.mp4 ! qtdemux ! h264parse ! mppvideodec format=RGBA ! waylandsink# X11 场景:NV12→RGB(适配 xvimagesink)
gst-launch-1.0 filesrc location=/root/bad_apple.mp4 ! qtdemux ! h264parse ! mppvideodec format=RGB ! xvimagesink

3. RGA 与 GPU 选择原则

维度 RGA GPU
负载情况 低占用、波动小,多核心支持 高占用、波动大,易超 50%
功能侧重 图像缩放、格式转换(专用) 渲染、多画面拼接(通用)
适用场景 单视频缩放、格式转换 多视频拼接、3D 渲染
选择建议 能用 RGA 则优先用,平衡负载 RGA 不支持的场景(如拼接)

五、多画面拼接实践

多画面拼接依赖 glvideomixer(GPU 实现),需注意多路流冲突处理队列缓冲优化
实际上rga也可以拼接,但是gst的元件上没有实现 直接用rga编程是可以拼接的。

1. 2 路画面拼接(基础版)

多路视频需为 qtdemux 命名(避免冲突),通过 xpos/ypos 定义画面位置:

gst-launch-1.0 \
filesrc location=/root/bad_apple.mp4 ! \
qtdemux name=demux_left ! h264parse ! \
mppvideodec format=RGBA width=960 height=1080 ! \
glvideomixer.sink_0 \
filesrc location=/root/bad_apple.mp4 ! \
qtdemux name=demux_right ! h264parse ! \
mppvideodec format=RGBA width=960 height=1080 ! \
glvideomixer.sink_1 \
glvideomixer name=glvideomixer \
sink_0::xpos=0 sink_0::ypos=0 \ 
sink_1::xpos=960 sink_1::ypos=0 ! \
waylandsink

2. 2 路画面拼接(优化版,增加队列)

多路视频处理耗时增加,需添加 queue 缓冲防止卡顿(每路流关键节点均需加队列):

gst-launch-1.0 \
filesrc location=/root/bad_apple.mp4 ! queue ! \
qtdemux name=demux_left ! queue ! h264parse ! queue ! \
mppvideodec format=RGBA width=960 height=1080 ! queue ! \
glvideomixer.sink_0 \
filesrc location=/root/bad_apple.mp4 ! queue ! \
qtdemux name=demux_right ! queue ! h264parse ! queue ! \
mppvideodec format=RGBA width=960 height=1080 ! queue ! \
glvideomixer.sink_1 \
glvideomixer name=glvideomixer \
sink_0::xpos=0 sink_0::ypos=0 \
sink_1::xpos=960 sink_1::ypos=0 ! queue ! \
waylandsink

3. 4 路画面拼接(2×2 网格)

gst-launch-1.0 \
filesrc location=/root/bad_apple.mp4 ! qtdemux name=demux1 ! queue ! h264parse ! \
mppvideodec format=RGBA width=960 height=540 ! queue ! glvideomixer.sink_0 \
filesrc location=/root/bad_apple.mp4 ! qtdemux name=demux2 ! queue ! h264parse ! \
mppvideodec format=RGBA width=960 height=540 ! queue ! glvideomixer.sink_1 \
filesrc location=/root/bad_apple.mp4 ! qtdemux name=demux3 ! queue ! h264parse ! \
mppvideodec format=RGBA width=960 height=540 ! queue ! glvideomixer.sink_2 \
filesrc location=/root/bad_apple.mp4 ! qtdemux name=demux4 ! queue ! h264parse ! \
mppvideodec format=RGBA width=960 height=540 ! queue ! glvideomixer.sink_3 \
glvideomixer name=glvideomixer \
sink_0::xpos=0    sink_0::ypos=0    sink_0::width=960 sink_0::height=540 \
sink_1::xpos=960  sink_1::ypos=0    sink_1::width=960 sink_1::height=540 \
sink_2::xpos=0    sink_2::ypos=540  sink_2::width=960 sink_2::height=540 \
sink_3::xpos=960  sink_3::ypos=540  sink_3::width=960 sink_3::height=540 ! queue ! \
waylandsink

4. 16 路画面拼接(4×4 网格,高负载场景)

(1)解决文件描述符上限问题

16 路视频会创建大量 DMA 缓冲区(占用 Linux 文件描述符 FD),需先提高 FD 上限:

ulimit -n 4096  # 临时生效,重启后需重新设置

(2)16 路拼接命令

gst-launch-1.0 \
filesrc location=/root/bad_apple.mp4 ! qtdemux name=demux1 ! queue ! h264parse ! queue ! \
mppvideodec format=RGBA width=480 height=270 ! queue ! \
glvideomixer.sink_0 \
filesrc location=/root/bad_apple.mp4 ! qtdemux name=demux2 ! queue ! h264parse ! queue ! \
mppvideodec format=RGBA width=480 height=270 ! queue ! \
glvideomixer.sink_1 \
filesrc location=/root/bad_apple.mp4 ! qtdemux name=demux3 ! queue ! h264parse ! queue ! \
mppvideodec format=RGBA width=480 height=270 ! queue ! \
glvideomixer.sink_2 \
filesrc location=/root/bad_apple.mp4 ! qtdemux name=demux4 ! queue ! h264parse ! queue ! \
mppvideodec format=RGBA width=480 height=270 ! queue ! \
glvideomixer.sink_3 \
filesrc location=/root/bad_apple.mp4 ! qtdemux name=demux5 ! queue ! h264parse ! queue ! \
mppvideodec format=RGBA width=480 height=270 ! queue ! \
glvideomixer.sink_4 \
filesrc location=/root/bad_apple.mp4 ! qtdemux name=demux6 ! queue ! h264parse ! queue ! \
mppvideodec format=RGBA width=480 height=270 ! queue ! \
glvideomixer.sink_5 \
filesrc location=/root/bad_apple.mp4 ! qtdemux name=demux7 ! queue ! h264parse ! queue ! \
mppvideodec format=RGBA width=480 height=270 ! queue ! \
glvideomixer.sink_6 \
filesrc location=/root/bad_apple.mp4 ! qtdemux name=demux8 ! queue ! h264parse ! queue ! \
mppvideodec format=RGBA width=480 height=270 ! queue ! \
glvideomixer.sink_7 \
filesrc location=/root/bad_apple.mp4 ! qtdemux name=demux9 ! queue ! h264parse ! queue ! \
mppvideodec format=RGBA width=480 height=270 ! queue ! \
glvideomixer.sink_8 \
filesrc location=/root/bad_apple.mp4 ! qtdemux name=demux10 ! queue ! h264parse ! queue ! \
mppvideodec format=RGBA width=480 height=270 ! queue ! \
glvideomixer.sink_9 \
filesrc location=/root/bad_apple.mp4 ! qtdemux name=demux11 ! queue ! h264parse ! queue ! \
mppvideodec format=RGBA width=480 height=270 ! queue ! \
glvideomixer.sink_10 \
filesrc location=/root/bad_apple.mp4 ! qtdemux name=demux12 ! queue ! h264parse ! queue ! \
mppvideodec format=RGBA width=480 height=270 ! queue ! \
glvideomixer.sink_11 \
filesrc location=/root/bad_apple.mp4 ! qtdemux name=demux13 ! queue ! h264parse ! queue ! \
mppvideodec format=RGBA width=480 height=270 ! queue ! \
glvideomixer.sink_12 \
filesrc location=/root/bad_apple.mp4 ! qtdemux name=demux14 ! queue ! h264parse ! queue ! \
mppvideodec format=RGBA width=480 height=270 ! queue ! \
glvideomixer.sink_13 \
filesrc location=/root/bad_apple.mp4 ! qtdemux name=demux15 ! queue ! h264parse ! queue ! \
mppvideodec format=RGBA width=480 height=270 ! queue ! \
glvideomixer.sink_14 \
filesrc location=/root/bad_apple.mp4 ! qtdemux name=demux16 ! queue ! h264parse ! queue ! \
mppvideodec format=RGBA width=480 height=270 ! queue ! \
glvideomixer.sink_15 \
glvideomixer name=glvideomixer \
sink_0::xpos=0 sink_0::ypos=0 sink_0::width=480 sink_0::height=270 \
sink_1::xpos=480 sink_1::ypos=0 sink_1::width=480 sink_1::height=270 \
sink_2::xpos=960 sink_2::ypos=0 sink_2::width=480 sink_2::height=270 \
sink_3::xpos=1440 sink_3::ypos=0 sink_3::width=480 sink_3::height=270 \
sink_4::xpos=0 sink_4::ypos=270 sink_4::width=480 sink_4::height=270 \
sink_5::xpos=480 sink_5::ypos=270 sink_5::width=480 sink_5::height=270 \
sink_6::xpos=960 sink_6::ypos=270 sink_6::width=480 sink_6::height=270 \
sink_7::xpos=1440 sink_7::ypos=270 sink_7::width=480 sink_7::height=270 \
sink_8::xpos=0 sink_8::ypos=540 sink_8::width=480 sink_8::height=270 \
sink_9::xpos=480 sink_9::ypos=540 sink_9::width=480 sink_9::height=270 \
sink_10::xpos=960 sink_10::ypos=540 sink_10::width=480 sink_10::height=270 \
sink_11::xpos=1440 sink_11::ypos=540 sink_11::width=480 sink_11::height=270 \
sink_12::xpos=0 sink_12::ypos=810 sink_12::width=480 sink_12::height=270 \
sink_13::xpos=480 sink_13::ypos=810 sink_13::width=480 sink_13::height=270 \
sink_14::xpos=960 sink_14::ypos=810 sink_14::width=480 sink_14::height=270 \
sink_15::xpos=1440 sink_15::ypos=810 sink_15::width=480 sink_15::height=270 ! queue ! \
waylandsink

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/935808.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全面适配iOS 26液态玻璃,基于开源IM即时通讯框架MobileIMSDK:RainbowChat-iOS端v10.2发布

全面适配iOS 26液态玻璃,基于开源IM即时通讯框架MobileIMSDK:RainbowChat-iOS端v10.2发布基于开源IM即时通讯框架MobileIMSDK:RainbowChat-iOS端v10.2发布,全面适配iOS 26 Liquid Glass(液态玻璃)。1、MobileIMS…

freertos的调度过程

一.Preface 理解Freertos的任务调度对理解整个实时操作系统是非常有帮助的,最近抽空又复习了一遍源码,所以在此记录一下。二.freertos的3各任务链表 2.1ready list(array) a.这是一个链表组,定义了最高优先级为10,…

「2025 高一上学期笔记 / 日记」

「2025 高一上学期笔记 / 日记」 9.1 上午 P10449 费解的开关25 盏灯排成一个 55 的方形。每一个灯都有一个开关,游戏者可以改变它的状态。每一步,游戏者可以改变某一个灯的状态。游戏者改变一个灯的状态会产生连锁反…

「2025 暑假日记 / 笔记」

「2025 暑假日记 / 笔记」 7.1 - 7.2目前鸽了一部分题没时间写/太难的,后期补出来并查集简单并查集 并查集是一种用于管理元素所属集合的数据结构,支持查询和合并的操作。查询int find(int x){return (f[x] == x) ?…

2025羊城杯初赛Misc-writeup

别笑,你试你也过不了第二关 构造变量 hilogo 使其值等于指定的 ASCII 艺术图案,代码长度必须小于 285 字符 第一关通过尝试,发现题目存在沙箱,禁了import,print,base64等,同时禁用使用字符串格式化 我们采用Code…

将 GPU 级性能带到企业级 Java:CUDA 集成实用指南

引言 在企业软件世界中,Java 依靠其可靠性、可移植性与丰富生态持续占据主导地位。 然而,一旦涉及高性能计算(HPC)或数据密集型作业,Java 的托管运行时与垃圾回收开销会在满足现代应用的低延迟与高吞吐需求上带来…

我的个人空间

Hero BannerMCPAPPMovie H5浏览器插件微信

2025.10.12总结

今天继续学习软考相关知识,目前过完数据结构和算法相关知识,在看操作系统,看的课程讲的云里雾里的听不懂。 目前任务 1.软考 2.继续学苍穹外卖 软考下个月就开始考试很紧急 苍穹外卖对找工作有帮助,而这仅仅是一个…

Windows 文件管理器中重复的 OneDrive 图标原因与解决方案

最近发现 Windows 文件管理器左侧出现了两个 OneDrive 图标。 检查注册表后发现,它们分别对应两个不同的命名空间(CLSID): {018D5C66-4533-4307-9B53-224DE2ED1FE6} → 系统版 OneDrive(个人) {04271989-C4D2-F…

10.12总结

1.今天啥都没干 2.明天学习组建模板

【Python】pandas的向量化操作

dict_nb={[1,2,3]:[4,5]}#多层循环效率不高 for i in range(0, df2.shape[0]): #循环,如果df2的列表中,每行第1列等于GOOD,且第4列等于字典键的第二个值(此处为2),第5列等于字典键的第三个值(此处为3)if df2.v…

docker部署doris

拉取镜像 docker pull apache/doris:fe-3.0.4 docker pull apache/doris:be-3.0.4docker-compose.yamlversion: "3" services: fe: image: apache/doris:fe-3.0.4 hostname: fe environment: - FE_SERVERS=f…

ES客户端8版本与ES服务端7版本的兼容问题

🎬 第一阶段:发现问题(认识症状) 🔴 看到的错误日志: 2025-09-30 14:23:45.123 ERROR - ES全量同步任务执行失败 co.elastic.clients.transport.TransportException: Missing [X-Elastic-Product] header. P…

AI 改变数据库产品实践探索

AI 改变数据库产品实践探索OceanBase 结合 AI 技术,通过 Agent 和任务调度简化数据库操作,支持多数据库管理与易用性提升。01 obloader agent 导数工具使用中的难题 在实际使用导数工具进行数据导入的过程中,用户普…

使用Sender和io_uring改造Webserver

前言 我以前有写过一个练手玩具,参考 tinywebserver 当然那时候我稍微改了下,改成了主从 Reactor 和 epoll 不过那时候感觉最后实现的有线程问题,查了半天没查出来红温了,索性加了一把大锁 最近读了下 Sender 模型…

乐理 -04 打拍子

.. 四N拍子 打拍子.....附点小切分 强的在中间大附点&大切分八N拍子 打拍子 3个

如何在Renpy尝试中调整人物和背景图像大小

在初步绘制好立绘或者是背景后,如果直接存入images文件中进行图像调用,往往会出现图像过于大或者是过于小,导致当前场景观感不佳等问题。 解决方案主要有两种: (1)重新选择较大或者是较小的画布,重新绘制立绘,…

开源软件站

1. OSCHINA - 中文开源技术交流社区 https://www.oschina.net/2. 开源软件 - Gitee.com3. Trending repositories on GitHub today GitHub4. Explore projects GitLab5. GitCode - 全球开发者的开源社区,开源代码托…

如何安装claude code以及ccr code

如何安装claude code以及ccr code 1. 安装 node 1.1 node的常规安装(适用于linux18.04,linux20.04等新版本) 参考官网安装顺序:https://nodejs.org/en/download 1.2 常规安装失败,其他情况下node的安装(适用于li…