testProgs/testRTSPClient.cpp File Reference

#include "liveMedia.hh"
#include "BasicUsageEnvironment.hh"

Include dependency graph for testRTSPClient.cpp:

Go to the source code of this file.

Data Structures

class  StreamClientState
class  ourRTSPClient
class  DummySink

Defines

#define RTSP_CLIENT_VERBOSITY_LEVEL   1
#define REQUEST_STREAMING_OVER_TCP   False
#define DUMMY_SINK_RECEIVE_BUFFER_SIZE   100000
#define DEBUG_PRINT_EACH_RECEIVED_FRAME   1

Functions

void continueAfterDESCRIBE (RTSPClient *rtspClient, int resultCode, char *resultString)
void continueAfterSETUP (RTSPClient *rtspClient, int resultCode, char *resultString)
void continueAfterPLAY (RTSPClient *rtspClient, int resultCode, char *resultString)
void subsessionAfterPlaying (void *clientData)
void subsessionByeHandler (void *clientData)
void streamTimerHandler (void *clientData)
void openURL (UsageEnvironment &env, char const *progName, char const *rtspURL)
void setupNextSubsession (RTSPClient *rtspClient)
void shutdownStream (RTSPClient *rtspClient, int exitCode=1)
UsageEnvironmentoperator<< (UsageEnvironment &env, const RTSPClient &rtspClient)
UsageEnvironmentoperator<< (UsageEnvironment &env, const MediaSubsession &subsession)
void usage (UsageEnvironment &env, char const *progName)
int main (int argc, char **argv)

Variables

char eventLoopWatchVariable = 0
static unsigned rtspClientCount = 0


Define Documentation

#define DEBUG_PRINT_EACH_RECEIVED_FRAME   1

Definition at line 498 of file testRTSPClient.cpp.

#define DUMMY_SINK_RECEIVE_BUFFER_SIZE   100000

Definition at line 473 of file testRTSPClient.cpp.

Referenced by DummySink::continuePlaying(), and DummySink::DummySink().

#define REQUEST_STREAMING_OVER_TCP   False

Definition at line 229 of file testRTSPClient.cpp.

Referenced by setupNextSubsession().

#define RTSP_CLIENT_VERBOSITY_LEVEL   1

Definition at line 166 of file testRTSPClient.cpp.

Referenced by openURL().


Function Documentation

void continueAfterDESCRIBE ( RTSPClient rtspClient,
int  resultCode,
char *  resultString 
)

void continueAfterPLAY ( RTSPClient rtspClient,
int  resultCode,
char *  resultString 
)

void continueAfterSETUP ( RTSPClient rtspClient,
int  resultCode,
char *  resultString 
)

int main ( int  argc,
char **  argv 
)

Definition at line 65 of file testRTSPClient.cpp.

References BasicUsageEnvironment::createNew(), BasicTaskScheduler::createNew(), TaskScheduler::doEventLoop(), env, eventLoopWatchVariable, openURL(), UsageEnvironment::taskScheduler(), and usage().

00065                                 {
00066   // Begin by setting up our usage environment:
00067   TaskScheduler* scheduler = BasicTaskScheduler::createNew();
00068   UsageEnvironment* env = BasicUsageEnvironment::createNew(*scheduler);
00069 
00070   // We need at least one "rtsp://" URL argument:
00071   if (argc < 2) {
00072     usage(*env, argv[0]);
00073     return 1;
00074   }
00075 
00076   // There are argc-1 URLs: argv[1] through argv[argc-1].  Open and start streaming each one:
00077   for (int i = 1; i <= argc-1; ++i) {
00078     openURL(*env, argv[0], argv[i]);
00079   }
00080 
00081   // All subsequent activity takes place within the event loop:
00082   env->taskScheduler().doEventLoop(&eventLoopWatchVariable);
00083     // This function call does not return, unless, at some point in time, "eventLoopWatchVariable" gets set to something non-zero.
00084 
00085   return 0;
00086 
00087   // If you choose to continue the application past this point (i.e., if you comment out the "return 0;" statement above),
00088   // and if you don't intend to do anything more with the "TaskScheduler" and "UsageEnvironment" objects,
00089   // then you can also reclaim the (small) memory used by these objects by uncommenting the following code:
00090   /*
00091     env->reclaim(); env = NULL;
00092     delete scheduler; scheduler = NULL;
00093   */
00094 }

