RTP::Session & Session::createSession(const Url &url, const Channel::Description & remote, const boost::optional< TSSrc > & ssrc ) throw( RTSP::Exception::ManagedError ) { try { Session::Lock lk( *this ); // setup channel boost::shared_ptr< Channel::Bi > rtpChan, rtcpChan; TPortPair local; // udp if ( remote.type == Channel::Owned ) { local = Port::Udp::getInstance()->getPair(); Log::debug("%s: creating udp socket locally bound to %d / %d", getLogName(), local.first, local.second ); auto_ptr< KGD::Socket::Udp > rtp( new KGD::Socket::Udp( local.first, url.host ) ), rtcp( new KGD::Socket::Udp( local.second, url.host ) ); Log::debug("%s: connecting udp socket to remote %d / %d", getLogName(), remote.ports.first, remote.ports.second); try { rtp->connectTo( remote.ports.first, url.remoteHost ); rtcp->connectTo( remote.ports.second, url.remoteHost ); } catch( const KGD::Socket::Exception & e ) { Log::debug( "%s: socket error: %s", getLogName(), e.what() ); throw RTSP::Exception::ManagedError( Error::UnsupportedTransport ); } rtp->setWriteTimeout( KGD::Socket::WRITE_TIMEOUT ); rtcp->setWriteTimeout( KGD::Socket::WRITE_TIMEOUT ); rtcp->setReadBlock( true ); rtcp->setReadTimeout( RTCP::Receiver::POLL_INTERVAL ); rtpChan = rtp; rtcpChan = rtcp; } // tcp interleaved else { Socket & rtsp = _conn.getSocket(); local = rtsp.addInterleavePair( remote.ports, _id ); rtpChan = rtsp.getInterleave( local.first ); rtcpChan = rtsp.getInterleave( local.second ); rtcpChan->setReadTimeout( RTCP::Receiver::POLL_INTERVAL ); } // get description int mediumIndex = fromString< int >( url.track ); SDP::Medium::Base & med = _conn.getDescription( url.file ).getMedium( mediumIndex ); // create session auto_ptr< RTP::Session > s( new RTP::Session( *this, url, med, rtpChan, rtcpChan, _conn.getUserAgent() ) ); if ( ssrc ) s->setSsrc( *ssrc ); // temp to return RTP::Session * sPtr = s.get(); // add to basket { string tmpTrack( url.track ); _sessions.insert( tmpTrack, s ); } Log::debug("%s: RTP session created / track: %s / ports: RTP %d %d - RTCP %d %d" , getLogName() , url.track.c_str() , local.first , remote.ports.first , local.second , remote.ports.second ); return *sPtr; } catch( const KGD::Socket::Exception & e ) { Log::debug( "%s: socket error: %s", getLogName(), e.what() ); throw RTSP::Exception::ManagedError( Error::InternalServerError ); } // no more ports catch( const KGD::Exception::NotFound & e ) { Log::debug( "%s: %s", getLogName(), e.what() ); throw RTSP::Exception::ManagedError( Error::NotEnoughBandwidth ); } }
int main(int argc, char **argv) { register int c, i, r, errflg = 0; struct stat64 s2; int eflag; int extsize = - 1; progname = basename(argv[0]); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); while ((c = getopt(argc, argv, "pe:V")) != EOF) { switch (c) { case 'e': eflag = 1; extsize = atoi(optarg); break; case 'p': pflag = 1; break; case 'V': printf(_("%s version %s\n"), progname, VERSION); exit(0); default: errflg++; } } /* * Check for sufficient arguments or a usage error. */ argc -= optind; argv = &argv[optind]; if (argc < 2) { fprintf(stderr, _("%s: must specify files to copy\n"), progname); errflg++; } if (errflg) usage(); /* * If there is more than a source and target, * the last argument (the target) must be a directory * which really exists. */ if (argc > 2) { if (stat64(argv[argc-1], &s2) < 0) { fprintf(stderr, _("%s: stat64 of %s failed\n"), progname, argv[argc-1]); exit(2); } if (!S_ISDIR(s2.st_mode)) { fprintf(stderr, _("%s: final argument is not directory\n"), progname); usage(); } } /* * Perform a multiple argument rtcp by * multiple invocations of rtcp(). */ r = 0; for (i = 0; i < argc-1; i++) r += rtcp(argv[i], argv[argc-1], extsize); /* * Show errors by nonzero exit code. */ exit(r?2:0); }