摄像头编程及其动态能力

摘要:
在基于OMCS开发类似视频聊天的应用程序时,我们通常需要获取相关的摄像机信息;在视频聊天中,我们可能还需要一些动态功能。如果索引为0的摄像机不可用,或者用户指定使用其他摄像机,则可以将指定摄像机的索引保存到配置文件中。相机提供另一种静态方法GetCameraCapability,以获取目标相机的能力信息。这种要求称为动态切换摄像机。OMCS支持在没有任何中断的情况下修改正在使用的相机的采集分辨率。

在基于OMCS在开发类似视频聊天的应用时,我们经常需要获取摄像头的相关信息;而在进行视频聊天时,我们可能还希望有一些动态的能力。比如,在不中断视频聊天的情况下,切换一个摄像头、或者修改摄像头采集的分辨率或编码质量等等。OMCS提供了很多有用的特性以支持上述需求。

一.枚举摄像头

我们如何得知当前的计算机有哪些摄像头了?

OMCS提供了一个工具类OMCS.Tools.Camera,来帮助我们获取这些信息。Camera有个静态方法GetCameras,用于枚举当前计算机上的所有摄像头。

/// <summary>
  ///枚举当前计算机上的所有摄像头设备。
  /// </summary>        
  public static List<CameraInformation> GetCameras()

CameraInformation封装了摄像头的基本信息,其类图如下所示:

摄像头编程及其动态能力第1张

我们可以将GetCameras方法返回的列表直接绑定到Combox控件,效果如下所示:

摄像头编程及其动态能力第2张

默认情况下,IMultimediaManager使用的摄像头的索引为0。如果索引为0的摄像头不可用,或者,用户指定使用其它的摄像头,则可以将指定摄像头的索引保存到配置文件。当客户端程序启动时,从配置文件中读取该索引值,并将其赋值给IMultimediaManager的CameraDeviceIndex属性。

二.获取摄像头支持的分辨率

当选定了一个摄像头,我们如何知道该摄像头支持哪些采集分辨率、支持最高的帧频是多少了?

Camera提供了另一个静态方法GetCameraCapability,来获取目标摄像头的能力信息。

/// <summary>
  ///获取目标摄像头的能力信息(分辨率、最大帧频)
  /// </summary>
  /// <param name="deviceIndex">目标摄像头的索引</param>        
  public static List<CameraCapability> GetCameraCapability(int deviceIndex)

CameraCapability类封装了摄像头的能力信息,其类图如下所示:

摄像头编程及其动态能力第3张

我们可以将GetCameraCapability方法返回的列表直接绑定到Combox控件,效果如下所示:

摄像头编程及其动态能力第4张

三.动态切换摄像头

下面我们设想一种情况,假设我的电脑上装有两个可用的摄像头,我正在使用索引为0的摄像头和我的朋友视频聊天,某个时刻,我想在不中断视频聊天的情况下,切换到索引为1的摄像头。这种需求就称为动态切换摄像头。

OMCS支持动态切换摄像头,并且操作相当简单:我们只需要将IMultimediaManager的CameraDeviceIndex属性赋值为要切换到的摄像头的索引即可。

切换会在OMCS内部自动进行,在很短的时间切换完成后,OMCS会将新摄像头采集的视频数据发送给各个guest。

四.动态修改摄像头的分辨率

还记得QQ视频聊天有这种能力,我们可以在视频聊天的时候,选择使用大窗口模式。这实际上就是使用摄像头更高的分辨率来采集视频,比如原始的采集分辨率为320*240,可切换到更高的640*480

OMCS支持在不需要任何中断的情况下,修改正在使用的摄像头的采集分辨率。操作也是相当简单:我们只需要将IMultimediaManager的CameraVideoSize属性设置为目标分辨率大小即可。当然,如果设置的分辨率不被当前摄像头所支持,则将抛出NotSupportedException。另外要注意,在编码质量相同的情况下,视频的分辨率越高,所输出的码流就越大,所要求的带宽也越大。

为了避免设置不恰当的分辨率给CameraVideoSize属性,在赋值之前,我们可以通过OMCS.Tools.Camera的静态方法Support来判断目标摄像头是否支持指定的分辨率:

/// <summary>
   ///目标摄像头是否支持采集指定的分辨率。
   /// </summary>     
   public static bool Support(int deviceIndex, Size videoSize)
五.动态调节编码质量

在客户端运行的任何时候,我们都可以通过设置IMultimediaManager的CameraEncodeQuality属性,来实时调整摄像头采集的视频的编码质量。编码质量越高(CameraEncodeQuality取值越小),对带宽的要求就越高;反之亦然。

当然,正如前面文章所介绍的,如果IMultimediaManager的AutoAdjustCameraEncodeQuality属性被设置为true,则CameraEncodeQuality将会被OMCS自动调节以优先保证语音的清晰连贯,手动对CameraEncodeQuality的设置就不起作用了。

如果我们将AutoAdjustCameraEncodeQuality设置为false,并且我们的应用自己能检测到网络状态的实时变化,那么,我们就可以根据当前的网络状态,来手动调整CameraEncodeQuality。

六.控制视频输出

设想这样一种情况:我在进行视频会议时,某个时间出于某种原因,我不想让与会者看到我的视频,一段时间后,我又希望恢复原样。

