PT2+FUSE_b25+MythTVをDebianで使う上で録画失敗から対策したことを対策箇所ごとにまとめる。
エンコードなどマシンに負荷をかけすぎると録画中、fuse_b25がsyslogに“Driver Baffar Overflowed"というエラーを出して、以降の部分が録画されなくなる。
エンコードの際は、CPUコア(スレッド)の数より少ないスレッド数を指定する。
#2コア2スレッドの場合 $ ffmpeg -threads 1 [オプション]
更にfuse_b25の優先度は高くし、エンコードの優先度を低くしておく。
/etc/rc.local、fuse_b25のマウント部分
#マウント先の数字を元のデバイスよりいくつ大きくするか
OFFSET=10
for ADAPTER in 0 1 2 3
do
NEW_ADAPTER=`expr $ADAPTER + $OFFSET`
/usr/local/sbin/b25dir $NEW_ADAPTER
nice --4 /usr/local/bin/fuse_b25 --target /dev/dvb/adapter$ADAPTER /dev/dvb/adapter$NEW_ADAPTER -o allow_other
done
ffmpegの優先度を下げる
$ nice -15 ffmpeg [オプション]
また、録画ディスクのI/Oに負荷をかけすぎても同様のことが起こるのでTsSplitterを使う場合は必ずWAITオプションを指定する。
$ wine TsSplitter.exe [オプション] -WAIT2,5
録画の開始時にMythTVのバックエンドが落ちることがある。PIDファイルが残るのでmythbackendのプロセスがなく、PIDファイルが残っていたら再起動させる。念のためfuse_b25の再マウントも行う。
$ sudo vi /usr/local/sbin/mythtv_check.sh
#!/bin/sh
#ロックファイルの存在確認
if [ ! -e /var/run/mythtv/mythbackend.pid ]
then
exit 0
fi
#プロセスの存在確認
if [ `pgrep -c mythbackend` -ne 0 ]
then
exit 0
fi
#ジョブが実行されていればkill
pkill -9 -u mythtv
#fuse_b25の再マウント
#マウント先の数字を元のデバイスよりいくつ大きくするか
OFFSET=10
for ADAPTER in 0 1 2 3
do
NEW_ADAPTER=`expr $ADAPTER + $OFFSET`
umount /dev/dvb/adapter$NEW_ADAPTER
if [ $? -eq 0 ]
then
nice --4 /usr/local/bin/fuse_b25 --target /dev/dvb/adapter$ADAPTER /dev/dvb/adapter$NEW_ADAPTER -o allow_other
fi
done
#mythtvの再起動
/etc/init.d/mythtv-backend restart
CRONに登録(毎分実行)
$ sudo crontab -e * * * * * /usr/local/sbin/mythtv_check.sh
MythTVがActive EIT Scanから録画に切り替わるときによく落ちているような感じではある。
Card I/O failed too many times. dropped an ECM due to the failed/slow card.
時々、fuse_b25がsyslogに上記エラーを吐き続けて、録画できなくなる。これはマウントし直すまで直らない。その上、MythTVがActive EIT Scanでロックするため、マウント解除できなくなる。
この異常はActive EIT Scanを行なっている時に起こりやすく、ロックされて再マウントできなくなるので、優先して使うチューナーはActive EIT Scanを無効にしておくと良いだろう。
原因は不明だが、受信状態の悪い信号やccidとの相性が考えられる。
swatchで/var/log/syslogを監視し、該当のログが出た場合にスクリプトを使って対処するようにする。
telnetを使って、Active EIT Scanを停止させるため、expectをインストールする。
$ sudo aptitude install expect
スクリプトの作成
$ sudo vi /usr/local/sbin/b25refresh_pid.sh
#!/bin/sh
#Myth Protocolのバージョン
PROTOCOL_VER="63"
PROTOCOL_TOKEN="3875641D"
#MythTVのDBに登録されているホスト名
HOSTNAME="localhost"
#MythTVのPort
CONTROL_PORT="6543"
#MythTVのStatus Port
STATUS_PORT="6544"
#PIDからデバイス名とマウント先を取得
PID=$1
ADAPTERS=`ps aux | awk -v PID=$PID '$2==PID{print $13FS$14}'`
set -- $ADAPTERS
ADAPTER=$1
NEW_ADAPTER=$2
#チューナーのIDを取得
RECORDER_ID=`wget http://localhost:$STATUS_PORT/ -O - -o /dev/null | \
awk -v ENCODER=${NEW_ADAPTER}/frontend0 '$6==ENCODER{print $2}'`
#IDが取得できたらチューナーを解放
if [ ! -z $RECORDER_ID ]
then
#Myth Protocolで通信(telnet)
expect -c "
set timeout 20
spawn telnet localhost $CONTROL_PORT
expect \"\n\"
expect \"\n\"
expect \"\n\"
send \"33 MYTH_PROTO_VERSION $PROTOCOL_VER $PROTOCOL_TOKEN\n\"
expect \"ACCEPT\"
expect \"$PROTOCOL_VER\"
send \"\n\"
send \"23 ANN Monitor $HOSTNAME 0\n\"
expect \"OK\"
send \"87 QUERY_RECORDER $RECORDER_ID\[\]:\[\]SPAWN_LIVETV\[\]:\[\]release\[\]:\[\]0\n\"
send \"87 QUERY_RECORDER $RECORDER_ID\[\]:\[\]SPAWN_LIVETV\[\]:\[\]release\[\]:\[\]0\n\"
expect \"ok\"
send \"87 QUERY_RECORDER $RECORDER_ID\[\]:\[\]STOP_LIVETV\n\"
send \"87 QUERY_RECORDER $RECORDER_ID\[\]:\[\]STOP_LIVETV\n\"
send \"87 QUERY_RECORDER $RECORDER_ID\[\]:\[\]STOP_LIVETV\n\"
expect \"ok\"
send \"\n\n\n\n\"
" > /dev/null
sleep 1
fi
#fuse_b25を再マウント
umount $NEW_ADAPTER
if [ $? -eq 0 ]
then
nice --4 /usr/local/bin/fuse_b25 --target $ADAPTER $NEW_ADAPTER -o allow_other
exit 0
else
exit 1
fi
PIDを指定すると、デバイスを解放させて再マウントするスクリプト。環境に合わせて変数を書き換えて利用する。バージョンとトークンの一覧はここにある。Myth Protocolで通信し、Live TVを利用するふりをして、デバイスを解放させる。
swatchのインストール
$ sudo aptitude install swatch
swatchで使用するディレクトリの作成
$ sudo mkdir /usr/local/swatch/ $ sudo mkdir /usr/local/swatch/rules/ #設定ファイルの格納先 $ sudo mkdir /usr/local/swatch/scripts/ #生成されるスクリプトの格納先
設定ファイルの作成
$ sudo vi /usr/local/swatch/rules/fuse_b25.rule watchfor /FUSE_b25\[([0-9]+)\]: Card I\/O failed too many times./ exec /usr/local/sbin/b25refresh_pid.sh $1
swatchによる監視の開始
$ sudo swatch --daemon -c /usr/local/swatch/rules/fuse_b25.rule --script-dir /usr/local/swatch/scripts/ -t /var/log/syslog
/etc/rc.localに追記
#マウント先の数字を元のデバイスよりいくつ大きくするか OFFSET=10 for ADAPTER in 0 1 2 3 do NEW_ADAPTER=`expr $ADAPTER + $OFFSET` /usr/local/sbin/b25dir $NEW_ADAPTER nice --4 /usr/local/bin/fuse_b25 --target /dev/dvb/adapter$ADAPTER /dev/dvb/adapter$NEW_ADAPTER -o allow_other done rm /usr/local/swatch/scripts/.swatch_script.* swatch --daemon -c /usr/local/swatch/rules/fuse_b25.rule --script-dir /usr/local/swatch/scripts/ -t /var/log/syslog
監視を停止させたりする必要がないので簡単に済ませた。
定期的に再マウントさせる。再マウント時にカードが初期化されるので録画中であった場合、関係のないチューナーでも映像が乱れる。そのため、録画中には再マウントを行わない。
再マウント用のシェルスクリプト
$ sudo vi /usr/local/sbin/b25refresh.sh
#!/bin/sh
#MythTVのStatus Port
PORT=6544
#マウント先の数字を元のデバイスよりいくつ大きくするか
OFFSET=10
#録画・視聴中に動作しない
if [ `wget http://localhost:$PORT/ -O - -o /dev/null | \
grep /dev/dvb/adapter | grep -c "recording"` -eq 0 ]
#視聴中は構わず再マウントする場合
#if [ `wget http://localhost:$PORT/ -O - -o /dev/null | \
# grep /dev/dvb/adapter | grep -c " is recording."` -eq 0 ]
then
for ADAPTER in 0 1 2 3
do
NEW_ADAPTER=`expr $ADAPTER + $OFFSET`
umount /dev/dvb/adapter$NEW_ADAPTER
if [ $? -eq 0 ]
then
sleep 1
nice --4 /usr/local/bin/fuse_b25 --target /dev/dvb/adapter$ADAPTER /dev/dvb/adapter$NEW_ADAPTER -o allow_other
else
exit 1
fi
done
fi
CRONに登録
$ sudo crontab -e */15 * * * * /usr/local/bin/b25refresh.sh > /dev/null 2>&1
Active EIT Scanが有効になっていると、チューナーがロックされてマウント解除できなくなるので、優先的に使うチューナーではActive EIT Scanを無効にしておく。この対策でActive EIT Scanが無効のチューナーでの録画成功率が上がる。
Active EIT Scanが有効になっているチューナーがsyslogにエラーを吐いている場合、一度視聴を行なってActive EIT Scanを停止させてからコマンドを実行するといい。
設置は簡単だが、チューナーの解放を行わないため、swatchを使った対策の方が確実になる。ただし、Active EIT Scanを使わない場合は十分な対策となる。
参考: Myth Protocol/Guide – MythTV Official Wiki
takaaki 4月 16th, 2012
Posted In: ソフトウェア
タグ: Debian, DVB, fuse_b25, Linux, MythTV, PT2, TV, WINE, 録画