You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
105 lines
3.6 KiB
105 lines
3.6 KiB
#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);
|
|
}
|