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 simple RTP sink that packs frames into each outgoing
19// packet, without any fragmentation or special headers.
20// Implementation
21
22#include "SimpleRTPSink.hh"
23
24SimpleRTPSink::SimpleRTPSink(UsageEnvironment& env, Groupsock* RTPgs,
25 unsigned char rtpPayloadFormat,
26 unsigned rtpTimestampFrequency,
27 char const* sdpMediaTypeString,
28 char const* rtpPayloadFormatName,
29 unsigned numChannels,
30 Boolean allowMultipleFramesPerPacket,
31 Boolean doNormalMBitRule)
32 : MultiFramedRTPSink(env, RTPgs, rtpPayloadFormat,
33 rtpTimestampFrequency, rtpPayloadFormatName,
34 numChannels),
35 fAllowMultipleFramesPerPacket(allowMultipleFramesPerPacket), fSetMBitOnNextPacket(False) {
36 fSDPMediaTypeString
37 = strDup(sdpMediaTypeString == NULL ? "unknown" : sdpMediaTypeString);
38 fSetMBitOnLastFrames = doNormalMBitRule && strcmp(fSDPMediaTypeString, "audio") != 0;
39}
40
41SimpleRTPSink::~SimpleRTPSink() {
42 delete[] (char*)fSDPMediaTypeString;
43}
44
45SimpleRTPSink*
46SimpleRTPSink::createNew(UsageEnvironment& env, Groupsock* RTPgs,
47 unsigned char rtpPayloadFormat,
48 unsigned rtpTimestampFrequency,
49 char const* sdpMediaTypeString,
50 char const* rtpPayloadFormatName,
51 unsigned numChannels,
52 Boolean allowMultipleFramesPerPacket,
53 Boolean doNormalMBitRule) {
54 return new SimpleRTPSink(env, RTPgs,
55 rtpPayloadFormat, rtpTimestampFrequency,
56 sdpMediaTypeString, rtpPayloadFormatName,
57 numChannels,
58 allowMultipleFramesPerPacket,
59 doNormalMBitRule);
60}
61
62void SimpleRTPSink::doSpecialFrameHandling(unsigned fragmentationOffset,
63 unsigned char* frameStart,
64 unsigned numBytesInFrame,
65 struct timeval framePresentationTime,
66 unsigned numRemainingBytes) {
67 if (numRemainingBytes == 0) {
68 // This packet contains the last (or only) fragment of the frame.
69 // Set the RTP 'M' ('marker') bit, if appropriate:
70 if (fSetMBitOnLastFrames) setMarkerBit();
71 }
72 if (fSetMBitOnNextPacket) {
73 // An external object has asked for the 'M' bit to be set on the next packet:
74 setMarkerBit();
75 fSetMBitOnNextPacket = False;
76 }
77
78 // Important: Also call our base class's doSpecialFrameHandling(),
79 // to set the packet's timestamp:
80 MultiFramedRTPSink::doSpecialFrameHandling(fragmentationOffset,
81 frameStart, numBytesInFrame,
82 framePresentationTime,
83 numRemainingBytes);
84}
85
86Boolean SimpleRTPSink::
87frameCanAppearAfterPacketStart(unsigned char const* /*frameStart*/,
88 unsigned /*numBytesInFrame*/) const {
89 return fAllowMultipleFramesPerPacket;
90}
91
92char const* SimpleRTPSink::sdpMediaType() const {
93 return fSDPMediaTypeString;
94}
95