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

📄 ondemandservermediasubsession.cpp

📁 流媒体传输协议的实现代码,非常有用.可以支持rtsp mms等流媒体传输协议
💻 CPP
📖 第 1 页 / 共 2 页
字号:
						unsigned& rtpTimestamp) {  StreamState* streamState = (StreamState*)streamToken;   Destinations* destinations    = (Destinations*)(fDestinationsHashTable->Lookup((char const*)clientSessionId));  if (streamState != NULL) {    streamState->startPlaying(destinations);    if (streamState->rtpSink() != NULL) {      rtpSeqNum = streamState->rtpSink()->currentSeqNo();      rtpTimestamp = streamState->rtpSink()->currentTimestamp();    }  }}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, float 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) {  // 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:  StreamState* streamState = (StreamState*)streamToken;   if (streamState != NULL) streamState->endPlaying(destinations);  // Delete the "StreamState" structure if it's no longer being used:  if (streamState != NULL && 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*/,						     float /*seekNPT*/) {  // Default implementation: Do nothing}void OnDemandServerMediaSubsession::setStreamSourceScale(FramedSource* /*inputSource*/, float /*scale*/) {  // Default implementation: Do nothing}void OnDemandServerMediaSubsession::setSDPLinesFromRTPSink(RTPSink* rtpSink, FramedSource* inputSource) {  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"    "%s"    "%s"    "%s"    "a=control:%s\r\n";  unsigned sdpFmtSize = strlen(sdpFmt)    + strlen(mediaType) + 5 /* max short len */ + 3 /* max char len */    + strlen(ipAddressStr)    + 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	  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) {  // When the input stream ends, keep it alive, in case the client wants to  // subsequently re-play the stream starting from somewhere other than the end.  // If, instead, you want to terminate the stream, enable the following code.#if 0  StreamState* streamState = (StreamState*)clientData;  streamState->reclaim();#endif}StreamState::StreamState(Port const& serverRTPPort, Port const& serverRTCPPort,			 RTPSink* rtpSink, BasicUDPSink* udpSink,			 unsigned totalBW, char* CNAME,			 FramedSource* mediaSource,			 Groupsock* rtpGS, Groupsock* rtcpGS)  : fAreCurrentlyPlaying(False), fReferenceCount(1),    fServerRTPPort(serverRTPPort), fServerRTCPPort(serverRTCPPort),    fRTPSink(rtpSink), fUDPSink(udpSink),    fTotalBW(totalBW), fCNAME(CNAME), fRTCPInstance(NULL) /* created later */,    fMediaSource(mediaSource), fRTPgs(rtpGS), fRTCPgs(rtcpGS) {}  StreamState::~StreamState() {  reclaim();}void StreamState::startPlaying(Destinations* dests) {  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*)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);    }    if (fRTCPInstance != NULL) {      fRTCPInstance->addStreamSocket(dests->tcpSocketNum, dests->rtcpChannelId);    }  } 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);  }}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);    }  } 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);  }}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;  Medium::close(fMediaSource); fMediaSource = NULL;  delete fRTPgs; fRTPgs = NULL;  delete fRTCPgs; fRTCPgs = NULL;  fReferenceCount = 0;}

⌨️ 快捷键说明

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