GV-MVP/RX2(ハードウェアMPEG2エンコード+TVチューナ付 キャプチャボード) で動画を見る
2008年3月23日(日) - 【カーネル・ドライバ, メディア】: 【RSS 2.0 feed】 【コメント】【トラックバック】
GV-MVP/RX2 を入手したので Linuxでの導入の流れをレポートします
Linuxで ハードウェアエンコード可能な TVキャプチャボードは数が限られていて
この GV-MVP/RX2 もその数少ない1つ

画像は 別のHPのを拾ってきた物なので注意 モノはもう中古ショップかオークションでしか手に入りません
| 名称 | GV-MVP/RX2 (生産終了) |
|---|---|
| MPEG2エンコーダ | CONEXANT CX23416-12 |
| デコーダ | Philips SAA7173HL |
| Y/C分離 | NEC uPD64084 |
| ゴーストリデューサ | NEC uPD64031 |
| チューナ | Panasonic VP27S/ENGE4324D |
| 音声 | XWM8739 (I2Sバス) |
| ADコンバータ | KHTEK AD1180 |
GV-MVP/RX と同等の構成のようです また GV-MVP/RX2E は Y/C分離やゴーストリデューサの機能が外れているようです
これらの構成チップが システム上で認識されるようにドライバモジュールを準備する必要があります
参考になる情報サイトとしては ぱ研 や ここFedora関係のページ
| CPU | Turion(tm)64-MT37 2.0GHz |
|---|---|
| マザーボード | KV8 Pro 3rd Eye |
| グラフィック | GeForce6600GT |
| OS | Linux kernel-2.6.24 |
| GCC | 4.1.2 |
| glibc | 2.5 |
カーネルのコンパイル
先に カーネルのコンフィグ&リコンパイルにより 必要な機能を追加しておきます 下記の表を参照ください
| i2c-core | 「I2C support」カーネルに組込み |
| i2c-dev | 「I2C device interface」カーネルに組込み |
| i2c-algo-bit | 「I2C bit-banging interfaces」カーネルに組込み |
| videodev | 「Video For Linux」カーネルに組込み CONFIG_VIDEO_V4L2=y も自動で設定される |
| v4l1-compat | 「Enable Video For Linux API 1 (DEPRECATED)」 と 「Enable Video For Linux API 1 compatible Layer」 をカーネルに組込み |
| ivtv, cx2341x | 「Video capture adapters」を組み込んだ上で 「Conexant cx23416/cx23415 MPEG encoder/decoder support」をモジュール組込みする ivtv.koが作られる |
| ivtvfb | 不要 もし組み込むなら「Graphics support」の「Support for frame buffer devices」の「Trident support」が必要らしい |
| tuner_simple | 「Customize analog tuner modules to build」した上で 「Simple tuner support」のみをカーネルに組込み (Customize〜 を選択しない場合 全てチューナモジュールがモジュール生成されるがそれはそれで動作する) |
| upd64031a | 「Autoselect pertinent encoders/decoders and other helper chips」を外した上で 「Encoders/decoders and other helper chips」の 「NEC Electronics uPD64031A Ghost Reduction」 をモジュール組込みする |
| upd64083 | 「Autoselect pertinent encoders/decoders and other helper chips」を外した上で 「Encoders/decoders and other helper chips」の 「NEC Electronics uPD64083 3-Dimensional Y/C separation」 をモジュール組込みする |
うちのカーネルコンフィグ(make menuconfig)を キャプチャイメージでお見せします

「I2C support」に *チェックをいれた上で 「I2C device interface」にも *チェック入れます

「I2C Algorithms」では 「I2C bit-banging interfaces」にチェックをいれます
M 指定して i2c_algo_bit モジュールとして作ってもかまいません

「Video For Linux」「Enable Video For Linux API 1」「同 compatible Layer」をチェックし
「customize analog tuner modules to build」のチェックを外しておけば
tuner モジュールをいれた場合に適切な チューナ用モジュールを選択してくれるようです
(customize analog tuner modules にチェックを入れて 不要なチューナを省略指定できるかも)
また 「Video capture adapters」を *選択したうえで次に

