liveMedia/AMRAudioFileSink.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 // AMR Audio File sinks
00019 // Implementation
00020 
00021 #include "AMRAudioFileSink.hh"
00022 #include "AMRAudioSource.hh"
00023 #include "OutputFile.hh"
00024 
00026 
00027 AMRAudioFileSink
00028 ::AMRAudioFileSink(UsageEnvironment& env, FILE* fid, unsigned bufferSize,
00029                    char const* perFrameFileNamePrefix)
00030   : FileSink(env, fid, bufferSize, perFrameFileNamePrefix),
00031     fHaveWrittenHeader(False) {
00032 }
00033 
00034 AMRAudioFileSink::~AMRAudioFileSink() {
00035 }
00036 
00037 AMRAudioFileSink*
00038 AMRAudioFileSink::createNew(UsageEnvironment& env, char const* fileName,
00039                             unsigned bufferSize, Boolean oneFilePerFrame) {
00040   do {
00041     FILE* fid;
00042     char const* perFrameFileNamePrefix;
00043     if (oneFilePerFrame) {
00044       // Create the fid for each frame
00045       fid = NULL;
00046       perFrameFileNamePrefix = fileName;
00047     } else {
00048       // Normal case: create the fid once
00049       fid = OpenOutputFile(env, fileName);
00050       if (fid == NULL) break;
00051       perFrameFileNamePrefix = NULL;
00052     }
00053 
00054     return new AMRAudioFileSink(env, fid, bufferSize, perFrameFileNamePrefix);
00055   } while (0);
00056 
00057   return NULL;
00058 }
00059 
00060 Boolean AMRAudioFileSink::sourceIsCompatibleWithUs(MediaSource& source) {
00061   // The input source must be a AMR Audio source:
00062   return source.isAMRAudioSource();
00063 }
00064 
00065 void AMRAudioFileSink::afterGettingFrame(unsigned frameSize,
00066                                          unsigned numTruncatedBytes,
00067                                          struct timeval presentationTime) {
00068   AMRAudioSource* source = (AMRAudioSource*)fSource;
00069   if (source == NULL) return; // sanity check
00070 
00071   if (!fHaveWrittenHeader && fPerFrameFileNameBuffer == NULL) {
00072     // Output the appropriate AMR header to the start of the file.
00073     // This header is defined in RFC 4867, section 5.
00074     // (However, we don't do this if we're creating one file per frame.)
00075     char headerBuffer[100];
00076     sprintf(headerBuffer, "#!AMR%s%s\n",
00077             source->isWideband() ? "-WB" : "",
00078             source->numChannels() > 1 ? "_MC1.0" : "");
00079     unsigned headerLength = strlen(headerBuffer);
00080     if (source->numChannels() > 1) {
00081       // Also add a 32-bit channel description field:
00082       headerBuffer[headerLength++] = 0;
00083       headerBuffer[headerLength++] = 0;
00084       headerBuffer[headerLength++] = 0;
00085       headerBuffer[headerLength++] = source->numChannels();
00086     }
00087 
00088     addData((unsigned char*)headerBuffer, headerLength, presentationTime);
00089   }
00090   fHaveWrittenHeader = True;
00091 
00092   // Add the 1-byte header, before writing the file data proper:
00093   // (Again, we don't do this if we're creating one file per frame.)
00094   if (fPerFrameFileNameBuffer == NULL) {
00095     u_int8_t frameHeader = source->lastFrameHeader();
00096     addData(&frameHeader, 1, presentationTime);
00097   }
00098 
00099   // Call the parent class to complete the normal file write with the input data:
00100   FileSink::afterGettingFrame(frameSize, numTruncatedBytes, presentationTime);
00101 }

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