Linux 音视频SDK开发实践

一、兼容性适配处理

为什么需要兼容处理?
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a5b31c22f20c4f23b9b382d12b16039b

1、c++兼容处理

主要有ABI兼容性问题,不同ubuntu系统依赖的ABI版本如下:

ubuntu 18.04ubuntu 16.04ubuntu 14.04
g++7.55.44.8
stdc++版本libstdc++.so.6.0.25libstdc++.so.6.0.21libstdc++.so.6.0.19
GLIBCXXGLIBCXX_3.4.25GLIBCXX_3.4.21GLIBCXX_3.4.19

若用ubuntu 18.04开发的SDK,在utuntu 16.04去集成SDK开发APP,链接大概率无法通过(如果使用到GLIBCXX_3.4.21以上或CXXABI_1.3.9以上的符号),错误举例如下:

undefined reference to `std::__exception_ptr::exception_ptr::exception_ptr(void*)@CXXABI_1.3.11
undefined reference to `std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)())@GLIBCXX_3.4.22
undefined reference to `__cxa_init_primary_exception@CXXABI_1.3.11'
undefined reference to `std::thread::_State::~_State()@GLIBCXX_3.4.22'
undefined reference to `typeinfo for std::thread::_State@GLIBCXX_3.4.22

鉴于此,我们采用静态链接C++标准库的方式解决高版本开发环境到低版本生成环境无法运行的问题。

思考:怎么操作?
cmake方式下可以在CMakeLists.txt增加一条链接命令target_link_libraries(${PROJECT_NAME} -static-libgcc -static-libstdc++

总结:为了充分利用C++语言的新特性和高级功能,我们开发使用了较高版本的gcc/g++和stdc++,但输出的SDK不再依赖c++,也就实现了开发环境和生产环境的解耦,这里的生产环境可以指代使用SDK的客户开发环境和生产环境。
在这里插入图片描述

2、c兼容处理

和c++兼容性一样,c也有同样问题。
如果采用静态链接c库的方式,会造成产物二进制体积暴增,如果对包体积大小不敏感,可以采用此方式,另外可以选择一个低版本的c库去编译链接,这样编译出来的产物就只依赖低版本的c库,这样在高版本的系统里运行是没有兼容性问题的。

target_link_libraries(${RTCSDK_LIBRARY_NAME} ${LIB_DIR}/libc-2.19.so) # ubuntu 14.04, gcc4.8
target_link_libraries(${RTCSDK_LIBRARY_NAME} ${LIB_DIR}/libm-2.19.so)

3、iot兼容处理

Linux音视频SDK除了运行于桌面端环境(比如x86_64-ubuntu, aarch64-uos等),也可以应用于IoT领域(arm-linux平台),比如arm云对讲,教育录播场景。

实践中发现OpenSSL在arm上存在一些兼容性问题,比如使用libcurl based on OpenSSL实现https通信场景下会出现ssl connect error等一系列疑难问题,后来使用libcurl based on mbedTLS顺利解决这个问题,mbedTLS是为嵌入式设备而开发的一个TLS协议的轻量级实现,用作OpenSSL的一个轻量级替代。(参考https://github.com/Mbed-TLS/mbedtls)

二、音频开发

音频开发技术栈包括:

  • 基于ALSA驱动开发
  • 基于PulseAudio服务开发
  • 基于PipeWire服务开发

基于ALSA驱动开发存在独占,混音等诸多难题,开发难度大;PulseAudio声音服务作为声音系统的代理,对上层应用开发较友好,开发者完全不用考虑底层复杂的处理细节;PipeWire作为新一代Linux audio/video bus,旨在取代PulseAudio并统一音视频框架,但目前尚未全面普及,稳定性暂时不如PulseAudio(进展:ubuntu 22.04桌面系统内部预安装了PulseAudio和PipeWire服务,ubuntu 22.10预计会用PipeWire直接替换PulseAudio,基于此并考虑到到当前大多数Linux桌面系统发行版(包括低版本)都将PulseAudio作为默认声音服务器提供音频能力,我们倾向于选用PulseAudio进行音频功能开发,包括:

  • 音频设备枚举
    • 包括输入设备(micphone)和输出设备(speaker)
  • 音频采集(输入)
  • 音频播放(渲染)
  • 音频设备事件通知
    • 包括默认设备变更,音频输入和输出设备插入、拔出等

三、视频开发

包括以下功能:

  • 基于V4L2视频采集
  • 基于OpenGL视频渲染
  • 视频设备事件通知
    • 插入、拔出操作等

V4L2(Video For Linux Two的缩写)是Linux下关于视频采集相关设备的驱动框架,为驱动和应用程序提供了一套统一的接口规范。应用程序通过一系列IO系统接口即可完成摄像头数据采集功能,摄像头在Linux系统下会被映射为/dev/video0,/dev/video1等设备文件,特别应注意,V4L2支持的设备十分广泛,但是其中只有很少一部分在本质上是真正的视频设备,实际使用过程中应该特别关注V4L2_CAP_VIDEO_CAPTURE特征,如下:

struct v4l2_capability {__u8 driver[16];__u8 card[32];__u8 bus_info[32];__u32 version;__u32 capabilities;__u32 device_caps;__u32 reserved[3];
};struct v4l2_capability cap;
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == 0) 
{if (cap.device_caps & V4L2_CAP_VIDEO_CAPTURE){ // it is real video}
}

Linux 桌面视频渲染较多采用OpenGL渲染,Qt跨平台框架QOpenGLWidget也是基于OpenGL实现的。

四、屏幕共享开发

在Linux的世界里,桌面、窗口或图形化界面并不是必须的,因为Linux是基于命令行的操作系统,图形界面只是Linux下的一个应用程序,不带桌面的发行版也可以自己动手安装上桌面,屏幕共享的实现依赖于桌面环境,更准确的说法应该窗口系统或显示服务器。

窗口系统:
在Linux系统下,有两个比较常见的窗口系统,X Window System(X11)和Wayland,但当前使用最多的还是X11,窗口系统均采用C/S架构。
在这里插入图片描述

1、 基于X11屏幕共享开发

适用于X11窗口系统

基于X11进行开发,包括桌面共享和窗口共享,依赖X11,Xdamage,Xfixes,Xext,Xcomposite,xcb,Xdmcp和Xau库等。
客户端应用使用xlib(参考https://www.x.org/releases/current/doc/libX11/libX11/libX11.html)与X Server进行通信,完成屏幕共享等图形功能。

2、基于pipewire 屏幕共享开发

适用于Wayland 窗口系统

WebRTC M95升级pipewire0.2到pipewire0.3,实现了基于pipewire进行屏幕共享和窗口共享功能,内部使用D-bus做为通信方式,依赖pipewire-0.3,glib-2.0,gio-2.0和gobject-2.0四个库。
在这里插入图片描述

以上流程分为两大模块,屏幕源选择(由xdg-desktop-portal实现),pipewire流处理和数据回调,针对屏幕源选择,不像X11需要自己去实现源选择对话框,这里开箱即用。

3、番外(ubuntu 桌面窗口系统演进)

在这里插入图片描述
ubuntu在17.04版本引入了wayland,但由于无法实现屏幕共享,远程桌面等问题,在18.04版本去除了wayland feature,重新拥抱Xorg,到22.04版本正式支持了wayland,默认启动wayland窗口系统,同时保留切换为X11的选项(登录界面可进行切换)。除了ubuntu 发行版,其它Linux发行版也在跟进wayland的支持,可见wayland已成为Linux 图形技术栈的最新方向。

4、补充(Linux 图形栈技术)

在这里插入图片描述

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

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

相关文章

Python `hasattr` 函数详解

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 在Python中&#xff0c;hasattr 函数用于检查对象是否具有指定的属性或方法。它是一种动态检查对象特性的方式&#xff0c;适用于许多编程场景&#xff0c;特别是在处理不同类型的对象时。 基本用法 hasattr 函…

C#经典面试题:冒泡算法的使用

Hi i,m JinXiang ⭐ 前言 ⭐ 本篇文章主要介绍C#经典面试题&#xff1a;冒泡算法的使用以及部分理论知识 &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&#x1f601; &#x1f349;博主收将持续更新学习记录获&#xff0c;友友们有任何问题可…

telnet的交互原理(wireshark分析)

telnet的交互原理&#xff08;wireshark篇&#xff09; telnet的协议类型是tcp&#xff0c;他的密钥用的是明文的&#xff0c;容易被捕获&#xff0c;所以后来的windows基本弃用了telnet服务端但依然保留了客户端。 下面是他的交互抓包&#xff1a; 这里面的前三条运用的是tc…

IDEA tomcat内存不足

-Xms256m -Xmx256m -XX:MaxNewSize256m -XX:MaxPermSize256m

你对葡萄酒中的亚硫酸盐是不是有误解呢?

亚硫酸盐不会让某些人对酒产生不良的反应首先&#xff0c;让我谈谈欧洲生产的葡萄酒不含亚硫酸盐的观点&#xff0c;这在很大程度上是一种误解。虽然我听说过某些生产商在酿造葡萄酒时不添加亚硫酸盐&#xff0c;但这些确实是例外&#xff0c;添加亚硫酸盐是世界公认的酿酒传统…

Unity学习笔记(零基础到就业)|Chapter01:C#入门

Unity学习笔记&#xff08;零基础到就业&#xff09;&#xff5c;Chapter01:C#入门 前言一、控制台输入输出语句二、初识变量1.一些好用的tips2.变量声明的固定写法3.变量类型 三、变量的本质1.变量的存储空间2.变量的本质&#xff1a;2进制 四、变量的命名规范1.必须遵守的规则…

工行吉林省分行联合微信支付开展“反诈我在行”志愿服务活动

时值《中华人民共和国反电信网络诈骗法》颁布一周年&#xff0c;为积极响应国家号召&#xff0c;深入落实反电诈法&#xff0c;积极践行“金融为民”服务理念。12月7日&#xff0c;工商银行联合微信支付启动工行驿站“反诈我在行”志愿服务活动&#xff0c;普及反诈防诈与安全支…

C#中(, ||)与(, |)的区别

前言 在C#编程语言中&#xff0c;逻辑运算符用于组合和比较条件&#xff0c;以控制程序的流程和行为。在逻辑运算符中&#xff0c;有两对非常重要的运算符&#xff1a;&&和||、&和|。尽管它们看起来很相似&#xff0c;但其实它们有着不同的行为和使用场景。下面我们…

在Linux安装的Docker中开启IPv6

先在Linux中安装docker&#xff0c;然后在docker中开启IPv6。 安装docker 第一步&#xff0c;卸载旧版本docker。 若系统中已安装旧版本docker&#xff0c;则需要卸载旧版本docker以及与旧版本docker相关的依赖项。 命令&#xff1a;yum -y remove docker docker-client do…

MyBatis持久层框架

四、MyBatis持久层框架 目录 一、Mybatis简介 1. 简介2. 持久层框架对比3. 快速入门&#xff08;基于Mybatis3方式&#xff09; 二、日志框架扩展 1. 用日志打印替代sout2. Java日志体系演变3. 最佳拍档用法4. Lombok插件的使用 4.1 Lombok简介4.2 Lombok安装4.3 Lombok使用注…

zynqmp Linux + 裸机 (A53-0 Linux,A53-1 2 3 裸机大数据量实时处理,R5-0 协议处理,R5-1 屏幕显示逻辑等)填坑笔记

fpga 和arm 采用预留内存的方式&#xff0c;采用neon 协处理器只能做到 250M/S 的速度&#xff0c;预留内存采用mmap的方式&#xff0c;当读取内存页的时候采用缺页中断的方式&#xff0c;导致速度拖沓而且预留内存没有进行Linux系统的内存管理&#xff08;在系统内 memcpy的速…

JavaSE 泛型

目录 1 泛型类的定义1.1 为什么需要泛型1.2 泛型的概念1.3 泛型的分类 2 泛型类2.1 泛型类的定义2.2 泛型类的例子2.3 泛型类的实例化2.3.1 实例化语法2.3.2 裸类型(Raw Type) 2.4 泛型类的定义-类型边界2.5 泛型类的使用-通配符(Wildcards)2.5.1 基本概念2.5.2 通配符-上界2.5…