[MPlayer-users] Bugreport and proposed fix: XviD sync-bug

armin.gerritsen at philips.com armin.gerritsen at philips.com
Fri May 23 10:18:40 CEST 2003


Hello all,

I may have not been clear in my previous post, which might explain why some
people were under the impression that there is no bug at all.

In my previous post I put too much emphasis on the second bug, which is
related to special content, which may cause people to not notice the others.
The other two are generic though!

Whether it is only for a short period due to external reasons or whether you
use a too slow CPU like our embedded ARM doesn't matter: these two bugs
apply to all systems, although its symptoms will mostly appear on slower
systems and therefore not on powerful desktop PC's etc.

So here I go in my final attempt. I hope I'll be clearer now.


[1]  This first bug is the simple fact that -hardframedrop doesn't add
anything.

At line 615 of h263dec.c one sees the hurry_up value must be 5 in order to
start dropping any non-B frames. However using -hardframedrop only makes
hurry_up equal to 2. So in every case where the normal -framedrop option is
not enough, -hardframedrop will never help.

Nobody noticed this, because desktop-system usually have enough power to
display XviD movies and if they don't the normal -framedrop will be enough.
In cases it isn't, you're out of luck though.

Changing the 5 to a 2 would be a nice fix:

/* skip everything if we are in a hurry>=2 */
if(s->hurry_up>=2) return get_consumed_bytes(s, buf_size);

Note that this is a general bug! So it is not related to special content,
embedded platforms, etc.

It applies to all systems, from Mac's to PC's, from very high-end to very
low-end.


[2]  But there is more. A bug exists that causes that on platforms with lack
of CPU horsepower playing certain XviD (or DivX or anything else played with
h263dec.c !) content without B-frames, you'll loose A/V-synchronisation.
With XviD/DivX/MPEG/etc content it is 100% legal to have no B-frames. And
this may be less rare than you may think.

Since -framedrop will only drop B-frames, this will never drop anything for
such content.

So, if we don't fix the first bug, we'll always get out of sync with such
content if our CPU isn't fast enough, even with -hardframedrop. Even if our
system is only too slow for bit or only for very short period of time!

But if we do fix the first bug, we'll stay in sync but get serious image
corruption.

So this leaves these people with two options: out of sync or serious
corruption. Not very nice I would say.

There is a third option: stay in sync, have no corruption, but at the
expense of dropping more frames.
Instead of fixing line 615, simply replace it with:


if ( (1 < s->hurry_up) && (s->pict_type != I_TYPE) )
{
 // If we drop a P-frame, we must drop all other B/P's too,
 // in order to prevent serious image-corruption ... ;-(
 //if ( s->pict_type == P_TYPE ) // We know it is P.
  must_flush_non_I_frames = 1 ;
 return get_consumed_bytes( s, buf_size ) ;
}

// Flush all non B/P-frames.
if ( must_flush_non_I_frames )
{
 if ( s->pict_type == I_TYPE )
  must_flush_non_I_frames = 0 ;
 else
  return get_consumed_bytes(s, buf_size) ;
}


Our experience is that this produces often nicer results than accepting the
image-corruption.

I fully admit that this is a rare case, because it only applies for this
special content and on slower systems. But it is of course nice to know
these situations also exist, and there is 'a way out'.


[3]  The third bug is a very tiny one. I only mention it to be complete and
because I found it by accident. It is in vd_ffmpeg.c. Dropping frames can be
done in three ways: drop decoding, drop dithering or drop output. Not all
make sense of course (like dithering, when not outputting).

Point is that vd_ffmpeg doesn't provide all options. It never drops
dithering. This may be useful when there is the need to drop an I-frame or
P-frame, which is decoded (because other frames depend on it) but cannot

be displayed because we need to drop frames in order to remain A/V sync.

Some other mplayer-codecs do offer this option, so all I had to do is copy a
peace of code from such a codec (for instance vd_odivx.c) and add the
feature. Small 'problem', easy fix.

Add at line 604 of vd_ffmepg.c, something like:

if ( 3 & flags )
{
 return NULL ;
}

This is also a general bug, which applies to all content and all systems,
although again its symptoms will usually only become visible on slower
systems.

If any questions arise and/or more information is required, don't hesitate
to contact me.

Regards,

Armin




More information about the MPlayer-users mailing list