[Mplayer-dvb] Re: [linux-dvb] Re: mplayer playback through dvb takes 100% cpu time

Michael Hunold hunold at convergence.de
Fri Jan 9 21:53:27 CET 2004


Hello all,

shortly after posting my previous mail, I found the problem:

On 09.01.2004 20:44, Michael Hunold schrieb:
 > On 03.01.2004 22:33, Soeren Sonnenburg schrieb:

> I have inserted some debugging output into the dvb driver, but it did 
> not reveal any problems. So I think it's an sync issue of mplayer. (see 
> below)
> 
>> I noticed a weirdness with mplayer and -vo mpegpes playback. If I don't
>> also use -ao mpegpes the CPU load goes up to 100% instead of like 10%,
>> i.e. both
>> mplayer -ao mpegpes -vo mpegpes <file>
>> and mplayer -nosound -vo mpegpes <file>
>> both take like 10% CPU but,
>> mplayer -ao null -vo mpegpes <file>
>> or
>> mplayer -ao alsa9 -vo mpegpes <file>
>>
>> eat up all CPU there is but plays (of course gives frame drops)
> 
> 
> I think one important thing is "-nosound".
> 
> While "-ao null" is a valid "sound device" which "consumes" the sound 
> with a defined rate (just like -ao alsa9), "-nosound" simply disables 
> sound output and uses some constants to skip audio inside mplayer.c.
> 
> Perhaps there is a problem that "-vo mpegpes" needs the raw PES data, 
> but "-ao null" or "-ao alsa9" need the decoded PCM audio, and so 
> decoding and timing the output are severly messed up.

There is the following code inside "mplayer.c":
------------------------schnipp-------------------------------
//============================== SLEEP: ===================================

time_frame/=playback_speed;

// flag 256 means: libvo driver does its timing (dvb card)
if(time_frame>0.001 && !(vo_flags&256)){

#ifdef HAVE_RTC
     if(rtc_fd>=0){
[...]
------------------------schnipp-------------------------------

If the vo-driver has flag VFCAP_TIMER (256 = 0x100) set, then it can do 
it's own timing, it does not need to rely on the rtc or sleep() to let 
time pass.

This is true if you have both audio and video going through "-vo 
mpegpes" and "-ao mpegpes". "mplayer" will stuff the buffers of the dvb 
card by calling draw_frame() => send_pes_packet() => my_write() until 
the buffers are filled and the driver will "sleep". The DVB card does 
all the timing and output. Ok.

But because "-vo mpegpes" sets this flag VFCAP_TIMER even if it does not 
play sound, something goes wrong. Sound is played through "-ao null" 
with the correct sample rate. Video is shipped to "-vo mpegpes". The 
select call in my_write() does never sleep, because the video buffer is 
never filled. (debug output of dvb_ringbuffer_free(&av7110->avout) shows 
  this)

This is ok, because audio must be played in sync. "time_frame" is always 
 > 0.001 (don't know what it is exactly)

So, actually "mplayer" never really sleeps but jumps immediately to the 
beginning of it's main loop, because the sleeping code is disabled!

Thanks to the sync code A/V stays in sync, but the CPU is never put to 
sleep and spends most of the time in syscalls polling the DVB 
audio/video queue. This is where the 100% CPU usage comes from.

"-nosound" works, because it sets time_frame=0 under some circumstances 
(search mplayer.c for "NOSOUND") and then the above check is false and 
"mplayer" sleeps.

Please try to comment out the above line and the closing brace of the 
sleeping code in order to force mplayer to sleep. For me, it "solved" 
the 100% CPU usage bug.

Of course this is not the real fix, but it shows what's going wrong.

CU
Michael.





More information about the MPlayer-dvb mailing list