liveMedia/ByteStreamMemoryBufferSource.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-2012 Live Networks, Inc.  All rights reserved.
00018 // A class for streaming data from a (static) memory buffer, as if it were a file.
00019 // Implementation
00020 
00021 #include "ByteStreamMemoryBufferSource.hh"
00022 #include "GroupsockHelper.hh"
00023 
00025 
00026 ByteStreamMemoryBufferSource*
00027 ByteStreamMemoryBufferSource::createNew(UsageEnvironment& env,
00028                                         u_int8_t* buffer, u_int64_t bufferSize,
00029                                         Boolean deleteBufferOnClose,
00030                                         unsigned preferredFrameSize,
00031                                         unsigned playTimePerFrame) {
00032   if (buffer == NULL) return NULL;
00033 
00034   return new ByteStreamMemoryBufferSource(env, buffer, bufferSize, deleteBufferOnClose, preferredFrameSize, playTimePerFrame);
00035 }
00036 
00037 ByteStreamMemoryBufferSource::ByteStreamMemoryBufferSource(UsageEnvironment& env,
00038                                                            u_int8_t* buffer, u_int64_t bufferSize,
00039                                                            Boolean deleteBufferOnClose,
00040                                                            unsigned preferredFrameSize,
00041                                                            unsigned playTimePerFrame)
00042   : FramedSource(env), fBuffer(buffer), fBufferSize(bufferSize), fCurIndex(0), fDeleteBufferOnClose(deleteBufferOnClose),
00043     fPreferredFrameSize(preferredFrameSize), fPlayTimePerFrame(playTimePerFrame), fLastPlayTime(0) {
00044 }
00045 
00046 ByteStreamMemoryBufferSource::~ByteStreamMemoryBufferSource() {
00047   if (fDeleteBufferOnClose) delete[] fBuffer;
00048 }
00049 
00050 void ByteStreamMemoryBufferSource::seekToByteAbsolute(u_int64_t byteNumber, u_int64_t numBytesToStream) {
00051   fCurIndex = byteNumber;
00052   if (fCurIndex > fBufferSize) fCurIndex = fBufferSize;
00053 
00054   fNumBytesToStream = numBytesToStream;
00055   fLimitNumBytesToStream = fNumBytesToStream > 0;
00056 }
00057 
00058 void ByteStreamMemoryBufferSource::seekToByteRelative(int64_t offset) {
00059   int64_t newIndex = fCurIndex + offset;
00060   if (newIndex < 0) {
00061     fCurIndex = 0;
00062   } else {
00063     fCurIndex = (u_int64_t)offset;
00064     if (fCurIndex > fBufferSize) fCurIndex = fBufferSize;
00065   }
00066 }
00067 
00068 void ByteStreamMemoryBufferSource::doGetNextFrame() {
00069   if (fCurIndex >= fBufferSize || (fLimitNumBytesToStream && fNumBytesToStream == 0)) {
00070     handleClosure(this);
00071     return;
00072   }
00073 
00074   // Try to read as many bytes as will fit in the buffer provided (or "fPreferredFrameSize" if less)
00075   fFrameSize = fMaxSize;
00076   if (fLimitNumBytesToStream && fNumBytesToStream < (u_int64_t)fFrameSize) {
00077     fFrameSize = (unsigned)fNumBytesToStream;
00078   }
00079   if (fPreferredFrameSize > 0 && fPreferredFrameSize < fFrameSize) {
00080     fFrameSize = fPreferredFrameSize;
00081   }
00082 
00083   if (fCurIndex + fFrameSize > fBufferSize) {
00084     fFrameSize = (unsigned)(fBufferSize - fCurIndex);
00085   }
00086 
00087   memmove(fTo, &fBuffer[fCurIndex], fFrameSize);
00088   fCurIndex += fFrameSize;
00089   fNumBytesToStream -= fFrameSize;
00090 
00091   // Set the 'presentation time':
00092   if (fPlayTimePerFrame > 0 && fPreferredFrameSize > 0) {
00093     if (fPresentationTime.tv_sec == 0 && fPresentationTime.tv_usec == 0) {
00094       // This is the first frame, so use the current time:
00095       gettimeofday(&fPresentationTime, NULL);
00096     } else {
00097       // Increment by the play time of the previous data:
00098       unsigned uSeconds = fPresentationTime.tv_usec + fLastPlayTime;
00099       fPresentationTime.tv_sec += uSeconds/1000000;
00100       fPresentationTime.tv_usec = uSeconds%1000000;
00101     }
00102 
00103     // Remember the play time of this data:
00104     fLastPlayTime = (fPlayTimePerFrame*fFrameSize)/fPreferredFrameSize;
00105     fDurationInMicroseconds = fLastPlayTime;
00106   } else {
00107     // We don't know a specific play time duration for this data,
00108     // so just record the current time as being the 'presentation time':
00109     gettimeofday(&fPresentationTime, NULL);
00110   }
00111 
00112   // Inform the downstream object that it has data:
00113   FramedSource::afterGetting(this);
00114 }

Generated on Thu May 17 07:11:45 2012 for live by  doxygen 1.5.2