Skip to content

Commit

Permalink
Optimization by t.sirgedas: Open MP4s faster. Attempt to read tables …
Browse files Browse the repository at this point in the history
…from disk in batches instead of 4 or 8 bytes at a time
  • Loading branch information
dchengTSC committed Apr 4, 2014
1 parent d70cecb commit cfe74b4
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 4 deletions.
91 changes: 87 additions & 4 deletions src/mp4property.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -744,14 +744,93 @@ bool MP4TableProperty::FindContainedProperty(const char *name,
return false;
}

struct FastRead32Attr
{
typedef uint32_t PropertyType;
typedef MP4Integer32Property MP4PropertyType;
static uint32_t ReverseBytes( const uint32_t& x ) { return MP4V2_BYTESWAP_32( x ); }
};

struct FastRead64Attr
{
typedef uint64_t PropertyType;
typedef MP4Integer64Property MP4PropertyType;
static uint64_t ReverseBytes( const uint64_t& x ) { return MP4V2_BYTESWAP_64( x ); }
};

template <class ATTR>
bool FastReadAttr( MP4File& file, MP4PropertyArray& properties, int32_t numEntries )
{
uint8_t buf[10000]; // use stack, since allocating on heap is slow

uint32_t numProperties = properties.Size();
uint32_t propertySize = sizeof( ATTR::PropertyType );
uint32_t entrySize = propertySize * numProperties;
int32_t numEntriesThatFitInBuffer = sizeof(buf) / entrySize;

ATTR::PropertyType* p = NULL;
for (int32_t i = 0; i < numEntries; i++)
{
if ( i % numEntriesThatFitInBuffer == 0 ) // refresh the buffer if necessary
{
int numEntriesLeft = numEntries - i;
int numEntriesToRead = numEntriesLeft < numEntriesThatFitInBuffer ? numEntriesLeft : numEntriesThatFitInBuffer;
file.ReadBytes( buf, numEntriesToRead * entrySize );
p = (ATTR::PropertyType*) buf;
}
for (uint32_t j = 0; j < numProperties; j++, p++)
{
((ATTR::MP4PropertyType*) properties[j])->SetValue( ATTR::ReverseBytes( *p ), i );
}
}
return true;
}

bool MP4TableProperty::FastRead(MP4File& file)
{
uint32_t numProperties = m_pProperties.Size();
if ( numProperties <= 0 )
return false;

MP4PropertyType propType = m_pProperties[0]->GetType();

// make sure all property types match
for (uint32_t j = 0; j < numProperties; j++)
if ( m_pProperties[j]->GetType() != propType )
return false;

// make sure no properties are implicit
for (uint32_t j = 0; j < numProperties; j++)
if ( m_pProperties[j]->IsImplicit() )
return false;

// make sure no properties are read-only
for (uint32_t j = 0; j < numProperties; j++)
if ( m_pProperties[j]->IsReadOnly() )
return false;

uint32_t numEntries = GetCount();

if ( propType == Integer32Property )
{
return FastReadAttr<FastRead32Attr>( file, m_pProperties, numEntries );
}
else if ( propType == Integer64Property )
{
return FastReadAttr<FastRead64Attr>( file, m_pProperties, numEntries );
}

return false;
}

void MP4TableProperty::Read(MP4File& file, uint32_t index)
{
ASSERT(index == 0);

if (m_implicit) {
return;
}

uint32_t numProperties = m_pProperties.Size();

if (numProperties == 0) {
Expand All @@ -765,9 +844,13 @@ void MP4TableProperty::Read(MP4File& file, uint32_t index)
for (uint32_t j = 0; j < numProperties; j++) {
m_pProperties[j]->SetCount(numEntries);
}

for (uint32_t i = 0; i < numEntries; i++) {
ReadEntry(file, i);

bool fastReadSucceeded = FastRead(file);
if ( !fastReadSucceeded )
{
for (uint32_t i = 0; i < numEntries; i++) {
ReadEntry(file, i);
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/mp4property.h
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,7 @@ class MP4TableProperty : public MP4Property {
m_pCountProperty->SetValue(count);
}


void Read(MP4File& file, uint32_t index = 0);
void Write(MP4File& file, uint32_t index = 0);
void Dump(uint8_t indent,
Expand All @@ -502,6 +503,8 @@ class MP4TableProperty : public MP4Property {
MP4Property** ppProperty, uint32_t* pIndex = NULL);

protected:
bool FastRead(MP4File& file);

virtual void ReadEntry(MP4File& file, uint32_t index);
virtual void WriteEntry(MP4File& file, uint32_t index);

Expand Down

0 comments on commit cfe74b4

Please sign in to comment.