Compare commits

..

9 Commits

Author SHA1 Message Date
matthewjheaney
a977a2b536 libwebm: changed version to 1.0.0.15
Change-Id: I70c6b22d75defcb11fecbbcd8763659cca7f77e0
2011-01-28 16:56:27 -05:00
matthewjheaney
5e72a2dfc2 libwebm: changed signature of CuePoint::GetTime
Change-Id: Ia80da8af5607c7067e848bafd453842cfe8cfcca
2011-01-28 00:52:13 -05:00
matthewjheaney
056b0d96a8 libwebm: changed version to 1.0.0.14
Change-Id: Id8147672e7fb761b2a69ff0d1ec05705e34eefc1
2011-01-26 19:08:43 -05:00
matthewjheaney
dbc58d0510 libwebm: make unserialize operations endian-neutral
Change-Id: I0c754ea8192020886dac14e3a0bd6a74c3165a92
2011-01-26 18:50:07 -05:00
matthewjheaney
a131a01446 libwebm: incrementally load block entries
Change-Id: I566df5979e7638b6a5411a3338bbb0cf7d9ad111
2011-01-25 23:01:51 -05:00
Hwasoo Lee
b8cb358204 fixed build error in sample
Change-Id: Id6ac66f5e625952918857c3e13e655452c32abc8
2011-01-25 11:31:20 -05:00
matthewjheaney
5b06b22b31 libwebm: removed warning in x64 mode
Change-Id: I391ad625babdede58c8025b332ee2c949e930454
2011-01-24 22:45:10 -05:00
matthewjheaney
598de03ef3 libwebm: version 1.0.0.13
Change-Id: I6417dfd731604461939a780d0fb411b888ae1d32
2011-01-24 22:40:19 -05:00
matthewjheaney
94f2d589fc libwebm: tolerate errors in SeekHead element
Change-Id: I380f43dd495dc5107f5df37f9d05ff67da4f8424
2011-01-24 20:50:12 -05:00
3 changed files with 205 additions and 53 deletions

View File

