1 | /* --------------------------------------------------------------------------- |
2 | ** This software is in the public domain, furnished "as is", without technical |
3 | ** support, and with no warranty, express or implied, as to its usefulness for |
4 | ** any purpose. |
5 | ** |
6 | ** TSServerMediaSubsession.cpp |
7 | ** |
8 | ** -------------------------------------------------------------------------*/ |
9 | |
10 | #include "TSServerMediaSubsession.h" |
11 | #include "AddH26xMarkerFilter.h" |
12 | |
13 | TSServerMediaSubsession::TSServerMediaSubsession(UsageEnvironment& env, StreamReplicator* videoreplicator, const std::string& videoformat, StreamReplicator* audioreplicator, const std::string& audioformat, unsigned int sliceDuration) |
14 | : UnicastServerMediaSubsession(env, videoreplicator, "video/MP2T" ), m_slice(0) |
15 | { |
16 | // Create a source |
17 | FramedSource* source = videoreplicator->createStreamReplica(); |
18 | MPEG2TransportStreamFromESSource* muxer = MPEG2TransportStreamFromESSource::createNew(env); |
19 | |
20 | if (videoformat == "video/H264" ) { |
21 | // add marker |
22 | FramedSource* filter = new AddH26xMarkerFilter(env, source); |
23 | // mux to TS |
24 | muxer->addNewVideoSource(filter, 5); |
25 | } else if (videoformat == "video/H265" ) { |
26 | // add marker |
27 | FramedSource* filter = new AddH26xMarkerFilter(env, source); |
28 | // mux to TS |
29 | muxer->addNewVideoSource(filter, 6); |
30 | } |
31 | |
32 | if (audioformat == "audio/MPEG" ) { |
33 | // mux to TS |
34 | muxer->addNewAudioSource(source, 1); |
35 | } |
36 | |
37 | FramedSource* tsSource = createSource(env, muxer, m_format); |
38 | |
39 | // Start Playing the HLS Sink |
40 | m_hlsSink = MemoryBufferSink::createNew(env, OutPacketBuffer::maxSize, sliceDuration); |
41 | m_hlsSink->startPlaying(*tsSource, NULL, NULL); |
42 | } |
43 | |
44 | TSServerMediaSubsession::~TSServerMediaSubsession() |
45 | { |
46 | Medium::close(m_hlsSink); |
47 | } |
48 | |
49 | float TSServerMediaSubsession::getCurrentNPT(void* streamToken) |
50 | { |
51 | return (m_hlsSink->firstTime()); |
52 | } |
53 | |
54 | float TSServerMediaSubsession::duration() const |
55 | { |
56 | return (m_hlsSink->duration()); |
57 | } |
58 | |
59 | void TSServerMediaSubsession::seekStream(unsigned clientSessionId, void* streamToken, double& seekNPT, double streamDuration, u_int64_t& numBytes) |
60 | { |
61 | m_slice = seekNPT / m_hlsSink->getSliceDuration(); |
62 | seekNPT = m_slice * m_hlsSink->getSliceDuration(); |
63 | numBytes = m_hlsSink->getBufferSize(m_slice); |
64 | std::cout << "seek seekNPT:" << seekNPT << " slice:" << m_slice << " numBytes:" << numBytes << std::endl; |
65 | } |
66 | |
67 | FramedSource* TSServerMediaSubsession::getStreamSource(void* streamToken) |
68 | { |
69 | FramedSource* source = NULL; |
70 | |
71 | std::string buffer = m_hlsSink->getBuffer(m_slice); |
72 | unsigned int size = buffer.size(); |
73 | if ( size != 0 ) { |
74 | u_int8_t* content = new u_int8_t[size]; |
75 | memcpy(content, buffer.c_str(), size); |
76 | source = ByteStreamMemoryBufferSource::createNew(envir(), content, size); |
77 | } |
78 | return source; |
79 | } |
80 | |