1 /**********
2 This library is free software; you can redistribute it and/or modify it under
3 the terms of the GNU Lesser General Public License as published by the
4 Free Software Foundation; either version 3 of the License, or (at your
5 option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
6 
7 This library is distributed in the hope that it will be useful, but WITHOUT
8 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9 FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
10 more details.
11 
12 You should have received a copy of the GNU Lesser General Public License
13 along with this library; if not, write to the Free Software Foundation, Inc.,
14 51 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 
SimpleRTPSink(UsageEnvironment & env,Groupsock * RTPgs,unsigned char rtpPayloadFormat,unsigned rtpTimestampFrequency,char const * sdpMediaTypeString,char const * rtpPayloadFormatName,unsigned numChannels,Boolean allowMultipleFramesPerPacket,Boolean doNormalMBitRule)24 SimpleRTPSink::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 
~SimpleRTPSink()41 SimpleRTPSink::~SimpleRTPSink() {
42   delete[] (char*)fSDPMediaTypeString;
43 }
44 
45 SimpleRTPSink*
createNew(UsageEnvironment & env,Groupsock * RTPgs,unsigned char rtpPayloadFormat,unsigned rtpTimestampFrequency,char const * sdpMediaTypeString,char const * rtpPayloadFormatName,unsigned numChannels,Boolean allowMultipleFramesPerPacket,Boolean doNormalMBitRule)46 SimpleRTPSink::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 
doSpecialFrameHandling(unsigned fragmentationOffset,unsigned char * frameStart,unsigned numBytesInFrame,struct timeval framePresentationTime,unsigned numRemainingBytes)62 void 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 
86 Boolean SimpleRTPSink::
frameCanAppearAfterPacketStart(unsigned char const *,unsigned) const87 frameCanAppearAfterPacketStart(unsigned char const* /*frameStart*/,
88 			       unsigned /*numBytesInFrame*/) const {
89   return fAllowMultipleFramesPerPacket;
90 }
91 
sdpMediaType() const92 char const* SimpleRTPSink::sdpMediaType() const {
93   return fSDPMediaTypeString;
94 }
95