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

#define DUMMY_SINK_RECEIVE_BUFFER_SIZE   100000

Definition at line 447 of file testRTSPClient.cpp.

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

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

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

00226                                                  {
00227   UsageEnvironment& env = rtspClient->envir(); // alias
00228   StreamClientState& scs = ((ourRTSPClient*)rtspClient)->scs; // alias
00229   
00230   scs.subsession = scs.iter->next();
00231   if (scs.subsession != NULL) {
00232     if (!scs.subsession->initiate()) {
00233       env << *rtspClient << "Failed to initiate the \"" << *scs.subsession << "\" subsession: " << env.getResultMsg() << "\n";
00234       setupNextSubsession(rtspClient); // give up on this subsession; go to the next one
00235     } else {
00236       env << *rtspClient << "Initiated the \"" << *scs.subsession
00237           << "\" subsession (client ports " << scs.subsession->clientPortNum() << "-" << scs.subsession->clientPortNum()+1 << ")\n";
00238 
00239       // Continue setting up this subsession, by sending a RTSP "SETUP" command:
00240       rtspClient->sendSetupCommand(*scs.subsession, continueAfterSETUP);
00241     }
00242     return;
00243   }
00244 
00245   // We've finished setting up all of the subsessions.  Now, send a RTSP "PLAY" command to start the streaming:
00246   scs.duration = scs.session->playEndTime() - scs.session->playStartTime();
00247   rtspClient->sendPlayCommand(*scs.session, continueAfterPLAY);
00248 }

void shutdownStream ( RTSPClient rtspClient,
int  exitCode = 1 
)

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

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

void streamTimerHandler ( void *  clientData  ) 

Definition at line 356 of file testRTSPClient.cpp.

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

00356                                           {
00357   ourRTSPClient* rtspClient = (ourRTSPClient*)clientData;
00358   StreamClientState& scs = rtspClient->scs; // alias
00359 
00360   scs.streamTimerTask = NULL;
00361 
00362   // Shut down the stream:
00363   shutdownStream(rtspClient);
00364 }

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 Thu May 17 07:14:47 2012 for live by  doxygen 1.5.2