void openURL ( UsageEnvironment env,
char const *  progName,
char const *  rtspURL 
)

Definition at line 170 of file testRTSPClient.cpp.

References continueAfterDESCRIBE(), ourRTSPClient::createNew(), env, UsageEnvironment::getResultMsg(), NULL, RTSP_CLIENT_VERBOSITY_LEVEL, rtspClientCount, and RTSPClient::sendDescribeCommand().

Referenced by main().

00170                                                                                {
00171   // Begin by creating a "RTSPClient" object.  Note that there is a separate "RTSPClient" object for each stream that we wish
00172   // to receive (even if more than stream uses the same "rtsp://" URL).
00173   RTSPClient* rtspClient = ourRTSPClient::createNew(env, rtspURL, RTSP_CLIENT_VERBOSITY_LEVEL, progName);
00174   if (rtspClient == NULL) {
00175     env << "Failed to create a RTSP client for URL \"" << rtspURL << "\": " << env.getResultMsg() << "\n";
00176     return;
00177   }
00178 
00179   ++rtspClientCount;
00180 
00181   // Next, send a RTSP "DESCRIBE" command, to get a SDP description for the stream.
00182   // Note that this command - like all RTSP commands - is sent asynchronously; we do not block, waiting for a response.
00183   // Instead, the following function call returns immediately, and we handle the RTSP response later, from within the event loop:
00184   rtspClient->sendDescribeCommand(continueAfterDESCRIBE); 
00185 }

UsageEnvironment& operator<< ( UsageEnvironment env,
const MediaSubsession subsession 
)

Definition at line 54 of file testRTSPClient.cpp.

References MediaSubsession::codecName(), env, MediaSubsession::mediumName(), and subsession.

00054                                                                                        {
00055   return env << subsession.mediumName() << "/" << subsession.codecName();
00056 }

UsageEnvironment& operator<< ( UsageEnvironment env,
const RTSPClient rtspClient 
)

Definition at line 49 of file testRTSPClient.cpp.

References env, and RTSPClient::url().

00049                                                                                   {
00050   return env << "[URL:\"" << rtspClient.url() << "\"]: ";
00051 }

void setupNextSubsession ( RTSPClient rtspClient  ) 

Definition at line 231 of file testRTSPClient.cpp.

References MediaSession::absEndTime(), MediaSession::absStartTime(), MediaSubsession::clientPortNum(), continueAfterPLAY(), continueAfterSETUP(), StreamClientState::duration, env, Medium::envir(), False, UsageEnvironment::getResultMsg(), MediaSubsession::initiate(), StreamClientState::iter, MediaSubsessionIterator::next(), NULL, MediaSession::playEndTime(), MediaSession::playStartTime(), REQUEST_STREAMING_OVER_TCP, MediaSubsession::rtcpIsMuxed(), RTSPClient::sendPlayCommand(), RTSPClient::sendSetupCommand(), StreamClientState::session, and StreamClientState::subsession.

00231                                                  {
00232   UsageEnvironment& env = rtspClient->envir(); // alias
00233   StreamClientState& scs = ((ourRTSPClient*)rtspClient)->scs; // alias
00234   
00235   scs.subsession = scs.iter->next();
00236   if (scs.subsession != NULL) {
00237     if (!scs.subsession->initiate()) {
00238       env << *rtspClient << "Failed to initiate the \"" << *scs.subsession << "\" subsession: " << env.getResultMsg() << "\n";
00239       setupNextSubsession(rtspClient); // give up on this subsession; go to the next one
00240     } else {
00241       env << *rtspClient << "Initiated the \"" << *scs.subsession << "\" subsession (";
00242       if (scs.subsession->rtcpIsMuxed()) {
00243         env << "client port " << scs.subsession->clientPortNum();
00244       } else {
00245         env << "client ports " << scs.subsession->clientPortNum() << "-" << scs.subsession->clientPortNum()+1;
00246       }
00247       env << ")\n";
00248 
00249       // Continue setting up this subsession, by sending a RTSP "SETUP" command:
00250       rtspClient->sendSetupCommand(*scs.subsession, continueAfterSETUP, False, REQUEST_STREAMING_OVER_TCP);
00251     }
00252     return;
00253   }
00254 
00255   // We've finished setting up all of the subsessions.  Now, send a RTSP "PLAY" command to start the streaming:
00256   if (scs.session->absStartTime() != NULL) {
00257     // Special case: The stream is indexed by 'absolute' time, so send an appropriate "PLAY" command:
00258     rtspClient->sendPlayCommand(*scs.session, continueAfterPLAY, scs.session->absStartTime(), scs.session->absEndTime());
00259   } else {
00260     scs.duration = scs.session->playEndTime() - scs.session->playStartTime();
00261     rtspClient->sendPlayCommand(*scs.session, continueAfterPLAY);
00262   }
00263 }