从节省带宽的角度,最好的方式就是在这段时间内不输出视频帧。OMCS能简单地实现这种控制:我们只需将IMultimediaManager的OutputVideo属性设置为false,即可关闭视频帧的输出。

七.广播时选择丢弃视频帧

下面要设想的场景稍微复杂一点:在视频会议时,我的视频会发送给与会的每个人,假设我与每个与会者之间都建立的是P2P通道,视频帧都经过P2P通道传送。现在的问题时,每个P2P通道的质量是不一样的,有的可能很快,有的可能很慢。我们假设到与会者A的通道非常慢,到其他与会者的通道质量都很好。那么,我们来分析一下在两种广播模式下,可能出现的情况。

1.同步广播模式

在同步广播模式下,只有当某个视频帧在所有的通道上都发送完毕时,才会去发送下一个视频帧。这样就会出现因为与A之间的通道缓慢,而导致其他与会者看到自己的视频出现卡或不连贯的情况。

2.异步广播模式

在异步广播模式下,视频帧在所有的通道上都是异步发送的,这样A通道的缓慢不会影响到其它的与会者。OMCS采用的就是这种模式。

但是,由于通道A的缓慢,生产视频帧的速度远大于通道A消费视频帧的速度,这就导致了需要使用更多的内存来缓存那些来不及发送的视频帧。就客户端进程看来,其所占用的内存会不断增加,就像内存泄漏一样。

如何解决这个问题了?OMCS给出的方案是可以选择在通道繁忙时丢弃帧。通过将IMultimediaManager的AllowDiscardFrameWhenBroadcast属性设置为true,便可启用这种方案。

AllowDiscardFrameWhenBroadcast被启用后,当一个新的视频帧要通过某个P2P通道发送给对应的与会者时,会先检测一下该P2P通道是否繁忙,如果繁忙,就取消该视频帧在这个通道上的发送。这样,就避免了内存无线增长的情况。但在这种方案下,那些通道比较慢的与会者,因为丢弃视频帧的原因,看到别人的视频可能就会出现马赛克、卡、不连续的现象。

-----------------------------------------------------------------------------------------------------------------------------------------------

下载免费版本的OMCS以及 demo源码

阅读 更多OMCS开发手册系列文章

免责声明:文章转载自《摄像头编程及其动态能力》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇I2C 上拉电阻选择计算公式netbeans的xdebug的安装下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Android_自适应布局

1、屏幕相关概念1.1分辨率是指屏幕上有横竖各有多少个像素1.2屏幕尺寸指的是手机实际的物理尺寸,比如常用的2.8英寸,3.2英寸,3.5英寸,3.7英寸android将屏幕大小分为四个级别(small,normal,large,and extra large)。1.3屏幕密度每英寸像素数手机可以有相同的分辨率,但屏幕尺寸可以不相同,Diagonal pi...

C# WinForm在高分辨率下界面模糊问题的解决

前言 昨天刚搞定了DevExpress,今天就遇到了之前遇到过的一个问题,那就是WinForm在高分辨率下界面模糊。我的开发环境是Windows10 64位和VS2010,电脑屏幕分辨率为1920*1080,采用的是WinForm程序设计方法开发。在程序运行时遇到了这样一个问题,在VS设计的很清晰的菜单和界面,运行的时候菜单和控件上字体变得很模糊,界面大小...

利用@media screen实现网页布局的自适应

1280分辨率以上(大于1200px) @media screen and (min-1200px){ #page{ 1100px; }#content,.div1{ 730px;}#secondary{310px} } 1100分辨率(大于960px,小于1199px) @media screen and (min- 960px) and (m...

多尺度理论及图像特征(一)

1.尺度    2.尺度研究的问题       1)尺度在空间模式和地表过程检测中的作用以及尺度对环境建模的冲击;        2)尺度域(尺度不变范围)和尺度阈值的识别;        3)尺度转换,尺度分析和多尺度建模放的实现。 3.遥感尺度的问题        遥感尺度主要关注的是测量尺度,不同来源的遥感信息数据在时间尺度和空间尺度上都有很大的差...

物理像素,ppi,逻辑分辨率和物理分辨率

1 明确几个概念:物理像素:屏幕物理像素屏幕像素密度ppi:pixels per inch,屏幕上每英寸可以显示的像素点的数量,即屏幕像素密度。顺便一提,ppi就是dpi,只不过有文章里说苹果喜欢用ppi,dpi安卓喜欢用,emmmm,所以还是用ppi吧。ppi的计算:屏幕对角线的屏幕物理像素密度除以屏幕尺寸。 以 iphone6 为例子,屏幕是 1334...

DeepFacelab更新:分辨率提至640,效率翻倍!

这几天又更新了,好事儿是又有新功能可以玩了,“坏事儿”是感觉又要升级设备了。其实,总的来说这次更新,对低配高配玩家都有好消息。 1. 对于高配玩家,可以跑更高像素的模型。 2. 对于低配玩家,那些跑不起的像素也能跑起来了。 下面就来说说重点更新内容: 1.  模型训练参数 resolution 的最大值从512调到了640。 ​ 这意味着对于高配玩家来说可...