Show
Ignore:
Timestamp:
03/30/07 01:44:02 (1 year ago)
Author:
dconrad
Message:

Use simple buffered read for Matroska. 20-30% faster import.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/DataHandlerCallback.cpp

    r322 r395  
    4343} 
    4444 
     45 
     46DataHBuffer::DataHBuffer(size_t bufferSize) 
     47{ 
     48        buffer = new uint8_t[bufferSize]; 
     49        allocatedSize = bufferSize; 
     50        fileOffset = -1; 
     51        dataSize = 0; 
     52} 
     53 
     54DataHBuffer::~DataHBuffer() 
     55{ 
     56        if (buffer) 
     57                delete[] buffer; 
     58} 
     59 
     60void DataHBuffer::Realloc(size_t bufferSize) 
     61{ 
     62        if (buffer) 
     63                delete[] buffer; 
     64         
     65        buffer = new uint8_t[bufferSize]; 
     66        allocatedSize = bufferSize; 
     67        fileOffset = -1; 
     68        dataSize = 0; 
     69} 
     70 
     71bool DataHBuffer::ContainsOffset(uint64_t offset) 
     72{ 
     73        return offset >= fileOffset && offset < fileOffset + dataSize; 
     74} 
     75 
     76uint8_t * DataHBuffer::GetBuffer(uint64_t offset, size_t size) 
     77{ 
     78        if (size > allocatedSize) 
     79                Realloc(size); 
     80         
     81        fileOffset = offset; 
     82        dataSize = size; 
     83        return buffer; 
     84} 
     85 
     86size_t DataHBuffer::Read(uint64_t offset, size_t size, uint8_t *store) 
     87{ 
     88        if (!ContainsOffset(offset)) 
     89                return 0; 
     90         
     91        uint8_t *dataStart = buffer + (offset - fileOffset); 
     92        size_t amountToRead = MIN(fileOffset + dataSize - offset, size); 
     93        memcpy(store, dataStart, amountToRead); 
     94        return amountToRead; 
     95} 
     96 
     97 
    4598DataHandlerCallback::DataHandlerCallback(ComponentInstance dataHandler, const open_mode aMode) 
    4699{        
    47         closeHandler = false; 
    48         supportsWideOffsets = true; 
    49         this->dataHandler = NULL; 
    50         mCurrentPosition = 0; 
    51         filesize = 0; 
    52         this->aMode = aMode; 
     100        Initialize(aMode); 
    53101         
    54102        switch (aMode) 
     
    71119{ 
    72120    ComponentResult err = noErr; 
    73     Component dataHComponent = NULL; 
    74          
    75         closeHandler = true; 
    76         supportsWideOffsets = true; 
    77         dataHComponent = NULL; 
    78         mCurrentPosition = 0; 
    79         filesize = 0; 
    80         this->aMode = aMode; 
     121        Component dataHComponent = NULL; 
     122         
     123        Initialize(aMode); 
    81124         
    82125        if (aMode == MODE_READ) 
     
    111154        } 
    112155         
     156        closeHandler = true; 
     157         
    113158        // figure out if we support wide offesets 
    114159        getFileSize(); 
    115160} 
    116161 
     162void DataHandlerCallback::Initialize(const open_mode aMode) 
     163{ 
     164        closeHandler = false; 
     165        supportsWideOffsets = true; 
     166        this->dataHandler = NULL; 
     167        mCurrentPosition = 0; 
     168        filesize = 0; 
     169        this->aMode = aMode; 
     170} 
    117171 
    118172DataHandlerCallback::~DataHandlerCallback() throw() 
     
    121175} 
    122176 
    123  
    124  
    125 uint32 DataHandlerCallback::read(void *Buffer, size_t Size) 
     177uint32 DataHandlerCallback::read(void *buffer, size_t size) 
    126178{ 
    127179        ComponentResult err = noErr; 
    128          
    129     if (Size < 1 || mCurrentPosition > filesize) 
     180        size_t amountRead = 0; 
     181        uint64_t oldPos = mCurrentPosition; 
     182        uint8_t *internalBuffer, *myBuffer = (uint8_t *)buffer; 
     183         
     184    if (size < 1 || mCurrentPosition > filesize) 
    130185        return 0; 
    131186         
    132         if (mCurrentPosition + Size > filesize) 
    133                 Size = filesize - mCurrentPosition; 
    134          
    135         if (supportsWideOffsets) { 
    136                 wide wideOffset = SInt64ToWide(mCurrentPosition); 
    137                  
    138                 err = DataHScheduleData64(dataHandler, (Ptr)Buffer, &wideOffset, Size, 0, NULL, NULL); 
    139         } else { 
    140                 err = DataHScheduleData(dataHandler, (Ptr)Buffer, mCurrentPosition, Size, 0, NULL, NULL); 
    141         } 
    142          
    143         if (err) { 
    144                 throw CRTError("Error reading data", err); 
    145         } 
    146         mCurrentPosition += Size; 
    147          
    148         // does QuickTime tell us how much it's read? 
    149         return Size; 
    150 
    151  
    152 void DataHandlerCallback::setFilePointer(int64 Offset, LIBEBML_NAMESPACE::seek_mode Mode) 
     187        if (mCurrentPosition + size > filesize) 
     188                size = filesize - mCurrentPosition; 
     189         
     190        while (size > 0) { 
     191                if (dataBuffer.ContainsOffset(mCurrentPosition)) { 
     192                        amountRead = dataBuffer.Read(mCurrentPosition, size, myBuffer); 
     193                        myBuffer += amountRead; 
     194                        mCurrentPosition += amountRead; 
     195                        size -= amountRead; 
     196                } 
     197                 
     198                if (size <= 0) 
     199                        break; 
     200                 
     201                internalBuffer = dataBuffer.GetBuffer(mCurrentPosition, READ_SIZE); 
     202                 
     203                if (supportsWideOffsets) { 
     204                        wide wideOffset = SInt64ToWide(mCurrentPosition); 
     205                         
     206                        err = DataHScheduleData64(dataHandler, (Ptr)internalBuffer, &wideOffset,  
     207                                                                          READ_SIZE, 0, NULL, NULL); 
     208                } else { 
     209                        err = DataHScheduleData(dataHandler, (Ptr)internalBuffer, mCurrentPosition,  
     210                                                                        READ_SIZE, 0, NULL, NULL); 
     211                } 
     212         
     213                if (err) { 
     214                        throw CRTError("Error reading data", err); 
     215                } 
     216        } 
     217         
     218        return mCurrentPosition - oldPos; 
     219
     220 
     221void DataHandlerCallback::setFilePointer(int64 Offset, seek_mode Mode) 
    153222{ 
    154223        switch ( Mode )