void shutdownStream ( RTSPClient rtspClient,
int  exitCode = 1 
)

Definition at line 392 of file testRTSPClient.cpp.

References Medium::close(), env, Medium::envir(), exit, False, iter, MediaSubsessionIterator::next(), NULL, MediaSubsession::rtcpInstance(), rtspClientCount, RTSPClient::sendTeardownCommand(), StreamClientState::session, RTCPInstance::setByeHandler(), MediaSubsession::sink, subsession, and True.

Referenced by streamTimerHandler().

00392                                                           {
00393   UsageEnvironment& env = rtspClient->envir(); // alias
00394   StreamClientState& scs = ((ourRTSPClient*)rtspClient)->scs; // alias
00395 
00396   // First, check whether any subsessions have still to be closed:
00397   if (scs.session != NULL) { 
00398     Boolean someSubsessionsWereActive = False;
00399     MediaSubsessionIterator iter(*scs.session);
00400     MediaSubsession* subsession;
00401 
00402     while ((subsession = iter.next()) != NULL) {
00403       if (subsession->sink != NULL) {
00404         Medium::close(subsession->sink);
00405         subsession->sink = NULL;
00406 
00407         if (subsession->rtcpInstance() != NULL) {
00408           subsession->rtcpInstance()->setByeHandler(NULL, NULL); // in case the server sends a RTCP "BYE" while handling "TEARDOWN"
00409         }
00410 
00411         someSubsessionsWereActive = True;
00412       }
00413     }
00414 
00415     if (someSubsessionsWereActive) {
00416       // Send a RTSP "TEARDOWN" command, to tell the server to shutdown the stream.
00417       // Don't bother handling the response to the "TEARDOWN".
00418       rtspClient->sendTeardownCommand(*scs.session, NULL);
00419     }
00420   }
00421 
00422   env << *rtspClient << "Closing the stream.\n";
00423   Medium::close(rtspClient);
00424     // Note that this will also cause this stream's "StreamClientState" structure to get reclaimed.
00425 
00426   if (--rtspClientCount == 0) {
00427     // The final stream has ended, so exit the application now.
00428     // (Of course, if you're embedding this code into your own application, you might want to comment this out,
00429     // and replace it with "eventLoopWatchVariable = 1;", so that we leave the LIVE555 event loop, and continue running "main()".)
00430     exit(exitCode);
00431   }
00432 }

void streamTimerHandler ( void *  clientData  ) 

Definition at line 382 of file testRTSPClient.cpp.

References NULL, ourRTSPClient::scs, shutdownStream(), and StreamClientState::streamTimerTask.

00382                                           {
00383   ourRTSPClient* rtspClient = (ourRTSPClient*)clientData;
00384   StreamClientState& scs = rtspClient->scs; // alias
00385 
00386   scs.streamTimerTask = NULL;
00387 
00388   // Shut down the stream:
00389   shutdownStream(rtspClient);
00390 }

void subsessionAfterPlaying ( void *  clientData  ) 

void subsessionByeHandler ( void *  clientData  ) 

void usage ( UsageEnvironment env,
char const *  progName 
)

Definition at line 58 of file testRTSPClient.cpp.

References env.

00058                                                         {
00059   env << "Usage: " << progName << " <rtsp-url-1> ... <rtsp-url-N>\n";
00060   env << "\t(where each <rtsp-url-i> is a \"rtsp://\" URL)\n";
00061 }


Variable Documentation

char eventLoopWatchVariable = 0

Definition at line 63 of file testRTSPClient.cpp.

Referenced by main().

unsigned rtspClientCount = 0 [static]

Definition at line 168 of file testRTSPClient.cpp.

Referenced by openURL(), and shutdownStream().


Generated on Tue Mar 25 14:38:53 2014 for live by  doxygen 1.5.2