[vdr] Understanding how vdr's tuning algo works.

Reinhard Nissl rnissl at gmx.de
Fri Mar 9 23:47:47 CET 2007


Stone wrote:

>    I am curious how vdr's tuning algorithm, in general, works. With all
> the refactoring that has gone on with how vdr tunes, locks, retunes, and
> otherwise tries to anticipate various forms of interference, storms, or
> other activities that could hinder vdr from performing its job
> adequitely, please describe, in pseudocode, how the tuning algorythm
> actually works. 
> Some of my questions are:
> 1) What do all the tuning timers mean? There are some constants in vdr
> code,  what are the meanings of each tuning state? (i.e. the switch
> statement in dvbdevice.c.

Let me start with the switch statement which implements some sort of
state automaton. The state tsIdle is the initial state.

When a tuning request arrives at the tuner, the state switches to tsSet.
The automaton (= tuner thread) then sets up the frontend (e. g. sends
the DiSEqC message and sets the frequency to tune to) and enters state
tsTuned (or -- in the unlikely case that the driver doesn't like the set
parameters -- goes back to tsIdle).

The next loop iteration enters at case tsTuned (and falls immediately
through to the code at case tsLocked) where the frontend's status is
checked (which was read as one of the loops first instructions). I'll
now concentrate on the common case FE_HAS_LOCK: when the frontend
signals this status, it has successfully tuned to the transponder. So
the state switches on to tsLocked.

>From that time on, the frontend status is continuously monitored to
detect when the frontend looses FE_HAS_LOCK. In such a case the state
falls back to tsTuned and hopefully (e. g. just by a short distortion of
the signal) the frontend regains FE_HAS_LOCK without further
intervention, so the state switches once again to tsLocked.

In the case where the frontend doesn't regain FE_HAS_LOCK on its own (e.
g. consider a powerfailure at the multiswitch) the state falls back from
tsTuned to tsSet so that for example the DiSEqC message is sent again to
the multiswitch and hopefully we'll shortly see the transition to
tsTuned and tsLocked afterwards.

Now to the timings: in the next to last paragraph I wrote about a short
distortion. "short" means in this case "up to DVBT_LOCK_TIMEOUT". It is
used to filter away spurious lost lock situations where there is no need
to intervene. In other words: if the lock is lost at least for that
time, we need to retune.

The other constant is DVBS_TUNE_TIMEOUT. It is used in the opposite
direction, i. e. how long do we wait from setting up the frontend until
retuning. Consider the case, where at tsSet a DiSEqC message is sent to
the multiswitch, but for any reason the message gets damaged, so the
multiswitch doesn't switch. As the state tsLocked isn't reached in time,
we need to retune and hopefully the message doesn't get damaged this time.

> 2) Given that we understand what all the timers do, which ones depend on
> eachother? What are safe limits for each timer? For example, one timer
> is the DVBS_TUNE_TIMEOUT that traditionally is set to 9000 (miliseconds)
> but at times it takes my dvb card upwards of 18 seconds to actually tune
> the channel (so I might wish to set this to 19000 instead of 9000). What
> other timers need to be adjusted if any to account for this?

Both constants are independent, as one is used for the transition from
tsSet to tsLocked and the other from tsLocked to tsSet (the state
tsTuned just serves as a central point at which the timeout is monitored).

When I contributed the code during 1.3.x development, DVBS_TUNE_TIMEOUT
was at about 1500 ms, as my TechniSat receiver repeated the DiSEqC
message at that period. But it was simply to fast for some DVB-T
devices/drivers, so that's the reason why there are different constants
for DVB-S/-C/-T.

Then there were some complaints from users with rotor setups, so
DVBS_TUNE_TIMEOUT was increased to the same value as for DVB-C/-T.
That's why all three DVB variants use the same timeouts at the moment.

>From your writing I assume, that you use a rotor setup too. I further
assume that your rotor stops for a short time when it receives the
repeated DiSEqC message. I don't think that you want to suppress the
tuning timeout log messages by setting the timeout to 19000 ms.

Anyway, a larger timeout (e. g. 19000 ms) should be possible but keep in
mind, that the timeout must also expire for a retuning to happen when
the dish doesn't need to be moved. For example when zapping on the same
satellite and the initial DiSEqC message for a multiswitch gets damaged
you'll see a black screen for 19000 ms. The only way out of this is to
tune to a different transponder and back by your remote control.

Concerning other timers: consider the worst case where the initial
DiSEqC message gets lost and after 19000 ms (at the first repetition of
DiSEqC message) the dish starts moving for 18000 ms. In this scenario,
it will take 37000+ ms until VDR receives the stream. In the case of a
recording, this is simply to long as recorder.c defines a
MAXBROKENTIMEOUT of 30 seconds. VDR's recorder considers a stream to be
broken when it doesn't receive a PES packet for that time. So I'd
suggest to double this timeout.

I further assume that you've disabled EPG scans as your dish would start
moving like mad. The reason is that VDR switches to a different
transponder every 10 seconds which is to fast when your dish needs up to
19 seconds for positioning. I didn't have a closer look into this code
so the transponder list used for EPG scanning might even not be sorted
by satellite position which let's the dish move more often -- but this
is just a guess.

> 3) Does vdr care or know anything about a rotor setup where the channel
> isn't always present the moment the diseqc commands are sent?

>From my writing above, I don't think that VDR cares about a rotor setup.
When I contributed the code I've bought a USALS compatible DiSEqC 1.2
rotor just for testing and returned it after testing. I didn't put any
rotor specific DiSEqC commands into VDR's diseqc.conf but used the
rotor-plugin instead. Retuning while the rotor was moving didn't seem to
disturb the rotor but maybe this was an effect of not putting rotor
specific commands into diseqc.conf.

> 4) There has been some talk in the past about refactoring this process
> some, do we think the current approach is the best approach? Does
> vdr-1.5.x plan to offer new and improved tuning algos?

I don't know whether Klaus (or maybe somebody else) has already a
concept of how things should be changed.

Dipl.-Inform. (FH) Reinhard Nissl
mailto:rnissl at gmx.de

More information about the vdr mailing list