private void ShutdownStream(RTSPClient rtspClient, int exitCode = 1) { var scs = ((OurRtspClient)rtspClient).scs; // alias if (scs.session != null) { var someSubsessionsWereActive = false; var iter = new MediaSubsessionIterator(scs.session); MediaSubsession subsession; while ((subsession = iter.Next()) != null) { if (subsession.sink != null) { Medium.Close(subsession.sink); subsession.sink = null; if (subsession.RtcpInstance() != null) { subsession.RtcpInstance().SetByeHandler(null, IntPtr.Zero, 1); // in case the server sends a RTCP "BYE" while handling "TEARDOWN" } someSubsessionsWereActive = true; } } if (someSubsessionsWereActive) { // Send a RTSP "TEARDOWN" command, to tell the server to shutdown the stream. // Don't bother handling the response to the "TEARDOWN". rtspClient.SendTeardownCommand(scs.session, null, null); } } Console.Error.WriteLine(rtspClient + "Closing the stream."); Medium.Close(rtspClient); // Note that this will also cause this stream's "StreamClientState" structure to get reclaimed. if (--rtspClientCount == 0) { // The final stream has ended, so exit the application now. // (Of course, if you're embedding this code into your own application, you might want to comment this out.) Environment.Exit(exitCode); // If you choose *not* to "exit()" the application (i.e., if you comment out the call to "exit()" above), // and you don't intend to do anything more with this "TaskScheduler" and "UsageEnvironment", // then you can also reclaim the (small) memory used by these objects by doing the following. // (However, you must not do this until after you have left the event loop.) /* * TaskScheduler* scheduler = &(env.taskScheduler()); * env.reclaim(); * delete scheduler; */ } }
private void SubsessionAfterPlaying(IntPtr clientData) { var subsession = new MediaSubsession(clientData); var rtspClient = new RTSPClient(subsession.miscPtr); // Begin by closing this subsession's stream: Medium.Close(subsession.sink); subsession.sink = null; // Next, check whether *all* subsessions' streams have now been closed: var session = subsession.ParentSession(); var iter = new MediaSubsessionIterator(session); while ((subsession = iter.Next()) != null) { if (subsession.sink != null) { return; // this subsession is still active } } // All subsessions' streams have now been closed, so shutdown the client: ShutdownStream(rtspClient); }