嵌入式Linux基于QML开发QT Multimedia应用

Friday, June 29, 2018

简介

使用 QML 语言进行 Qt 应用程序开发可以将界面开发和逻辑控制分开,提高应用的开发周期和灵活性;另外对于多媒体应用非常重要的一点是,基于 QML/Qt Quick 的应用程序可以直接调用 GPU 进行加速,这大大提高了多媒体应用在嵌入式系统环境下的处理效率和资源占用,因此本文就基于 QML 和 Qt Multimedia 组件介绍多媒体应用开发。

本文所演示的平台来自于 Toradex Apalis iMX6 ARM 嵌入式平台,这是一个基于 NXP iMX6 Arm 处理器,支持双核/四核 Cortex-A9。


准备

a). Apalis iMX6 Arm 核心版配合 Ixora 载板,连接调试串口 UART1 到开发主机方便调试。

b). Apalis iMX6 系统使用基于 OpenEmbedded 框架重新编译的集成 Qt5.9 支持的 Toradex Linux image release V2.8b2 版本以及对应的SDK。可以结合这里的说明自行编译,需要修改的 local.conf 文件如下,image更新方法请参考这里

IMAGE_INSTALL_append = " gstreamer1.0-plugins-bad-* gstreamer1.0-plugins-ugly-* gstreamer1.0-libav"
PACKAGECONFIG_append_pn-qtmultimedia = " gstreamer"

c). 关于开发主机 SDK 安装和 Qt creator 开发环境的配置请参考这里

d). 演示程序使用的 LCD 为 10inch 18bit LVDS 屏幕,请参考这里修改配置 U-Boot 显示分辨率。

e). 如果需要,可以打开 Qt debug logging
./ 打开所有 debug logging
$ export QT_LOGGING_RULES=*.debug=true

./ 打开 multimedia 相关debug logging
$ export QT_LOGGING_RULES=*.debug=true

f). 本文演示应用程序分为两个部分,对应为两个页面;应用启动后默认页面为视频播放(Video Player)页面,通过点击按钮可以切换为摄像头捕获页面(Camera Capture)页面。下面就逐一进行一些说明。

Qt 演示程序开发 – Video Player

a). 源代码和运行效果如下:
代码
main.qml - https://github.com/simonqin09/QtQMLMultimedia/blob/master/main.qml
main.cpp - https://github.com/simonqin09/QtQMLMultimedia/blob/master/main.cpp

b). 具体要点说明如下
由于 Qt Multimedia 组件在底层也是调用 Gstreamer playbin 元件进行媒体播放操作,因此在编程之前,首先可以直接使用 Gstreamer pipeline 在嵌入式系统先验证下,确保媒体可以正常播放,没有解码器缺失的情况。
$ gst-launch-1.0 playbin uri=file:///home/root/ready-player-one-trailer-2_h720p.mov

main.cpp 文件用于识别输入变量并通过下面代码将其传递给QML来指定媒体文件位置。
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("mysource", source);

main.qml 文件用于实现video player界面以及媒体播放。
- 媒体播放主要由 ”Mediaplayer” 元素和 ”VideoOutput” 元素来配合实现。然后将其显示在定义好的 640x480分 辨率的 rectangle 中。
- 定义了一些控制播放和音量的按键,当点击时候会有颜色的变化指示。
- 使用了 Connections 用于信号触发操作,这里对应为当发现媒体播放停止的时候自动将 Play 按键的颜色变更为初始状态。
- 在页面切换按键处,使用了 loader 功能来加载 Camera Capture 页面,需要注意的是同时也需要在 main.qml 中创建一个 CameraMode.qml 的实例以便于操作。
CameraMode {
id: cameramode1
anchors.fill: parent
z: 1
}


QT演示程序开发 – Camera Capture

a). 源代码和运行效果如下:
./ 代码
CameraMode.qml - https://github.com/simonqin09/QtQMLMultimedia/blob/master/CameraMode.qml

b). 具体要点说明如下
./ QML 文件首先通过 Item 和 Component 组合,并通过定义函数 show 来加载 Component 也就是 Camera Capture 主页面。这里为了控制 CameraMode.qml 不在程序一启动就自动加载,增加了一个从 main.qml 传递过来的变量 camera_mode_visible。
./ 摄像头的 capture 功能由 Camera 元素和 Videooutput 元素配合实现,同样将 camera capture 画面显示到预定义好的 640x480 分辨率的 rectangle 中。
./ 使用 ListView 来显示目前系统所连接的所有可用 camera id,当点击时候实现 camera id 的切换以及重点显示。
./ 定义了 start 和 stop 按键,用于开始和停止所选定 camera id 的图像捕获。
./ 定义截图按键,通过 Camera 元素里面的 imageCapture 属性实现将所保存的图片显示在图像捕获窗口的下方区域。
./ 定义了 pagedestroy 函数,用于从当前页面返回 video player 页面。


程序部署配置

a). 将编译好的可执行程序 “videotest” 和所需要的视频文件 “ready-player-one-trailer-2_h720p.mov” 复制到Apalis iMX6模块 “/home/root” 目录下。

b). 配置程序开机自启动
./ 修改 /usr/bin/x-window-manager 文件为如下
RET=1
while [ $RET -ne 0 ]; do
cd /home/root
/home/root/videotest -url file:///home/root/ready-player-one-trailer-2_h720p.mov
RET=$?
done


程序运行演示

a). 开机后,系统自动启动程序,如下所示
./ video player

./ camera capture
系统上面一共连接了两个摄像头,第一个目前正在 cpature 的是 MIPI CSI OV5640 摄像头模块,第二个是一个Logitech 720P USB 摄像头。

b). CPU占用率,通过 top 命令查看
./ video player 播放视频状态,约为20% 左右。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
640 root 20 0 384796 45628 34032 S 19.8 4.4 2:15.30 videotest
554 root 19 -1 174652 12404 8684 S 3.3 1.2 0:20.38 Xorg
678 root 20 0 4796 2352 1920 R 1.2 0.2 0:00.19 top

./ camera capture 开始捕获图像状态,约为 21% 左右。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
640 root 20 0 435508 45092 34012 S 21.6 4.4 1:46.03 videotest
554 root 19 -1 174652 12404 8684 S 3.3 1.2 0:16.26 Xorg
676 root 20 0 4796 2368 1936 R 1.5 0.2 0:01.80 top


总结

本文基于 NXP iMX6 嵌入式平台在嵌入式 Linux 系统下测试基于 QML 和 Qt Multimedia 的多媒体应用,通过代码说明和程序运行结果可见,QML 和 Qt multimedia 的结合确实可以快速高效的构建一个界面化的多媒体应用,同时得益于 QML 的 GPU 加速以及针对 NXP iMX 系列的对应加速优化,其执行效率也非常之高。当然,在进行开发过程中也发现了一些问题,比如不够灵活,不能像直接使用 Gstreamer 框架一样自行定义 pipeline 元件,另外 QML 和 C++ 的配合也需要一些学习和经验才能灵活掌握,因此具体采用哪种方式还是要根据实际需要来决定。

#Camera #Qt
Author 秦海,技术销售工程师,韬睿(上海)

Leave a comment

Your email ID will be kept confidential. Required fields are marked *


Please enter the letters as they are shown in the image above. Letters are not case-sensitive.



* Your comment will be reviewed and then added. Thank you.