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 を視聴できる。