void MPEG1or2AudioStreamFramer::continueReadProcessing() { unsigned acquiredFrameSize = fParser->parse(fNumTruncatedBytes); if (acquiredFrameSize > 0) { // We were able to acquire a frame from the input. // It has already been copied to the reader's space. fFrameSize = acquiredFrameSize; // Also set the presentation time, and increment it for next time, // based on the length of this frame: fPresentationTime = fNextFramePresentationTime; struct timeval framePlayTime = currentFramePlayTime(); fDurationInMicroseconds = framePlayTime.tv_sec*MILLION + framePlayTime.tv_usec; fNextFramePresentationTime.tv_usec += framePlayTime.tv_usec; fNextFramePresentationTime.tv_sec += framePlayTime.tv_sec + fNextFramePresentationTime.tv_usec/MILLION; fNextFramePresentationTime.tv_usec %= MILLION; // Call our own 'after getting' function. Because we're not a 'leaf' // source, we can call this directly, without risking infinite recursion. afterGetting(this); } else { // We were unable to parse a complete frame from the input, because: // - we had to read more data from the source stream, or // - the source stream has ended. } }
float MP3StreamState::filePlayTime() const { unsigned numFramesInFile = fNumFramesInFile; if (numFramesInFile == 0) { // Estimate the number of frames from the file size, and the // size of the current frame: numFramesInFile = fFileSize/(4 + fCurrentFrame.frameSize); } struct timeval const pt = currentFramePlayTime(); return numFramesInFile*(pt.tv_sec + pt.tv_usec/(float)MILLION); }
unsigned MP3StreamState::findNextHeader(struct timeval& presentationTime) { presentationTime = fNextFramePresentationTime; if (!findNextFrame()) return 0; // From this frame, figure out the *next* frame's presentation time: struct timeval framePlayTime = currentFramePlayTime(); if (fPresentationTimeScale > 1) { // Scale this value unsigned secondsRem = framePlayTime.tv_sec % fPresentationTimeScale; framePlayTime.tv_sec -= secondsRem; framePlayTime.tv_usec += secondsRem*MILLION; framePlayTime.tv_sec /= fPresentationTimeScale; framePlayTime.tv_usec /= fPresentationTimeScale; } fNextFramePresentationTime.tv_usec += framePlayTime.tv_usec; fNextFramePresentationTime.tv_sec += framePlayTime.tv_sec + fNextFramePresentationTime.tv_usec/MILLION; fNextFramePresentationTime.tv_usec %= MILLION; return fr().hdr; }
resultFrameSize = outBufSize; return False; } if (resultFrameSize >= 4) { unsigned& hdr = fr().hdr; *outBuf++ = (unsigned char)(hdr>>24); *outBuf++ = (unsigned char)(hdr>>16); *outBuf++ = (unsigned char)(hdr>>8); *outBuf++ = (unsigned char)(hdr); memmove(outBuf, fr().frameBytes, resultFrameSize-4); } struct timeval const pt = currentFramePlayTime(); resultDurationInMicroseconds = pt.tv_sec*MILLION + pt.tv_usec; return True; } void MP3StreamState::getAttributes(char* buffer, unsigned bufferSize) const { char const* formatStr = "bandwidth %d MPEGnumber %d MPEGlayer %d samplingFrequency %d isStereo %d playTime %d isVBR %d"; unsigned fpt = (unsigned)(filePlayTime() + 0.5); // rounds to nearest integer #if defined(IRIX) || defined(ALPHA) || defined(_QNX4) || defined(IMN_PIM) || defined(CRIS) /* snprintf() isn't defined, so just use sprintf() - ugh! */ sprintf(buffer, formatStr, fr().bitrate, fr().isMPEG2 ? 2 : 1, fr().layer, fr().samplingFreq, fr().isStereo, fpt, fIsVBR); #else