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 488 of file testRTSPClient.cpp.

#define DUMMY_SINK_RECEIVE_BUFFER_SIZE   100000

Definition at line 463 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, 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
00242           << "\" subsession (client ports " << scs.subsession->clientPortNum() << "-" << scs.subsession->clientPortNum()+1 << ")\n";
00243 
00244       // Continue setting up this subsession, by sending a RTSP "SETUP" command:
00245       rtspClient->sendSetupCommand(*scs.subsession, continueAfterSETUP, False, REQUEST_STREAMING_OVER_TCP);
00246     }
00247     return;
00248   }
00249 
00250   // We've finished setting up all of the subsessions.  Now, send a RTSP "PLAY" command to start the streaming:
00251   if (scs.session->absStartTime() != NULL) {
00252     // Special case: The stream is indexed by 'absolute' time, so send an appropriate "PLAY" command:
00253     rtspClient->sendPlayCommand(*scs.session, continueAfterPLAY, scs.session->absStartTime(), scs.session->absEndTime());
00254   } else {
00255     scs.duration = scs.session->playEndTime() - scs.session->playStartTime();
00256     rtspClient->sendPlayCommand(*scs.session, continueAfterPLAY);
00257   }
00258 }

void shutdownStream ( RTSPClient rtspClient,
int  exitCode = 1 
)

Definition at line 382 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().

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

void streamTimerHandler ( void *  clientData  ) 

Definition at line 372 of file testRTSPClient.cpp.

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

00372                                           {
00373   ourRTSPClient* rtspClient = (ourRTSPClient*)clientData;
00374   StreamClientState& scs = rtspClient->scs; // alias
00375 
00376   scs.streamTimerTask = NULL;
00377 
00378   // Shut down the stream:
00379   shutdownStream(rtspClient);
00380 }

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 Jun 18 13:19:52 2013 for live by  doxygen 1.5.2