[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