Linux的應用--Video Streaming探討 三

作者: 陳俊宏、劉力彰
www.jollen.org

本期的重點在介紹影像擷取卡與影像擷取卡常見的 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 檔案。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章