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-2008 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::afterGettingFrame1(unsigned frameSize,
00066                                           struct timeval presentationTime) {
00067   AMRAudioSource* source = (AMRAudioSource*)fSource;
00068   if (source == NULL) return; // sanity check
00069 
00070   if (!fHaveWrittenHeader && fPerFrameFileNameBuffer == NULL) {
00071     // Output the appropriate AMR header to the start of the file.
00072     // This header is defined in RFC 3267, section 5.
00073     // (However, we don't do this if we're creating one file per frame.)
00074     char headerBuffer[100];
00075     sprintf(headerBuffer, "#!AMR%s%s\n",
00076             source->isWideband() ? "-WB" : "",
00077             source->numChannels() > 1 ? "_MC1.0" : "");
00078     unsigned headerLength = strlen(headerBuffer);
00079     if (source->numChannels() > 1) {
00080       // Also add a 32-bit channel description field:
00081       headerBuffer[headerLength++] = 0;
00082       headerBuffer[headerLength++] = 0;
00083       headerBuffer[headerLength++] = 0;
00084       headerBuffer[headerLength++] = source->numChannels();
00085     }
00086 
00087     addData((unsigned char*)headerBuffer, headerLength, presentationTime);
00088   }
00089   fHaveWrittenHeader = True;
00090 
00091   // Add the 1-byte header, before writing the file data proper:
00092   // (Again, we don't do this if we're creating one file per frame.)
00093   if (fPerFrameFileNameBuffer == NULL) {
00094     u_int8_t frameHeader = source->lastFrameHeader();
00095     addData(&frameHeader, 1, presentationTime);
00096   }
00097 
00098   // Call the parent class to complete the normal file write with the input data:
00099   FileSink::afterGettingFrame1(frameSize, presentationTime);
00100 }

Generated on Tue Oct 7 15:38:08 2008 for live by  doxygen 1.5.2