[FFmpeg-devel] [PATCH] What is missing for working AVFMT_FLAG_NONBLOCK?

Michael Niedermayer michaelni
Tue Mar 3 19:45:33 CET 2009


On Tue, Mar 03, 2009 at 07:06:25PM +0100, Nicolas George wrote:
> Hi.
> 
> Le tridi 13 vent?se, an CCXVII, Michael Niedermayer a ?crit?:
> > are you saying that sched_yield() will blow up and cause actual undefined
> > behaviour and that we should use usleep(0) or what else?
> > I really feel that sched_yield() is correct and usleep() is not.
> > thats IMHO from reading POSIX and the man pages
> 
> I remember a message on lkml where someone really good explained that
> sched_yield is very rarely useful, and that most of the times people use it
> wrongly.
> 
> What sched_yield does is the following:
> 
> It several processes are competing to hog one CPU and have the same
> priority, each in turn get some CPU time, and when that time is exhausted,
> they are preempted and the CPU goes to the next one.
> 
> If process #1 calls sched_yield, it has the same effect as if it were
> preempted after exhausting its time slice: the CPU goes to the next process,
> and comes back to process #1 when all process have exhausted their time
> slice.
> 
> If process #1 is busy-waiting to something, and there are other
> CPU-intensive processes with the same priority, then sched_yield has the
> desired effect: process #1 will run just as long as necessary to see if
> something new happened and let other processes run most of the time.
> 
> But the "correct" behaviour of sched_yield stops here.
> 
> If there are no other CPU-intensive processes, or if all other such
> processes have a lower priority, then sched_yield is just a no-operation,
> and the process hogs the CPU.
> 
> The man page of Linux implementation gives some hints of the real purpose of
> sched_yield:
> 
>        Strategic calls to sched_yield()  can  improve  performance  by  giving
>        other  threads  or  processes  a chance to run when (heavily) contended
>        resources (e.g., mutexes) have been  released  by  the  caller.
> 
> 
> As for the solutions to the current problem:
> 
> usleep(0) is useless, Single Unix says "If the value of useconds is 0, then
> the call has no effect."
> 
> usleep(1000) will mostly work, but will have two opposite problems:
> 
> - 1000 may be too big. For example, the ALSA capture device sets the period
>   time of the ALSA PCM device to the lowest possible value, to allow
>   low-latency programs to work. But with some devices, that may be really
>   low: with my Intel HDA, the sample rate can be 192kHz and the period is 32
>   samples, which means reads every 1/6000 of a second.
> 
> - 1000 may be to low: in practice, most of the device return much less than
>   1000 packets per second, which means a lot of useless wakes. On embedded
>   devices, that means power consumption, for example.
> 
> One possible solution could be to keep one device (preferably the fastest)
> in blocking mode, and poll the other devices in non-blocking mode when it
> returns data. This is an ugly hack, but it would probably work quite well.
> 
> Another, much cleaner solution, would be to manage to get real Unix file
> descriptors for the devices and poll() them.
> 
> But I am not sure that all devices can actually be tested that way. For
> example, mmaped V4L1, as far as I remember, uses a blocking ioctl, which can
> not be poll()ed. In fact, I am not sure it can be set to non-blocking-mode
> either.
> 
> Furthermore, this is really less portable: I would be very surprised if VFW
> capture could be poll()ed, for example.
> 

> The only real solution to the problem of simultaneous capture from several
> devices is using threads.

yes, though its a per device/API question if a thread is needed or if the
device/API has buffers that are large enough.

the JACK patch already uses a seperate thread but possibly should use a
larger buffer ...

adding a seperate thread to anything that has less than 500ms worth of
buffers is welcome. I also suspect&suspected in the past that lack of this
is the cause of many issues with capturing with ffmpeg.


> 
> This is not a very complex solution either: each device in its own thread,
> in blocking mode; whenever a packet is read, it is added in an asynchronous
> message queue and the main program is blocked waiting on that message queue.

if by message que you mean the stuff from posix then i must say i would
prefer the kind of fifo/ringbuffer i suggested for jack unless i missed some
issues with it.

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Thouse who are best at talking, realize last or never when they are wrong.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090303/2d8f780e/attachment.pgp>



More information about the ffmpeg-devel mailing list