[Live-devel] Behavior of DeviceSource::doGetNextFrame() when no data available
Ross Finlayson
finlayson at live555.com
Thu Aug 10 10:57:49 PDT 2006
>On 8/10/06, David Arnold <darnold at futurec.net> wrote:
>> What should a DeviceSource, such as a frame grabber, do in doGetNextFrame()
>> when it determines there is no frame available? I find no answer in the
>> FAQ. The comment in DeviceSource.cpp reads:
>
>You need to reschedule a retry.
>
>In my device source (which I copied from one of the examples), after
>reading and validating the frame from the device it uses
>scheduleDelayedTask with a 0 delay to schedule a call to
>'afterGetting'. If a frame is not available it uses
>scheduleDelayedTask to retry reading a frame from the device at some
>point in the future. If you have a read selectable file descriptor for
>your device then there is a more efficient method to do this.
>
>For example:
> /* poll again in 5ms */
> nextTask() = envir().taskScheduler().scheduleDelayedTask (
> 5 * 1000, (TaskFunc*) dspRetryGet, this );
This works, but can be inefficient - because it polls frequently, and
because it incurs a delay of at least 5 ms (in your example), even if
new frame data becomes available almost immediately.
A better way is to make the availability of new frame data an
'event', and just handle this in the event loop.
If your frame grabber is implemented as a readable open file (i.e.,
socket), then you can just call
"envir().taskScheduler().turnOnBackgroundReadHandling( ...)" on it.
This will schedule a handler function that gets called (via
"select()") within the event loop.
If your frame grabber is *not* a readable socket, then you need to do
something else to trigger the arrival of new frame data as being an
'event'. One simple way to do this is to use the "watchVariable"
parameter to "doEventLoop()". (Look at the code, and the FAQ.) If
your custom events are more complicated than can be handled using the
"watchVariable", then you would need to write your own event loop -
i.e., your own subclass of "TaskScheduler" - that handles them.
>The problem is if I just return, as in:
>
>doGetNextFrame()
>{
> if (grabNextFrame() == NO_FRAME_AVAILABLE)
> return;
>}
>
>The task scheduler seems to stop.
The task scheduler doesn't 'stop', it is just waiting until events
happen. That's why you need to make the availability of new frame
data an 'event'. Apart from that, your code above is correct.
> It appears as though I must invoke
>afterGetting(this). If I must invoke afterGetting() what to I set all the
>expected output parameters to (such as fFrameSize, etc) to.
You must invoke "afterGetting()" *only* after you have new data that
you have just delivered to the downstream reader - i.e., only after
you have copied new data to "fTo", and set "fFrameSize", etc.
--
Ross Finlayson
Live Networks, Inc.
http://www.live555.com/
More information about the live-devel
mailing list