俄语的GUI或VKS终端机自己做

具有为俄罗斯视频会议系统(VKS)开发C ++ GUI的经验。现代技术的合成和认证要求。开发的主要“耙”以及解决这些问题的方法。GUI和俄罗斯芭蕾舞有什么共同点。

视频会议系统用户所看到的第一件事是界面。在大多数情况下,他们通过外观和功能来判断系统。界面不便或泛滥将无法评估系统的高性能或广泛功能。从技术上讲,“美丽”的系统应包裹在美观且稳定的工作外壳中。因此,在国内VKS系统开发之初,就立即考虑了这一时刻。

图片

谁将成为俄罗斯视频会议系统的用户?


自2020年春季以来,对于开发成熟的VKS系统的可取性问题的答案已变得显而易见。官员,商业公司,医院和学校需要具有一定水平的生产力和安全性的现代化通讯方式。您可以使用Zoom进行交谈,但是值得用于认真的商业谈判或经理人的运营会议吗?

对于俄罗斯公司的各种任务,有必要创建一个家庭视频会议系统。而且,一个系统不仅包括软件组件,而且还包括成熟的硬件。在世界著名的供应商中,至少有5家公司提供多功能视频会议系统。但是在俄罗斯,进口替代的概念逐渐开始起作用。另外,许多产品的安全性问题已变得比产品的原产国更为重要,以当前汇率计算的价格也不在最后。从头开始开发界面的“美感”是相当现实的。

启动GUI


现代接口的主要要求是实现速度,最新外观和完整的可用性。因此,图形用户界面(GUI)开发人员的首要任务是明确定义视频会议的软件功能。

从GUI的角度出发,提出了以下要求:

  • 拨打视频/音频电话;
  • 接受/拒绝来电;
  • 在自定义时间间隔自动接听来电;
  • 在通话期间和通话外部在两个音频设备(耳机/扬声器)之间切换;
  • 在通话过程中和通话期间打开/关闭麦克风和摄像头;
  • 通话中的DTMF拨号;
  • 在航站楼举行会议;
  • 管理PTZ摄像机,保存PTZ预设及其应用;
  • 能够将视频输出到几个不同的窗口;
  • 控制鼠标,键盘,遥控器;
  • 从Web界面远程控制终端的能力。

此功能列表使您可以通过各种方式解决开发接口的问题。此外,对特定类型的实现的选择受到编程语言类型的限制的影响(例如,出于认证原因,Java绝对不适合,根据功能CSS / HTML),开发人员的专业化和时间安排。总的来说,选择使用C ++和使用Qt5框架是因为,例如,更现代的QML技术不允许使用任意OpenGL上下文渲染视频,而根据VKS终端的ToR,这是必需的。

图片

快速高效


第一个GUI原型是为Qt的软件电话创建的,并使用了许多开源库。例如,对于SIP协议,使用了eXosip / oSIP库,用于对视频和音频进行编码/解码-ffmpeg,与音频设备一起使用-PortAudio。该软件电话可在Linux,Windows,MacOS上运行,并且是技术演示者,而不是真正的设备。

后来,一个抽象的软件电话被转换为一个真实的视频电话项目,并且该软件的第一个版本应该在启动后两个月就创建了。为了在这么短的时间内解决这个问题,电话软件被分为模块,并根据能力分配给几组开发人员。这样的流程组织有助于快速有效地开发可视电话项目。

核心与前线


为了统一和使用现有项目在其他设备中使用现有GUI开发的可能性,通用代码库位于单独的模块-GUI后端或GUI核心模块中。直接表示法(针对不同设备而不同)在单独的GUI前端模块中实现。

GUI模块的这种体系结构被证明是有利的,并导致了预期的结果:用于VKS系统本身的新组件的接口的开发已经变得相对快速和高质量。毕竟,现在不需要从头开始重写VKS终端的接口。

折磨与胜利


在创建任何软件的过程中,自然会遇到困难和问题。创建视频会议的GUI也不例外。无论系统的特定目的如何,都可以在任何命令中重复它们。对于同事而言,发展道路上的困难和胜利很有趣,也许他们会在没有我们的“耙子”的情况下提供有效的解决方案。

永远的一致性


从历史上看,在针对各种VKS终端的GUI的开发过程中出现的第一个有趣的问题是一致性问题,即所有模块的协调状态。在操作期间,GUI与其他几个模块交互:用于与硬件交互的模块,呼叫管理子系统,媒体处理模块(MCU)和用户交互子系统。

图片

最初,GUI与所有这些模块独立工作,也就是说,它可以同时将请求发送到2个不同的模块。事实证明这是错误的,有时会导致问题,因为这些模块本身并不是独立的,并且彼此之间是积极交互的。解决该问题的方法是创建一个特殊的工作方案,以确保在所有模块中严格顺序地执行请求。

