[Live-devel] infinite recursion

Florian Winter fw at graphics.cs.uni-sb.de
Mon Jan 12 13:02:04 PST 2004


we have written a class BufferedSink which packs data received from an 
RTPSource into the internal
data structure of our middleware. the BufferedSink class is based on the 
FileSink code. it does essentially
the same, except that something else is done to the frames when they 
have been received.

now there seems to be a problem: as soon as data is received, the 
liveMedia thread goes into infinite recursion.
the reason for this seems to be the following code, found in 
MultiFramedRTPSource.cpp:

    // Call our own 'after getting' function.  Because we're preceded
    // by a network read, we can call this directly, without risking
    // infinite recursion.
    afterGetting(this);

it seems that if the sink is a FileSink (or our BufferedSink), this 
claim is not correct:

MultiFramedRTPSource::doGetNextFrame1 calls MediaSource::afterGetting
MediaSource::afterGetting calls BufferedSink::afterGettingFrame
BufferedSink::afterGettingFrame calls BufferedSink::continuePlaying
BufferedSink::continuePlaying calls MediaSource::getNextFrame
MediaSource::getNextFrame calls MultiFramedRTPSource::doGetNextFrame
MultiFramedRTPSource::doGetNextFrame calls 
MultiFramedRTPSource::doGetNextFrame1
LOOP!

this is also true for the original FileSink code. The afterGettingFrame 
callback calls continuePlaying
(is that really necessary? if I don't call it, the flow graph doesn't 
seem to do anything...) and continuePlaying
calls getNextFrame.

the strange thing is that until recently it worked! I don't know why it 
worked, and which changes of mine caused
it not to work anymore, but clearly, from looking at the code, it should 
never have worked at all!
(unless, of course, I am wrong)

I suppose that before my changes (which made continuePlaying and 
afterGettingFrame more complicated), the
infinite recursion did not cause a stack overflow due to compiler 
optimisations (such as inlining or replacing the
CALL, RET sequence at the end of continuePlaying by a JMP. this is a 
common optimisation which, as a side effect,
makes it possible to make recursive calls without using any stack space).

my question now is:
am I doing something wrong, or is this a bug in FileSink or 
MultiFramedRTPSource?
shouldn't MultiFramedRTPSource use the task scheduler...

nextTask() = envir().taskScheduler().scheduleDelayedTask(0, 
reinterpret_cast<TaskFunc*>(afterGetting), this);

... instead of calling afterGetting(this) directly ?




More information about the live-devel mailing list