diff --git a/inc/MulticastServerMediaSubsession.h b/inc/MulticastServerMediaSubsession.h new file mode 100644 index 0000000..03f1937 --- /dev/null +++ b/inc/MulticastServerMediaSubsession.h @@ -0,0 +1,40 @@ +/* --------------------------------------------------------------------------- +** This software is in the public domain, furnished "as is", without technical +** support, and with no warranty, express or implied, as to its usefulness for +** any purpose. +** +** ServerMediaSubsession.h +** +** -------------------------------------------------------------------------*/ + +#pragma once + +#include "ServerMediaSubsession.h" + +// ----------------------------------------- +// ServerMediaSubsession for Multicast +// ----------------------------------------- +class MulticastServerMediaSubsession : public PassiveServerMediaSubsession , public BaseServerMediaSubsession +{ + public: + static MulticastServerMediaSubsession* createNew(UsageEnvironment& env + , struct in_addr destinationAddress + , Port rtpPortNum, Port rtcpPortNum + , int ttl + , StreamReplicator* replicator + , const std::string& format); + + protected: + MulticastServerMediaSubsession(StreamReplicator* replicator, RTPSink* rtpSink, RTCPInstance* rtcpInstance) + : PassiveServerMediaSubsession(*rtpSink, rtcpInstance), BaseServerMediaSubsession(replicator), m_rtpSink(rtpSink) {}; + + virtual char const* sdpLines() ; + virtual char const* getAuxSDPLine(RTPSink* rtpSink,FramedSource* inputSource); + + protected: + RTPSink* m_rtpSink; + std::string m_SDPLines; +}; + + + diff --git a/inc/SegmentServerMediaSubsession.h b/inc/SegmentServerMediaSubsession.h new file mode 100644 index 0000000..cafdcad --- /dev/null +++ b/inc/SegmentServerMediaSubsession.h @@ -0,0 +1,78 @@ +/* --------------------------------------------------------------------------- +** This software is in the public domain, furnished "as is", without technical +** support, and with no warranty, express or implied, as to its usefulness for +** any purpose. +** +** ServerMediaSubsession.h +** +** -------------------------------------------------------------------------*/ + +#pragma once + +#include "UnicastServerMediaSubsession.h" + +// ----------------------------------------- +// ServerMediaSubsession for HLS +// ----------------------------------------- +class HLSServerMediaSubsession : public UnicastServerMediaSubsession +{ + class HLSSink : public MediaSink + { + public: + static HLSSink* createNew(UsageEnvironment& env, unsigned int bufferSize, unsigned int sliceDuration) + { + return new HLSSink(env, bufferSize, sliceDuration); + } + + protected: + HLSSink(UsageEnvironment& env, unsigned bufferSize, unsigned int sliceDuration); + virtual ~HLSSink(); + + virtual Boolean continuePlaying(); + + static void afterGettingFrame(void* clientData, unsigned frameSize, + unsigned numTruncatedBytes, + struct timeval presentationTime, + unsigned durationInMicroseconds) { + HLSSink* sink = (HLSSink*)clientData; + sink->afterGettingFrame(frameSize, numTruncatedBytes, presentationTime); + } + + void afterGettingFrame(unsigned frameSize, unsigned numTruncatedBytes, struct timeval presentationTime); + + public: + unsigned int getHLSBufferSize(unsigned int slice); + const char* getHLSBuffer(unsigned int slice); + unsigned int firstTime(); + unsigned int duration(); + unsigned int getSliceDuration() { return m_sliceDuration; } + + private: + unsigned char * m_buffer; + unsigned int m_bufferSize; + std::map m_outputBuffers; + unsigned int m_refTime; + unsigned int m_sliceDuration; + }; + + public: + static HLSServerMediaSubsession* createNew(UsageEnvironment& env, StreamReplicator* replicator, const std::string& format, unsigned int sliceDuration) + { + return new HLSServerMediaSubsession(env, replicator, format, sliceDuration); + } + + protected: + HLSServerMediaSubsession(UsageEnvironment& env, StreamReplicator* replicator, const std::string& format, unsigned int sliceDuration); + virtual ~HLSServerMediaSubsession(); + + virtual float getCurrentNPT(void* streamToken); + virtual float duration() const ; + virtual void seekStream(unsigned clientSessionId, void* streamToken, double& seekNPT, double streamDuration, u_int64_t& numBytes); + virtual FramedSource* getStreamSource(void* streamToken); + + protected: + unsigned int m_slice; + HLSSink * m_hlsSink; +}; + + diff --git a/inc/ServerMediaSubsession.h b/inc/ServerMediaSubsession.h index 3f6c4ea..536176d 100644 --- a/inc/ServerMediaSubsession.h +++ b/inc/ServerMediaSubsession.h @@ -7,8 +7,7 @@ ** ** -------------------------------------------------------------------------*/ -#ifndef SERVER_MEDIA_SUBSESSION -#define SERVER_MEDIA_SUBSESSION +#pragma once #include @@ -16,7 +15,6 @@ #include #include #include -#include // live555 #include @@ -41,234 +39,3 @@ class BaseServerMediaSubsession StreamReplicator* m_replicator; }; -// ----------------------------------------- -// ServerMediaSubsession for Multicast -// ----------------------------------------- -class MulticastServerMediaSubsession : public PassiveServerMediaSubsession , public BaseServerMediaSubsession -{ - public: - static MulticastServerMediaSubsession* createNew(UsageEnvironment& env - , struct in_addr destinationAddress - , Port rtpPortNum, Port rtcpPortNum - , int ttl - , StreamReplicator* replicator - , const std::string& format); - - protected: - MulticastServerMediaSubsession(StreamReplicator* replicator, RTPSink* rtpSink, RTCPInstance* rtcpInstance) - : PassiveServerMediaSubsession(*rtpSink, rtcpInstance), BaseServerMediaSubsession(replicator), m_rtpSink(rtpSink) {}; - - virtual char const* sdpLines() ; - virtual char const* getAuxSDPLine(RTPSink* rtpSink,FramedSource* inputSource); - - protected: - RTPSink* m_rtpSink; - std::string m_SDPLines; -}; - -// ----------------------------------------- -// ServerMediaSubsession for Unicast -// ----------------------------------------- -class UnicastServerMediaSubsession : public OnDemandServerMediaSubsession , public BaseServerMediaSubsession -{ - public: - static UnicastServerMediaSubsession* createNew(UsageEnvironment& env, StreamReplicator* replicator, const std::string& format); - - protected: - UnicastServerMediaSubsession(UsageEnvironment& env, StreamReplicator* replicator, const std::string& format) - : OnDemandServerMediaSubsession(env, False), BaseServerMediaSubsession(replicator), m_format(format) {}; - - virtual FramedSource* createNewStreamSource(unsigned clientSessionId, unsigned& estBitrate); - virtual RTPSink* createNewRTPSink(Groupsock* rtpGroupsock, unsigned char rtpPayloadTypeIfDynamic, FramedSource* inputSource); - virtual char const* getAuxSDPLine(RTPSink* rtpSink,FramedSource* inputSource); - - protected: - const std::string m_format; -}; - -// ----------------------------------------- -// ServerMediaSubsession for HLS -// ----------------------------------------- -class HLSServerMediaSubsession : public UnicastServerMediaSubsession -{ - class HLSSink : public MediaSink - { - public: - static HLSSink* createNew(UsageEnvironment& env, unsigned int bufferSize, unsigned int sliceDuration) - { - return new HLSSink(env, bufferSize, sliceDuration); - } - - protected: - HLSSink(UsageEnvironment& env, unsigned bufferSize, unsigned int sliceDuration) : MediaSink(env), m_bufferSize(bufferSize), m_refTime(0), m_sliceDuration(sliceDuration) - { - m_buffer = new unsigned char[m_bufferSize]; - } - - virtual ~HLSSink() - { - delete[] m_buffer; - } - - - virtual Boolean continuePlaying() - { - Boolean ret = False; - if (fSource != NULL) - { - fSource->getNextFrame(m_buffer, m_bufferSize, - afterGettingFrame, this, - onSourceClosure, this); - ret = True; - } - return ret; - } - - static void afterGettingFrame(void* clientData, unsigned frameSize, - unsigned numTruncatedBytes, - struct timeval presentationTime, - unsigned durationInMicroseconds) - { - HLSSink* sink = (HLSSink*)clientData; - sink->afterGettingFrame(frameSize, numTruncatedBytes, presentationTime); - } - - void afterGettingFrame(unsigned frameSize, unsigned numTruncatedBytes, struct timeval presentationTime) - { - if (numTruncatedBytes > 0) - { - envir() << "FileSink::afterGettingFrame(): The input frame data was too large for our buffer size \n"; - // realloc a bigger buffer - m_bufferSize += numTruncatedBytes; - delete[] m_buffer; - m_buffer = new unsigned char[m_bufferSize]; - } - else - { - // append buffer to slice buffer - if (m_refTime == 0) - { - m_refTime = presentationTime.tv_sec; - } - unsigned int slice = (presentationTime.tv_sec-m_refTime)/m_sliceDuration; - std::string& outputBuffer = m_outputBuffers[slice]; - outputBuffer.append((const char*)m_buffer, frameSize); - - // remove old buffers - while (m_outputBuffers.size()>5) - { - m_outputBuffers.erase(m_outputBuffers.begin()); - } - } - - continuePlaying(); - } - - public: - unsigned int getHLSBufferSize(unsigned int slice) - { - unsigned int size = 0; - std::map::iterator it = m_outputBuffers.find(slice); - if (it != m_outputBuffers.end()) - { - size = it->second.size(); - } - return size; - } - - const char* getHLSBuffer(unsigned int slice) - { - const char* content = NULL; - std::map::iterator it = m_outputBuffers.find(slice); - if (it != m_outputBuffers.end()) - { - content = it->second.c_str(); - } - return content; - } - - unsigned int firstTime() - { - unsigned int firstTime = 0; - if (m_outputBuffers.size() != 0) - { - firstTime = m_outputBuffers.begin()->first; - } - return firstTime*m_sliceDuration; - } - - unsigned int duration() - { - unsigned int duration = 0; - if (m_outputBuffers.size() != 0) - { - duration = m_outputBuffers.rbegin()->first - m_outputBuffers.begin()->first; - } - return (duration)*m_sliceDuration; - } - unsigned int getSliceDuration() - { - return m_sliceDuration; - } - - private: - unsigned char * m_buffer; - unsigned int m_bufferSize; - std::map m_outputBuffers; - unsigned int m_refTime; - unsigned int m_sliceDuration; - }; - - public: - static HLSServerMediaSubsession* createNew(UsageEnvironment& env, StreamReplicator* replicator, const std::string& format, unsigned int sliceDuration) - { - return new HLSServerMediaSubsession(env, replicator, format, sliceDuration); - } - - protected: - HLSServerMediaSubsession(UsageEnvironment& env, StreamReplicator* replicator, const std::string& format, unsigned int sliceDuration) - : UnicastServerMediaSubsession(env, replicator, format), m_slice(0) - { - // Create a source - FramedSource* source = replicator->createStreamReplica(); - FramedSource* videoSource = createSource(env, source, format); - - // Start Playing the HLS Sink - m_hlsSink = HLSSink::createNew(env, OutPacketBuffer::maxSize, sliceDuration); - m_hlsSink->startPlaying(*videoSource, NULL, NULL); - } - virtual ~HLSServerMediaSubsession() - { - Medium::close(m_hlsSink); - } - - virtual float getCurrentNPT(void* streamToken) - { - return (m_hlsSink->firstTime()); - } - virtual float duration() const - { - return (m_hlsSink->duration()); - } - virtual void seekStream(unsigned clientSessionId, void* streamToken, double& seekNPT, double streamDuration, u_int64_t& numBytes) - { - m_slice = seekNPT / m_hlsSink->getSliceDuration(); - seekNPT = m_slice * m_hlsSink->getSliceDuration(); - numBytes = m_hlsSink->getHLSBufferSize(m_slice); - std::cout << "seek seekNPT:" << seekNPT << " slice:" << m_slice << " numBytes:" << numBytes << std::endl; - - } - virtual FramedSource* getStreamSource(void* streamToken) - { - unsigned int size = m_hlsSink->getHLSBufferSize(m_slice); - u_int8_t* content = new u_int8_t[size]; - memcpy(content, m_hlsSink->getHLSBuffer(m_slice), size); - return ByteStreamMemoryBufferSource::createNew(envir(), content, size); - } - - protected: - unsigned int m_slice; - HLSSink * m_hlsSink; -}; - -#endif diff --git a/inc/UnicastServerMediaSubsession.h b/inc/UnicastServerMediaSubsession.h new file mode 100644 index 0000000..f6c48f6 --- /dev/null +++ b/inc/UnicastServerMediaSubsession.h @@ -0,0 +1,34 @@ +/* --------------------------------------------------------------------------- +** This software is in the public domain, furnished "as is", without technical +** support, and with no warranty, express or implied, as to its usefulness for +** any purpose. +** +** ServerMediaSubsession.h +** +** -------------------------------------------------------------------------*/ + +#pragma once + +#include "ServerMediaSubsession.h" + +// ----------------------------------------- +// ServerMediaSubsession for Unicast +// ----------------------------------------- +class UnicastServerMediaSubsession : public OnDemandServerMediaSubsession , public BaseServerMediaSubsession +{ + public: + static UnicastServerMediaSubsession* createNew(UsageEnvironment& env, StreamReplicator* replicator, const std::string& format); + + protected: + UnicastServerMediaSubsession(UsageEnvironment& env, StreamReplicator* replicator, const std::string& format) + : OnDemandServerMediaSubsession(env, False), BaseServerMediaSubsession(replicator), m_format(format) {}; + + virtual FramedSource* createNewStreamSource(unsigned clientSessionId, unsigned& estBitrate); + virtual RTPSink* createNewRTPSink(Groupsock* rtpGroupsock, unsigned char rtpPayloadTypeIfDynamic, FramedSource* inputSource); + virtual char const* getAuxSDPLine(RTPSink* rtpSink,FramedSource* inputSource); + + protected: + const std::string m_format; +}; + + diff --git a/src/MulticastServerMediaSubsession.cpp b/src/MulticastServerMediaSubsession.cpp new file mode 100644 index 0000000..d9a409d --- /dev/null +++ b/src/MulticastServerMediaSubsession.cpp @@ -0,0 +1,62 @@ +/* --------------------------------------------------------------------------- +** This software is in the public domain, furnished "as is", without technical +** support, and with no warranty, express or implied, as to its usefulness for +** any purpose. +** +** MulticastServerMediaSubsession.cpp +** +** -------------------------------------------------------------------------*/ + +#include "MulticastServerMediaSubsession.h" +#include "DeviceSource.h" + +// ----------------------------------------- +// ServerMediaSubsession for Multicast +// ----------------------------------------- +MulticastServerMediaSubsession* MulticastServerMediaSubsession::createNew(UsageEnvironment& env + , struct in_addr destinationAddress + , Port rtpPortNum, Port rtcpPortNum + , int ttl + , StreamReplicator* replicator + , const std::string& format) +{ + // Create a source + FramedSource* source = replicator->createStreamReplica(); + FramedSource* videoSource = createSource(env, source, format); + + // Create RTP/RTCP groupsock + Groupsock* rtpGroupsock = new Groupsock(env, destinationAddress, rtpPortNum, ttl); + Groupsock* rtcpGroupsock = new Groupsock(env, destinationAddress, rtcpPortNum, ttl); + + // Create a RTP sink + RTPSink* videoSink = createSink(env, rtpGroupsock, 96, format); + + // Create 'RTCP instance' + const unsigned maxCNAMElen = 100; + unsigned char CNAME[maxCNAMElen+1]; + gethostname((char*)CNAME, maxCNAMElen); + CNAME[maxCNAMElen] = '\0'; + RTCPInstance* rtcpInstance = RTCPInstance::createNew(env, rtcpGroupsock, 500, CNAME, videoSink, NULL); + + // Start Playing the Sink + videoSink->startPlaying(*videoSource, NULL, NULL); + + return new MulticastServerMediaSubsession(replicator, videoSink, rtcpInstance); +} + +char const* MulticastServerMediaSubsession::sdpLines() +{ + if (m_SDPLines.empty()) + { + // Ugly workaround to give SPS/PPS that are get from the RTPSink + m_SDPLines.assign(PassiveServerMediaSubsession::sdpLines()); + m_SDPLines.append(getAuxSDPLine(m_rtpSink,NULL)); + } + return m_SDPLines.c_str(); +} + +char const* MulticastServerMediaSubsession::getAuxSDPLine(RTPSink* rtpSink,FramedSource* inputSource) +{ + return this->getAuxLine(dynamic_cast(m_replicator->inputSource()), rtpSink->rtpPayloadType()); +} + diff --git a/src/SegmentServerMediaSubsession.cpp b/src/SegmentServerMediaSubsession.cpp new file mode 100644 index 0000000..c981784 --- /dev/null +++ b/src/SegmentServerMediaSubsession.cpp @@ -0,0 +1,158 @@ +/* --------------------------------------------------------------------------- +** This software is in the public domain, furnished "as is", without technical +** support, and with no warranty, express or implied, as to its usefulness for +** any purpose. +** +** SegmentServerMediaSubsession.cpp +** +** -------------------------------------------------------------------------*/ + +#include + +#include "SegmentServerMediaSubsession.h" + +// ----------------------------------------- +// ServerMediaSubsession for HLS +// ----------------------------------------- +HLSServerMediaSubsession::HLSSink::HLSSink(UsageEnvironment& env, unsigned bufferSize, unsigned int sliceDuration) : MediaSink(env), m_bufferSize(bufferSize), m_refTime(0), m_sliceDuration(sliceDuration) +{ + m_buffer = new unsigned char[m_bufferSize]; +} + +HLSServerMediaSubsession::HLSSink::~HLSSink() +{ + delete[] m_buffer; +} + + +Boolean HLSServerMediaSubsession::HLSSink::continuePlaying() +{ + Boolean ret = False; + if (fSource != NULL) + { + fSource->getNextFrame(m_buffer, m_bufferSize, + afterGettingFrame, this, + onSourceClosure, this); + ret = True; + } + return ret; +} + + +void HLSServerMediaSubsession::HLSSink::afterGettingFrame(unsigned frameSize, unsigned numTruncatedBytes, struct timeval presentationTime) +{ + if (numTruncatedBytes > 0) + { + envir() << "FileSink::afterGettingFrame(): The input frame data was too large for our buffer size \n"; + // realloc a bigger buffer + m_bufferSize += numTruncatedBytes; + delete[] m_buffer; + m_buffer = new unsigned char[m_bufferSize]; + } + else + { + // append buffer to slice buffer + if (m_refTime == 0) + { + m_refTime = presentationTime.tv_sec; + } + unsigned int slice = (presentationTime.tv_sec-m_refTime)/m_sliceDuration; + std::string& outputBuffer = m_outputBuffers[slice]; + outputBuffer.append((const char*)m_buffer, frameSize); + + // remove old buffers + while (m_outputBuffers.size()>5) + { + m_outputBuffers.erase(m_outputBuffers.begin()); + } + } + + continuePlaying(); +} + +unsigned int HLSServerMediaSubsession::HLSSink::getHLSBufferSize(unsigned int slice) +{ + unsigned int size = 0; + std::map::iterator it = m_outputBuffers.find(slice); + if (it != m_outputBuffers.end()) + { + size = it->second.size(); + } + return size; +} + +const char* HLSServerMediaSubsession::HLSSink::getHLSBuffer(unsigned int slice) +{ + const char* content = NULL; + std::map::iterator it = m_outputBuffers.find(slice); + if (it != m_outputBuffers.end()) + { + content = it->second.c_str(); + } + return content; +} + +unsigned int HLSServerMediaSubsession::HLSSink::firstTime() +{ + unsigned int firstTime = 0; + if (m_outputBuffers.size() != 0) + { + firstTime = m_outputBuffers.begin()->first; + } + return firstTime*m_sliceDuration; +} + +unsigned int HLSServerMediaSubsession::HLSSink::duration() +{ + unsigned int duration = 0; + if (m_outputBuffers.size() != 0) + { + duration = m_outputBuffers.rbegin()->first - m_outputBuffers.begin()->first; + } + return (duration)*m_sliceDuration; +} + + +HLSServerMediaSubsession::HLSServerMediaSubsession(UsageEnvironment& env, StreamReplicator* replicator, const std::string& format, unsigned int sliceDuration) + : UnicastServerMediaSubsession(env, replicator, format), m_slice(0) +{ + // Create a source + FramedSource* source = replicator->createStreamReplica(); + FramedSource* videoSource = createSource(env, source, format); + + // Start Playing the HLS Sink + m_hlsSink = HLSSink::createNew(env, OutPacketBuffer::maxSize, sliceDuration); + m_hlsSink->startPlaying(*videoSource, NULL, NULL); +} + +HLSServerMediaSubsession::~HLSServerMediaSubsession() +{ + Medium::close(m_hlsSink); +} + +float HLSServerMediaSubsession::getCurrentNPT(void* streamToken) +{ + return (m_hlsSink->firstTime()); +} + +float HLSServerMediaSubsession::duration() const +{ + return (m_hlsSink->duration()); +} + +void HLSServerMediaSubsession::seekStream(unsigned clientSessionId, void* streamToken, double& seekNPT, double streamDuration, u_int64_t& numBytes) +{ + m_slice = seekNPT / m_hlsSink->getSliceDuration(); + seekNPT = m_slice * m_hlsSink->getSliceDuration(); + numBytes = m_hlsSink->getHLSBufferSize(m_slice); + std::cout << "seek seekNPT:" << seekNPT << " slice:" << m_slice << " numBytes:" << numBytes << std::endl; + +} + +FramedSource* HLSServerMediaSubsession::getStreamSource(void* streamToken) +{ + unsigned int size = m_hlsSink->getHLSBufferSize(m_slice); + u_int8_t* content = new u_int8_t[size]; + memcpy(content, m_hlsSink->getHLSBuffer(m_slice), size); + return ByteStreamMemoryBufferSource::createNew(envir(), content, size); +} diff --git a/src/ServerMediaSubsession.cpp b/src/ServerMediaSubsession.cpp index 912f8d8..4223bb0 100644 --- a/src/ServerMediaSubsession.cpp +++ b/src/ServerMediaSubsession.cpp @@ -9,10 +9,6 @@ #include -// live555 -#include -#include -#include // project #include "ServerMediaSubsession.h" @@ -113,77 +109,3 @@ char const* BaseServerMediaSubsession::getAuxLine(V4L2DeviceSource* source,unsig return auxLine; } -// ----------------------------------------- -// ServerMediaSubsession for Multicast -// ----------------------------------------- -MulticastServerMediaSubsession* MulticastServerMediaSubsession::createNew(UsageEnvironment& env - , struct in_addr destinationAddress - , Port rtpPortNum, Port rtcpPortNum - , int ttl - , StreamReplicator* replicator - , const std::string& format) -{ - // Create a source - FramedSource* source = replicator->createStreamReplica(); - FramedSource* videoSource = createSource(env, source, format); - - // Create RTP/RTCP groupsock - Groupsock* rtpGroupsock = new Groupsock(env, destinationAddress, rtpPortNum, ttl); - Groupsock* rtcpGroupsock = new Groupsock(env, destinationAddress, rtcpPortNum, ttl); - - // Create a RTP sink - RTPSink* videoSink = createSink(env, rtpGroupsock, 96, format); - - // Create 'RTCP instance' - const unsigned maxCNAMElen = 100; - unsigned char CNAME[maxCNAMElen+1]; - gethostname((char*)CNAME, maxCNAMElen); - CNAME[maxCNAMElen] = '\0'; - RTCPInstance* rtcpInstance = RTCPInstance::createNew(env, rtcpGroupsock, 500, CNAME, videoSink, NULL); - - // Start Playing the Sink - videoSink->startPlaying(*videoSource, NULL, NULL); - - return new MulticastServerMediaSubsession(replicator, videoSink, rtcpInstance); -} - -char const* MulticastServerMediaSubsession::sdpLines() -{ - if (m_SDPLines.empty()) - { - // Ugly workaround to give SPS/PPS that are get from the RTPSink - m_SDPLines.assign(PassiveServerMediaSubsession::sdpLines()); - m_SDPLines.append(getAuxSDPLine(m_rtpSink,NULL)); - } - return m_SDPLines.c_str(); -} - -char const* MulticastServerMediaSubsession::getAuxSDPLine(RTPSink* rtpSink,FramedSource* inputSource) -{ - return this->getAuxLine(dynamic_cast(m_replicator->inputSource()), rtpSink->rtpPayloadType()); -} - -// ----------------------------------------- -// ServerMediaSubsession for Unicast -// ----------------------------------------- -UnicastServerMediaSubsession* UnicastServerMediaSubsession::createNew(UsageEnvironment& env, StreamReplicator* replicator, const std::string& format) -{ - return new UnicastServerMediaSubsession(env,replicator,format); -} - -FramedSource* UnicastServerMediaSubsession::createNewStreamSource(unsigned clientSessionId, unsigned& estBitrate) -{ - FramedSource* source = m_replicator->createStreamReplica(); - return createSource(envir(), source, m_format); -} - -RTPSink* UnicastServerMediaSubsession::createNewRTPSink(Groupsock* rtpGroupsock, unsigned char rtpPayloadTypeIfDynamic, FramedSource* inputSource) -{ - return createSink(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic, m_format); -} - -char const* UnicastServerMediaSubsession::getAuxSDPLine(RTPSink* rtpSink,FramedSource* inputSource) -{ - return this->getAuxLine(dynamic_cast(m_replicator->inputSource()), rtpSink->rtpPayloadType()); -} - diff --git a/src/UnicastServerMediaSubsession.cpp b/src/UnicastServerMediaSubsession.cpp new file mode 100644 index 0000000..5fdcf8e --- /dev/null +++ b/src/UnicastServerMediaSubsession.cpp @@ -0,0 +1,37 @@ +/* --------------------------------------------------------------------------- +** This software is in the public domain, furnished "as is", without technical +** support, and with no warranty, express or implied, as to its usefulness for +** any purpose. +** +** ServerMediaSubsession.cpp +** +** -------------------------------------------------------------------------*/ + + +#include "UnicastServerMediaSubsession.h" +#include "DeviceSource.h" + +// ----------------------------------------- +// ServerMediaSubsession for Unicast +// ----------------------------------------- +UnicastServerMediaSubsession* UnicastServerMediaSubsession::createNew(UsageEnvironment& env, StreamReplicator* replicator, const std::string& format) +{ + return new UnicastServerMediaSubsession(env,replicator,format); +} + +FramedSource* UnicastServerMediaSubsession::createNewStreamSource(unsigned clientSessionId, unsigned& estBitrate) +{ + FramedSource* source = m_replicator->createStreamReplica(); + return createSource(envir(), source, m_format); +} + +RTPSink* UnicastServerMediaSubsession::createNewRTPSink(Groupsock* rtpGroupsock, unsigned char rtpPayloadTypeIfDynamic, FramedSource* inputSource) +{ + return createSink(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic, m_format); +} + +char const* UnicastServerMediaSubsession::getAuxSDPLine(RTPSink* rtpSink,FramedSource* inputSource) +{ + return this->getAuxLine(dynamic_cast(m_replicator->inputSource()), rtpSink->rtpPayloadType()); +} + diff --git a/src/main.cpp b/src/main.cpp index 91e4d4f..1a3c303 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -37,6 +37,9 @@ #include "H264_V4l2DeviceSource.h" #include "ServerMediaSubsession.h" +#include "UnicastServerMediaSubsession.h" +#include "MulticastServerMediaSubsession.h" +#include "SegmentServerMediaSubsession.h" #include "HTTPServer.h" #ifdef HAVE_ALSA