Hi Ross,<br><br>I have modified OnDemandServerMediaSubsession, FileServerMediaSubsession and MPEG2TransportFileServerMediaSubsession to handle the session closure<br> on source end. <br><br><br>*** include/OnDemandServerMediaSubsession.hh 2007-08-03 06:44:
32.000000000 +0200<br>--- include/OnDemandServerMediaSubsession.hh.new 2007-08-03 17:46:37.000000000 +0200<br>***************<br>*** 32,38 ****<br> class OnDemandServerMediaSubsession: public ServerMediaSubsession {<br>
protected: // we're a virtual base class<br> OnDemandServerMediaSubsession(UsageEnvironment& env, Boolean reuseFirstSource,<br>! portNumBits initialPortNum = 6970);<br> virtual ~OnDemandServerMediaSubsession();
<br> <br> protected: // redefined virtual functions<br>--- 32,38 ----<br> class OnDemandServerMediaSubsession: public ServerMediaSubsession {<br> protected: // we're a virtual base class<br> OnDemandServerMediaSubsession(UsageEnvironment& env, Boolean reuseFirstSource,
<br>! Boolean tearDownOnSourceEnd = False, portNumBits initialPortNum = 6970);<br> virtual ~OnDemandServerMediaSubsession();<br> <br> protected: // redefined virtual functions<br>***************
<br>*** 75,80 ****<br>--- 75,83 ----<br> unsigned char rtpPayloadTypeIfDynamic,<br> FramedSource* inputSource) = 0;<br> <br>+ protected:<br>+ Boolean fTearDownOnSourceEnd;
<br>+ <br> private:<br> void setSDPLinesFromRTPSink(RTPSink* rtpSink, FramedSource* inputSource);<br> // used to implement "sdpLines()"<br><br><br><br>*** OnDemandServerMediaSubsession.cpp 2007-08-03 06:44:
32.000000000 +0200<br>--- OnDemandServerMediaSubsession.cpp.new 2007-08-03 18:02:49.000000000 +0200<br>***************<br>*** 27,35 ****<br> OnDemandServerMediaSubsession<br> ::OnDemandServerMediaSubsession(UsageEnvironment& env,
<br> Boolean reuseFirstSource,<br> portNumBits initialPortNum)<br> : ServerMediaSubsession(env),<br>! fReuseFirstSource(reuseFirstSource), fInitialPortNum(initialPortNum),
<br> fLastStreamToken(NULL), fSDPLines(NULL) {<br> fDestinationsHashTable = HashTable::create(ONE_WORD_HASH_KEYS);<br> gethostname(fCNAME, sizeof fCNAME);<br>--- 27,37 ----<br> OnDemandServerMediaSubsession<br>
::OnDemandServerMediaSubsession(UsageEnvironment& env,<br> Boolean reuseFirstSource,<br>+ Boolean tearDownOnSourceEnd,<br> portNumBits initialPortNum)
<br> : ServerMediaSubsession(env),<br>! fTearDownOnSourceEnd(tearDownOnSourceEnd), fReuseFirstSource(reuseFirstSource),<br>! fInitialPortNum(initialPortNum),<br> fLastStreamToken(NULL), fSDPLines(NULL) {<br>
fDestinationsHashTable = HashTable::create(ONE_WORD_HASH_KEYS);<br> gethostname(fCNAME, sizeof fCNAME);<br>***************<br>*** 123,128 ****<br>--- 125,132 ----<br> <br> FramedSource* mediaSource() const { return fMediaSource; }
<br> <br>+ Boolean tearDownOnSourceEnd() const { return fMaster.fTearDownOnSourceEnd; }<br>+ <br> private:<br> OnDemandServerMediaSubsession& fMaster;<br> Boolean fAreCurrentlyPlaying;<br>***************<br>
*** 393,399 ****<br> <br> static void afterPlayingStreamState(void* clientData) {<br> StreamState* streamState = (StreamState*)clientData;<br>! if (streamState->streamDuration() == 0.0) {<br> // When the input stream ends, tear it down. This will cause a RTCP "BYE"
<br> // to be sent to each client, teling it that the stream has ended.<br> // (Because the stream didn't have a known duration, there was no other<br>--- 397,403 ----<br> <br> static void afterPlayingStreamState(void* clientData) {
<br> StreamState* streamState = (StreamState*)clientData;<br>! if ((streamState->tearDownOnSourceEnd() == True) || (streamState->streamDuration() == 0.0)) {<br> // When the input stream ends, tear it down. This will cause a RTCP "BYE"
<br> // to be sent to each client, teling it that the stream has ended.<br> // (Because the stream didn't have a known duration, there was no other<br><br><br><br>*** include/FileServerMediaSubsession.hh 2007-08-03 06:44:
32.000000000 +0200<br>--- include/FileServerMediaSubsession.hh.new 2007-08-03 18:24:09.000000000 +0200<br>***************<br>*** 29,35 ****<br> class FileServerMediaSubsession: public OnDemandServerMediaSubsession {
<br> protected: // we're a virtual base class<br> FileServerMediaSubsession(UsageEnvironment& env, char const* fileName,<br>! Boolean reuseFirstSource);<br> virtual ~FileServerMediaSubsession();
<br> <br> protected:<br>--- 29,35 ----<br> class FileServerMediaSubsession: public OnDemandServerMediaSubsession {<br> protected: // we're a virtual base class<br> FileServerMediaSubsession(UsageEnvironment& env, char const* fileName,
<br>! Boolean reuseFirstSource, Boolean tearDownOnSourceEnd = False);<br> virtual ~FileServerMediaSubsession();<br> <br> protected:<br><br><br><br>*** FileServerMediaSubsession.cpp 2007-08-03 06:44:
32.000000000 +0200<br>--- FileServerMediaSubsession.cpp.new 2007-08-03 18:27:21.000000000 +0200<br>***************<br>*** 23,30 ****<br> <br> FileServerMediaSubsession<br> ::FileServerMediaSubsession(UsageEnvironment& env, char const* fileName,
<br>! Boolean reuseFirstSource)<br>! : OnDemandServerMediaSubsession(env, reuseFirstSource),<br> fFileSize(0) {<br> fFileName = strDup(fileName);<br> }<br>--- 23,30 ----<br> <br> FileServerMediaSubsession
<br> ::FileServerMediaSubsession(UsageEnvironment& env, char const* fileName,<br>! Boolean reuseFirstSource, Boolean tearDownOnSourceEnd)<br>! : OnDemandServerMediaSubsession(env, reuseFirstSource, tearDownOnSourceEnd),
<br> fFileSize(0) {<br> fFileName = strDup(fileName);<br> }<br><br><br><br><br>*** include/MPEG2TransportFileServerMediaSubsession.hh 2007-08-03 06:44:32.000000000 +0200<br>--- include/MPEG2TransportFileServerMediaSubsession.hh.new 2007-08-03 18:29:
56.000000000 +0200<br>***************<br>*** 36,48 ****<br> static MPEG2TransportFileServerMediaSubsession*<br> createNew(UsageEnvironment& env,<br> char const* dataFileName, char const* indexFileName,
<br>! Boolean reuseFirstSource);<br> <br> protected:<br> MPEG2TransportFileServerMediaSubsession(UsageEnvironment& env,<br> char const* fileName,<br> MPEG2TransportStreamIndexFile* indexFile,
<br>! Boolean reuseFirstSource);<br> // called only by createNew();<br> virtual ~MPEG2TransportFileServerMediaSubsession();<br> <br>--- 36,50 ----<br> static MPEG2TransportFileServerMediaSubsession*
<br> createNew(UsageEnvironment& env,<br> char const* dataFileName, char const* indexFileName,<br>! Boolean reuseFirstSource,<br>! Boolean tearDownOnSourceEnd = False);<br> <br> protected:
<br> MPEG2TransportFileServerMediaSubsession(UsageEnvironment& env,<br> char const* fileName,<br> MPEG2TransportStreamIndexFile* indexFile,
<br>! Boolean reuseFirstSource, <br>! Boolean tearDownOnSourceEnd);<br> // called only by createNew();<br> virtual ~MPEG2TransportFileServerMediaSubsession();
<br> <br><br><br><br>*** MPEG2TransportFileServerMediaSubsession.cpp 2007-08-03 06:44:32.000000000 +0200<br>--- MPEG2TransportFileServerMediaSubsession.cpp.new 2007-08-03 18:32:31.000000000 +0200<br>***************<br>*** 71,77 ****
<br> MPEG2TransportFileServerMediaSubsession::createNew(UsageEnvironment& env,<br> char const* fileName,<br> char const* indexFileName,
<br>! Boolean reuseFirstSource) {<br> if (indexFileName != NULL && reuseFirstSource) {<br> // It makes no sense to support trick play if all clients use the same source. Fix this:
<br> env << "MPEG2TransportFileServerMediaSubsession::createNew(): ignoring the index file name, because \"reuseFirstSource\" is set\n";<br>--- 71,78 ----<br> MPEG2TransportFileServerMediaSubsession::createNew(UsageEnvironment& env,
<br> char const* fileName,<br> char const* indexFileName,<br>! Boolean reuseFirstSource,
<br>! Boolean tearDownOnSourceEnd) {<br> if (indexFileName != NULL && reuseFirstSource) {<br> // It makes no sense to support trick play if all clients use the same source. Fix this:
<br> env << "MPEG2TransportFileServerMediaSubsession::createNew(): ignoring the index file name, because \"reuseFirstSource\" is set\n";<br>***************<br>*** 79,93 ****<br> }<br> MPEG2TransportStreamIndexFile* indexFile = MPEG2TransportStreamIndexFile::createNew(env, indexFileName);
<br> return new MPEG2TransportFileServerMediaSubsession(env, fileName, indexFile,<br>! reuseFirstSource);<br> }<br> <br> MPEG2TransportFileServerMediaSubsession<br>
::MPEG2TransportFileServerMediaSubsession(UsageEnvironment& env,<br> char const* fileName,<br> MPEG2TransportStreamIndexFile* indexFile,
<br>! Boolean reuseFirstSource)<br>! : FileServerMediaSubsession(env, fileName, reuseFirstSource),<br> fIndexFile(indexFile), fDuration(0.0), fClientSessionHashTable(NULL) {<br>
if (fIndexFile != NULL) { // we support 'trick play'<br> fDuration = fIndexFile->getPlayingDuration();<br>--- 80,95 ----<br> }<br> MPEG2TransportStreamIndexFile* indexFile = MPEG2TransportStreamIndexFile::createNew(env, indexFileName);
<br> return new MPEG2TransportFileServerMediaSubsession(env, fileName, indexFile,<br>! reuseFirstSource, tearDownOnSourceEnd);<br> }<br> <br> MPEG2TransportFileServerMediaSubsession
<br> ::MPEG2TransportFileServerMediaSubsession(UsageEnvironment& env,<br> char const* fileName,<br> MPEG2TransportStreamIndexFile* indexFile,
<br>! Boolean reuseFirstSource,<br>! Boolean tearDownOnSourceEnd)<br>! : FileServerMediaSubsession(env, fileName, reuseFirstSource, tearDownOnSourceEnd),
<br> fIndexFile(indexFile), fDuration(0.0), fClientSessionHashTable(NULL) {<br> if (fIndexFile != NULL) { // we support 'trick play'<br> fDuration = fIndexFile->getPlayingDuration();<br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br>Is this work correct ?<br><br>Thank you for your attention<br><br>Massimo Zito<br><br><br>