1/**********
2This library is free software; you can redistribute it and/or modify it under
3the terms of the GNU Lesser General Public License as published by the
4Free Software Foundation; either version 3 of the License, or (at your
5option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
6
7This library is distributed in the hope that it will be useful, but WITHOUT
8ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
10more details.
11
12You should have received a copy of the GNU Lesser General Public License
13along with this library; if not, write to the Free Software Foundation, Inc.,
1451 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15**********/
16// "liveMedia"
17// Copyright (c) 1996-2020 Live Networks, Inc. All rights reserved.
18// A 'ServerMediaSubsession' object that creates new, unicast, "RTPSink"s
19// on demand, from an incoming UDP (or RTP/UDP) MPEG-2 Transport Stream
20// Implementation
21
22#include "MPEG2TransportUDPServerMediaSubsession.hh"
23#include "BasicUDPSource.hh"
24#include "SimpleRTPSource.hh"
25#include "MPEG2TransportStreamFramer.hh"
26#include "SimpleRTPSink.hh"
27#include "GroupsockHelper.hh"
28
29
30MPEG2TransportUDPServerMediaSubsession*
31MPEG2TransportUDPServerMediaSubsession::createNew(UsageEnvironment& env,
32 char const* inputAddressStr, Port const& inputPort, Boolean inputStreamIsRawUDP) {
33 return new MPEG2TransportUDPServerMediaSubsession(env, inputAddressStr, inputPort, inputStreamIsRawUDP);
34}
35
36MPEG2TransportUDPServerMediaSubsession
37::MPEG2TransportUDPServerMediaSubsession(UsageEnvironment& env,
38 char const* inputAddressStr, Port const& inputPort, Boolean inputStreamIsRawUDP)
39 : OnDemandServerMediaSubsession(env, True/*reuseFirstSource*/),
40 fInputPort(inputPort), fInputGroupsock(NULL), fInputStreamIsRawUDP(inputStreamIsRawUDP) {
41 fInputAddressStr = strDup(inputAddressStr);
42}
43
44MPEG2TransportUDPServerMediaSubsession::
45~MPEG2TransportUDPServerMediaSubsession() {
46 delete fInputGroupsock;
47 delete[] (char*)fInputAddressStr;
48}
49
50FramedSource* MPEG2TransportUDPServerMediaSubsession
51::createNewStreamSource(unsigned/* clientSessionId*/, unsigned& estBitrate) {
52 estBitrate = 5000; // kbps, estimate
53
54 if (fInputGroupsock == NULL) {
55 // Create a 'groupsock' object for receiving the input stream:
56 struct in_addr inputAddress;
57 inputAddress.s_addr = fInputAddressStr == NULL ? 0 : our_inet_addr(fInputAddressStr);
58 fInputGroupsock = new Groupsock(envir(), inputAddress, fInputPort, 255);
59 }
60
61 FramedSource* transportStreamSource;
62 if (fInputStreamIsRawUDP) {
63 transportStreamSource = BasicUDPSource::createNew(envir(), fInputGroupsock);
64 } else {
65 transportStreamSource = SimpleRTPSource::createNew(envir(), fInputGroupsock, 33, 90000, "video/MP2T", 0, False /*no 'M' bit*/);
66 }
67 return MPEG2TransportStreamFramer::createNew(envir(), transportStreamSource);
68}
69
70RTPSink* MPEG2TransportUDPServerMediaSubsession
71::createNewRTPSink(Groupsock* rtpGroupsock, unsigned char /*rtpPayloadTypeIfDynamic*/, FramedSource* /*inputSource*/) {
72 return SimpleRTPSink::createNew(envir(), rtpGroupsock,
73 33, 90000, "video", "MP2T",
74 1, True, False /*no 'M' bit*/);
75}
76