[vdr] problem vdr-xine-0.7.3 plugin
rnissl at gmx.de
Sun Apr 17 13:30:12 CEST 2005
Jouni Karvo wrote:
> > Please enable vdr-xine's PTS logger by changing the if (0) in
> > cXineDevice::PlayCommon3() (xineDevice.c:1018) into a if (1).
> > All pts* values should always step forward or stay at the same value.
> > The d* values show the difference to xine's metronom and should
> > typically be > 60000.
> Well, they are when xine plays normally. Then something else happens:
> When the sound (and shortly after video) disappears, first dA may jump to
> a high value. Then it starts getting smaller, and then:
Well, I've reformatted the output a little bit to show you what happens:
deltaV ptsVideo deltaAV ptsAudio deltaA deltaDisc
43200 19440 19440
43200 17280 17280
Columns ptsVideo and ptsAudio show you the PTS seen on PES packets with
the specified content. deltaV and deltaA show the difference in PTS of
consecutive packets of the specified type. Finally, deltaAV shows the
difference between two consecutive packets of different type and
deltaDisc results in the difference of two consecutive packets.
A few words how xine works: xine's metronom dictates when audio frames
respecitively video images need to be sent to the hardware. Therefore
the metronom generates virtual presentation time stamps (vpts). vpts and
the PTS of the stream are related and differ by vpts_offset. vpts_offset
is calculated when xine's demuxer sees the first PTS of the stream and
later, when the demuxer sees the PTS of stream jump. A typical jump
happens when the 33 bit PTS counter overflows which happens about every
When the demuxer indicates a discontinuity, a special buffer element is
put on both the video and the audio fifo. Then when audio and video
decoder process this element, both decoders wait for the other to reach
this state too. At this point, all packets with PTS before the jump have
been processed and it is now safe to compute vpts_offset with the new
PTS when the jump was detected. After that, any further PTS after the
wrap will be transformed into a vpts that is continuous (vpts is a 64
bit counter and doesn't see a wrap in a humans life).
demux_mpeg_pes's wrap detection code considered the wrap of video PTS
and audio PTS independently. I. e., it indicated a discontinuity when
either deltaV or deltaA where larger then WRAP_THRESHOLD (default
120000). The code relied on the wrap to happen on consecutive audio and
video packets, i. e. it didn't work properly in the case where after a
video discontinuity an audio packet with a PTS value before the wrap was
seen. The example below shows this more clearly (PTS is considered to be
just a single digit):
works for: V7 A7 V8 V9 A9 V0 V1 A1 V2 V3 A3
didn't work: V7 V8 A7 V9 V0 A9 V1 V2 A1 V3 V4
In such a case an audio jump was detected and output was hold for about
As it was almost impossible to reorder audio and video packets in a way
that the original constraint of the code was fulfilled, I've modified
the wrap detection code in demux_mpeg_pes for vdr-xine-0.7.3: it
nolonger determines the wrap by independently looking on audio
respectively video PTSs.
Instead it simply looks on the delta of two consecutive PTS values (see
column deltaDisc in the above table). This fixed the problem for my
sample stream where a real wrap happend. Let's repeat the above example:
works for: V7_A7_V8_V9_A9:V0_V1_A1_V2_V3_A3
works for: V7_V8_A7_V9:V0:A9:V1_V2_A1_V3_V4
Legend: _ indicates a delta below WRAP_THRESHOLD and : a delta above
this value. Now, up to three discontinuities are indicated to xine's
metronom to properly decode the area V9:V0:A9:V1.
To come back to your problem: when you read about demuxing you'll find
that there is a typical delta between audio and video of up to 700 ms
which corresponds to 63000 pts. So I thought the default WRAP_THRESHOLD
of 120000 pts would be ok to not trigger any false discontinuities. As
you wrote below, a larger value seems to fix your problem. Would you
please be so kind and try 150000 (= 5/3 seconds) and if this doesn't
solve the issue 180000 (= 2 seconds). As this value typically serves for
detecting a PTS wrap, it would also be ok to choose a really larger
value up to 2^31.
> Even negative. In this example, when dA goes to approx -100000, dV
> goes also negative. At this phase, the "bad frame" messages appear:
This is the effect of xine seeking the stream to catch up. Negative
values indicate that xine want's already display frames that vdr-xine
has not even got from VDR to send it to xine. One could take this number
as latency time of the connection VDR -- vdr-xine -- xine.
> > You might also want to play with xine's demuxer. Locate WRAP_THRESHOLD
> > in xine-lib/src/demuxers/demux_mpeg_pes.c:54 and reduce this value to
> > 90000 (i. e. smaller than the above reported diff). Feel free to
> > experiment with this value, e. g. increase it.
> With 90000, the problem is still there. Putting 50000 makes this
> problem much worse. With 200000, the dA seems to depend on the
> channel (mux?). For "YLE TV1", it seems mainly float around 30000, while "the Voice"
> shows around 70000 (the same as with YLE and WRAP_THRESHOLD 120000).
> I'll keep the 200000 for a while now and see how it looks like.
It is true that the total buffer differs from channel to channel. There
is even a difference when you switch to the same channel again. It has
to do with xine seeking to skip the PTS difference between the first
audio and video packet.
vdr-xine's extra buffering tries to compensate this effect but the
resulting buffer still differs. vdr-xine-0.7.4 will have a new softstart
algorithm that takes into account the absolute buffer established. And
it may also take into account the latency of the connection to further
reduce the number of dropped frames when switching channels.
Dipl.-Inform. (FH) Reinhard Nissl
mailto:rnissl at gmx.de
More information about the vdr