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// RTP sink for MPEG-4 audio, using LATM multiplexing (RFC 3016)
19// Implementation
20
21#include "MPEG4LATMAudioRTPSink.hh"
22
23MPEG4LATMAudioRTPSink
24::MPEG4LATMAudioRTPSink(UsageEnvironment& env, Groupsock* RTPgs,
25 u_int8_t rtpPayloadFormat,
26 u_int32_t rtpTimestampFrequency,
27 char const* streamMuxConfigString,
28 unsigned numChannels,
29 Boolean allowMultipleFramesPerPacket)
30 : AudioRTPSink(env, RTPgs, rtpPayloadFormat,
31 rtpTimestampFrequency, "MP4A-LATM", numChannels),
32 fStreamMuxConfigString(strDup(streamMuxConfigString)),
33 fAllowMultipleFramesPerPacket(allowMultipleFramesPerPacket) {
34 // Set up the "a=fmtp:" SDP line for this stream:
35 char const* fmtpFmt =
36 "a=fmtp:%d "
37 "cpresent=0;config=%s\r\n";
38 unsigned fmtpFmtSize = strlen(fmtpFmt)
39 + 3 /* max char len */
40 + strlen(fStreamMuxConfigString);
41 char* fmtp = new char[fmtpFmtSize];
42 sprintf(fmtp, fmtpFmt,
43 rtpPayloadType(),
44 fStreamMuxConfigString);
45 fFmtpSDPLine = strDup(fmtp);
46 delete[] fmtp;
47}
48
49MPEG4LATMAudioRTPSink::~MPEG4LATMAudioRTPSink() {
50 delete[] fFmtpSDPLine;
51 delete[] (char*)fStreamMuxConfigString;
52}
53
54MPEG4LATMAudioRTPSink*
55MPEG4LATMAudioRTPSink::createNew(UsageEnvironment& env, Groupsock* RTPgs,
56 u_int8_t rtpPayloadFormat,
57 u_int32_t rtpTimestampFrequency,
58 char const* streamMuxConfigString,
59 unsigned numChannels,
60 Boolean allowMultipleFramesPerPacket) {
61 return new MPEG4LATMAudioRTPSink(env, RTPgs, rtpPayloadFormat,
62 rtpTimestampFrequency, streamMuxConfigString,
63 numChannels,
64 allowMultipleFramesPerPacket);
65}
66
67Boolean MPEG4LATMAudioRTPSink
68::frameCanAppearAfterPacketStart(unsigned char const* /*frameStart*/,
69 unsigned /*numBytesInFrame*/) const {
70 return fAllowMultipleFramesPerPacket;
71}
72
73void MPEG4LATMAudioRTPSink
74::doSpecialFrameHandling(unsigned fragmentationOffset,
75 unsigned char* frameStart,
76 unsigned numBytesInFrame,
77 struct timeval framePresentationTime,
78 unsigned numRemainingBytes) {
79 if (numRemainingBytes == 0) {
80 // This packet contains the last (or only) fragment of the frame.
81 // Set the RTP 'M' ('marker') bit:
82 setMarkerBit();
83 }
84
85 // Important: Also call our base class's doSpecialFrameHandling(),
86 // to set the packet's timestamp:
87 MultiFramedRTPSink::doSpecialFrameHandling(fragmentationOffset,
88 frameStart, numBytesInFrame,
89 framePresentationTime,
90 numRemainingBytes);
91}
92
93char const* MPEG4LATMAudioRTPSink::auxSDPLine() {
94 return fFmtpSDPLine;
95}
96