Compare commits

..

6 Commits

Author SHA1 Message Date
matthewjheaney
093b78faf2 set version to 1.0.0.5
Change-Id: I3643a0019110b1ff7359a8d414bf0cd2ba9b5d54
2010-10-29 14:31:47 -04:00
matthewjheaney
ed90de0d52 check lacing bits
Change-Id: Iaa3a65429b7f3211868a86bbb83ce8018350554a
2010-10-29 14:04:43 -04:00
matthewjheaney
a01e568293 removed IsBFrame selector
Change-Id: Iae51165c318997a9131e9af5c667cfac1f37e773
2010-10-28 17:28:59 -04:00
matthewjheaney
d7ce23a019 handle empty clusters when seeking
Change-Id: I9bb39ff95e308639402e1c7f9aec59c81350d091
2010-10-28 14:45:27 -04:00
matthewjheaney
acf7ddb273 handle empty clusters
Change-Id: I57b085367e1b900acb0ddd6ee419e317f261718a
2010-10-27 16:47:14 -04:00
matthewjheaney
fc12207e15 handle case when no duration
Change-Id: I694f6ce6ae9ecc6fc3b90b954dd7041e82fb9ac0
2010-10-22 13:46:39 -04:00
2 changed files with 154 additions and 41 deletions

View File

