liveMedia/AC3AudioRTPSink.cpp

Go to the documentation of this file.
00001 /**********
00002 This library is free software; you can redistribute it and/or modify it under
00003 the terms of the GNU Lesser General Public License as published by the
00004 Free Software Foundation; either version 2.1 of the License, or (at your
00005 option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
00006 
00007 This library is distributed in the hope that it will be useful, but WITHOUT
00008 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00009 FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
00010 more details.
00011 
00012 You should have received a copy of the GNU Lesser General Public License
00013 along with this library; if not, write to the Free Software Foundation, Inc.,
00014 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
00015 **********/
00016 // "liveMedia"
00017 // Copyright (c) 1996-2013 Live Networks, Inc.  All rights reserved.
00018 // RTP sink for AC3 audio
00019 // Implementation
00020 
00021 #include "AC3AudioRTPSink.hh"
00022 
00023 AC3AudioRTPSink::AC3AudioRTPSink(UsageEnvironment& env, Groupsock* RTPgs,
00024                                  u_int8_t rtpPayloadFormat,
00025                                  u_int32_t rtpTimestampFrequency)
00026   : AudioRTPSink(env, RTPgs, rtpPayloadFormat,
00027                        rtpTimestampFrequency, "AC3"),
00028     fTotNumFragmentsUsed(0) {
00029 }
00030 
00031 AC3AudioRTPSink::~AC3AudioRTPSink() {
00032 }
00033 
00034 AC3AudioRTPSink*
00035 AC3AudioRTPSink::createNew(UsageEnvironment& env, Groupsock* RTPgs,
00036                            u_int8_t rtpPayloadFormat,
00037                            u_int32_t rtpTimestampFrequency) {
00038   return new AC3AudioRTPSink(env, RTPgs,
00039                              rtpPayloadFormat, rtpTimestampFrequency);
00040 }
00041 
00042 Boolean AC3AudioRTPSink
00043 ::frameCanAppearAfterPacketStart(unsigned char const* /*frameStart*/,
00044                                  unsigned /*numBytesInFrame*/) const {
00045   // (For now) allow at most 1 frame in a single packet:
00046   return False;
00047 }
00048 
00049 void AC3AudioRTPSink
00050 ::doSpecialFrameHandling(unsigned fragmentationOffset,
00051                          unsigned char* frameStart,
00052                          unsigned numBytesInFrame,
00053                          struct timeval framePresentationTime,
00054                          unsigned numRemainingBytes) {
00055   // Set the 2-byte "payload header", as defined in RFC 4184.
00056   unsigned char headers[2];
00057 
00058   Boolean isFragment = numRemainingBytes > 0 || fragmentationOffset > 0;
00059   if (!isFragment) {
00060     headers[0] = 0; // One or more complete frames
00061     headers[1] = 1; // because we (for now) allow at most 1 frame per packet
00062   } else {
00063     if (fragmentationOffset > 0) {
00064       headers[0] = 3; // Fragment of frame other than initial fragment
00065     } else {
00066       // An initial fragment of the frame
00067       unsigned const totalFrameSize = fragmentationOffset + numBytesInFrame + numRemainingBytes;
00068       unsigned const fiveEighthsPoint = totalFrameSize/2 + totalFrameSize/8;
00069       headers[0] = numBytesInFrame >= fiveEighthsPoint ? 1 : 2;
00070 
00071       // Because this outgoing packet will be full (because it's an initial fragment), we can compute how many total
00072       // fragments (and thus packets) will make up the complete AC-3 frame:
00073       fTotNumFragmentsUsed = (totalFrameSize + (numBytesInFrame-1))/numBytesInFrame;
00074     }
00075 
00076     headers[1] = fTotNumFragmentsUsed;
00077   }
00078 
00079   setSpecialHeaderBytes(headers, sizeof headers);
00080 
00081   if (numRemainingBytes == 0) {
00082     // This packet contains the last (or only) fragment of the frame.
00083     // Set the RTP 'M' ('marker') bit:
00084     setMarkerBit();
00085   }
00086 
00087   // Important: Also call our base class's doSpecialFrameHandling(),
00088   // to set the packet's timestamp:
00089   MultiFramedRTPSink::doSpecialFrameHandling(fragmentationOffset,
00090                                              frameStart, numBytesInFrame,
00091                                              framePresentationTime,
00092                                              numRemainingBytes);
00093 }
00094 
00095 unsigned AC3AudioRTPSink::specialHeaderSize() const {
00096   return 2;
00097 }

Generated on Mon Apr 29 13:28:00 2013 for live by  doxygen 1.5.2