Linux 的魅力: 访问 Nokia N800 摄像机构建应用程序以访问 Webcam 简介: Linux 的魅力 的 3 期文章用实际例子演示了如何构建应用程序:使用摄像机功能创建 Webcam。在这期文章中,讨论如何使用 gstreamer 开始构建摄像机应用程序,以访问 Nokia N800 设备的 Webcam(需要做的工作也许比您想象的更少,尤其是在我们借鉴现有的应用程序之后)。 在这个分三部分的系列的 第 1 期 中,演示了 Nokia N800 Linux® 的内部结构,列出了它的 技术规范和物理参数,并阐述了如何设置和测试构建环境。 本文从 网站上描述的一个摄像机应用程序开始讨论。此处只是提供这篇 maemo 文章的链接并建议您熟悉其中包含的信息,而不会重复其内容并加以解释:“ How to use the Camera API”。 尽管不需要 shell 访问也能在 N800 上运行摄像机应用程序,但是在 N800 上加载一个终端程序将非常有用。我还安装了一个 ssh 服务器,以便在测试时可以使用实际的键盘。提示一下:如果在 N800 上安装 ssh 服务器(和之前的 770 一样),系统将允许通过 ssh 进行根登录(密码为 “rootme”)。毫无疑问应该修改这个设置,但是人们总会单击附件来查看其行为,因此建议更改 root 密码。 GStreamer 是一种开源的多媒体框架 — 这个时髦词的具体含义就是提供了连接各种媒体流(比如音频或视频)的胶合代码。如果仅此而已也没多大用处,最大的优势在于它包含了对大量任务的支持。默认 情况下 N800 上安装了 GStreamer 库,但这并不是命令行工具。如果有一个根 shell,则可以弥补这个缺陷,并能执行更多命令(参阅 获取更多软件 侧栏)。只需从 maemo 存储库安装 gstreamer-tools 包,就能够获得命令行前端。 如果按照以上步骤进行了操作,就可以打开摄像机了;否则,应该禁用视频聊天应用程序的 “start when camera opened” 功能(查看 Tools 菜单)。 gstreamer 的重要用途是设置管道。和 UNIX® shell 中使用管道将小部件汇编成完整的应用程序一样,gstreamer 管道将各种部件组合在一起。我将简单展示一个使用 gstreamer 库的 C 程序,也可以使用一个名为 gst-launch 的命令行工具。这个工具在 gstreamer-tools 包中,可以使用 apt-get 工具安装该包,但是不能使用 Application Manager 安装,因为它只显示经过过滤的部分可用项目(还需要向 apt-get 配置添加一些存储库,参阅 获取更多软件 侧栏)。 清单 1. 安装 gstreamer-tools
注意这些包没有经过 “验证”,在此处并无关系。下面是一个简单的命令行调用:
请记住命令中使用的是一个感叹号,而不是一个 pipe(|)符号。如果执行了该命令,屏幕上将会出现来自摄像机的实况视频。这个方法很容易掌握。 在本文中,v4l2src 插件是 video4linux2 源;其默认行为是查找内核能够识别的第一个支持的视频设备及其生成的流视频。xvimagesink 插件在物理显示器上显示视频流。 一些元素既可以是源也可以是接收器。每个插件可以定义 pad 或连接器;一个给定的 pad 可以是源也可以是接收器。许多插件都支持其中的一种,并对输入进行转换以生成输出。 还存在许多特殊元素。例如,有一个名为 fakesink 的特殊元素,它只能消耗输出。为什么需要这样的元素呢?因为如果元素带有断开的输出,那么它将会等待其他元素消耗其输出。 首先快速回顾一下现有的资源。我们是从 maemo 站点的示例摄像机应用程序开始讨论的(参考资料)。此程序可以开箱即用,尽管其速度较慢。基本设计思想是,从 video4linux 源开始,将其过滤为 RGB,然后将它的一个副本发送到屏幕,另一个发送到可以临时保存 JPEG 文件的图像接收器。 实际上,颜色空间转换将占用大量资源,并且如果不需要保存实际的 JPEG 文件,没有必要进行转换。标准 xvimagesink 元素显示用摄像机的 YUV 格式编码的帧。 需要更改的第一步是将 colorspace 过滤器移动到进行 JPEG 转换的路径中。原始代码将过滤器的输出提供给一个 tee 元素,然后传送到一个图像接收器(用来在需要时保存 JPEG 文件)和屏幕上。这需要对每帧图像都进行转换。 对于 tee 元素,colorspace 过滤器将一直运行所有帧,但是现在这一情况可能被改变。gstreamer 库包含一些 探测器(probe) 函数,可用来修改元素的行为。对到达给定 pad 的帧调用探测器函数。如果探测器函数返回 TRUE,该帧被传递给流,如果返回 FALSE,该帧将被丢弃。只要用户按下按钮,示例代码注册特定的 save as JPEG 探测器函数。探测器函数然后保存帧并注销自身的注册。 但是,还有另一个选择:注册一个探测器(通常返回 FALSE)并在颜色空间转换之前连接它。然后,可以设置为如果用户单击 “take photo” 按钮,探测器就返回 TRUE。这意味着在其余时间里,colorspace 过滤器处理的流中没有数据。 现在,对管道设置的更改就再简单不过了:只需一次调用,将探测器添加到 tee 过滤器的一个输出 pad 中。探测器又叫做缓冲区探测器 — 它只在实际的数据块上被调用,比如视频帧。不会影响到无关的信息。 下面是用于添加回调的代码: 清单 2. 探测数据流
清单 3. 保留还是丢弃帧?
如果设置了 这应该能显著改善性能,但是在我的系统中性能仍不太好。最初的例子为流使用队列对象。从屏幕流删除队列对象可以消除对性能
的影响,但保存图像时例外。通过确保 JPEG 转换在与主显示器独立的线程中进行,其他流中的队列能够显著提升可感知的性能。这也允许从
save-as-JPEG 探测器删除更复杂的注册/注销代码、按钮 press callback,通过简单地编写 我最初使用 gstreamer 的 jpegenc 插件。从插件元素的名称就可以知道它的用途:将图像帧转换为 JPEG。不幸的是,它没有包含在 N800 的基本版本中。更糟的是,本应该在 gstreamer 的 plugins-good 版本中的包被分为多个部分发布。 可以使用一种简单的手动方法进行测试;下载 scratchbox 上的插件,配置并运行,将该插件的共享库复制到 N800。还有许多工作要做。example_camera 程序附带了 gdk_pixbuf;非常容易安装(已经安装上了)。 然而,gdk_pixbuf 似乎有点大材小用,而且我一直喜欢标准 libjpeg 库,该库也包含在 N800 中。附带这个库有一个很重要的原因,将在下一篇文章中说明。现在,我将演示用 libjpeg 来压缩文件的简单代码: 清单 4. 创建 JPEG 文件
我们的文件保存为 test.jpg。 现在摄像机应用程序能够正常工作了 — 捕捉单个视频帧并将其转换为流行的格式 — 下一步是将其和系统的其他部分结合并上传这些文件。在 N800 系列的第 3 期(最后一期)将讨论如何操作。 学习
获得产品和技术
讨论
|
|