@@ -21,7 +21,7 @@ void mkvparser::GetVersion(int& major, int& minor, int& build, int& revision)
major = 1; major = 1;
minor = 0; minor = 0;
build = 0; build = 0;
revision = 12; revision = 15;
} }
long long mkvparser::ReadUInt(IMkvReader* pReader, long long pos, long& len) long long mkvparser::ReadUInt(IMkvReader* pReader, long long pos, long& len)
@@ -228,13 +228,16 @@ float mkvparser::Unserialize4Float(
assert(pReader); assert(pReader);
assert(pos >= 0); assert(pos >= 0);
#ifdef _DEBUG
long long total, available; long long total, available;
long hr = pReader->Length(&total, &available); long hr = pReader->Length(&total, &available);
assert(hr >= 0); assert(hr >= 0);
assert(available <= total); assert(available <= total);
assert((pos + 4) <= available); assert((pos + 4) <= available);
#endif
#if 0
float result; float result;
unsigned char* const p = (unsigned char*)&result; unsigned char* const p = (unsigned char*)&result;
@@ -250,6 +253,32 @@ float mkvparser::Unserialize4Float(
++pos; ++pos;
} }
#else
union
{
float result;
unsigned long buf;
};
buf = 0;
for (int i = 0;;)
{
unsigned char b;
const int status = pReader->Read(pos++, 1, &b);
if (status < 0) //error
return static_cast<float>(status);
buf |= b;
if (++i >= 4)
break;
buf <<= 8;
}
#endif
return result; return result;
} }
@@ -262,6 +291,7 @@ double mkvparser::Unserialize8Double(
assert(pReader); assert(pReader);
assert(pos >= 0); assert(pos >= 0);
#if 0
double result; double result;
unsigned char* const p = (unsigned char*)&result; unsigned char* const p = (unsigned char*)&result;
@@ -277,6 +307,32 @@ double mkvparser::Unserialize8Double(
++pos; ++pos;
} }
#else
union
{
double result;
long long buf;
};
buf = 0;
for (int i = 0;;)
{
unsigned char b;
const int status = pReader->Read(pos++, 1, &b);
if (status < 0) //error
return static_cast<double>(status);
buf |= b;
if (++i >= 8)
break;
buf <<= 8;
}
#endif
return result; return result;
} }
@@ -288,17 +344,20 @@ signed char mkvparser::Unserialize1SInt(
assert(pReader); assert(pReader);
assert(pos >= 0); assert(pos >= 0);
#ifdef _DEBUG
long long total, available; long long total, available;
long hr = pReader->Length(&total, &available); long hr = pReader->Length(&total, &available);
assert(hr == 0); assert(hr == 0);
assert(available <= total); assert(available <= total);
assert(pos < available); assert(pos < available);
#endif
signed char result; signed char result;
unsigned char& b = reinterpret_cast<unsigned char&>(result);
hr = pReader->Read(pos, 1, (unsigned char*)&result); const int status = pReader->Read(pos, 1, &b);
assert(hr == 0); assert(status == 0); //TODO: must be handled somehow
return result; return result;
} }
@@ -310,13 +369,16 @@ short mkvparser::Unserialize2SInt(
assert(pReader); assert(pReader);
assert(pos >= 0); assert(pos >= 0);
#ifdef _DEBUG
long long total, available; long long total, available;
long hr = pReader->Length(&total, &available); long hr = pReader->Length(&total, &available);
assert(hr >= 0); assert(hr >= 0);
assert(available <= total); assert(available <= total);
assert((pos + 2) <= available); assert((pos + 2) <= available);
#endif
#if 0
short result; short result;
unsigned char* const p = (unsigned char*)&result; unsigned char* const p = (unsigned char*)&result;
@@ -332,6 +394,24 @@ short mkvparser::Unserialize2SInt(
++pos; ++pos;
} }
#else
short result = 0;
for (int i = 0;;)
{
unsigned char b;
const int status = pReader->Read(pos++, 1, &b);
assert(status == 0); //TODO: must be handled somehow
result |= b;
if (++i >= 2)
break;
result <<= 8;
}
#endif
return result; return result;
} }
@@ -1308,7 +1388,7 @@ long Segment::LoadCluster(
{ {
long long total, avail; long long total, avail;
const int status = m_pReader->Length(&total, &avail); long status = m_pReader->Length(&total, &avail);
if (status < 0) //error if (status < 0) //error
return status; return status;
@@ -1450,11 +1530,12 @@ long Segment::LoadCluster(
++m_clusterCount; ++m_clusterCount;
--m_clusterPreloadCount; --m_clusterPreloadCount;
pCluster->Load(); //establish invariant
m_pos = pos + size; //consume payload m_pos = pos + size; //consume payload
assert(m_pos <= stop); assert(m_pos <= stop);
status = pCluster->LoadBlockEntries(pos, len);
assert(status == 0); //TODO
return 0; //we have a new cluster return 0; //we have a new cluster
} }
} }
@@ -1476,7 +1557,8 @@ long Segment::LoadCluster(
assert(idx < m_clusterSize); assert(idx < m_clusterSize);
assert(m_clusters[idx] == pCluster); assert(m_clusters[idx] == pCluster);
pCluster->Load(); //establish invariant status = pCluster->LoadBlockEntries(pos, len);
assert(status == 0); //TODO
return 0; //we have a new cluster return 0; //we have a new cluster
} }
@@ -1824,6 +1906,8 @@ SeekHead::SeekHead(
//first count the seek head entries //first count the seek head entries
int count = 0;
while (pos < stop) while (pos < stop)
{ {
long len; long len;
@@ -1842,7 +1926,7 @@ SeekHead::SeekHead(
assert((pos + size) <= stop); assert((pos + size) <= stop);
if (id == 0x0DBB) //SeekEntry ID if (id == 0x0DBB) //SeekEntry ID
++m_count; ++count;
pos += size; //consume payload pos += size; //consume payload
assert(pos <= stop); assert(pos <= stop);
@@ -1850,10 +1934,10 @@ SeekHead::SeekHead(
assert(pos == stop); assert(pos == stop);
if (m_count <= 0) if (count <= 0)
return; //nothing else for us to do return; //nothing else for us to do
m_entries = new (std::nothrow) Entry[m_count]; m_entries = new (std::nothrow) Entry[count];
assert(m_entries); //TODO assert(m_entries); //TODO
//now parse the entries //now parse the entries
@@ -1879,14 +1963,19 @@ SeekHead::SeekHead(
assert((pos + size) <= stop); assert((pos + size) <= stop);
if (id == 0x0DBB) //SeekEntry ID if (id == 0x0DBB) //SeekEntry ID
ParseEntry(pReader, pos, size, pEntry++); ParseEntry(pReader, pos, size, pEntry);
pos += size; //consume payload pos += size; //consume payload
assert(pos <= stop); assert(pos <= stop);
} }
assert(pos == stop); assert(pos == stop);
assert(ptrdiff_t(pEntry - m_entries) == m_count);
const ptrdiff_t count_ = ptrdiff_t(pEntry - m_entries);
assert(count_ >= 0);
assert(count_ <= count);
m_count = static_cast<int>(count_);
} }
SeekHead::~SeekHead() SeekHead::~SeekHead()
@@ -2153,7 +2242,7 @@ void SeekHead::ParseEntry(
IMkvReader* pReader, IMkvReader* pReader,
long long start, long long start,
long long size_, long long size_,
Entry* pEntry) Entry*& pEntry)
{ {
long long pos = start; long long pos = start;
const long long stop = start + size_; const long long stop = start + size_;
@@ -2164,16 +2253,27 @@ void SeekHead::ParseEntry(
const long long seekIdId = ReadUInt(pReader, pos, len); const long long seekIdId = ReadUInt(pReader, pos, len);
//seekIdId; //seekIdId;
assert(seekIdId == 0x13AB); //SeekID ID
assert((pos + len) <= stop);
pos += len; //consume id if (seekIdId != 0x13AB) //SeekID ID
return;
if ((pos + len) > stop)
return;
pos += len; //consume SeekID id
const long long seekIdSize = ReadUInt(pReader, pos, len); const long long seekIdSize = ReadUInt(pReader, pos, len);
assert(seekIdSize >= 0);
assert((pos + len) <= stop);
pos += len; //consume size if (seekIdSize <= 0)
return;
if ((pos + len) > stop)
return;
pos += len; //consume size of field
if ((pos + seekIdSize) > stop)
return;
//TODO: it's not clear whether this is correct //TODO: it's not clear whether this is correct
//It seems as if the payload here is "binary" which //It seems as if the payload here is "binary" which
@@ -2181,31 +2281,49 @@ void SeekHead::ParseEntry(
//not parsed as an uint. //not parsed as an uint.
// //
pEntry->id = ReadUInt(pReader, pos, len); //payload pEntry->id = ReadUInt(pReader, pos, len); //payload
assert(pEntry->id >= 0);
assert(len == seekIdSize);
assert((pos + len) <= stop);
pos += seekIdSize; //consume payload if (pEntry->id <= 0)
return;
if (len != seekIdSize)
return;
pos += seekIdSize; //consume SeekID payload
const long long seekPosId = ReadUInt(pReader, pos, len); const long long seekPosId = ReadUInt(pReader, pos, len);
//seekPosId;
assert(seekPosId == 0x13AC); //SeekPos ID if (seekPosId != 0x13AC) //SeekPos ID
assert((pos + len) <= stop); return;
if ((pos + len) > stop)
return;
pos += len; //consume id pos += len; //consume id
const long long seekPosSize = ReadUInt(pReader, pos, len); const long long seekPosSize = ReadUInt(pReader, pos, len);
assert(seekPosSize >= 0);
assert((pos + len) <= stop); if (seekPosSize <= 0)
return;
if ((pos + len) > stop)
return;
pos += len; //consume size pos += len; //consume size
assert((pos + seekPosSize) <= stop);
if ((pos + seekPosSize) > stop)
return;
pEntry->pos = UnserializeUInt(pReader, pos, seekPosSize); pEntry->pos = UnserializeUInt(pReader, pos, seekPosSize);
assert(pEntry->pos >= 0);
if (pEntry->pos < 0)
return;
pos += seekPosSize; //consume payload pos += seekPosSize; //consume payload
assert(pos == stop);
if (pos != stop)
return;
++pEntry; //success
} }
#endif #endif
@@ -2952,7 +3070,7 @@ long long CuePoint::GetTimeCode() const
return m_timecode; return m_timecode;
} }
long long CuePoint::GetTime(Segment* pSegment) const long long CuePoint::GetTime(const Segment* pSegment) const
{ {
assert(pSegment); assert(pSegment);
assert(m_timecode >= 0); assert(m_timecode >= 0);
@@ -3225,7 +3343,7 @@ long Segment::ParseNext(
long long total, avail; long long total, avail;
const int status = m_pReader->Length(&total, &avail); long status = m_pReader->Length(&total, &avail);
if (status < 0) //error if (status < 0) //error
return status; return status;
@@ -3437,10 +3555,8 @@ long Segment::ParseNext(
len = static_cast<long>(size); len = static_cast<long>(size);
#if 1 //TODO: get rid of this
if (element_stop > avail) if (element_stop > avail)
return E_BUFFER_NOT_FULL; return E_BUFFER_NOT_FULL;
#endif
if (Cluster::HasBlockEntries(this, idoff)) //relative if (Cluster::HasBlockEntries(this, idoff)) //relative
{ {
@@ -3491,6 +3607,9 @@ long Segment::ParseNext(
j = k; j = k;
else else
{ {
status = pNext->LoadBlockEntries(pos, len);
assert(status == 0);
pResult = pNext; pResult = pNext;
return 0; //success return 0; //success
} }
@@ -3512,7 +3631,8 @@ long Segment::ParseNext(
assert(idx_next < m_clusterSize); assert(idx_next < m_clusterSize);
assert(m_clusters[idx_next] == pNext); assert(m_clusters[idx_next] == pNext);
pNext->Load(); //because we need this now status = pNext->LoadBlockEntries(pos, len);
assert(status == 0); //TODO
pResult = pNext; pResult = pNext;
return 0; //success return 0; //success
@@ -4930,23 +5050,24 @@ void Cluster::Load() const
} }
long Cluster::Load(long long& pos, long& len) const long Cluster::LoadBlockEntries(long long& pos, long& len) const
{ {
assert(m_pSegment); assert(m_pSegment);
assert(m_pos); assert(m_pos);
assert(m_size); assert(m_size);
if (m_pos > 0) //loaded //if (m_pos > 0) //loaded
{ //{
assert(m_size > 0); // assert(m_size > 0);
assert(m_timecode >= 0); // assert(m_timecode >= 0);
// assert(m_entries_count >= 0);
return 0; //
} // return 0;
//}
assert(m_pos < 0); //not loaded yet //
assert(m_size < 0); //assert(m_pos < 0); //not loaded yet
assert(m_timecode < 0); //assert(m_size < 0);
//assert(m_timecode < 0);
IMkvReader* const pReader = m_pSegment->m_pReader; IMkvReader* const pReader = m_pSegment->m_pReader;
@@ -4962,6 +5083,28 @@ long Cluster::Load(long long& pos, long& len) const
const long long segment_stop = m_pSegment->m_start + m_pSegment->m_size; const long long segment_stop = m_pSegment->m_start + m_pSegment->m_size;
if (m_pos > 0) //at least partially loaded
{
assert(m_size > 0);
if (m_entries_count >= 0)
return 0;
pos = m_pSegment->m_start + m_pos; //absolute pos of payload
const long long cluster_stop = pos + m_size;
len = static_cast<long>(m_size);
if (cluster_stop > avail)
return E_BUFFER_NOT_FULL;
LoadBlockEntries(); //TODO
assert(m_entries_count >= 0);
return 0;
}
//m_pos *= -1; //relative to segment //m_pos *= -1; //relative to segment
pos = m_pSegment->m_start - m_pos; //absolute pos = m_pSegment->m_start - m_pos; //absolute
@@ -5115,6 +5258,8 @@ long Cluster::Load(long long& pos, long& len) const
m_size = size_; // m_size > 0 means we're partially loaded m_size = size_; // m_size > 0 means we're partially loaded
m_timecode = timecode; // m_timecode >= 0 means we're partially loaded m_timecode = timecode; // m_timecode >= 0 means we're partially loaded
LoadBlockEntries(); //TODO
return 0; return 0;
} }
@@ -5528,6 +5673,12 @@ const BlockEntry* Cluster::GetNext(const BlockEntry* pEntry) const
} }
long Cluster::GetEntryCount() const
{
return m_entries_count;
}
const BlockEntry* Cluster::GetEntry( const BlockEntry* Cluster::GetEntry(
const Track* pTrack, const Track* pTrack,
long long time_ns) const long long time_ns) const

View File

@@ -427,7 +427,7 @@ private:
IMkvReader*, IMkvReader*,
long long pos, long long pos,
long long size, long long size,
Entry*); Entry*&);
}; };
@@ -449,7 +449,7 @@ public:
void Load(IMkvReader*); void Load(IMkvReader*);
long long GetTimeCode() const; //absolute but unscaled long long GetTimeCode() const; //absolute but unscaled
long long GetTime(Segment*) const; //absolute and scaled (ns units) long long GetTime(const Segment*) const; //absolute and scaled (ns units)
struct TrackPosition struct TrackPosition
{ {
@@ -568,9 +568,11 @@ public:
const BlockEntry* GetMaxKey(const VideoTrack*) const; const BlockEntry* GetMaxKey(const VideoTrack*) const;
static bool HasBlockEntries(const Segment*, long long); static bool HasBlockEntries(const Segment*, long long);
long GetEntryCount() const;
void Load() const; void Load() const;
long Load(long long& pos, long& size) const; void LoadBlockEntries() const;
long LoadBlockEntries(long long& pos, long& size) const;
protected: protected:
Cluster( Cluster(
@@ -593,7 +595,6 @@ private:
mutable BlockEntry** m_entries; mutable BlockEntry** m_entries;
mutable long m_entries_count; mutable long m_entries_count;
void LoadBlockEntries() const;
void ParseBlockGroup(long long, long long, size_t) const; void ParseBlockGroup(long long, long long, size_t) const;
void ParseSimpleBlock(long long, long long, size_t) const; void ParseSimpleBlock(long long, long long, size_t) const;

View File

@@ -142,7 +142,7 @@ int main(int argc, char* argv[])
// size of segment payload // size of segment payload
printf("\t\tSize(Segment)\t\t: %lld\n", pSegment->m_size); printf("\t\tSize(Segment)\t\t: %lld\n", pSegment->m_size);
mkvparser::Tracks* const pTracks = pSegment->GetTracks(); const mkvparser::Tracks* pTracks = pSegment->GetTracks();
unsigned long i = 0; unsigned long i = 0;
const unsigned long j = pTracks->GetTracksCount(); const unsigned long j = pTracks->GetTracksCount();