@@ -10,6 +10,7 @@
#include <cassert>
#include <cstring>
#include <new>
#include <climits>
//#include <windows.h>
//#include "odbgstream.hpp"
//using std::endl;
@@ -24,7 +25,7 @@ void mkvparser::GetVersion(int& major, int& minor, int& build, int& revision)
major = 1;
minor = 0;
build = 0;
revision = 4;
revision = 5;
}
@@ -2033,6 +2034,50 @@ bool Cues::FindNext(
#endif
const CuePoint* Cues::GetFirst() const
{
LoadCuePoint(); //init cues
const size_t count = m_count + m_preload_count;
if (count == 0) //weird
return NULL;
CuePoint* const* const pp = m_cue_points;
assert(pp);
CuePoint* const pCP = pp[0];
assert(pCP);
assert(pCP->GetTimeCode() >= 0);
return pCP;
}
const CuePoint* Cues::GetLast() const
{
LoadCuePoint(); //init cues
const size_t count = m_count + m_preload_count;
if (count == 0) //weird
return NULL;
const size_t index = count - 1;
CuePoint* const* const pp = m_cue_points;
assert(pp);
CuePoint* const pCP = pp[index];
assert(pCP);
pCP->Load(m_pSegment->m_pReader);
assert(pCP->GetTimeCode() >= 0);
return pCP;
}
const CuePoint* Cues::GetNext(const CuePoint* pCurr) const
{
if (pCurr == NULL)
@@ -2304,8 +2349,8 @@ void CuePoint::TrackPosition::Parse(
}
assert(m_pos >= 0);
//assert(m_track > 0);
//assert(m_block > 0);
assert(m_track > 0);
assert(m_block > 0);
}
@@ -2672,11 +2717,21 @@ const BlockEntry* Segment::Seek(
assert(lo > i);
assert(lo <= j);
Cluster* const pCluster = *--lo;
assert(pCluster);
assert(pCluster->GetTime() <= time_ns);
while (lo > i)
{
Cluster* const pCluster = *--lo;
assert(pCluster);
assert(pCluster->GetTime() <= time_ns);
return pCluster->GetEntry(pTrack);
const BlockEntry* const pBE = pCluster->GetEntry(pTrack);
if ((pBE != 0) && !pBE->EOS())
return pBE;
//landed on empty cluster (no entries)
}
return pTrack->GetEOS(); //weird
}
assert(pTrack->GetType() == 1); //video
@@ -2717,17 +2772,16 @@ const BlockEntry* Segment::Seek(
{
const BlockEntry* const pBlockEntry = pCluster->GetEntry(pTrack);
assert(pBlockEntry);
if (!pBlockEntry->EOS()) //found a keyframe
if ((pBlockEntry != 0) && !pBlockEntry->EOS()) //found a keyframe
{
const Block* const pBlock = pBlockEntry->GetBlock();
assert(pBlock);
//TODO: this isn't necessarily the keyframe we want,
//NOTE: this isn't necessarily the keyframe we want,
//since there might another keyframe on this same
//cluster with a greater timecode that but that is
//still less than the requested time. For now we
//cluster with a greater timecode, that is still
//less than the requested time. For now we
//simply return the first keyframe we find.
if (pBlock->GetTime(pCluster) <= time_ns)
@@ -2744,9 +2798,8 @@ const BlockEntry* Segment::Seek(
assert(pCluster->GetTime() <= time_ns);
const BlockEntry* const pBlockEntry = pCluster->GetMaxKey(pVideo);
assert(pBlockEntry);
if (!pBlockEntry->EOS())
if ((pBlockEntry != 0) && !pBlockEntry->EOS())
return pBlockEntry;
}
@@ -2827,7 +2880,7 @@ SegmentInfo::SegmentInfo(Segment* pSegment, long long start, long long size_) :
const long long stop = start + size_;
m_timecodeScale = 1000000;
m_duration = 0;
m_duration = -1;
while (pos < stop)
{
@@ -2843,8 +2896,9 @@ SegmentInfo::SegmentInfo(Segment* pSegment, long long start, long long size_) :
else if (Match(pReader, pos, 0x1741, m_pWritingAppAsUTF8)) //[57][41]
assert(m_pWritingAppAsUTF8);
else if (Match(pReader, pos, 0x3BA9, m_pTitleAsUTF8)) //[7B][A9]
else if (Match(pReader, pos, 0x3BA9, m_pTitleAsUTF8)) //[7B][A9]
assert(m_pTitleAsUTF8);
else
{
long len;
@@ -2898,7 +2952,9 @@ long long SegmentInfo::GetTimeCodeScale() const
long long SegmentInfo::GetDuration() const
{
assert(m_duration >= 0);
if (m_duration < 0)
return -1;
assert(m_timecodeScale >= 1);
const double dd = double(m_duration) * double(m_timecodeScale);
@@ -2944,6 +3000,7 @@ Track::Info::Info():
codecPrivate(NULL),
codecPrivateSize(0),
codecNameAsUTF8(NULL)
//lacing(false)
{
}
@@ -3003,6 +3060,12 @@ const unsigned char* Track::GetCodecPrivate(size_t& size) const
}
bool Track::GetLacing() const
{
return m_info.lacing;
}
long Track::GetFirst(const BlockEntry*& pBlockEntry) const
{
Cluster* pCluster = m_pSegment->GetFirst();
@@ -3406,7 +3469,13 @@ Tracks::Tracks(Segment* pSegment, long long start, long long size_) :
//pos now desinates start of element
if (id == 0x2E) //TrackEntry ID
ParseTrackEntry(pos, size1, *m_trackEntriesEnd++);
{
Track*& pTrack = *m_trackEntriesEnd;
ParseTrackEntry(pos, size1, pTrack);
if (pTrack)
++m_trackEntriesEnd;
}
pos += size1; //consume payload
assert(pos <= stop);
@@ -3441,6 +3510,8 @@ void Tracks::ParseTrackEntry(
Track::Settings audioSettings;
audioSettings.start = -1;
long long lacing = 1; //default is true
while (pos < stop)
{
#ifdef _DEBUG
@@ -3459,6 +3530,8 @@ void Tracks::ParseTrackEntry(
assert(i.nameAsUTF8);
else if (Match(pReader, pos, 0x06, i.codecId))
;
else if (Match(pReader, pos, 0x1C, lacing))
assert(lacing <= 1);
else if (Match(pReader,
pos,
0x23A2,
@@ -3505,6 +3578,8 @@ void Tracks::ParseTrackEntry(
//and that it is unique among all tracks.
assert(i.number > 0);
i.lacing = (lacing > 0) ? true : false;
//TODO: vet settings, to ensure that video settings (0x60)
//were specified when type = 1, and that audio settings (0x61)
//were specified when type = 2.
@@ -3899,6 +3974,19 @@ long long Cluster::GetFirstTime()
}
long long Cluster::GetLastTime()
{
const BlockEntry* const pEntry = GetLast();
if (pEntry == NULL) //empty cluster
return GetTime();
const Block* const pBlock = pEntry->GetBlock();
assert(pBlock);
return pBlock->GetTime(this);
}
void Cluster::ParseBlockGroup(long long start, long long size, size_t index)
{
@@ -3931,11 +4019,12 @@ void Cluster::ParseSimpleBlock(long long start, long long size, size_t index)
const BlockEntry* Cluster::GetFirst()
{
//TODO: handle empty cluster
LoadBlockEntries();
assert(m_entries);
assert(m_entriesCount >= 1);
//assert(m_entries);
//assert(m_entriesCount >= 1);
if ((m_entries == NULL) || (m_entriesCount == 0))
return NULL;
const BlockEntry* const pFirst = m_entries[0];
assert(pFirst);
@@ -3946,11 +4035,12 @@ const BlockEntry* Cluster::GetFirst()
const BlockEntry* Cluster::GetLast()
{
//TODO: handle empty cluster
LoadBlockEntries();
assert(m_entries);
assert(m_entriesCount >= 1);
//assert(m_entries);
//assert(m_entriesCount >= 1);
if ((m_entries == NULL) || (m_entriesCount == 0))
return NULL;
const size_t idx = m_entriesCount - 1;
@@ -3989,6 +4079,9 @@ const BlockEntry* Cluster::GetEntry(const Track* pTrack)
LoadBlockEntries();
if ((m_entries == NULL) || (m_entriesCount == 0))
return NULL;
BlockEntry** i = m_entries;
assert(i);
@@ -4057,6 +4150,11 @@ Cluster::GetEntry(
while (i != j)
{
#ifdef _DEBUG
const ptrdiff_t idx = i - m_entries;
idx;
#endif
const BlockEntry* const pEntry = *i++;
assert(pEntry);
assert(!pEntry->EOS());
@@ -4110,7 +4208,7 @@ const BlockEntry* Cluster::GetMaxKey(const VideoTrack* pTrack)
return pTrack->GetEOS();
LoadBlockEntries();
assert(m_entries);
//assert(m_entries);
BlockEntry** i = m_entries + m_entriesCount;
BlockEntry** const j = m_entries;
@@ -4182,10 +4280,10 @@ const Block* SimpleBlock::GetBlock() const
}
bool SimpleBlock::IsBFrame() const
{
return false;
}
//bool SimpleBlock::IsBFrame() const
//{
// return false;
//}
BlockGroup::BlockGroup(
@@ -4321,10 +4419,10 @@ short BlockGroup::GetNextTimeCode() const
}
bool BlockGroup::IsBFrame() const
{
return (m_nextTimeCode > 0);
}
//bool BlockGroup::IsBFrame() const
//{
// return (m_nextTimeCode > 0);
//}
@@ -4352,14 +4450,21 @@ Block::Block(long long start, long long size_, IMkvReader* pReader) :
const long hr = pReader->Read(pos, 1, &m_flags);
assert(hr == 0L);
const int invisible = int(m_flags & 0x08);
invisible;
assert(!invisible);
const int lacing = int(m_flags & 0x06);
lacing;
assert(!lacing);
++pos;
assert(pos <= stop);
m_frameOff = pos;
const long long frame_size = stop - pos;
assert(frame_size <= 2147483647L);
assert(frame_size <= LONG_MAX);
m_frameSize = static_cast<long>(frame_size);
}

View File

@@ -105,7 +105,7 @@ public:
virtual Cluster* GetCluster() const = 0;
virtual size_t GetIndex() const = 0;
virtual const Block* GetBlock() const = 0;
virtual bool IsBFrame() const = 0;
//virtual bool IsBFrame() const = 0;
protected:
BlockEntry();
@@ -125,7 +125,7 @@ public:
Cluster* GetCluster() const;
size_t GetIndex() const;
const Block* GetBlock() const;
bool IsBFrame() const;
//bool IsBFrame() const;
protected:
Cluster* const m_pCluster;
@@ -148,7 +148,7 @@ public:
Cluster* GetCluster() const;
size_t GetIndex() const;
const Block* GetBlock() const;
bool IsBFrame() const;
//bool IsBFrame() const;
short GetPrevTimeCode() const; //relative to block's time
short GetNextTimeCode() const; //as above
@@ -192,6 +192,7 @@ public:
const char* GetCodecNameAsUTF8() const;
const char* GetCodecId() const;
const unsigned char* GetCodecPrivate(size_t&) const;
bool GetLacing() const;
const BlockEntry* GetEOS() const;
@@ -211,7 +212,9 @@ public:
unsigned char* codecPrivate;
size_t codecPrivateSize;
char* codecNameAsUTF8;
bool lacing;
Settings settings;
Info();
void Clear();
};
@@ -403,6 +406,9 @@ public:
const CuePoint::TrackPosition*&) const;
#endif
const CuePoint* GetFirst() const;
const CuePoint* GetLast() const;
const CuePoint* GetNext(const CuePoint*) const;
const BlockEntry* GetBlock(
@@ -429,7 +435,6 @@ class Cluster
public:
Segment* const m_pSegment;
long m_index;
public:
static Cluster* Parse(Segment*, long, long long off);
@@ -442,6 +447,7 @@ public:
long long GetTimeCode(); //absolute, but not scaled
long long GetTime(); //absolute, and scaled (nanosecond units)
long long GetFirstTime(); //time (ns) of first (earliest) block
long long GetLastTime(); //time (ns) of last (latest) block
const BlockEntry* GetFirst();
const BlockEntry* GetLast();
@@ -456,6 +462,8 @@ protected:
Cluster(Segment*, long, long long off);
public:
//TODO: these should all be private, with public selector functions
long m_index;
long long m_pos;
long long m_size;