#include <H264VideoRTPSink.hh>
|
#include <H264VideoStreamFramer.hh>
|
|
#include "H264LiveVideoServerMediaSubsession.h"
|
#include "H264LiveVideoSource.h"
|
|
H264LiveVideoServerMediaSubsession* H264LiveVideoServerMediaSubsession::createNew(UsageEnvironment& env,
|
Boolean reuseFirstSource,
|
void* listener)
|
{
|
return new H264LiveVideoServerMediaSubsession(env, reuseFirstSource, listener);
|
}
|
|
H264LiveVideoServerMediaSubsession::H264LiveVideoServerMediaSubsession(UsageEnvironment& env, Boolean reuseFirstSource,
|
void* listener)
|
: OnDemandServerMediaSubsession(env, reuseFirstSource), fAuxSDPLine(NULL), fDoneFlag(0), fDummyRTPSink(NULL)
|
{
|
fListener = listener;
|
}
|
|
H264LiveVideoServerMediaSubsession::~H264LiveVideoServerMediaSubsession()
|
{
|
}
|
|
static void afterPlayingDummy(void* clientData)
|
{
|
H264LiveVideoServerMediaSubsession* subsess = (H264LiveVideoServerMediaSubsession*)clientData;
|
subsess->afterPlayingDummy1();
|
}
|
|
void H264LiveVideoServerMediaSubsession::afterPlayingDummy1()
|
{
|
// Unschedule any pending 'checking' task:
|
envir().taskScheduler().unscheduleDelayedTask(nextTask());
|
// Signal the event loop that we're done:
|
setDoneFlag();
|
}
|
|
static void checkForAuxSDPLine(void* clientData)
|
{
|
H264LiveVideoServerMediaSubsession* subsess = (H264LiveVideoServerMediaSubsession*)clientData;
|
subsess->checkForAuxSDPLine1();
|
}
|
|
void H264LiveVideoServerMediaSubsession::checkForAuxSDPLine1()
|
{
|
char const* dasl;
|
if (fAuxSDPLine != NULL) {
|
// Signal the event loop that we're done:
|
setDoneFlag();
|
} else if (fDummyRTPSink != NULL && (dasl = fDummyRTPSink->auxSDPLine()) != NULL) {
|
fAuxSDPLine = strDup(dasl);
|
fDummyRTPSink = NULL;
|
|
// Signal the event loop that we're done:
|
setDoneFlag();
|
} else if (!fDoneFlag) {
|
// try again after a brief delay:
|
int uSecsToDelay = 100;
|
nextTask() = envir().taskScheduler().scheduleDelayedTask(uSecsToDelay, (TaskFunc*)checkForAuxSDPLine, this);
|
}
|
}
|
|
char const* H264LiveVideoServerMediaSubsession::getAuxSDPLine(RTPSink* rtpSink, FramedSource* inputSource)
|
{
|
if (fAuxSDPLine != NULL)
|
return fAuxSDPLine; // it's already been set up (for a previous client)
|
|
if (fDummyRTPSink == NULL) {
|
fDummyRTPSink = rtpSink;
|
|
// Start reading the file:
|
fDummyRTPSink->startPlaying(*inputSource, afterPlayingDummy, this);
|
|
// Check whether the sink's 'auxSDPLine()' is ready:
|
checkForAuxSDPLine(this);
|
}
|
envir().taskScheduler().doEventLoop(&fDoneFlag);
|
|
return fAuxSDPLine;
|
}
|
|
FramedSource* H264LiveVideoServerMediaSubsession::createNewStreamSource(unsigned, unsigned& estBitrate)
|
{
|
estBitrate = 500; // kbps, estimate
|
|
// Create the video source:
|
H264LiveVideoSource* liveSource = H264LiveVideoSource::createNew(envir(), fListener);
|
if (liveSource == NULL)
|
return NULL;
|
|
// Create a framer for the Video Elementary Stream:
|
return H264VideoStreamFramer::createNew(envir(), liveSource);
|
}
|
|
RTPSink* H264LiveVideoServerMediaSubsession::createNewRTPSink(Groupsock* rtpGroupsock,
|
unsigned char rtpPayloadTypeIfDynamic,
|
FramedSource* /*inputSource*/)
|
{
|
// setVideoRTPSinkBufferSize
|
OutPacketBuffer::maxSize = 1920 * 1088 * 2;
|
|
return H264VideoRTPSink::createNew(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic);
|
}
|