⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ondemandservermediasubsession.cpp

📁 H.264 RTSP 串流(live 555)視窗版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
						void* serverRequestAlternativeByteHandlerClientData) {  StreamState* streamState = (StreamState*)streamToken;  Destinations* destinations    = (Destinations*)(fDestinationsHashTable->Lookup((char const*)clientSessionId));  if (streamState != NULL) {    streamState->startPlaying(destinations,			      rtcpRRHandler, rtcpRRHandlerClientData,			      serverRequestAlternativeByteHandler, serverRequestAlternativeByteHandlerClientData);    if (streamState->rtpSink() != NULL) {      rtpSeqNum = streamState->rtpSink()->currentSeqNo();      rtpTimestamp = streamState->rtpSink()->presetNextTimestamp();    }  }}void OnDemandServerMediaSubsession::pauseStream(unsigned /*clientSessionId*/,						void* streamToken) {  // Pausing isn't allowed if multiple clients are receiving data from  // the same source:  if (fReuseFirstSource) return;  StreamState* streamState = (StreamState*)streamToken;  if (streamState != NULL) streamState->pause();}void OnDemandServerMediaSubsession::seekStream(unsigned /*clientSessionId*/,					       void* streamToken, double seekNPT) {  // Seeking isn't allowed if multiple clients are receiving data from  // the same source:  if (fReuseFirstSource) return;  StreamState* streamState = (StreamState*)streamToken;  if (streamState != NULL && streamState->mediaSource() != NULL) {    seekStreamSource(streamState->mediaSource(), seekNPT);  }}void OnDemandServerMediaSubsession::setStreamScale(unsigned /*clientSessionId*/,						   void* streamToken, float scale) {  // Changing the scale factor isn't allowed if multiple clients are receiving data  // from the same source:  if (fReuseFirstSource) return;  StreamState* streamState = (StreamState*)streamToken;  if (streamState != NULL && streamState->mediaSource() != NULL) {    setStreamSourceScale(streamState->mediaSource(), scale);  }}void OnDemandServerMediaSubsession::deleteStream(unsigned clientSessionId,						 void*& streamToken) {  StreamState* streamState = (StreamState*)streamToken;  // Look up (and remove) the destinations for this client session:  Destinations* destinations    = (Destinations*)(fDestinationsHashTable->Lookup((char const*)clientSessionId));  if (destinations != NULL) {    fDestinationsHashTable->Remove((char const*)clientSessionId);    // Stop streaming to these destinations:    if (streamState != NULL) streamState->endPlaying(destinations);  }  // Delete the "StreamState" structure if it's no longer being used:  if (streamState != NULL) {    if (streamState->referenceCount() > 0) --streamState->referenceCount();    if (streamState->referenceCount() == 0) {      delete streamState;      if (fLastStreamToken == streamToken) fLastStreamToken = NULL;      streamToken = NULL;    }  }  // Finally, delete the destinations themselves:  delete destinations;}char const* OnDemandServerMediaSubsession::getAuxSDPLine(RTPSink* rtpSink, FramedSource* /*inputSource*/) {  // Default implementation:  return rtpSink == NULL ? NULL : rtpSink->auxSDPLine();}void OnDemandServerMediaSubsession::seekStreamSource(FramedSource* /*inputSource*/,						     double /*seekNPT*/) {  // Default implementation: Do nothing}void OnDemandServerMediaSubsession::setStreamSourceScale(FramedSource* /*inputSource*/, float /*scale*/) {  // Default implementation: Do nothing}void OnDemandServerMediaSubsession::closeStreamSource(FramedSource *inputSource) {  Medium::close(inputSource);}void OnDemandServerMediaSubsession::setSDPLinesFromRTPSink(RTPSink* rtpSink, FramedSource* inputSource, unsigned estBitrate) {  if (rtpSink == NULL) return;  char const* mediaType = rtpSink->sdpMediaType();  unsigned char rtpPayloadType = rtpSink->rtpPayloadType();  struct in_addr serverAddrForSDP; serverAddrForSDP.s_addr = fServerAddressForSDP;  char* const ipAddressStr = strDup(our_inet_ntoa(serverAddrForSDP));  char* rtpmapLine = rtpSink->rtpmapLine();  char const* rangeLine = rangeSDPLine();  char const* auxSDPLine = getAuxSDPLine(rtpSink, inputSource);  if (auxSDPLine == NULL) auxSDPLine = "";  char const* const sdpFmt =    "m=%s %u RTP/AVP %d\r\n"    "c=IN IP4 %s\r\n"    "b=AS:%u\r\n"    "%s"    "%s"    "%s"    "a=control:%s\r\n";  unsigned sdpFmtSize = strlen(sdpFmt)    + strlen(mediaType) + 5 /* max short len */ + 3 /* max char len */    + strlen(ipAddressStr)    + 20 /* max int len */    + strlen(rtpmapLine)    + strlen(rangeLine)    + strlen(auxSDPLine)    + strlen(trackId());  char* sdpLines = new char[sdpFmtSize];  sprintf(sdpLines, sdpFmt,	  mediaType, // m= <media>	  fPortNumForSDP, // m= <port>	  rtpPayloadType, // m= <fmt list>	  ipAddressStr, // c= address	  estBitrate, // b=AS:<bandwidth>	  rtpmapLine, // a=rtpmap:... (if present)	  rangeLine, // a=range:... (if present)	  auxSDPLine, // optional extra SDP line	  trackId()); // a=control:<track-id>  delete[] (char*)rangeLine; delete[] rtpmapLine; delete[] ipAddressStr;  fSDPLines = strDup(sdpLines);  delete[] sdpLines;}////////// StreamState implementation //////////static void afterPlayingStreamState(void* clientData) {  StreamState* streamState = (StreamState*)clientData;  if (streamState->streamDuration() == 0.0) {    // When the input stream ends, tear it down.  This will cause a RTCP "BYE"    // to be sent to each client, teling it that the stream has ended.    // (Because the stream didn't have a known duration, there was no other    //  way for clients to know when the stream ended.)    streamState->reclaim();  }  // Otherwise, keep the stream alive, in case a client wants to  // subsequently re-play the stream starting from somewhere other than the end.  // (This can be done only on streams that have a known duration.)}StreamState::StreamState(OnDemandServerMediaSubsession& master,                         Port const& serverRTPPort, Port const& serverRTCPPort,			 RTPSink* rtpSink, BasicUDPSink* udpSink,			 unsigned totalBW, FramedSource* mediaSource,			 Groupsock* rtpGS, Groupsock* rtcpGS)  : fMaster(master), fAreCurrentlyPlaying(False), fReferenceCount(1),    fServerRTPPort(serverRTPPort), fServerRTCPPort(serverRTCPPort),    fRTPSink(rtpSink), fUDPSink(udpSink), fStreamDuration(master.duration()),    fTotalBW(totalBW), fRTCPInstance(NULL) /* created later */,    fMediaSource(mediaSource), fRTPgs(rtpGS), fRTCPgs(rtcpGS) {}StreamState::~StreamState() {  reclaim();}void StreamState::startPlaying(Destinations* dests,	       TaskFunc* rtcpRRHandler, void* rtcpRRHandlerClientData,	       ServerRequestAlternativeByteHandler* serverRequestAlternativeByteHandler,	       void* serverRequestAlternativeByteHandlerClientData) {  if (dests == NULL) return;  if (!fAreCurrentlyPlaying && fMediaSource != NULL) {    if (fRTPSink != NULL) {      fRTPSink->startPlaying(*fMediaSource, afterPlayingStreamState, this);      fAreCurrentlyPlaying = True;    } else if (fUDPSink != NULL) {      fUDPSink->startPlaying(*fMediaSource, afterPlayingStreamState, this);      fAreCurrentlyPlaying = True;    }  }  if (fRTCPInstance == NULL && fRTPSink != NULL) {    // Create (and start) a 'RTCP instance' for this RTP sink:    fRTCPInstance      = RTCPInstance::createNew(fRTPSink->envir(), fRTCPgs,				fTotalBW, (unsigned char*)fMaster.fCNAME,				fRTPSink, NULL /* we're a server */);        // Note: This starts RTCP running automatically  }  if (dests->isTCP) {    // Change RTP and RTCP to use the TCP socket instead of UDP:    if (fRTPSink != NULL) {      fRTPSink->addStreamSocket(dests->tcpSocketNum, dests->rtpChannelId);      fRTPSink->setServerRequestAlternativeByteHandler(serverRequestAlternativeByteHandler, serverRequestAlternativeByteHandlerClientData);    }    if (fRTCPInstance != NULL) {      fRTCPInstance->addStreamSocket(dests->tcpSocketNum, dests->rtcpChannelId);      fRTCPInstance->setSpecificRRHandler(dests->tcpSocketNum, dests->rtcpChannelId,					  rtcpRRHandler, rtcpRRHandlerClientData);    }  } else {    // Tell the RTP and RTCP 'groupsocks' about this destination    // (in case they don't already have it):    if (fRTPgs != NULL) fRTPgs->addDestination(dests->addr, dests->rtpPort);    if (fRTCPgs != NULL) fRTCPgs->addDestination(dests->addr, dests->rtcpPort);    if (fRTCPInstance != NULL) {      fRTCPInstance->setSpecificRRHandler(dests->addr.s_addr, dests->rtcpPort,					  rtcpRRHandler, rtcpRRHandlerClientData);    }  }}void StreamState::pause() {  if (fRTPSink != NULL) fRTPSink->stopPlaying();  if (fUDPSink != NULL) fUDPSink->stopPlaying();  fAreCurrentlyPlaying = False;}void StreamState::endPlaying(Destinations* dests) {  if (dests->isTCP) {    if (fRTPSink != NULL) {      fRTPSink->removeStreamSocket(dests->tcpSocketNum, dests->rtpChannelId);    }    if (fRTCPInstance != NULL) {      fRTCPInstance->removeStreamSocket(dests->tcpSocketNum, dests->rtcpChannelId);      fRTCPInstance->setSpecificRRHandler(dests->tcpSocketNum, dests->rtcpChannelId,					  NULL, NULL);    }  } else {    // Tell the RTP and RTCP 'groupsocks' to stop using these destinations:    if (fRTPgs != NULL) fRTPgs->removeDestination(dests->addr, dests->rtpPort);    if (fRTCPgs != NULL) fRTCPgs->removeDestination(dests->addr, dests->rtcpPort);    if (fRTCPInstance != NULL) {      fRTCPInstance->setSpecificRRHandler(dests->addr.s_addr, dests->rtcpPort,					  NULL, NULL);    }  }}void StreamState::reclaim() {  // Delete allocated media objects  Medium::close(fRTCPInstance) /* will send a RTCP BYE */; fRTCPInstance = NULL;  Medium::close(fRTPSink); fRTPSink = NULL;  Medium::close(fUDPSink); fUDPSink = NULL;  fMaster.closeStreamSource(fMediaSource); fMediaSource = NULL;  delete fRTPgs; fRTPgs = NULL;  delete fRTCPgs; fRTCPgs = NULL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -