Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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



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.




--
Info:
To unsubscribe send a mail to ecartis@linuxtv.org with "unsubscribe linux-dvb" as subject.



Home | Main Index | Thread Index