This commit is contained in:
mpromonet 2016-04-10 17:58:03 +02:00
parent ee0f49e9b7
commit ff81a9590c
3 changed files with 149 additions and 1 deletions

View File

@ -13,6 +13,7 @@
#include <string> #include <string>
#include <iomanip> #include <iomanip>
#include <iostream> #include <iostream>
#include <fstream>
// live555 // live555
#include <liveMedia.hh> #include <liveMedia.hh>
@ -76,10 +77,144 @@ class UnicastServerMediaSubsession : public OnDemandServerMediaSubsession , publ
virtual FramedSource* createNewStreamSource(unsigned clientSessionId, unsigned& estBitrate); virtual FramedSource* createNewStreamSource(unsigned clientSessionId, unsigned& estBitrate);
virtual RTPSink* createNewRTPSink(Groupsock* rtpGroupsock, unsigned char rtpPayloadTypeIfDynamic, FramedSource* inputSource); virtual RTPSink* createNewRTPSink(Groupsock* rtpGroupsock, unsigned char rtpPayloadTypeIfDynamic, FramedSource* inputSource);
virtual char const* getAuxSDPLine(RTPSink* rtpSink,FramedSource* inputSource); virtual char const* getAuxSDPLine(RTPSink* rtpSink,FramedSource* inputSource);
protected: protected:
const std::string m_format; const std::string m_format;
}; };
// -----------------------------------------
// ServerMediaSubsession for HLS
// -----------------------------------------
class HLSSink : public MediaSink
{
public:
static HLSSink* createNew(UsageEnvironment& env, unsigned int bufferSize)
{
return new HLSSink(env, bufferSize);
}
protected:
HLSSink(UsageEnvironment& env, unsigned bufferSize) : MediaSink(env), m_bufferSize(bufferSize), m_slice(0)
{
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";
}
if (m_os.is_open())
{
if (m_slice != (presentationTime.tv_sec/10))
{
m_os.close();
}
}
if (!m_os.is_open())
{
m_slice = presentationTime.tv_sec/10;
std::ostringstream os;
os << m_slice << ".ts";
m_os.open(os.str().c_str());
}
if (m_os.is_open())
{
m_os.write((char*)m_buffer, frameSize);
}
continuePlaying();
}
private:
unsigned char * m_buffer;
unsigned int m_bufferSize;
std::ofstream m_os;
unsigned int m_slice;
};
class HLSServerMediaSubsession : public OnDemandServerMediaSubsession , public BaseServerMediaSubsession
{
public:
static HLSServerMediaSubsession* createNew(UsageEnvironment& env, StreamReplicator* replicator, const std::string& format)
{
return new HLSServerMediaSubsession(env,replicator,format);
}
protected:
HLSServerMediaSubsession(UsageEnvironment& env, StreamReplicator* replicator, const std::string& format)
: OnDemandServerMediaSubsession(env, False), BaseServerMediaSubsession(replicator), m_format(format)
{
// Create a source
FramedSource* source = replicator->createStreamReplica();
FramedSource* videoSource = createSource(env, source, format);
// Start Playing the Sink
HLSSink * videoSink = HLSSink::createNew(env, 65535);
videoSink->startPlaying(*videoSource, NULL, NULL);
}
virtual FramedSource* createNewStreamSource(unsigned clientSessionId, unsigned& estBitrate)
{
FramedSource* source = m_replicator->createStreamReplica();
return createSource(envir(), source, m_format);
}
virtual RTPSink* createNewRTPSink(Groupsock* rtpGroupsock, unsigned char rtpPayloadTypeIfDynamic, FramedSource* inputSource)
{
return createSink(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic, m_format);
}
virtual char const* getAuxSDPLine(RTPSink* rtpSink,FramedSource* inputSource);
virtual float duration() const { return 20; }
virtual void seekStream(unsigned clientSessionId, void* streamToken, double& seekNPT, double streamDuration, u_int64_t& numBytes)
{
m_slice = seekNPT / 10;
seekNPT = m_slice*10;
numBytes = 1;
}
virtual FramedSource* getStreamSource(void* streamToken)
{
std::ostringstream os;
os << m_slice << ".ts";
return ByteStreamFileSource::createNew(envir(), os.str().c_str());
}
protected:
const std::string m_format;
unsigned int m_slice;
};
#endif #endif

View File

@ -144,3 +144,11 @@ char const* UnicastServerMediaSubsession::getAuxSDPLine(RTPSink* rtpSink,FramedS
{ {
return this->getAuxLine(dynamic_cast<V4L2DeviceSource*>(m_replicator->inputSource()), rtpSink->rtpPayloadType()); return this->getAuxLine(dynamic_cast<V4L2DeviceSource*>(m_replicator->inputSource()), rtpSink->rtpPayloadType());
} }
// -----------------------------------------
// ServerMediaSubsession for Unicast
// -----------------------------------------
char const* HLSServerMediaSubsession::getAuxSDPLine(RTPSink* rtpSink,FramedSource* inputSource)
{
return this->getAuxLine(dynamic_cast<V4L2DeviceSource*>(m_replicator->inputSource()), rtpSink->rtpPayloadType());
}

View File

@ -318,6 +318,11 @@ int main(int argc, char** argv)
} }
// Create Unicast Session // Create Unicast Session
addSession(rtspServer, baseUrl+url, UnicastServerMediaSubsession::createNew(*env,replicator,rtpFormat)); addSession(rtspServer, baseUrl+url, UnicastServerMediaSubsession::createNew(*env,replicator,rtpFormat));
if (muxTS)
{
addSession(rtspServer, "/hls", HLSServerMediaSubsession::createNew(*env,replicator,rtpFormat));
}
} }
if (out) if (out)
{ {