📄 buffer.h
字号:
//// Copyright (c) 2003 by Istv醤 V醨adi//// This file is part of dxr3Player, a DVD player written specifically // for the DXR3 (aka Hollywood+) decoder card.// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program 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 General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA#ifndef DXR3PLAYER_DVD_READER_BUFFER_H#define DXR3PLAYER_DVD_READER_BUFFER_H//------------------------------------------------------------------------------#include "dvd/demux/Sector.h"#include "dvd/packet/Packet.h"#include "dvd/packet/PacketQueue.h"#include "dvd/Statistics.h"#include "sched/WaitCondition.h"#include "util/Reference.h"#include "util/DefaultAllocator.h"#include <cstdlib>//------------------------------------------------------------------------------namespace dvd { namespace packet {class PacketQueue;} }//------------------------------------------------------------------------------namespace dvd { namespace reader {//------------------------------------------------------------------------------class Control;class SectorProxy;//------------------------------------------------------------------------------/** * Buffer for data read from the DVD. It has a fixed size and is * filled circularly. */class Buffer{private: /** * Type for the sector descriptor structure. */ class SectorDescriptor { private: /** * The possible states for a sector. */ typedef enum state_t { /// Unallocated FREE, /// Being read READING, /// Being processed PROCESSING }; /** * The state of the sector. */ state_t state; /** * The number of references. */ size_t referenceCount; public: /** * Construct the sector descriptor */ SectorDescriptor(); /** * Destruct the sector descriptor */ ~SectorDescriptor(); /** * Check if the sector is free */ bool isFree() const; /** * Mark the sector for reading. */ void markForReading(); /** * Discard the sector after data has been read into it. */ void discardRead(); /** * Mark the sector for processing. Returns and clears the list * of packets to be sent after the sector. */ void markForProcessing(); /** * Add a reference. */ void addReference(); /** * Remove a reference. * * @return fi all references have been removed */ bool removeReference(); }; /** * The size of the buffer. */ size_t size; /** * The sectors. */ dvd::demux::Sector* sectors; /** * The sector descriptors */ SectorDescriptor* sectorDescriptors; /** * The sector proxies. */ SectorProxy* sectorProxies; /** * The index of the first free sector (i.e. the sector after the * last one being read or used). */ size_t firstFreeSector; /** * The number of free consecutive sectors after the last non-free one. */ size_t numFreeSectors; /** * The number of the sectors requested for reading. If 0, no * sector request is pending */ size_t numRequestedSectors; /** * Wait condition which is fulfilled when the requested sectors * are available. */ sched::WaitCondition sectorsAvailable;public: /** * Construct the buffer. */ Buffer(); /** * Destruct the buffer. */ ~Buffer(); /** * Get the # of the first free sector. */ size_t getFirstFreeSector() const; /** * Get the # of the free sectors. */ size_t getNumFreeSectors() const; /** * Get the sector with the given index. */ const dvd::demux::Sector& getSector(size_t index) const; /** * Request the given number of sectors for reading. */ dvd::demux::Sector* requestForReading(size_t& numSectors); /** * Discard the sectors starting with the given one after they have * been read (they should not have been made available for * processing). The sectors should just precede the first free sector! */ void discardRead(dvd::demux::Sector* sectors, size_t numSectors = 1); /** * Enqueue one or more read sectors into the given queue. */ void makeAvailable(dvd::packet::PacketQueue& queue, dvd::demux::Sector* sectors, size_t numSectors = 1);private: /** * Get the index of the given sector. */ size_t getIndexOf(const dvd::demux::Sector* sector) const; /** * Check if we have the requested number of sectors, and if so, * set their state and call back thr controller. */ void checkRequest(); /** * Check for free sectors starting from the end of the free sector * block. */ void checkFreeSectors(); /** * Mark the first n free sectors for reading. * * @return the first free sector's address */ dvd::demux::Sector* markForReading(size_t n); /** * Add a reference to the sector with the given index. */ void addReference(size_t index); /** * Remove a reference from the sector with the given index. */ void removeReference(size_t index); friend class SectorProxy; friend class ReaderSectorReference;};//------------------------------------------------------------------------------// Inline definitions//------------------------------------------------------------------------------inline Buffer::SectorDescriptor::SectorDescriptor() : state(FREE), referenceCount(0){ ++Statistics::get().numFreeSectors;}//------------------------------------------------------------------------------inline Buffer::SectorDescriptor::~SectorDescriptor(){ assert(referenceCount==0); assert(state==FREE); --Statistics::get().numFreeSectors;}//------------------------------------------------------------------------------inline size_t Buffer::getFirstFreeSector() const{ return firstFreeSector;}//------------------------------------------------------------------------------inline size_t Buffer::getNumFreeSectors() const{ return numFreeSectors;}//------------------------------------------------------------------------------inline bool Buffer::SectorDescriptor::isFree() const{ return state==FREE;}//------------------------------------------------------------------------------inline void Buffer::SectorDescriptor::markForReading(){ assert(state==FREE); assert(referenceCount==0); Statistics::sectorFree2Reading(); state = READING;}//------------------------------------------------------------------------------inline void Buffer::SectorDescriptor::discardRead(){ assert(state==READING); assert(referenceCount==0); Statistics::sectorReading2Free(); state = FREE;}//------------------------------------------------------------------------------inline void Buffer::SectorDescriptor::markForProcessing(){ assert(state==READING); assert(referenceCount==0); Statistics::sectorReading2Processing(); state = PROCESSING;}//------------------------------------------------------------------------------inline void Buffer::SectorDescriptor::addReference(){ assert(state==PROCESSING); ++referenceCount;}//------------------------------------------------------------------------------inline bool Buffer::SectorDescriptor::removeReference(){ assert(state==PROCESSING); assert(referenceCount>0); --referenceCount; if (referenceCount==0) { Statistics::sectorProcessing2Free(); state = FREE; } return referenceCount==0;}//------------------------------------------------------------------------------//------------------------------------------------------------------------------inline const dvd::demux::Sector& Buffer::getSector(size_t index) const{ assert(index<size); return sectors[index];}//------------------------------------------------------------------------------inline size_t Buffer::getIndexOf(const dvd::demux::Sector* sector) const{ size_t index = sector - sectors; assert(index<size); return index;}//------------------------------------------------------------------------------} /* namespace dvd::reader */ } /* namespace dvd *///------------------------------------------------------------------------------#endif // DXR3PLAYER_DVD_READER_BUFFER_H// Local variables:// mode: c++// End:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -