liveMedia/ByteStreamMultiFileSource.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 // A source that consists of multiple byte-stream files, read sequentially
00019 // Implementation
00020 
00021 #include "ByteStreamMultiFileSource.hh"
00022 
00023 ByteStreamMultiFileSource
00024 ::ByteStreamMultiFileSource(UsageEnvironment& env, char const** fileNameArray,
00025                             unsigned preferredFrameSize, unsigned playTimePerFrame)
00026   : FramedSource(env),
00027     fPreferredFrameSize(preferredFrameSize), fPlayTimePerFrame(playTimePerFrame),
00028     fCurrentlyReadSourceNumber(0), fHaveStartedNewFile(False) {
00029     // Begin by counting the number of sources:
00030     for (fNumSources = 0; ; ++fNumSources) {
00031       if (fileNameArray[fNumSources] == NULL) break;
00032     }
00033 
00034     // Next, copy the source file names into our own array:
00035     fFileNameArray = new char const*[fNumSources];
00036     if (fFileNameArray == NULL) return;
00037     unsigned i;
00038     for (i = 0; i < fNumSources; ++i) {
00039       fFileNameArray[i] = strDup(fileNameArray[i]);
00040     }
00041 
00042     // Next, set up our array of component ByteStreamFileSources
00043     // Don't actually create these yet; instead, do this on demand
00044     fSourceArray = new ByteStreamFileSource*[fNumSources];
00045     if (fSourceArray == NULL) return;
00046     for (i = 0; i < fNumSources; ++i) {
00047       fSourceArray[i] = NULL;
00048     }
00049 }
00050 
00051 ByteStreamMultiFileSource::~ByteStreamMultiFileSource() {
00052   unsigned i;
00053   for (i = 0; i < fNumSources; ++i) {
00054     Medium::close(fSourceArray[i]);
00055   }
00056   delete[] fSourceArray;
00057 
00058   for (i = 0; i < fNumSources; ++i) {
00059     delete[] (char*)(fFileNameArray[i]);
00060   }
00061   delete[] fFileNameArray;
00062 }
00063 
00064 ByteStreamMultiFileSource* ByteStreamMultiFileSource
00065 ::createNew(UsageEnvironment& env, char const** fileNameArray,
00066             unsigned preferredFrameSize, unsigned playTimePerFrame) {
00067   ByteStreamMultiFileSource* newSource
00068     = new ByteStreamMultiFileSource(env, fileNameArray,
00069                                     preferredFrameSize, playTimePerFrame);
00070 
00071   return newSource;
00072 }
00073 
00074 void ByteStreamMultiFileSource::doGetNextFrame() {
00075   do {
00076     // First, check whether we've run out of sources:
00077     if (fCurrentlyReadSourceNumber >= fNumSources) break;
00078 
00079     fHaveStartedNewFile = False;
00080     ByteStreamFileSource*& source
00081       = fSourceArray[fCurrentlyReadSourceNumber];
00082     if (source == NULL) {
00083       // The current source hasn't been created yet.  Do this now:
00084       source = ByteStreamFileSource::createNew(envir(),
00085                        fFileNameArray[fCurrentlyReadSourceNumber],
00086                        fPreferredFrameSize, fPlayTimePerFrame);
00087       if (source == NULL) break;
00088       fHaveStartedNewFile = True;
00089     }
00090 
00091     // (Attempt to) read from the current source.
00092     source->getNextFrame(fTo, fMaxSize,
00093                                afterGettingFrame, this,
00094                                onSourceClosure, this);
00095     return;
00096   } while (0);
00097 
00098   // An error occurred; consider ourselves closed:
00099   handleClosure(this);
00100 }
00101 
00102 void ByteStreamMultiFileSource
00103   ::afterGettingFrame(void* clientData,
00104                       unsigned frameSize, unsigned numTruncatedBytes,
00105                       struct timeval presentationTime,
00106                       unsigned durationInMicroseconds) {
00107   ByteStreamMultiFileSource* source
00108     = (ByteStreamMultiFileSource*)clientData;
00109   source->fFrameSize = frameSize;
00110   source->fNumTruncatedBytes = numTruncatedBytes;
00111   source->fPresentationTime = presentationTime;
00112   source->fDurationInMicroseconds = durationInMicroseconds;
00113   FramedSource::afterGetting(source);
00114 }
00115 
00116 void ByteStreamMultiFileSource::onSourceClosure(void* clientData) {
00117   ByteStreamMultiFileSource* source
00118     = (ByteStreamMultiFileSource*)clientData;
00119   source->onSourceClosure1();
00120 }
00121 
00122 void ByteStreamMultiFileSource::onSourceClosure1() {
00123   // This routine was called because the currently-read source was closed
00124   // (probably due to EOF).  Close this source down, and move to the
00125   // next one:
00126   ByteStreamFileSource*& source
00127     = fSourceArray[fCurrentlyReadSourceNumber++];
00128   Medium::close(source);
00129   source = NULL;
00130 
00131   // Try reading again:
00132   doGetNextFrame();
00133 }

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