Mailing List Archive

Re: mythtv-dev digest, Vol 1 #138 - 17 msgs
Date: Mon, 04 Nov 2002 06:01:14 -0500
From: John Coiner <jcoiner@stanfordalumni.org>
To: mythtv-dev@snowman.net
Subject: [mythtv] Re: Audio problem when changing channels

Our A/V sync works by varying the rate at which video frames are
displayed, to keep sync with the audio. We can't vary how fast the audio
is played; once we request a sample rate from the sound card, we're stuck
with that (or, as close as the sound card gets to it, some cards are off
by a few percent.)

On each frame, we calculate the error, how far off we are from perfect
sync. The first (stupid) implementation I did corrected the entire error
on each frame, but this produces jittery (i.e. jerky) video output. The
reason is that our error calculation is based on querying the sound
driver to find out where it is -- but the value returned by the sound
driver is inexact, and the calculated error has a lot of noise as a result.

The solution is to correct only a small fraction of the measured error
on each frame (currently we correct 1/50th of the error.) This is
sufficient to maintain sync, and it also smooths out the noise, so that
the video output has the lowest possible jitter.

Everything I've described so far exists to maintain A/V sync at steady
state, when mythtv has been running, unpaused, on the same channel, for
at least a few seconds. But we don't always have steady state-- a
channel change is a disruptive event, which empties all the buffers, and
usually puts the A/V out of sync. With '1/50th' feedback, it took too
long to resync after a channel change. To deal with this, if we detect a
very large A/V sync error, we use stiffer feedback to get back into sync
quickly.

Uhm, you've heard of PID controllers, yes? In general, in a feedback
system, one controls the driving term with a constant k1 times the error
(thus P, "proportional"), plus a constant k2 times the derivative of the
error (D, "derivative"), plus a constant k3 times the integral of the error
(I, "integral"). The proportional term does most of the work (and was the
first you implemented, initially with k1 = 1, then later with k1 = 1/50).
The differential term is vital to insure good response to large transients
and depending on the system k2 can often be near 1 (as you suggest, you're
using stiffer feedback when there's a large error; it might be interesting
to experiment with using the derivative instead). The integral term k3 is
often overlooked but is very important for maintaining long term stability
as errors below what is nominally corrected by the P term can slowly
accumulate. If the servo signal is noisy (as you suggest the sound
driver's answers to position queries can be), then the integral term
becomes doubly important since it will act to smooth the servo noise.

Cheers,

- pz.

--
John Pezaris, Ph.D.
pz@hms.harvard.edu