User:Yeffetn
I'm documenting my mythtv setup so others can used ideas and code...
This page (including the code) is here in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Contents
Hardware
- Computer: modified dell e520: 3GB Ram, 1TB disks total (inc. ext. USB drives), some old Firewire card and Nvidia 8600GT (for best HD experience)
- Tuner 1: Comcast HD box (motorolla DCT62xx) connected using FireWire
- Tuner 2+3: Silicondust_HDHomeRun
Software
- Ubuntu Feisty, and mythtv packages that comes from the repositories of Feisty.
Getting the DCT6200 to work
First, it is important to read the FireWire page. I've found out that it is better to "prime" the firewire after every channel change. This way there are much less failures; so I'm not using mythtv's internal channel changer, instead I have the following script:
/usr/local/bin/6200ch.sh:
#!/bin/bash # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ ( /usr/local/bin/6200ch $2 -n $1 /usr/local/bin/firewire_tester -B -n $1 || \ /usr/local/bin/firewire_tester -B -n $1 || \ /usr/local/bin/firewire_tester -B -n $1 || \ /usr/local/bin/firewire_tester -B -n $1 ) >/dev/null 2>&1
The reasons I'm not using firewire_tester -r <n> (run action <n> times) are: once it is ok, I'd like it to return, and -r isn't fixing well as rerunning.
I also had to patch 6200ch.c to match my DCT6200 device:
--- 6200ch.c 2006-08-12 15:49:00.000000000 -0700 +++ ../../../6200ch.c 2007-09-21 19:38:21.397796375 -0700 @@ -40,6 +40,7 @@ #define DCT6200_VENDOR_ID9 0x000014e8 #define DCT6200_VENDOR_ID10 0x000016b5 #define DCT6200_VENDOR_ID11 0x00001371 +#define DCT6200_VENDOR_ID12 0x000019a6 #define DCT6200_SPEC_ID 0x00005068 #define DCT6200_SW_VERSION 0x00010101 #define DCT6200_MODEL_ID1 0x0000620a @@ -173,6 +174,7 @@ (dir.vendor_id == DCT6200_VENDOR_ID9) || (dir.vendor_id == DCT6200_VENDOR_ID10) || (dir.vendor_id == DCT6200_VENDOR_ID11) || + (dir.vendor_id == DCT6200_VENDOR_ID12) || (dir.vendor_id == DCT6412_VENDOR_ID1)) && ((dir.model_id == DCT6200_MODEL_ID1) || (dir.model_id == DCT6200_MODEL_ID2) ||
Making sure mythconverg (mysql db) is in memory all the time
Some function of mythtv will work much faster if the DB (mythconverg) is in memory all the time. Functions such as program guide, searches and even watch recordings are using the DB. However, since in most cases the mysql DB server is also the video recorder, the video files being recorded or watched will cause the DB files to be swapped out of cache. The very simple way around it is to read the files all the time. once every minute is more than enough. The size of the DB is about ~250MB which fits well in 3GB total RAM (2GB cache) and will stay there for 1 minute even while recording multiple HD shows and watching HD. I've used "cd /var/lib/mysql/mythconverg && cat * >/dev/null" in crontab, but I wanted to be more efficient, so I wrote nocat.c, that will only read 1 byte from each page (reading 1 byte is enough to tell the cache that this page is "hot"):
nocat.c:
/* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include <error.h> #include <errno.h> #include <sys/types.h> #include <sys/ioctl.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #define _GNU_SOURCE 1 #define _FILE_OFFSET_BITS 64 #define READSIZE 1 #define MYERR { error (0, errno, "%s", argv[argind]); ret=1; } int main (int argc, char **argv) { int ret=0; int argind=0; int pageskip=getpagesize()-READSIZE; int fd; ssize_t rd; char buf[READSIZE]; while (++argind < argc) { fd = open(argv[argind], O_RDONLY); if (fd < 0) MYERR else { while (rd=read(fd,&buf,READSIZE)==READSIZE) { if (lseek(fd,pageskip,SEEK_CUR) < 0) MYERR; } if (rd < 0) MYERR; if (close(fd) < 0) MYERR; } } return ret; }
I'm not using cron anymore, since it filled logfiles with messages. See below how it works.
One script that guard it all
I've noticed lack of robustness in the following areas;
- mythbacked is crashing from time to time. (rarely, but still annoying).
- HDHomeRun does not save config, and since I'm using it as the remote receiver as well, I'd like it to be configured all the time.
- The DCT6200 reboots itself from time to time, and could move firewire node number becuase of that. mythtv will stop using it.
In addition, I wanted to keep mythconverg in memory (see above), but wanted to avoid cron messages every minute.
The following script prevents failures like the above, and helps keeping mythconverg in memory. I run it from /etc/rc.local with redirecting std* to and from /dev/null.
#!/bin/bash # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ # my hdhomerun hdhr=10106EE1 # my dct6200 dct6200=0019a6fffef3a046 plugreport=/usr/bin/plugreport cardid=4 cardidfilter='where cardid=' getnode='select firewire_node from capturecard' setnode='update capturecard set firewire_node=' setextcmd='update cardinput set externalcommand=' extcmd='/usr/local/bin/6200ch.sh' dbname=mythconverg dbhost=localhost dbuser=mythtv dbpass=yourpassword mysql=/usr/bin/mysql mysqlcmd="$mysql -h$dbhost -u$dbuser -p$dbpass $dbname" # Monitor mythbackendpid=/var/run/mythtv/mythbackend.pid # mysql cache mysqlcachecmd='cd /var/lib/mysql/mythconverg && /usr/local/bin/nocat *' mysqlcacheint=60 # What port myport=5000 # Where is hdhomerun_config hdhr_config=/usr/local/bin/hdhomerun_config # Check every (too high might skip a powercycle, 5 is good) interval=5 # Find my IP hostname=`hostname` myip=`getent hosts $hostname | cut -d' ' -f1` # Leave blank hdhrip= #mysql counter init mysqlcount=0 mythdct=`echo $getnode $cardidfilter $cardid | $mysqlcmd | tail -1` while sleep $interval; do # HdHomeRun while ! ping -c1 -w1 $hdhrip >/dev/null 2>&1; do hdhrip=`$hdhr_config discover | grep $hdhr | cut -d' ' -f 6 2>/dev/null` $hdhr_config $hdhr set /ir/target $myip:$myport >/dev/null 2>&1 done # MysqlCache let "mysqlcount = mysqlcount + interval" if [ $mysqlcount -ge $mysqlcacheint ]; then mysqlcount=0 eval $mysqlcachecmd fi # check dct6200 node dctisat=`$plugreport 2>/dev/null | grep $dct6200 | cut -d' ' -f 2` if [ -n "$dctisat" -a $dctisat -ne $mythdct ]; then mythdct=$dctisat echo $setnode $dctisat $cardidfilter $cardid \; $setextcmd \"$extcmd $dctisat\" $cardidfilter $cardid | $mysqlcmd /etc/init.d/mythtv-backend restart fi # check mythbackend if [ -f $mythbackendpid ]; then grep mythbackend /proc/`cat $mythbackendpid`/cmdline 2>&1 >/dev/null || \ /etc/init.d/mythtv-backend restart fi done