June 7, 2008

Audio Distortion with the Hauppauge PVR-150 and MythTV

I've been using the Hauppauge (pronounced hop-awg) PVR-150 to record standard-quality television from our Comcast Digital Cable service. So, far, the quality and performance of the card has been outstanding, especially when considering the cost of the card (~$75). It comes with a hardware MPEG-2 encoder that imposes hardly any load on the MythTV backend when recording because the compression and encoding of the video & audio is performed in hardware. This leaves plenty of system resources for other tasks, such as playback or transcoding into other media formats.

But there has been one problem that occurs intermittently: the audio on live & recorded programs will sound like it's being projected from a tin can. The sound is discernible, but wrong. Enduring an hour-long program with bad sound can be difficult.

At first, I wasn't sure if the sound distortion was coming from the digital cable box, the PVR-150 encoder card, or MythTV playback. We had never experienced this kind of audio distortion with our old Tivo service using the same digital cable box, so I had to rule out the cable box. Also, we never had any problems when using the PVR-150 tuner input, which combines video & audio in a single input. I had recently switched from the tuner input to the composite audio & video input on the PVR-150 due to the generally higher quality they deliver in comparison to coaxial feeds. So, I concluded that problem was with the PVR-150 composite audio input.

I'd noticed that leaving and then promptly returning to the channel would resolve the problem. But this is not possible when recording programs while away. After reading several posting on MythTV user lists, I decided to modify the channel-change script to fork a background that re-establishes the audio input 2 seconds after the channel-change script returns. This has worked successfully for a week now, which is a marked improvement over where we were.

The following shows the channel-change script:

[scott@eowyn ~]$ cat /usr/local/bin/change_chan.sh 
#!/bin/sh

# send infrared signals to change the current channel
REMOTE_NAME=comcast
for digit in $(echo $1 | sed -e 's/./& /g'); do 
  /usr/local/bin/irsend SEND_ONCE $REMOTE_NAME $digit
  sleep 0.4
done
/usr/local/bin/irsend SEND_ONCE $REMOTE_NAME "ok"

# start audio fix script in the background
/usr/local/bin/ivtv_audio_fix.sh &

And the following shows the contents of the audio fix-it script that runs in the background after the channel-change process has finished.

[scott@eowyn ~]$ cat /usr/local/bin/ivtv_audio_fix.sh 
#!/bin/sh

sleep 2

# reset the audio input to source 1
/usr/local/bin/v4l2-ctl --set-audio-input 1

I'll also mention that I don't notice any glitches in the audio despite the fact that the fix-it script runs 2 seconds after the channel has been changed.

April 25, 2008

OpenGL Vsync on MythTV

I had enabled Open Vsync on our MythTV frontend during the initial configuration with the belief that there couldn't be any harm in adding an additional method of vertical synchronization. I changed my mind when I began noticing strange delays in the video playback on my NVidia FX 5200 with XVMC. After changing channels, there would be about 3-5 glitches in video playback for 30 seconds, followed by okay playback. I was okay with it until we began seeing much more dramatic choppiness in playback coupled with higher CPU utilization (typically 18-20%, but as high as 70%).

I searched the web for the symptoms and saw a lot of people reporting problems with video playback when OpenGL Vsync is enabled (here and here). Since disabling OpenGL Vsync, I've not seen any delays in playback. I might re-enable UseEvents in /etc/X11/xorg.conf, but it's currently set to False.

April 1, 2008

Using XvMC with MythTV and an NVidia FX 5200

Yesterday I wrote about my foray into using the proprietary NVidia Linux display driver on my MythTV box to get better hardware acceleration. This initially meant using OpenGL for rendering of the MyhTV menus. The responsiveness of the menus was greatly improved; however, the mythfrontend process continued to use around 70% of the CPU. This was surprising, especially considering that it's a Pentium 4 3.0 GHz CPU with HyperThreading. I determined that playback of the recordings and live programming was not using the MPEG-2 acceleration present in the NVidia FX 5200 graphics card, which meant the MPEG-2 decoding was being performed entirely on the CPU. This resulted in a higher system load and arguably lower-quality output.

I found the XvMC section of the MythTV wiki describing how to use X-Video Motion Compensation (XvMC) to utilize hardware acceleration when decoding MPEG-2 video. It actually took me several hours to get XvMC working, but I'll summarize the effective steps below:

First, install the NVidia display driver for Linux. The x.org driver doesn't support XvMC, so there's no way around it. My previous post has information on how to do this.

First, set-up the /etc/X11/xorg.conf file for the NVidia driver. XvMC worked only when NVAGP was set to '1'. You find explanations of these options on the NVidia support site. The relevant section of my /etc/X11/xorg.conf follows:

Section "Device"
    Identifier     "Videocard0"
    Driver         "nvidia"
    Option  "NVAGP"                 "1"
    Option  "NoLogo"                "True"
    Option  "RenderAccel"           "True"
    Option  "XvmcUsesTextures"      "True"
    Option  "UseEdidDpi"            "False"
    Option  "DPI"                   "100 x 100"
    Option  "UseEvents"             "False"
    Option  "DPMS"                  "False"
EndSection

Next, create or edit the file /etc/X11/XvMCConfig. Following are some shell commands that show my system setup:

[scott@eowyn lib]$ cd /usr/lib
[scott@eowyn lib]$ ll libXvMCNVIDIA*
-r--r--r-- 1 root root 152808 2008-03-31 08:47 libXvMCNVIDIA.a
lrwxrwxrwx 1 root root     23 2008-03-31 08:47 libXvMCNVIDIA_dynamic.so.1 -> libXvMCNVIDIA.so.169.12
-rwxr-xr-x 1 root root 139604 2008-03-31 08:47 libXvMCNVIDIA.so.169.12
[scott@eowyn lib]$ cat /etc/X11/XvMCConfig 
libXvMCNVIDIA_dynamic.so.1

To confirm that XvMC is working in X Windows, start up X Windows (i.e. startx), create a shell window and run xdpyinfo to look for the XvMC info:

[scott@eowyn lib]$ xdpyinfo | grep XVideo
     XVideo
     XVideo-MotionCompensation

The next step is to instruct mythfrontend to use XvMC for playback. I did this by choosing a playback profile in the mythfrontend via the Setup -> TV Settings -> Playback menus. The CPU-- profile uses 'ivtv' for Standard Definition (SD) Television, and 'xvmc' for higher definition content. I'm only recording SD content right now, but would like to use 'xvmc' to lower the CPU load. So, I created a new playback profile that uses 'xvmc' for all content.

I'll also mention that the picture became skewed on my 16:9 Sony 32" flat-panel television. I corrected this by adding scaling values of X=2, Y=3 in the Setup -> TV Settings -> Playback menu. This shifted the picture left and down to fill the screen. I'm also using the DVI output of the NVidia FX 5200 card. I've got a DVI-to-HDMI cable that delivers a pure digital signal to the television. The clarity is phenomenal.

After making all of these changes, I was able to confirm that XvMC was in use simply by looking at the CPU utilization of the 'mythfrontend' process with 'top'. Before I enabled XvMC, CPU utilization was at 68-72% when playing video. After switching to XvMC, utilization is merely 18-20%. That's more than a 300% reduction in CPU utilization! Since I use the MythTV machine for the backend and frontend, the reduction in CPU utilization opens up the possibility of adding another encoder card, or running some additional services such as ZoneMinder.