1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
/**********
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more details.
You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
**********/
// "liveMedia"
// Copyright (c) 1996-2005 Live Networks, Inc. All rights reserved.
// A file source that is a plain byte stream (rather than frames)
// Implementation
#if (defined(__WIN32__) || defined(_WIN32)) && !defined(_WIN32_WCE)
#include <io.h>
#include <fcntl.h>
#endif
#include "ByteStreamFileSource.hh"
#include "InputFile.hh"
#include "GroupsockHelper.hh"
////////// ByteStreamFileSource //////////
ByteStreamFileSource*
ByteStreamFileSource::createNew(UsageEnvironment& env, char const* fileName,
unsigned preferredFrameSize,
unsigned playTimePerFrame) {
FILE* fid = OpenInputFile(env, fileName);
if (fid == NULL) return NULL;
Boolean deleteFidOnClose = fid == stdin ? False : True;
ByteStreamFileSource* newSource
= new ByteStreamFileSource(env, fid, deleteFidOnClose,
preferredFrameSize, playTimePerFrame);
newSource->fFileSize = GetFileSize(fileName, fid);
return newSource;
}
ByteStreamFileSource*
ByteStreamFileSource::createNew(UsageEnvironment& env, FILE* fid,
Boolean deleteFidOnClose,
unsigned preferredFrameSize,
unsigned playTimePerFrame) {
if (fid == NULL) return NULL;
ByteStreamFileSource* newSource
= new ByteStreamFileSource(env, fid, deleteFidOnClose,
preferredFrameSize, playTimePerFrame);
newSource->fFileSize = GetFileSize(NULL, fid);
return newSource;
}
void ByteStreamFileSource::seekToByteAbsolute(u_int64_t byteNumber) {
SeekFile64(fFid, (int64_t)byteNumber, SEEK_SET);
}
void ByteStreamFileSource::seekToByteRelative(int64_t offset) {
SeekFile64(fFid, offset, SEEK_CUR);
}
ByteStreamFileSource::ByteStreamFileSource(UsageEnvironment& env, FILE* fid,
Boolean deleteFidOnClose,
unsigned preferredFrameSize,
unsigned playTimePerFrame)
: FramedFileSource(env, fid), fPreferredFrameSize(preferredFrameSize),
fPlayTimePerFrame(playTimePerFrame), fLastPlayTime(0), fFileSize(0),
fDeleteFidOnClose(deleteFidOnClose) {
}
ByteStreamFileSource::~ByteStreamFileSource() {
if (fDeleteFidOnClose && fFid != NULL) fclose(fFid);
}
void ByteStreamFileSource::doGetNextFrame() {
if (feof(fFid) || ferror(fFid)) {
handleClosure(this);
return;
}
// Try to read as many bytes as will fit in the buffer provided
// (or "fPreferredFrameSize" if less)
if (fPreferredFrameSize > 0 && fPreferredFrameSize < fMaxSize) {
fMaxSize = fPreferredFrameSize;
}
fFrameSize = fread(fTo, 1, fMaxSize, fFid);
// Set the 'presentation time':
if (fPlayTimePerFrame > 0 && fPreferredFrameSize > 0) {
if (fPresentationTime.tv_sec == 0 && fPresentationTime.tv_usec == 0) {
// This is the first frame, so use the current time:
gettimeofday(&fPresentationTime, NULL);
} else {
// Increment by the play time of the previous data:
unsigned uSeconds = fPresentationTime.tv_usec + fLastPlayTime;
fPresentationTime.tv_sec += uSeconds/1000000;
fPresentationTime.tv_usec = uSeconds%1000000;
}
// Remember the play time of this data:
fLastPlayTime = (fPlayTimePerFrame*fFrameSize)/fPreferredFrameSize;
fDurationInMicroseconds = fLastPlayTime;
} else {
// We don't know a specific play time duration for this data,
// so just record the current time as being the 'presentation time':
gettimeofday(&fPresentationTime, NULL);
}
// Switch to another task, and inform the reader that he has data:
nextTask() = envir().taskScheduler().scheduleDelayedTask(0,
(TaskFunc*)FramedSource::afterGetting, this);
}
|