-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathH264LiveMediaSubsession.cc
105 lines (89 loc) · 3.54 KB
/
H264LiveMediaSubsession.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include "H264LiveMediaSubsession.hh"
#include "easyloggingpp/easylogging++.h"
#include "H264VideoStreamDiscreteFramer.hh"
#include "H264VideoStreamFramer.hh"
#include "H264VideoRTPSink.hh"
namespace LiveRTSP {
H264LiveMediaSubsession *H264LiveMediaSubsession::createNew(
UsageEnvironment &env, StreamReplicator *replicator, const ParamTypeKeyValMap &tkv)
{
H264LiveMediaSubsession *self = new H264LiveMediaSubsession(env, replicator);
return self;
}
H264LiveMediaSubsession::H264LiveMediaSubsession(UsageEnvironment &env, StreamReplicator *replicator) :
LiveMediaSubsession(env, replicator),
pollingDoneFlag(0), pollingCount(0), dummyRTPSink(NULL)
{
LOG(INFO) << "H264LiveMediaSubsession";
}
H264LiveMediaSubsession::~H264LiveMediaSubsession()
{
LOG(INFO) << "~H264LiveMediaSubsession";
}
static void afterPlayingDummy(void* clientData) {
LOG(INFO) << "afterPlayingDummy";
H264LiveMediaSubsession* subsess = (H264LiveMediaSubsession*)clientData;
subsess->afterPlayingDummy1();
}
void H264LiveMediaSubsession::afterPlayingDummy1() {
// Unschedule any pending 'checking' task:
envir().taskScheduler().unscheduleDelayedTask(nextTask());
// Signal the event loop that we're done:
setDoneFlag();
}
static void pollingAuxSDPLine(void* clientData) {
H264LiveMediaSubsession* subsess = (H264LiveMediaSubsession*)clientData;
subsess->pollingAuxSDPLine1();
}
void H264LiveMediaSubsession::pollingAuxSDPLine1() {
nextTask() = NULL;
char const* dasl;
if (!auxSDPLine.empty()) {
// Signal the event loop that we're done:
setDoneFlag();
} else if (dummyRTPSink != NULL && (dasl = dummyRTPSink->auxSDPLine()) != NULL) {
auxSDPLine = dasl;
dummyRTPSink = NULL;
// Signal the event loop that we're done:
setDoneFlag();
} else if (!pollingDoneFlag) {
if (pollingCount++ >= 10) {
LOG(WARNING) << "polling auxSDPLine timeout";
setDoneFlag();
} else {
// try again after a brief delay:
int uSecsToDelay = 100000; // 100 ms
nextTask() = envir().taskScheduler().scheduleDelayedTask(uSecsToDelay,
(TaskFunc*)pollingAuxSDPLine, this);
}
}
}
char const *H264LiveMediaSubsession::getAuxSDPLine(RTPSink *rtpSink, FramedSource *inputSource)
{
LOG(INFO) << "getAuxSDPLine";
if (!auxSDPLine.empty()) return auxSDPLine.c_str();
if (dummyRTPSink == NULL) {
dummyRTPSink = rtpSink;
dummyRTPSink->startPlaying(*inputSource, afterPlayingDummy, this);
pollingAuxSDPLine(this);
}
envir().taskScheduler().doEventLoop(&pollingDoneFlag);
return auxSDPLine.empty() ? "" : auxSDPLine.c_str();
}
// TOOD: H264VideoStreamFramer ffplay will lose some when docoding
// TODO: H264VideoStreamDiscreteFramer need remove start and feed one NALU one time
// reference v4l2rtspserver
FramedSource *H264LiveMediaSubsession::createNewStreamSource(unsigned clientSessionId, unsigned &estBitrate) {
LOG(INFO) << "createNewStreamSource";
estBitrate = 1000; // kps, estimate
FramedSource *source = streamReplicator().createStreamReplica();
return H264VideoStreamDiscreteFramer::createNew(envir(), source);
//return H264VideoStreamFramer::createNew(envir(), source, true);
}
RTPSink *H264LiveMediaSubsession::createNewRTPSink(Groupsock *rtpGroupsock,
unsigned char rtpPayloadTypeIfDynamic, FramedSource *inputSource)
{
LOG(INFO) << "createNewRTPSink";
return H264VideoRTPSink::createNew(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic);
}
}