Frame display timing
Frame Display Timing Methods
MythTV can make use of several timing methods to control how often frames are drawn in a process known as "page flipping" or "double buffering. Essentially, each frame is drawn to an off-screen buffer that is then "flipped" with the buffer that is being used for the on-screen frame. The next frame is then drawn into the buffer that contained the previously on-screen image while the frame that was just drawn into the off-screen buffer is being displayed.
The flipping of each buffer is controlled by one of the following methods:
Of the three, the video card method is often the most preferable, as buffer flipping should take place during a time when no image is being drawn (during the Vertical Blanking Interval, commonly abbreviated VBI) to prevent the buffer from being flipped before it has been fully drawn. However, the video card method is usually not available on the majority of cards. At the moment, it would appear that only some nVidia drivers support the feature to an extent that MythTV can utilize.
Second to the video card method, it is debatable whether RTC or usleep is better, although usleep is considered to consume more CPU time. Furthermore, some feel that usleep is not as accurate. Again, this is also debateable.
Side Effects of Poor Timing
The most obvious side effect of improper timing in MythTV is an effect known as "frame tearing", and can be seen during horizontal pans in scenes or in scenes where there is a high amount of horizontal motion, as in this example image provided by Intel in their article on video frame synchronization:
Currently, there do not seem to be any other noticeable side effects of poor buffer flip timing other than tearing, but tearing alone can sometimes mean the difference between an enjoyable show and an extremely distracting synchonization problem.
On some systems tearing may be present because of a lack of processing power. Such is the case with ION chipsets where Composite processing is stealing GPU cycles. More on this topic can be found VDPAU Deinterlacing modes and Tearing/Stuttering due to Composite Extension
Determining the Active Timing Method
To determine the method that is currently in use by Mythfrontend, start it from a console with the "-v playback" command-line argument, and begin watching a show, either one that is live or one that has been recorded earlier. Then, stop watching and switch back to the console. Scroll back through the console and look, after all the initial playback messages regarding finding decoders and setting up video surfaces, for something similar to the following:
2012-08-25 14:28:54.541834 I [3783/3783] CoreContext mythplayer.cpp:1737 (InitAVSync) - Player(l): Video timing method: RTC 2012-08-25 14:28:54.541874 I [3783/3783] CoreContext mythplayer.cpp:1741 (InitAVSync) - Player(l): Display Refresh Rate: 59.999 Video Frame Rate: 29.970
Receiving the above message would indicate that RTC timing is being used. If something like this appears instead:
2012-08-25 13:13:37.413235 E [3783/3783] CoreContext vsync.cpp:364 (TryInit) - VSYNC: RTCVideoSync: Could not set RTC frequency: eno: Permission denied (13)
It means that Mythfrontend was either unable to read the current clock frequency (probably from /dev/rtc) due to insufficient permissions, or set the clock frequency to a high-enough level to use the timer. Running Mythfrontend as root would permit it to read and set the frequency no matter what the permissions are, but this is not ideal; udev is preferable. Set the frequency to a high value like 1024 outside Mythfrontend, as discussed later. To let Mythfrontend know about the higher frequency, in /etc/udev/rules.d create a file called rtc.rules:
# "rtc0" may be "rtc" depending on whether /dev/rtc and/or /dev/rtc0 exists KERNEL=="rtc0", MODE="0664"
If the user has an nVidia card, the following message indicates that timing support is broken or unimplemented in the active driver release, and that MythTV will fall back to another method (usually RTC):
2005-01-04 18:21:25 nVidiaVideoSync: VBlank ioctl did not work, unimplemented in this driver?
Contrary to what Mythfrontend may say, VDPAU does not use vsync/vblank timing. RTC should be used instead.
Adjusting the RTC Interrupt Frequency
If MythTV will be using the RTC to time the display, it will usually request a high interrupt frequency, allowing it to time frames more precisely. However, unless MythFrontend is a privileged process, the highest frequency that it can request by default is 64 Hz. This is usually not sufficient for CRT monitors that are often set to a higher frequency, usually 85 or 100 Hz, as well as some LCD screens and projectors that can accept various frequencies, producing the tearing artifacts as mentioned earlier. The most common solution is simply to increase the maximum frequency that an unprivileged process can request from the RTC.
Using cat + /proc
To determine what the current maximum frequency for an unprivileged process is set at, run (as root or using sudo):
By default, this will be 64 on most systems. To increase it, issue the following (again, as root):
echo 1024 > /proc/sys/dev/rtc/max-user-freq
Verify that it has changed by issuing the "cat" command (above).
You may not find the setting like described above. Another possible location is
On Ubuntu 9.04
echo 2048 >/sys/class/rtc/rtc0/max_user_freq echo 2048 >/proc/sys/dev/hpet/max-user-freq
In some cases, /proc/sys/dev/hpet/max-user-freq may instead be found at /sys/devices/pnp0/00:05/rtc/rtc0/max_user_freq which changes the modification to the following:
echo 1024 > /sys/devices/pnp0/00\:05/rtc/rtc0/max_user_freq
This may change depending on your hardware. The PCI id may change, for example. According to this link the change of sys nodes is an artifact of newer kernels.
In some Ubuntu configurations /dev/rtc -> /dev/rtc0 is +rw by root only and mythtvfrontend will default to usleep. A fix is found at the LinuxMusicians wiki - system configuration page
Add the desired configuration to /etc/sysctl.conf to apply the values at startup.
$ cat /etc/sysctl.conf dev.rtc.max-user-freq = 1024