Linux でテレビ録画を行なう方法は、 多くの Web ページで紹介されているが、 ビデオキャプチャ・カードによっては、 Linux カーネルのバージョンが変わると一筋縄にはいかなかったりするので、 現時点での Linux カーネル安定版の最新バージョン 2.6.22.10 で、 I-O DATA 製 ハードウェア MPEG-2 エンコーダ搭載TVキャプチャボード GV-MVP/RX2W (2006年7月5日生産終了) を使う方法をメモ (2.6.24.4 で使う方法)。
といっても多くの方々の努力により、 GV-MVP/RX2 は標準のカーネルのままで (多少の不具合はあるにせよ) テレビ視聴が可能になりつつあるので、 Linux 2.6.22.10 の時点で必要なパッチは、 以下の三ヵ所のみ (モノラル音声で構わなければ saa7115 に対するパッチのみ)。 なお、 IVTV プロジェクト で 最新ドライバが公開されているが、 少なくとも GV-MVP/RX2W を使う限りにおいては 既に Linux 2.6.22.10 カーネルに取り込まれているドライバだけで問題がないので、 標準のカーネルのドライバのみを使っている。
まず、SAA7115 Video Decoder ドライバ・モジュール saa7115.ko に対するパッチ:
diff -ru linux-2.6.22.10.org/drivers/media/video/saa7115.c linux-2.6.22.10/drivers/media/video/saa7115.c --- linux-2.6.22.10.org/drivers/media/video/saa7115.c 2007-08-23 08:23:54.000000000 +0900 +++ linux-2.6.22.10/drivers/media/video/saa7115.c 2007-10-14 06:37:09.000000000 +0900 @@ -1543,7 +1543,8 @@ saa711x_writeregs(client, saa7113_init); break; default: - state->crystal_freq = SAA7115_FREQ_32_11_MHZ; + state->ucgc = 1; + state->cgcdiv = 0x04; saa711x_writeregs(client, saa7115_init_auto_input); } saa711x_writeregs(client, saa7115_init_misc);
CGC (Clock Generation Circuit) の設定。 SAA7115 は 32.11MHz か 24.576MHz の水晶発振子を利用できて、 GV-MVP/RX2 では後者なのであるが、 このパッチをあてておかないと 32.11MHz の設定になってしまって、 録画したものを再生すると音声が早回しになってしまう。
次に、オーディオ・チップ・ドライバ・モジュール tvaudio.ko に対するパッチ:
diff -ru linux-2.6.22.10.org/drivers/media/video/tvaudio.c linux-2.6.22.10/drivers/media/video/tvaudio.c --- linux-2.6.22.10.org/drivers/media/video/tvaudio.c 2007-08-23 08:23:54.000000000 +0900 +++ linux-2.6.22.10/drivers/media/video/tvaudio.c 2007-10-14 06:38:26.000000000 +0900 @@ -528,6 +528,31 @@ chip_write(chip,TDA985x_C6,c6); } +static int gvmvprx_getmode(struct CHIPSTATE *chip) { + return VIDEO_SOUND_MONO; +} + +extern int tda9887_tuner_init(struct i2c_client *c); +static void gvmvprx_setmode(struct CHIPSTATE *chip, int mode) { + u8 data[3] = { 0x00, 0x00, 0x04 }; + + switch (mode) { + case VIDEO_SOUND_MONO: + case VIDEO_SOUND_LANG1: + break; + case VIDEO_SOUND_STEREO: + data[1] = 0x01; + break; + case VIDEO_SOUND_LANG2: + data[1] = 0x02; + break; + } + + if (i2c_master_send(&chip->c, data, sizeof(data)) != sizeof(data)) { + v4l_err(&chip->c, "%s: I/O error setting audmode\n", chip->c.name); + } +} + /* ---------------------------------------------------------------------- */ /* audio chip descriptions - defines+functions for tda9873h */ @@ -1307,17 +1332,17 @@ .checkmode = generic_checkmode, }, { - .name = "tda9850", + .name = "tda9850 (GV-MVP/RX)", .id = I2C_DRIVERID_TDA9850, .insmodopt = &tda9850, .addr_lo = I2C_ADDR_TDA985x_L >> 1, .addr_hi = I2C_ADDR_TDA985x_H >> 1, .registers = 11, - .getmode = tda985x_getmode, - .setmode = tda985x_setmode, + .getmode = gvmvprx_getmode, + .setmode = gvmvprx_setmode, - .init = { 8, { TDA9850_C4, 0x08, 0x08, TDA985x_STEREO, 0x07, 0x10, 0x10, 0x03 } } + .init = { 3, { 0x00, 0x01, 0x04 } } }, { .name = "tda9855",
ステレオ/モノラル/音声多重(二ヶ国語放送) 音声モードの変更。 GV-MVP/RX2W は他のチューナと異なり、 設定変更の際 3 バイトのデータを送信する必要があるらしい。
tda9887 を deemphasis->off (このチップは deemphasis すると音声を強制でモノラルにしてしまう。 tda9887.c の NTSC-M-J の項では deemphasis を default で OFF にすべきなのではないでしょうか。 素人考えかな。)
ivtv-0.2.0-rc3j-paken.051002-bilingul.patch をベースに MPX 操作 (レジスタ0に3バイト書き込むほう) すればうちのカードでは音声多重に対応できるようです。 レジスタ 0 に 1 バイト書き込むほうのMPX操作では うちのカードでは動作しませんでした。 カードのリビジョンとかの関係かもしれません。ぱ研「LinuxでITVC16-STVLP」 の kazz 氏コメント (2007-03-10) から引用
DeEmphasis (DEM) モードを設定すると常にモノラル音声になってしまう。 kazz 氏が言及しているように default で DEM を off にしておけば 済むような気がするし、 そもそもなぜ DEM がデフォルトで ON になっているのか疑問だったので、 以下のようなパッチを tuner チップ・ドライバ・モジュール tuner.ko の tda9887.c にあてて、 NTSC-M-JP の場合は DeEmphasis を off にしてみた。
diff -ru linux-2.6.22.10.org/drivers/media/video/tda9887.c linux-2.6.22.10/drivers/media/video/tda9887.c --- linux-2.6.22.10.org/drivers/media/video/tda9887.c 2007-08-23 08:23:54.000000000 +0900 +++ linux-2.6.22.10/drivers/media/video/tda9887.c 2007-10-14 11:59:50.000000000 +0900 @@ -214,8 +214,7 @@ .name = "NTSC-M-JP", .b = ( cNegativeFmTV | cQSS ), - .c = ( cDeemphasisON | - cDeemphasis50 | + .c = ( cDeemphasisOFF | cTopDefault), .e = ( cGating_36 | cAudioIF_4_5 |
「cDeemphasisON | cDeemphasis50」の部分を「cDeemphasisOFF」に変更しただけの 安易なパッチ (^^;) であるが、 とりあえずこれでステレオ/音声多重での録画が可能になっている。
以上のように tvaudio と tuner (tda9887.c) の両ドライバ・モジュールに パッチをあてることにより、 ステレオ/音声多重で録画できる。 もちろん v4l2-ctl コマンドで音声モードを変更することもできるが、 録画は常に「ステレオ/音声多重」で行なっておいて、 再生時に音声モードを切替えたほうが便利。
私は録画 perl スクリプトを自作して使っているが、 この perl スクリプトで使用している Video::ivtv & Video::Frequencies モジュールには若干問題がある。 すなわち setFrequency する際にチューナ形式を指定し忘れているので、 正しく TV チャンネルの変更が行なえない。 私は以下のような修正パッチをあてて使用している。
diff -u Video-ivtv-0.13/ivtv.xs.org Video-ivtv-0.13/ivtv.xs --- Video-ivtv-0.13/ivtv.xs.org 2004-06-14 06:07:40.000000000 +0900 +++ Video-ivtv-0.13/ivtv.xs 2007-10-08 10:03:57.000000000 +0900 @@ -132,6 +132,7 @@ } CODE: vf.tuner = tuner; + vf.type = V4L2_OUTPUT_TYPE_ANALOG; if (ioctl(fd, VIDIOC_G_FREQUENCY, &vf) < 0) { RETVAL = -1; @@ -158,6 +159,7 @@ } CODE: vf.tuner = tuner; + vf.type = V4L2_OUTPUT_TYPE_ANALOG; vf.frequency = freq; if (ioctl(fd, VIDIOC_S_FREQUENCY, &vf) < 0) {
この録画スクリプトは
予約録画 (-t オプション) もサポートしている他、
tv -P 1234
などと実行すると、
TV サーバとして利用することもできる。
つまり LAN 内の任意のマシンで、
VLC media player を使って
http://senri:1234/?c=1
などとチャンネル指定付で tv サーバへ接続し、
TV を視聴できる。