增加了两个困难:首先,一些(但不是全部)请求需要响应,因为实际上终端处于不一致状态,因此无法执行其他请求。但是,在等待响应时阻塞用户界面也是不希望的。其次,模块对GUI请求的响应以及模块对GUI的请求都在它们自己的线程中进入,这与GUI不同,但是GUI必须在其线程中实现所有状态更改(对于某些操作Qt要求这样做,但是在某些情况下,这避免了确保线程同步的不必要困难。

找到了解决方案,该解决方案由两部分组成。首先,使用Qt信号槽机制以及QueuedConnection,即使用全局QApplication事件循环,将来自其他模块的所有请求/响应重定向到GUI流。然后,为了确保对所有请求的一致处理,开发了具有自己的队列和处理周期(TransitionLoop)的Transitions系统。

因此,当用户按下GUI中的某个操作按钮(例如,呼叫按钮)时,将创建一个对应的“过渡”,该过渡被放置在过渡队列中。此后,将为过渡处理周期生成一个信号。收到信号后,TransitionLoop会查看现在是否正在进行任何过渡。如果存在,则等待当前转换完成的过程继续;如果不是,则从过渡队列中检索下一个过渡并启动。当使用相同的信号从另一个TransitionLoop模块接收到响应时,将通知当前转换完成,并且TransitionLoop可以从队列开始下一个转换。

这里重要的是,所有过渡处理都在GUI线程中完成。这可以通过在QueuedConnection变量中使用Qt信号时隙机制来确保,在该机制中,将为每个信号生成一个事件并将其放置在应用程序的主EventLoop中。

低功耗硬件上的OpenGL渲染


我们必须处理的另一个困难是渲染视频的问题。 Qt为OpenGL渲染提供了一个特殊的QOpenGLWidget类和相关的帮助器类,该类最初用于渲染视频。用于渲染(解码的视频帧)的数据本身由媒体处理模块(MCU)提供,媒体处理模块(MCU)在视频流中(在GPU上)实现硬件解码。在低功率处理器上,发现“放慢了” FullHD视频的渲染速度。直接的解决方案是更换处理器,但这将需要对视频会议系统已经完成的组件进行认真处理,并且会增加设备本身的成本。因此,仔细分析了整个渲染过程,以找到解决问题的更佳方法。

使用标准的OpenGL渲染和硬件解码,会发生以下情况:带有编码视频的数据来自网络,将其存储在RAM中,然后将来自RAM的此数据传输到GPU上的视频内存,然后对其进行解码。然后,具有比编码数据大得多的体积的解码数据再次被传送到RAM。接下来,渲染代码开始起作用,该代码将这些数据从RAM直接传输回GPU进行渲染。因此,相当多的数据通过内存总线来回传输,而总线根本无法做到这一点。

在OpenGL的现代版本中,有一些特殊的扩展名,使您可以照常指定渲染GPU内存中的数据,而不是主RAM中的数据。这种机制排除了硬件解码帧的数据从GPU到RAM的移动,然后再返回。因此,几乎解决了在低功耗处理器上渲染的问题。

图片

另一个主要问题是Qt支持的OpenGL上下文。它们不允许您使用必需的OpenGL扩展,即,您不能将QOpenGLWidget与该选项一起使用。解决方案是使用常规QWidget,但关闭了Qt渲染管道。这样的机会存在于Qt中。但是,这里出现了一个问题,因为在此选项中,GUI完全负责此小部件区域中的所有渲染,因此Qt对我们没有帮助。这对于显示视频是正常的,但是对于在视频顶部使用小部件,则不能使用常规Qt工具,因为例如,需要在视频顶部显示其他弹出菜单。

解决此问题的方法如下:从现有的小部件中获取其图像(QWidget为此具有一个handle()方法),将生成的图像转换为OpenGL纹理,并使用OpenGL工具将其渲染到视频的顶部。通过添加适当的环境,实现了一种通用机制,该机制可用于以这种非标准方式在视频顶部显示任何标准小部件。

报亭和小部件


在“信息亭”模式下管理显示和分发用户界面片段的任务并不容易。 VKS终端可以在两种模式下运行-窗口模式(即操作系统桌面环境中的任何其他窗口应用程序)和“信息亭模式”(即操作系统仅运行具有图形界面的一个应用程序-VKST-并且没有环境)桌面)。

在窗口模式下,一切都相对简单:窗口由桌面环境的窗口管理器控制,应用程序在必要时创建第二个窗口,并且用户根据需要在显示器上分配窗口。但是在“信息亭”模式下,一切都变得更加复杂,因为系统没有窗口管理器,并且只能有一个窗口,并且用户没有能力移动它。因此,出现了自动检测事件的任务,例如连接/断开显示器。发生此事件时,有必要自动配置显示并在其上正确放置用户界面的片段。

图片

答案来自LINUX Xrandr OS系统库,该库负责处理显示器。 Internet上几乎没有文档,因此使用Internet(包括Habr)中的示例进行了实施。另外,有必要提出一种算法,用于在显示器之间分配接口片段,以及将两个不同的窗口集成到一个窗口中。后者的实现方式如下:在窗口模式下,什么是“信息亭”模式下的窗口是一个大窗口内的窗口小部件,该窗口跨越2个显示器(如果有2个)。在这种情况下,必须配置显示器的位置,以便创建连续的虚拟空间(使用XRandr库完成此操作),然后在单个全局窗口内设置内部小部件的几何形状,以便这样每个人都可以显示。

我们创造俄语


创建俄罗斯视频会议系统的整个方法包括多个阶段,并且由多个阶段组成,GUI只是冰山一角。最明显而不是最困难。但是,解决方案的复杂性,软件以及硬件和软件组件的结合以及对创建技术上和美学上“美丽”的系统的渴望在开发过程中造成了许多困难。新任务产生了非标准的解决方案,并帮助创建了一个不仅在俄罗斯而且在国外都无法展示的产品。

长期以来,俄罗斯的发展已证明了它们的表现,并具有精美的外观和竞争力。我们的生活技巧对于认真从事GUI开发的每个人都是有用的,我们希望它们将帮助其他开发人员加快并简化为俄罗斯新软件产品创建现代外壳的过程。我们认为,俄罗斯的决定在世界上将不亚于俄罗斯的芭蕾舞或黑鱼子酱。

All Articles