「Conexant cx23416/cx23415 MPEG encoder/decoder support」(ivtv)を M モジュール化します
カーネルで ivtv.ko モジュールを作らせてインストールしておいて
後で 外部の ivtv.ko で置き換えるという方針です
この時点で カーネルをビルド モジュールもインストール(make modules_install)し再起動します
$ lsmod Module Size Used by nvidia 4702512 22
この時点でまだ ビデオキャプチャ系のモジュールは見えません
$ dmesg 〜 i2c /dev entries driver 〜
I2Cドライバは モジュール化せずに組み込んだので ブート時に認識されています
ivtv.ko の置き換え
ivtv.ko を Linuxカーネルのものと置き換え saa717x.ko が Linuxカーネルにないので追加される構成となります
さきほど申したとおり ivtv モジュールを外部のものと置き換える必要があります
IVTVプロジェクトの ivtv-1.0.3.tar.gz を導入する必要があります
またこのパッケージでは saa717x.ko も提供されますがこれは必要ないかもしれません
カーネルに付属の saa7115.ko モジュールで動作しました
$ tar -xzf ivtv-1.0.3.tar.gz $ cd ivtv-1.0.3/ $ tar -xzf f9ivtv33.tar.gz $ CC=gcc make make -C driver all make[1]: Entering directory `/home/admin/ivtv-1.0.3/driver’ created ivtv-svnversion.h make -C /lib/modules/2.6.24/build M=/home/admin/ivtv-1.0.3/driver modules make[2]: Entering directory `/usr/src/linux-2.6.24′ CC [M] /home/admin/ivtv-1.0.3/driver/ivtv-routing.o CC [M] /home/admin/ivtv-1.0.3/driver/ivtv-cards.o CC [M] /home/admin/ivtv-1.0.3/driver/ivtv-controls.o CC [M] /home/admin/ivtv-1.0.3/driver/ivtv-driver.o 〜 gcc -I../driver -I../utils -D_GNU_SOURCE -O2 -Wall -lm vbi.c -o vbi gcc -I../driver -I../utils -D_GNU_SOURCE -O2 -Wall -lm wss.c -o wss gcc -I../driver -I../utils -D_GNU_SOURCE -O2 -Wall -lm vbi-passthrough.c -o vbi-passthrough gcc -I../driver -I../utils -D_GNU_SOURCE -O2 -Wall -lm vbi-detect.c -o vbi-detect gcc -I../driver -I../utils -D_GNU_SOURCE -O2 -Wall -lm ivtv-pcm-tester.c -o ivtv-pcm-tester gcc -I../driver -I../utils -D_GNU_SOURCE -O2 -Wall -lm mpeg-read-test.c -o mpeg-read-test gcc -I../driver -I../utils -D_GNU_SOURCE -O2 -Wall -lm mpeg-freq-test.c -o mpeg-freq-test gcc -I../driver -I../utils -D_GNU_SOURCE -O2 -Wall -lm mpeg-read-sleep-test.c -o mpeg-read-sleep-test make[1]: Leaving directory `/home/admin/ivtv-1.0.3/test’ $ su # CC=gcc make install # exit $
f9ivtv33.tar.gzは
かってにLinuxで配布されています
最終的に ivtv.ko が既存のものと置き換わり saa717x.ko モジュールも追加されます
また /usr/local/bin/ 以下に v4l2-ctl ivtvctl ivtv-tune などコマンドが追加されます
ファームウェアのインストール
実はここが 一番つまずいた部分でした
ivtv系のカードは別途 ファームウェアをアップロードする必要があります
ファームウェアを準備せず ivtvモジュールをロードすると しばらく固まったあと dmesg出力に
fw_setup_device() : name=v4l-cx2341x-enc.fw uevent=1 return=0<3>ivtv0: Unable to open firmware v4l-cx2341x-enc.fw (must be 376836 bytes) ivtv0: Did you put the firmware in the hotplug firmware directory? ivtv0: Retry loading firmware fw_setup_device() : name=v4l-cx2341x-enc.fw uevent=1 return=0<3>ivtv0: Unable to open firmware v4l-cx2341x-enc.fw (must be 376836 bytes) ivtv0: Did you put the firmware in the hotplug firmware directory? ivtv0: Failed to initialize on minor 0
となってしまいます
最近のカーネルでは デバイスがファームウェアを要求するケースに対応して request_firmware()
の機能をもっていますが ファームウェアは別途ファイルとして準備しておく必要があります
IVTVプロジェクトの firmware.tar.gz を使いました(ドライバCDから抽出する方法もあるらしい)
$ su # mkdir /lib/firmware # cd /lib/firmware # tar -xzf firmware.tar.gz # exit $ ls -l -rw-r–r– 1 505 502 262144 5月 26 2006 v4l-cx2341x-dec.fw -rw-r–r– 1 505 502 376836 2月 17 2007 v4l-cx2341x-enc.fw -rw-r–r– 1 505 502 155648 5月 26 2006 v4l-cx2341x-init.mpg -rw-r–r– 1 505 502 16382 5月 26 2006 v4l-cx25840.fw -rw-r–r– 1 505 502 8192 10月 6 2006 v4l-pvrusb2-24xxx-01.fw -rw-r–r– 1 505 502 8192 7月 1 2006 v4l-pvrusb2-29xxx-01.fw
さらに ファームウェアは HOTPLUG と sysfs の機能により読み込まれるようで
そちらの設定も必要です まず hotplug の確認から
$ cat /proc/sys/kernel/hotplug /sbin/hotplug
カーネルの機能により /sbin/hotplug スクリプトが読み込まれる設定となっています
実際の hotplugスクリプトの内容は以下のとおりです
$ cat /sbin/hotplug
〜
DIR=”/etc/hotplug.d”
# echo ‘/sbin/hotplug debug: ‘ $1 >> /ram/hotpluglog
for I in “${DIR}/$1/”*.hotplug “${DIR}/”default/*.hotplug ; do
if [ -f $I ]; then
test -x $I && $I $1 ;
fi
done
exit 1
数行のシェルスクリプトで /etc/hotplug.d/引数/*.hotplug のスクリプトを呼び出す仕様
であることがわかります ちなみに 引数は 「firmware」 が指定されるようです
従って /etc/hotplug.d/firmware/firmware.hotplug (755) を以下の内容で記述します
#!/bin/sh
#
# Firmware-specific hotplug policy agent.
#
# Kernel firmware hotplug params include:
#
# ACTION=%s [add or remove]
# DEVPATH=%s [in 2.5 kernels, /sys/$DEVPATH]
# FIRMWARE=%s
#
# HISTORY:
#
# 24-Jul-2003 Initial version of "new" hotplug agent.
#
# $Id: firmware.agent,v 1.1 2003/10/07 19:34:19 kroah Exp $
#
cd /etc/hotplug
. hotplug.functions
# DEBUG=yes export DEBUG
# directory of the firmware files
FIRMWARE_DIR=/lib/firmware
# mountpoint of sysfs
SYSFS=$(sed -n 's/^.* ([^ ]*) sysfs .*$/1/p' /proc/mounts)
# use /proc for 2.4 kernels
if [ "$SYSFS" = "" ]; then
SYSFS=/proc
fi
#
# What to do with this firmware hotplug event?
#
# new code
echo "ECHOING DEVICE PATH";
echo $DEVPATH;
echo $ACTION;
echo $SYSFS;
echo $FIRMWARE;
case "$ACTION" in
add)
if [ ! -e $SYSFS/$DEVPATH/loading ]; then
sleep 1
fi
if [ -f $FIRMWARE_DIR/$FIRMWARE ]; then
echo 1 > $SYSFS/$DEVPATH/loading
cp $FIRMWARE_DIR/$FIRMWARE $SYSFS/$DEVPATH/data
echo 0 > $SYSFS/$DEVPATH/loading
else
echo -1 > $SYSFS/$DEVPATH/loading
fi
;;
remove)
;;
*)
mesg "Firmware '$ACTION' event not supported"
exit 1
;;
esac
ちなみに このスクリプトは どっかのホームページからのパクリです
hotplugが呼び出されるときに $DEVPATH $ACTION $SYSFS $FIRMWARE の環境変数がセットされるようでそれを組み合わせて適切なファームウェアを /sys/〜/data にアップロードする仕組みです
モジュールのロード
関連するチップのモジュールをロードしてから ivtvモジュールをロードします
tuner=46 と ntsc=j のオプション指定は必須です
$ su # modprobe saa7115 # modprobe upd64031a # modprobe upd64083 # modprobe wm8739 # modprobe cx2341x # modprobe tuner # modprobe ivtv tuner=46 ntsc=j # chmod 666 /dev/video0 # exit
一般ユーザでも video0 にアクセスできるように アクセス権限を設定しています
モジュールとしては以下のように見えます
$ lsmod Module Size Used by ivtv 114752 0 tveeprom 13328 1 ivtv tuner 36768 0 tea5767 4804 1 tuner tda8290 10116 1 tuner tuner_simple 7048 1 tuner mt20xx 10760 1 tuner tea5761 4036 1 tuner cx2341x 10052 1 ivtv wm8739 5520 0 upd64083 4688 0 upd64031a 4944 0 saa7115 13392 0 nvidia 4702512 22
tunerのモジュールが複数読み込まれているのが見えます(使われているかどうかわかりませんが)
tveepromは tuner用の EEPROM処理モジュールです
$ dmesg ivtv: Start initialization, version 1.1.0 ivtv0: Initializing card #0 ivtv0: Autodetected I/O Data GV-MVP/RX, GV-MVP/RX2W (dual tuner) card (cx23416 based) ACPI: PCI Interrupt 0000:00:0b.0[A] -> GSI 19 (level, low) -> IRQ 21 ivtv0: Unreasonably low latency timer, setting to 64 (was 32) saa7115 3-0021: saa7115 found (1f7115d0e100000) @ 0×42 (ivtv i2c driver #0) upd64031a 3-0012: chip found @ 0×24 (ivtv i2c driver #0) upd64083 3-005c: chip found @ 0xb8 (ivtv i2c driver #0) wm8739 3-001a: chip found @ 0×34 (ivtv i2c driver #0) tuner 3-0043: chip found @ 0×86 (ivtv i2c driver #0) tda9887 3-0043: tda988[5/6/7] found @ 0×43 (tuner) tuner 3-0043: type set to tda9887 All bytes are equal. It is not a TEA5767 tuner 3-0060: chip found @ 0xc0 (ivtv i2c driver #0) ivtv0: Failed to load module tuner ivtv0: Failed to load module saa7115 ivtv0: Failed to load module upd64031a ivtv0: Failed to load module upd64083 ivtv0: Failed to load module vp27smpx ivtv0: Failed to load module wm8739 tuner-simple 3-0060: type set to 46 (Panasonic VP27s/ENGE4324D) tuner 3-0060: type set to Panasonic VP27s/ENG ivtv0: Registered device video0 for encoder MPG (4096 kB) ivtv0: Registered device video32 for encoder YUV (2048 kB) ivtv0: Registered device vbi0 for encoder VBI (1024 kB) ivtv0: Registered device video24 for encoder PCM (320 kB) ivtv0: Initialized card #0: I/O Data GV-MVP/RX, GV-MVP/RX2W (dual tuner) ivtv: End initialization
ivtvモジュールをロードした瞬間に dmesg的に 各種チップが認識されます
ひとまずドライバ関係はここまでです デバイスが認識され /dev/ 以下に次のファイルが作られます
$ ls -l /dev/ 〜 crw-rw—- 1 root root 89, 0 3月 25 22:36 i2c-0 crw-rw—- 1 root root 89, 1 3月 25 22:36 i2c-1 crw-rw—- 1 root root 89, 2 3月 25 22:36 i2c-2 crw-rw—- 1 root root 89, 3 3月 25 23:06 i2c-3 〜 crw-rw—- 1 root root 81, 224 3月 25 23:06 vbi0 crw-rw-rw- 1 root root 81, 0 3月 25 23:06 video0 crw-rw-rw- 1 root root 81, 24 3月 25 23:06 video24 crw-rw-rw- 1 root root 81, 32 3月 25 23:06 video32 〜
udevの設定で アクセス権の許可を与える設定にしているので
パーミッションの見えかたが多少異なるかもしれません
i2c-0 〜 i2c-3 は I2Cアダプタを表します
vbi0 は VBI(アナログ放送の垂直帰線期間中に埋め込まれるデータで テレテキストとか言われる)
video0 は エンコード済のデータ(この場合 MPEG2)
video24 は PCMサウンドのようです(未確認)
video32 は 非圧縮YUVデータのようです(未確認)
チャンネル選択
コンポジット入力 S端子入力 TVチューナー のいずれかを選択できます
$ v4l2-ctl -d /dev/video0 -i 2 Video input set to 2 (Composite 1)
$ v4l2-ctl -d /dev/video0 -i 1 Video input set to 1 (S-Video 1)
$ v4l2-ctl -d /dev/video0 -i 0 Video input set to 0 (Tuner 1)
チューナーの場合はさらにチャンネルを選択できます japan-bcaet と japan-cable が選択できます
$ ivtv-tune -d /dev/video0 -t japan-bcast -l 1 91.250 2 97.250 3 103.250 4 171.250 5 177.250 〜 57 735.250 58 741.250 59 747.250 60 753.250 61 759.250 62 765.250
アナログ放送周波数の一覧が確認できます
$ ivtv-tune -d /dev/video0 -t japan-cable -l 13 109.250 14 115.250 15 121.250 16 127.250 17 133.250 18 139.250 19 145.250 〜 57 427.250 58 433.250 59 439.250 60 445.250 61 451.250 62 457.250 63 463.250
ケーブルテレビに周波数テーブルです
実際にチャンネルを選択するには -c オプションです
$ ivtv-tune -d /dev/video0 -t japan-bcast -c 12 /dev/video0: 217.250 MHz
映像を確認
/dev/video0 は読みだしで MPEG2ストリームとして読み出せます
手元の環境には Xineがインストールされているので それで観賞できます

japan-bcastのキャプチャ画像です

コンポジット(ストリートファイター3 3rd on Dreamcast)のキャプチャ画像です
実際の映像と 最終的にディスプレイに出力される映像とでは 2秒ほどの遅延があるため
ゲームでの利用は残念ながら現実的ではありません
画質の調整
v4l2-ctl コマンドで画質をコントロールできるようです
文法としては v4l2-ctl -d /dev/video0 -c 項目名=値
項目名 とその意味と 値の範囲は以下のコマンドで情報がとれます
$ v4l2-ctl -d /dev/video0 -L
User Controls
brightness (int) : min=0 max=255 step=1 default=128 value=128 flags=slider
contrast (int) : min=0 max=127 step=1 default=64 value=64 flags=slider
saturation (int) : min=0 max=127 step=1 default=64 value=64 flags=slider
hue (int) : min=-128 max=127 step=1 default=0 value=0 flags=slider
volume (int) : min=0 max=65535 step=655 default=58880 value=50736
balance (int) : min=0 max=65535 step=655 default=32768 value=32768
mute (bool) : default=1 value=0
MPEG Encoder Controls
stream_type (menu) : min=0 max=5 default=0 value=0 flags=update
0: MPEG-2 Program Stream
2: MPEG-1 System Stream
3: MPEG-2 DVD-compatible Stream
4: MPEG-1 VCD-compatible Stream
5: MPEG-2 SVCD-compatible Stream
stream_vbi_format (menu) : min=0 max=1 default=0 value=0
0: No VBI
1: Private packet, IVTV format
audio_sampling_frequency (menu) : min=0 max=2 default=1 value=1
0: 44.1 kHz
1: 48 kHz
2: 32 kHz
audio_encoding_layer (menu) : min=1 max=1 default=1 value=1 flags=update
1: Layer II
audio_layer_ii_bitrate (menu) : min=9 max=13 default=10 value=10
9: 192 kbps
10: 224 kbps
11: 256 kbps
12: 320 kbps
13: 384 kbps
audio_stereo_mode (menu) : min=0 max=3 default=0 value=0 flags=update
0: Stereo
1: Joint Stereo
2: Dual
3: Mono
audio_stereo_mode_extension (menu) : min=0 max=3 default=0 value=0 flags=inactive
0: Bound 4
1: Bound 8
2: Bound 12
3: Bound 16
audio_emphasis (menu) : min=0 max=2 default=0 value=0
0: No Emphasis
1: 50/15 us
2: CCITT J17
audio_crc (menu) : min=0 max=1 default=0 value=0
0: No CRC
1: 16-bit CRC
audio_mute (bool) : default=0 value=0
video_encoding (menu) : min=0 max=1 default=1 value=1 flags=readonly
0: MPEG-1
1: MPEG-2
video_aspect (menu) : min=0 max=3 default=1 value=1
0: 1×1
1: 4×3
2: 16×9
3: 2.21×1
video_b_frames (int) : min=0 max=33 step=1 default=2 value=2 flags=update
video_gop_size (int) : min=1 max=34 step=1 default=12 value=15
video_gop_closure (bool) : default=1 value=1
video_bitrate_mode (menu) : min=0 max=1 default=0 value=0 flags=update
0: Variable Bitrate
1: Constant Bitrate
video_bitrate (int) : min=0 max=27000000 step=1 default=6000000 value=6000000
video_peak_bitrate (int) : min=0 max=27000000 step=1 default=8000000 value=8000000
video_temporal_decimation (int) : min=0 max=255 step=1 default=0 value=0
video_mute (bool) : default=0 value=0
video_mute_yuv (int) : min=0 max=16777215 step=1 default=32896 value=32896
spatial_filter_mode (menu) : min=0 max=1 default=0 value=0 flags=update
0: Manual
1: Auto
spatial_filter (int) : min=0 max=15 step=1 default=0 value=0 flags=slider
spatial_luma_filter_type (menu) : min=0 max=4 default=0 value=1
0: Off
1: 1D Horizontal
2: 1D Vertical
3: 2D H/V Separable
4: 2D Symmetric non-separable
spatial_chroma_filter_type (menu) : min=0 max=1 default=0 value=1
0: Off
1: 1D Horizontal
temporal_filter_mode (menu) : min=0 max=1 default=0 value=0 flags=update
0: Manual
1: Auto
temporal_filter (int) : min=0 max=31 step=1 default=0 value=8 flags=slider
median_filter_type (menu) : min=0 max=4 default=0 value=0 flags=update
0: Off
1: Horizontal
2: Vertical
3: Horizontal/Vertical
4: Diagonal
median_luma_filter_minimum (int) : min=0 max=255 step=1 default=0 value=0 flags=inactive slider
median_luma_filter_maximum (int) : min=0 max=255 step=1 default=255 value=255 flags=inactive slider
median_chroma_filter_minimum (int) : min=0 max=255 step=1 default=0 value=0 flags=inactive slider
median_chroma_filter_maximum (int) : min=0 max=255 step=1 default=255 value=255 flags=inactive slider
insert_navigation_packets (bool) : default=0 value=0
具体的には 例えば MPEG2のビットレートを落としてキャプチャ動画のサイズを落とすなどが考えられます
$ v4l2-ctl -d /dev/video0 -c video_bitrate=2000000
ハードディスクレコーダとして利用する場合は 事前に画質やチャンネルをチューニングした上で
$ cat /dev/video0 > movie.mpg
と単純にストリームをファイルにコピーするだけです
実際はスクリプトやツールなどを利用する形となるでしょう
ファームウェアの利用について
↑でファームウェアのロードの仕組みについて触れましたが
実際にファームウェアを ロード/アンロード するタイミングは /dev/video0 を open()/close()するタイミングのようです
具体的には Xineを開いたり閉じたりしたとき キャプチャの開始/終了時 となります
| open()時 | DEVPATH=/devices/pci0000:00/0000:00:0b.0/firmware/firmware-0000:00:0b ACTION=add SYSFS=/sys FIRMWARE=v4l-cx2341x-enc.fw |
| close()時 | DEVPATH=/devices/pci0000:00/0000:00:0b.0/firmware/firmware-0000:00:0b ACTION=remove SYSFS=/sys FIRMWARE=v4l-cx2341x-enc.fw |
Xawtvも 試してみましたが nvidiaドライバ(Depth 24までしか指定できない?)との相性からか
「32bppでないとダメっす」みたいなことを言われて見れませんでした
あと オーバーレイできると低速CPUにとってうれしい状況ですが 確認とれませんでした




