00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "MPEG1or2AudioStreamFramer.hh"
00022 #include "StreamParser.hh"
00023 #include "MP3Internals.hh"
00024 #include <GroupsockHelper.hh>
00025
00027
00028 class MPEG1or2AudioStreamParser: public StreamParser {
00029 public:
00030 MPEG1or2AudioStreamParser(MPEG1or2AudioStreamFramer* usingSource,
00031 FramedSource* inputSource);
00032 virtual ~MPEG1or2AudioStreamParser();
00033
00034 public:
00035 unsigned parse(unsigned& numTruncatedBytes);
00036
00037
00038 void registerReadInterest(unsigned char* to, unsigned maxSize);
00039
00040 MP3FrameParams const& currentFrame() const { return fCurrentFrame; }
00041
00042 private:
00043 unsigned char* fTo;
00044 unsigned fMaxSize;
00045
00046
00047 MP3FrameParams fCurrentFrame;
00048 };
00049
00050
00052
00053 MPEG1or2AudioStreamFramer
00054 ::MPEG1or2AudioStreamFramer(UsageEnvironment& env, FramedSource* inputSource,
00055 Boolean syncWithInputSource)
00056 : FramedFilter(env, inputSource),
00057 fSyncWithInputSource(syncWithInputSource) {
00058 reset();
00059
00060 fParser = new MPEG1or2AudioStreamParser(this, inputSource);
00061 }
00062
00063 MPEG1or2AudioStreamFramer::~MPEG1or2AudioStreamFramer() {
00064 delete fParser;
00065 }
00066
00067 MPEG1or2AudioStreamFramer*
00068 MPEG1or2AudioStreamFramer::createNew(UsageEnvironment& env,
00069 FramedSource* inputSource,
00070 Boolean syncWithInputSource) {
00071
00072 return new MPEG1or2AudioStreamFramer(env, inputSource, syncWithInputSource);
00073 }
00074
00075 void MPEG1or2AudioStreamFramer::flushInput() {
00076 reset();
00077 fParser->flushInput();
00078 }
00079
00080 void MPEG1or2AudioStreamFramer::reset() {
00081
00082 struct timeval timeNow;
00083 gettimeofday(&timeNow, NULL);
00084 resetPresentationTime(timeNow);
00085 }
00086
00087 void MPEG1or2AudioStreamFramer
00088 ::resetPresentationTime(struct timeval newPresentationTime) {
00089 fNextFramePresentationTime = newPresentationTime;
00090 }
00091
00092 void MPEG1or2AudioStreamFramer::doGetNextFrame() {
00093 fParser->registerReadInterest(fTo, fMaxSize);
00094 continueReadProcessing();
00095 }
00096
00097 #define MILLION 1000000
00098
00099 static unsigned const numSamplesByLayer[4] = {0, 384, 1152, 1152};
00100
00101 struct timeval MPEG1or2AudioStreamFramer::currentFramePlayTime() const {
00102 MP3FrameParams const& fr = fParser->currentFrame();
00103 unsigned const numSamples = numSamplesByLayer[fr.layer];
00104
00105 struct timeval result;
00106 unsigned const freq = fr.samplingFreq*(1 + fr.isMPEG2);
00107 if (freq == 0) {
00108 result.tv_sec = 0;
00109 result.tv_usec = 0;
00110 return result;
00111 }
00112
00113
00114 unsigned const uSeconds
00115 = ((numSamples*2*MILLION)/freq + 1)/2;
00116
00117 result.tv_sec = uSeconds/MILLION;
00118 result.tv_usec = uSeconds%MILLION;
00119 return result;
00120 }
00121
00122 void MPEG1or2AudioStreamFramer
00123 ::continueReadProcessing(void* clientData,
00124 unsigned char* , unsigned ,
00125 struct timeval presentationTime) {
00126 MPEG1or2AudioStreamFramer* framer = (MPEG1or2AudioStreamFramer*)clientData;
00127 if (framer->fSyncWithInputSource) {
00128 framer->resetPresentationTime(presentationTime);
00129 }
00130 framer->continueReadProcessing();
00131 }
00132
00133 void MPEG1or2AudioStreamFramer::continueReadProcessing() {
00134 unsigned acquiredFrameSize = fParser->parse(fNumTruncatedBytes);
00135 if (acquiredFrameSize > 0) {
00136
00137
00138 fFrameSize = acquiredFrameSize;
00139
00140
00141
00142 fPresentationTime = fNextFramePresentationTime;
00143 struct timeval framePlayTime = currentFramePlayTime();
00144 fDurationInMicroseconds = framePlayTime.tv_sec*MILLION + framePlayTime.tv_usec;
00145 fNextFramePresentationTime.tv_usec += framePlayTime.tv_usec;
00146 fNextFramePresentationTime.tv_sec
00147 += framePlayTime.tv_sec + fNextFramePresentationTime.tv_usec/MILLION;
00148 fNextFramePresentationTime.tv_usec %= MILLION;
00149
00150
00151
00152 afterGetting(this);
00153 } else {
00154
00155
00156
00157 }
00158 }
00159
00160
00162
00163 MPEG1or2AudioStreamParser
00164 ::MPEG1or2AudioStreamParser(MPEG1or2AudioStreamFramer* usingSource,
00165 FramedSource* inputSource)
00166 : StreamParser(inputSource, FramedSource::handleClosure, usingSource,
00167 &MPEG1or2AudioStreamFramer::continueReadProcessing, usingSource) {
00168 }
00169
00170 MPEG1or2AudioStreamParser::~MPEG1or2AudioStreamParser() {
00171 }
00172
00173 void MPEG1or2AudioStreamParser::registerReadInterest(unsigned char* to,
00174 unsigned maxSize) {
00175 fTo = to;
00176 fMaxSize = maxSize;
00177 }
00178
00179 unsigned MPEG1or2AudioStreamParser::parse(unsigned& numTruncatedBytes) {
00180 try {
00181 saveParserState();
00182
00183
00184 while (((fCurrentFrame.hdr = test4Bytes())&0xFFE00000) != 0xFFE00000) {
00185 skipBytes(1);
00186 saveParserState();
00187 }
00188
00189 fCurrentFrame.setParamsFromHeader();
00190
00191
00192 unsigned frameSize = fCurrentFrame.frameSize + 4;
00193 if (frameSize > fMaxSize) {
00194 numTruncatedBytes = frameSize - fMaxSize;
00195 frameSize = fMaxSize;
00196 } else {
00197 numTruncatedBytes = 0;
00198 }
00199
00200 getBytes(fTo, frameSize);
00201 skipBytes(numTruncatedBytes);
00202
00203 return frameSize;
00204 } catch (int ) {
00205 #ifdef DEBUG
00206 fprintf(stderr, "MPEG1or2AudioStreamParser::parse() EXCEPTION (This is normal behavior - *not* an error)\n");
00207 #endif
00208 return 0;
00209 }
00210 }