Buffer* BufferManager::getCurrentBuffer(__int32 minimumSize, bool forceNewBuffer) { Buffer* result = NULL; if (!_activeBuffers->empty()) { result = _activeBuffers->back(); // because some other action could change the currentPos // we should ensure its in the right place before returning the buffer result->seek(result->currentPos()); } if ((forceNewBuffer) || (result == NULL) || (result->spaceLeft() < minimumSize)) { bool newBuffer; int flag = 0x01; // Active buffer if (_reusableBuffers->empty()) { result = createNewBuffer(); newBuffer = true; } else { result = _reusableBuffers->front(); _reusableBuffers->pop(); result->reset(); newBuffer = false; } addBuffer(result); result->seek(0); registerBufferControlFile(result, newBuffer, flag); } return result; }
AMRDeinterleavingBuffer ::AMRDeinterleavingBuffer(unsigned numChannels, unsigned maxInterleaveGroupSize) : fNumChannels(numChannels), fMaxInterleaveGroupSize(maxInterleaveGroupSize), fIncomingBankId(0), fIncomingBinMax(0), fOutgoingBinMax(0), fNextOutgoingBin(0), fHaveSeenPackets(False), fNumSuccessiveSyncedFrames(0), fILL(0) { // Use two banks of descriptors - one for incoming, one for outgoing fFrames[0] = new FrameDescriptor[fMaxInterleaveGroupSize]; fFrames[1] = new FrameDescriptor[fMaxInterleaveGroupSize]; fInputBuffer = createNewBuffer(); }
void AMRDeinterleavingBuffer ::deliverIncomingFrame(unsigned frameSize, RawAMRRTPSource* source, struct timeval presentationTime) { fILL = source->ILL(); unsigned char const ILP = source->ILP(); unsigned frameIndex = source->frameIndex(); unsigned short packetSeqNum = source->curPacketRTPSeqNum(); // First perform a sanity check on the parameters: // (This is overkill, as the source should have already done this.) if (ILP > fILL || frameIndex == 0) { #ifdef DEBUG fprintf(stderr, "AMRDeinterleavingBuffer::deliverIncomingFrame() param sanity check failed (%d,%d,%d,%d)\n", frameSize, fILL, ILP, frameIndex); #endif source->envir().internalError(); } --frameIndex; // because it was incremented by the source when this frame was read u_int8_t frameHeader; if (frameIndex >= source->TOCSize()) { // sanity check frameHeader = FT_NO_DATA<<3; } else { frameHeader = source->TOC()[frameIndex]; } unsigned frameBlockIndex = frameIndex/fNumChannels; unsigned frameWithinFrameBlock = frameIndex%fNumChannels; // The input "presentationTime" was that of the first frame-block in this // packet. Update it for the current frame: unsigned uSecIncrement = frameBlockIndex*(fILL+1)*uSecsPerFrame; presentationTime.tv_usec += uSecIncrement; presentationTime.tv_sec += presentationTime.tv_usec/1000000; presentationTime.tv_usec = presentationTime.tv_usec%1000000; // Next, check whether this packet is part of a new interleave group if (!fHaveSeenPackets || seqNumLT(fLastPacketSeqNumForGroup, packetSeqNum + frameBlockIndex)) { // We've moved to a new interleave group #ifdef DEBUG fprintf(stderr, "AMRDeinterleavingBuffer::deliverIncomingFrame(): new interleave group\n"); #endif fHaveSeenPackets = True; fLastPacketSeqNumForGroup = packetSeqNum + fILL - ILP; // Switch the incoming and outgoing banks: fIncomingBankId ^= 1; unsigned char tmp = fIncomingBinMax; fIncomingBinMax = fOutgoingBinMax; fOutgoingBinMax = tmp; fNextOutgoingBin = 0; } // Now move the incoming frame into the appropriate bin: unsigned const binNumber = ((ILP + frameBlockIndex*(fILL+1))*fNumChannels + frameWithinFrameBlock) % fMaxInterleaveGroupSize; // the % is for sanity #ifdef DEBUG fprintf(stderr, "AMRDeinterleavingBuffer::deliverIncomingFrame(): frameIndex %d (%d,%d) put in bank %d, bin %d (%d): size %d, header 0x%02x, presentationTime %lu.%06ld\n", frameIndex, frameBlockIndex, frameWithinFrameBlock, fIncomingBankId, binNumber, fMaxInterleaveGroupSize, frameSize, frameHeader, presentationTime.tv_sec, presentationTime.tv_usec); #endif FrameDescriptor& inBin = fFrames[fIncomingBankId][binNumber]; unsigned char* curBuffer = inBin.frameData; inBin.frameData = fInputBuffer; inBin.frameSize = frameSize; inBin.frameHeader = frameHeader; inBin.presentationTime = presentationTime; inBin.fIsSynchronized = ((RTPSource*)source)->RTPSource::hasBeenSynchronizedUsingRTCP(); if (curBuffer == NULL) curBuffer = createNewBuffer(); fInputBuffer = curBuffer; if (binNumber >= fIncomingBinMax) { fIncomingBinMax = binNumber + 1; } }