2009年8月3日星期一

Linux的应用--Video Streaming探讨三

本期的重点在介绍影像撷取卡与影像撷取卡常见的 BT848/BT878
芯片。除了介绍影像撷取卡外, 也会来看 xawtv 这个有名的 video4linux/BTTV
应用程式。
什么是影像撷取卡
影像撷取卡的主要功能当然就是做影像的撷取了,
一张影像撷取卡应该拥有底下的基本功能。
影像撷取
影像撷取卡可撷取的影像页框 (frame) 的大小是很重要的,
本文第一篇里提到的几个基本影像页框大小都应该要支援, 包含 NTSC (640x480) 与
PAL (768x576)。影像撷取卡所捕捉的画面都是属于动态的画面,
影像的来源则要看所支援的视讯系统与所有的视讯装置。
支援的视讯系统
大部份影像撷取卡都会具备一组视讯输入端子, 即 S-Video (Y/C) 端子或
Composite 端子。在台湾的标准当然是 NTSC 系统, 一般而言,
我们是希望一张影像撷取卡可以支援越多视讯系统越好, 包括:
NTSC/PAL/PALN/PLAM/SECAM。可使用的视讯装置有较常见的 CCD, 或是家用 V8、Hi8
皆可, 一般而言我们也是希望一张影像撷取卡可以接越多视讯装置越好。
安装影像撷取卡
以笔者的影像撷取卡为例,使用的是 Chronos Video Shuttle I
的卡,所以只要安装 bttv模组即可,同时,bttv模组在 Linux kernel 2.2.17
下也会用到 i2c-old
与videodev两个模组,所以也要一并安装。在命令列下,安装这三个模组的命令为:
linux# insmod i2c-old
linux# insmod videodev
linux# insmod bttv
当然要确定 Linux kernel 有编译这三个模组的支援,然后再把这三个模组加到
/etc/modules.conf (Red Hat 7.0) 里。如果是使用 Linux kernel 2.4.x (如 Red
Hat Linux 7.1), 也可以直接在 /etc/modules.conf 里加上一行:
alias char-major-81 bttv
就可以了。然后再利用上一篇文章 (2) 的程序来做初始化, 可以看到底下的讯息:
/dev/video0: initialization OK... BT878(Chronos Video Shuttle I)
3 channels
3 audios
OK!
BT878 芯片初始化成功, 影象撷取卡名称为 Chronos Video Shuttle I,
成功找到并初始化 3 个 channel。bttv 模组就是底下会提到的 BTTV 躯动程序,
主要用途是躯动影像撷取卡上的 BT848/BT878 芯片。
影像撷取卡的应用
在 PC 上加装影像撷取卡, 就可以利用 PC 做影片剪辑的工作, 例如可以将类比的
V8 影片转换成数位影像, 并且储存到计算机里, 或制作成光盘保存。
配合这类的软件, 我们还可以 DIY
做影像的特效、转场特效、字幕、旁白等等。利用 PC
做影像剪辑的工是很耗计算机资源的, 所以不能用太阳春的 PC,
不然可以会很累人的!
压缩比
压缩比是判断一张影像撷取卡优劣的主要关键所在,
由于动态的影像所占用的空间相当大,
所以如果一张影像撷取卡无法有效将撷取出来的影像做压缩,
所需的硬盘空间都会相当惊人。
压缩比越好的影像撷取卡, 其工作效能越佳, 一般压缩比大约是 4:1,
使用压缩比越好的芯片, 当然也就越贵, 所以影像撷取卡是一分钱一分货的。
BT 878 芯片
目前大部份的数位影像撷取卡大部份都是以 BT878
单颗芯片为影像撷取卡之中心。BT878运作方式是以软件来进行影像解压缩工作,BT878
芯片负责将撷取之影像丢给 Linux 做影像处理, 而 BTTV 则是 Linuxkernel 的
BT878 芯片躯动程序。
由于影像是利用 BT878 撷取后交由软件来做影像处理,
因此在处理效能上自然就会比较差。如果是经由网络来传送影像的话,
我们就会再利用影像压缩技术 (H.261/H.263...等等) 来做影像处理。
什么是 BTTV
BTTV 是 Linux 上的 Bt848/849/878/879 芯片的躯动程序,
主要功能是做页框的截取 (frame grabber)。BTTV 是 video4linux
里重要的躯动程序, 目前分为二个版本:
0.8.x 的发展中版本
0.7.x 的稳定版本
Linux 上可用的影像撷取卡
http://www.linhardware.com/db/searchproduct.cgi?_catid=17
网页上可以找到在Linux 上支援程度比较好的几张影像撷取卡。而一般 Linux
上较受欢迎的影像撷取卡则是 Hauppauge 的几张卡, 笔者使用的也是Hauppauge
的卡。在 linhardware 网站上可以找到底下六张卡:
Hauppauge 401 WinTV-radio dbx-TV stereo
Hauppauge WinTV PCI TV Card
Hauppauge WinTV-GO PCI TV Card
Hauppauge WinTV-PCI Hauppauge
Hauppauge WinTV-Radio+NICAM
Hauppauge WinTV/PCI TV Card
关于 Linux 对于影像捕捉卡支援的中文文件 (HOWTO) 可以在 CLDP 网站上取得:
http://www.linux.org.tw/CLDP/Hardware-HOWTO-22.html
BTTV 相关软件 - xawtv
官方网站: http://bytesex.org/xawtv/index.html
安装方式:
1. linux# ./configure
2. linux# make depend
3. linux# make
4. linux# make install
如果您有 Red Hat Linux 7.1 PowerTools 光盘片的话, 也可以直接由 PowerTools
光盘片安装 xawtv 套件:
linux# rpm -ivh xawtv-3.34-1.i386.rpm
安装 xawtv 需要 libjpeg 与 libjpeg-devel 套件, 如果您是使用 Red Hat Linux
7.1 的话, 应该安装底下二个套件:
libjpeg-6b-15.i386.rpm (Disc 1)
libjpeg-devel-6b-15.i386.rpm (Disc 2)
xawtv 整个架构可以分成 7 个部份如下:
xawtv: 主程序部份。
fbtv: linux console 模式的 TV 应用程式, 使用 linux kernel 2.2.x 的
framebuffer。
set-tv: 命令列模式的工具, 用来设定 video4linux 的参数。
streamer: 命令列模式的工具, 用来捉取动态影像与 avi 影像。
radio: radio 应用程式。
webcam: 将捉取的影像以 FTP 方式上传到 Web Server 端, 用来设计 Web
即时影像的工具。
alevtd: videotext pages 的 Web Server。
xawtv 的 video4linux
xawtv 是相当好的 video4linux 方面的教材, 在上一期我们看过一遍 video4linux
的设计方法后, 接下来我们要先舍弃我们上一期所实作的 video4linux 程序库!
因为我们将要带导大家研究 xawtv 里以 video4linux API 设计的影像捕捉
(grab)部份的程序码,这个程序码的实作更完整, 因此在开始进入这个主题前,
必须先理解上一期所介绍的内容,
并且懂得我们实作的程序库内容,才能顺利进入状况。
取回 xawtv 的原始程序码解开后, 在 libng/ 目录下可以看到 grab-v4l.c
的档案,另外还有一个grab-v4l2.c 的档案, 这是 video4linux2 (version 2)
的版本。这里我们先介绍video4linux的版本 -grab-v4l.c。
grab-v4l.c 的程序码架构
大略扫瞄过 grab-v4l.c 的程序码后, 发现 grab-v4l.c 与上一期我们实作的
video4linux 程序库的架构很像。其实大多数利用 video4linux
来设计应用程式的软件, 其 video4linux 的 API
部份大多是自行重写的,反而很少利用现成的程序库, 因此仔细研究别人的程序码,
再来改进我们自己的 video4linux
程序库是我们的最终目的。程序一开始也是宣告了一个 ng_driver 结构的变数
(v4l_driver):
#ifndef __linux__
const struct ng_driver v4l_driver;
#else /* __linux__ */
然后可以看到 open 与 close 二个函数:
static void* v4l_open(char *device);
static int v4l_close(void *handle);
接下来还有许多函数的宣告, 同时还可以看到一些结构的宣告, 例如:
static struct STRTAB norms_v4l[] = {
{ VIDEO_MODE_PAL, "PAL" },
{ VIDEO_MODE_NTSC, "NTSC" },
{ VIDEO_MODE_SECAM, "SECAM" },
{ VIDEO_MODE_AUTO, "AUTO" },
{ -1, NULL }
};
我们可以用来显示 channel 是 PAL/NTSC/SECAM 或是 AUTO。xawtv 实作出来的
v4l_open() 函数可精彩了, 除了有设计函数应该要有的严谨的错误检查外,
v4l_open 也对硬件做了一些检查。xawtv 的 v4l 程序库也有 v4l_close() 函数,
用来关闭已开启的 video4linux 装置。在影像页框撷取方面, 共有底下 5 个函数:
static int v4l_setformat(void *handle, struct ng_video_fmt *fmt);
static int v4l_startvideo(void *handle, int fps, int buffers);
static void v4l_stopvideo(void *handle);
static struct ng_video_buf* v4l_nextframe(void *handle);
static struct ng_video_buf* v4l_getimage(void *handle);
函数的名称已经将其功能表达的很清楚了, 因此不再重覆解释。另外比较特别的是,
xawtv 的 video4linux 也支援了 framebuffer, 主要函数为:
int v4l_setupfb(void *handle, struct ng_video_fmt *fmt, void *base)
xawtv的 video4linux 程序库整体架构相当明白简单, 程序码也很好懂,
剩下的重点在于如何利用 video4linux 的 mmap模式来撷取二页的影像, xawtv 的
video4linux 程序库的使用方式我们只要了解这一点即可。
xawtv 的 video4linux 其中对影像撷取卡做初始化的方法我们已经会了,
再来就是做影象撷取的部份。mmap
方式我们将在下一期再做介绍。接下来的部份将浏览一下 xawtv
的功能架构与使用界面, 以利我们去研究 xawtv的程序码,并且还会介绍一个 Linux
下的 MP3 拨放程序 --, 会介绍 xxx 的原因是因为 xxx 也用到了
streaming的技术来拨放MP3 档案。
xawtv 的功能
底下我们将展示以 CCD (Composite 端子) 视讯装置输入影像, 并且利用 xawtv
显示动态影象的设定方式。
xawtv 的输出结果
这是 xawtv 显示动态影象的结果, 我们利用的是 CCD 视讯装置, 视讯来源为
Composite, TV Norm 为 NTSC。要有正确的显示结果, 必须正确地设定 TV Norm 与
Video Source 两个项目。
xawtv 的设定选单
在 xawtv 的主画面按二下鼠标右键后, 就会出现图 2
的视窗。几个常用的功能说明如下:
Full Screen on/off: 切换是否要全屏幕显示,
不过影像的大小则是跟视讯装置有关。
Grab Image: 将目前的画面存成图档 (ppm 或 jpeg)。
Record Movie (avi): 录制 avi 的电影档。
Bright/Hue/Contrast/Color: 调整视讯的对比、亮度、颜色。
设定 TV Norm
点取 TV Norm 项目后, 将 TV Norm 设定在正确的参数, 笔者使用的是 NTSC 的
CCD, 因此必须将这个项目设成 NTSC。
设定 Video Source
点取 Video Source 后, 再选取正确的视讯来源, 大部份的 CCD 都是 Compoiste
端子, 因此选择 Composite1。
xawtv 会列出目前影像撷取卡可用的视讯来源,
我们只要将视讯装置接到正确的视讯来源, 并完成 TV Norm 与 Video Source
的设定后就可以正确显示动态影像了。
利用 video4linux 来初始化影像撷取卡的方法在上一篇文章 (2)
中已列出完整范例程序码,
并且做了详细的说明。下一期我们将会更进一步来撰写设定 TV Norm 与 Video
Source 的程序码。
配合介绍如何设计 TV Norm 与 Video Source 的设定程序码, 我们还会根据 xawtv
的几个功能并配合 video4linux 来实作 xawtv 上的功能 (frame grab),
并且会列出完整的程序码范例做说明。
xawtv 也提供针对 FreeBSD 与 OpenBSD 的 BT848/BT878 躯动程序 (bktr)
所设计的影像撷取功能, 原始程序码放在 xawtv 里的 libng/ 目录, 档名为
grab-bsd.c 档案。

没有评论: