defaultcircularbuffer.cpp

来自「C++封装的视频采集代码」· C++ 代码 · 共 1,498 行 · 第 1/5 页

CPP
1,498
字号
            return (circularBufferSpaceInfo.GetFirstAvailableSection().GetLength() >= circularBufferSpaceInfo.GetSecondAvailableSection().GetLength()) ?                circularBufferSpaceInfo.GetFirstAvailableSection().GetLength() : circularBufferSpaceInfo.GetSecondAvailableSection().GetLength();        }        // }}}        CircularBufferSpaceInfo DefaultCircularBuffer::GetWriteSpaceInfo(            const CircularBufferPosition& writePosition) const        // {{{        {            syslib::Lock lock(mutex_);            CircularBufferPosition* oldestReadPosition = &readPositions_[0].position_;            for (unsigned i=1; i < numberOfReaders_; ++i)            {                if (readPositions_[i].position_ < *oldestReadPosition)                {                    oldestReadPosition = &readPositions_[i].position_;                }            }//TRACE("$WGWSI writeEmpty_ = %d$n\n", writeEmpty_);//TRACE("$WGWSI writePosition = [%lu:%lu:%lu]$n\n", writePosition.GetLoopCount(), writePosition.GetOffset(), writePosition.GetMargin());//TRACE("$WGWSI oldestReadPosition = [%lu:%lu:%lu]$n\n", oldestReadPosition->GetLoopCount(), oldestReadPosition->GetOffset(), oldestReadPosition->GetMargin());            // If writer points to the same location as the oldest reader, it            // means either that the buffer has no write space available for            // writing, or that the entire buffer is available for writing. Dis-            // tinguish the cases with the writeEmpty flag            if ((writePosition.GetOffset() == oldestReadPosition->GetOffset()) && writeEmpty_)            {//TRACE("$WGWSI Case 1$n\n");                return CircularBufferSpaceInfo(                    BufferSectionInfo(0, 0),                    BufferSectionInfo(0, 0));            }            if (oldestReadPosition->GetOffset() > writePosition.GetOffset())            {//TRACE("$WGWSI Case 2$n\n");                return CircularBufferSpaceInfo(                    BufferSectionInfo(                        reinterpret_cast<unsigned long>(buffer_->GetBuffer()) +                            writePosition.GetOffset(),                        oldestReadPosition->GetOffset() - writePosition.GetOffset()),                    BufferSectionInfo(0, 0));            }            else            {//TRACE("$WGWSI Case 3, buffer_ = 0x%lx, writePosition.GetOffset() = %lu, writePosition.GetMargin() = %lu$n\n", reinterpret_cast<unsigned long>(buffer_->GetBuffer()), writePosition.GetOffset(), writePosition.GetMargin());//TRACE("$WGWSI 0x%lx,%lu$n\n", reinterpret_cast<unsigned long>(buffer_->GetBuffer()) + writePosition.GetOffset(), writePosition.GetMargin());                return CircularBufferSpaceInfo(                    BufferSectionInfo(                        reinterpret_cast<unsigned long>(buffer_->GetBuffer()) +                            writePosition.GetOffset(),                        writePosition.GetMargin()),                    BufferSectionInfo(                        reinterpret_cast<unsigned long>(buffer_->GetBuffer()),                        oldestReadPosition->GetOffset()));            }        }        // }}}        bool DefaultCircularBuffer::IsComplete() const        // {{{        {            return buffer_->GetBuffer();        }        // }}}        bool DefaultCircularBuffer::IsAboveReadThreshold(unsigned readerNumber) const        // {{{        {            syslib::Lock lock(mutex_);            CircularBufferSpaceInfo readSpaceInfo;            bool aboveReadThreshold = false;                        if (!readPositions_[readerNumber].empty_)            {                readSpaceInfo       = GetReadSpaceInfo(readPositions_[readerNumber].position_);                aboveReadThreshold  = mpReadThresholds_[readerNumber].IsAboveThreshold(readSpaceInfo);            }//TRACE("$MR[%lu+%lu] %lu:%lu ->%s(%u)$n\n", readSpaceInfo.GetFirstAvailableSection().GetLength(), readSpaceInfo.GetSecondAvailableSection().GetLength(), GetReadThreshold(readerNumber), buffer_->GetSize(), aboveReadThreshold ? "above" : "below", readerNumber);//TRACE("$MR%s:%lu$n\n", aboveReadThreshold ? "above" : "below", totalLength);            return aboveReadThreshold;        }        // }}}        bool DefaultCircularBuffer::IsAboveWriteThreshold() const        // {{{        {            syslib::Lock lock(mutex_);            CircularBufferSpaceInfo writeSpaceInfo = GetWriteSpaceInfo(writePosition_);                        bool aboveWriteThreshold = writeThreshold_.IsAboveThreshold( writeSpaceInfo );            //TRACE("$MW[%lu+%lu]->%s(%lu)$n\n", writeSpaceInfo.GetFirstAvailableSection().GetLength(), writeSpaceInfo.GetSecondAvailableSection().GetLength(), aboveWriteThreshold ? "above" : "below", GetWriteThreshold() );            return aboveWriteThreshold;        }        // }}}        bool DefaultCircularBuffer::IsEmpty(unsigned readerNumber) const        // {{{        {            return readPositions_[readerNumber].empty_;        }        // }}}        void DefaultCircularBuffer::PostAdditionAction( ReadThresholdEventListener* pListener )        // {{{        {            TRACE("Listener has been added To DCB\n");            /*            for (unsigned readerNumber=0; readerNumber < numberOfReaders_; ++readerNumber)            {                if ( GetReadThreshold(readerNumber) )                {                    if ( IsAboveReadThreshold(readerNumber) )                    {                        NotifierWithParameter<ReadThresholdEventListener, unsigned>::NotifyListeners(readerNumber);                        TRACE("$CReader %u above threshold after addition $n\n", readerNumber );                    }                }            }            */        }        // }}}                        /**         * @param readerNumber An unsigned specifying the number of the         *  reader whose read pointer is to be advanced         * @return An unsigned int - the number of bytes used in the         *  circular buffer.         */        unsigned int DefaultCircularBuffer::BytesUsed(unsigned int readerNumber) const        // {{{        {            unsigned int totalLength;            if (readPositions_[readerNumber].empty_)            {                totalLength = 0;            }            else            {                CircularBufferSpaceInfo readSpaceInfo = GetReadSpaceInfo(readPositions_[readerNumber].position_);                totalLength = (readSpaceInfo.GetFirstAvailableSection().GetLength() +                              readSpaceInfo.GetSecondAvailableSection().GetLength());            }            return totalLength;        }        // }}}        std::pair<bool, unsigned> DefaultCircularBuffer::IsOldestReader(unsigned readerNumber) const        // {{{        {            // Determine the number of readers with the oldest position            bool isOldestReader = false;            int numberOfOldestReaders = 0;            CircularBufferPosition* oldestReadPosition = &readPositions_[0].position_;            for (unsigned i=0; i < numberOfReaders_; ++i)            {                if (readPositions_[i].position_ == *oldestReadPosition)                {                    if (readerNumber == i)                    {                        isOldestReader = true;                    }                    ++numberOfOldestReaders;                }                else if (readPositions_[i].position_ < *oldestReadPosition)                {                    numberOfOldestReaders = 1;                    isOldestReader = (readerNumber == i);                    oldestReadPosition = &readPositions_[i].position_;                }            }            return std::make_pair(isOldestReader, numberOfOldestReaders);        }        // }}}        void DefaultCircularBuffer::NotifyReaders()        // {{{        {            // Notify all readers blocked awaiting a buffer that one may now be            //  available//TRACE("$WNotifyReaders$n");            for (unsigned i = 0; i < readWaitCount_; ++i)            {//TRACE("$W.$n");                readSemaphore_.give();            }//TRACE("\n");            readWaitCount_ = 0;        }        // }}}        void DefaultCircularBuffer::NotifyWriters()        // {{{        {//TRACE("$WNotifyWriters$n\n");            // Notify all writers blocked awaiting a buffer that one may now be            //  available            for (unsigned i = 0; i < writeWaitCount_; ++i)            {                writeSemaphore_.give();            }            writeWaitCount_ = 0;        }        // }}}        bool DefaultCircularBuffer::RegisterResidentClass(            CircularBufferResidentObject::Id& id,            ObjectPool& pool)        // {{{        {            syslib::Lock lock(mutex_);            if (knownObjectTypes_.size() == knownObjectTypes_.max_size())            {                knownObjectTypes_.expand(knownObjectTypes_.max_size() * 2);            }            knownObjectTypes_.insert(                std::lower_bound(                    knownObjectTypes_.begin(),                    knownObjectTypes_.end(),                    nextFreeId_,                    SequenceOfPairsCompare<KNOWN_TYPES_CONTAINTER_TYPE::value_type>()),                std::make_pair(nextFreeId_, &pool));            id = nextFreeId_++;            return true;        }        // }}}        void DefaultCircularBuffer::ReleaseFromRead(            unsigned readerNumber,            CircularBufferResidentObject* object,            bool pending)        // {{{        {#ifdef INUSE_TRACKING            if (!object)            {                TRACE("$RDefaultCircularBuffer::ReleaseFromRead() Object pointer is null\n");                return;            }#endif            syslib::Lock lock(mutex_);//TRACE("$BRR entered: object=0x%lx, readerNumber=%u$n\n", reinterpret_cast<unsigned long>(object), readerNumber);#ifdef INUSE_TRACKING            // Catch trying to release object when none are in-use            if (!readerInUse_[readerNumber]->size())            {                TRACE("$RDefaultCircularBuffer::ReleaseFromRead() Attempt to release when no buffers in-use$n\n");                return;            }            // Check that the object being release is the object in the current            // in-use set that was acquired earliest            if (*readerInUse_[readerNumber]->begin() != object)            {                TRACE("$RDefaultCircularBuffer::ReleaseFromRead() Attempt to release buffer 0x%lx which is not the earliest in-use$n\n",                    reinterpret_cast<unsigned long>(object));                return;            }            // The earliest in-use is to be released, so remove from record            // of in-use objects            readerInUse_[readerNumber]->erase(readerInUse_[readerNumber]->begin());#endif            // There will be one less buffer currently acquired for read by the            // specified reader            --outstandingReadAcquisitions_[readerNumber];            if (pending)            {                // Return the object to its pool, but leave the circular buffer                // resident data untouched                GetPool(*object)->Free(object);                // The empty status for the read is set when a buffer is acquired                // for read, so we must ensure that it is reset here as a buffer                // is definitely now available for the specified reader                readPositions_[readerNumber].empty_ = false;//TRACE("$BRR Pending true, so restting empty flag\n");            }            else            {                // Determine whether the specified reader is the oldest and how                // many oldest readers there are

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?