mkvparser: Add support for CodecDelay, DiscardPadding, and SeekPreRoll elements.
Change-Id: Ic9e6ebcc2ba533f8cc1ab933d0bf55782ccab932
This commit is contained in:
parent
d2f7478148
commit
81c1d8415c
@ -5517,7 +5517,9 @@ Track::Info::Info():
|
|||||||
codecId(NULL),
|
codecId(NULL),
|
||||||
codecNameAsUTF8(NULL),
|
codecNameAsUTF8(NULL),
|
||||||
codecPrivate(NULL),
|
codecPrivate(NULL),
|
||||||
codecPrivateSize(0)
|
codecPrivateSize(0),
|
||||||
|
codecDelay(0),
|
||||||
|
seekPreRoll(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5581,6 +5583,8 @@ int Track::Info::Copy(Info& dst) const
|
|||||||
dst.type = type;
|
dst.type = type;
|
||||||
dst.number = number;
|
dst.number = number;
|
||||||
dst.defaultDuration = defaultDuration;
|
dst.defaultDuration = defaultDuration;
|
||||||
|
dst.codecDelay = codecDelay;
|
||||||
|
dst.seekPreRoll = seekPreRoll;
|
||||||
dst.uid = uid;
|
dst.uid = uid;
|
||||||
dst.lacing = lacing;
|
dst.lacing = lacing;
|
||||||
dst.settings = settings;
|
dst.settings = settings;
|
||||||
@ -5684,6 +5688,16 @@ unsigned long long Track::GetDefaultDuration() const
|
|||||||
return m_info.defaultDuration;
|
return m_info.defaultDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned long long Track::GetCodecDelay() const
|
||||||
|
{
|
||||||
|
return m_info.codecDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long Track::GetSeekPreRoll() const
|
||||||
|
{
|
||||||
|
return m_info.seekPreRoll;
|
||||||
|
}
|
||||||
|
|
||||||
long Track::GetFirst(const BlockEntry*& pBlockEntry) const
|
long Track::GetFirst(const BlockEntry*& pBlockEntry) const
|
||||||
{
|
{
|
||||||
const Cluster* pCluster = m_pSegment->GetFirst();
|
const Cluster* pCluster = m_pSegment->GetFirst();
|
||||||
@ -6766,6 +6780,15 @@ long Tracks::ParseTrackEntry(
|
|||||||
if (status)
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
else if (id == 0x16AA) //Codec Delay
|
||||||
|
{
|
||||||
|
info.codecDelay = UnserializeUInt(pReader, pos, size);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (id == 0x16BB) //Seek Pre Roll
|
||||||
|
{
|
||||||
|
info.seekPreRoll = UnserializeUInt(pReader, pos, size);
|
||||||
|
}
|
||||||
|
|
||||||
pos += size; //consume payload
|
pos += size; //consume payload
|
||||||
assert(pos <= track_stop);
|
assert(pos <= track_stop);
|
||||||
@ -7519,7 +7542,9 @@ long Cluster::ParseSimpleBlock(
|
|||||||
return E_BUFFER_NOT_FULL;
|
return E_BUFFER_NOT_FULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = CreateBlock(0x23, block_start, block_size); //simple block id
|
status = CreateBlock(0x23, //simple block id
|
||||||
|
block_start, block_size,
|
||||||
|
0); //DiscardPadding
|
||||||
|
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
return status;
|
return status;
|
||||||
@ -7558,6 +7583,8 @@ long Cluster::ParseBlockGroup(
|
|||||||
return E_BUFFER_NOT_FULL;
|
return E_BUFFER_NOT_FULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long long discard_padding = 0;
|
||||||
|
|
||||||
while (pos < payload_stop)
|
while (pos < payload_stop)
|
||||||
{
|
{
|
||||||
//parse sub-block element ID
|
//parse sub-block element ID
|
||||||
@ -7634,6 +7661,19 @@ long Cluster::ParseBlockGroup(
|
|||||||
if (size == unknown_size)
|
if (size == unknown_size)
|
||||||
return E_FILE_FORMAT_INVALID;
|
return E_FILE_FORMAT_INVALID;
|
||||||
|
|
||||||
|
if (id == 0x35A2) //DiscardPadding
|
||||||
|
{
|
||||||
|
result = GetUIntLength(pReader, pos, len);
|
||||||
|
|
||||||
|
if (result < 0) //error
|
||||||
|
return static_cast<long>(result);
|
||||||
|
|
||||||
|
status = UnserializeInt(pReader, pos, len, discard_padding);
|
||||||
|
|
||||||
|
if (status < 0) //error
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
if (id != 0x21) //sub-part of BlockGroup is not a Block
|
if (id != 0x21) //sub-part of BlockGroup is not a Block
|
||||||
{
|
{
|
||||||
pos += size; //consume sub-part of block group
|
pos += size; //consume sub-part of block group
|
||||||
@ -7761,8 +7801,9 @@ long Cluster::ParseBlockGroup(
|
|||||||
|
|
||||||
assert(pos == payload_stop);
|
assert(pos == payload_stop);
|
||||||
|
|
||||||
status = CreateBlock(0x20, payload_start, payload_size); //BlockGroup ID
|
status = CreateBlock(0x20, //BlockGroup ID
|
||||||
|
payload_start, payload_size,
|
||||||
|
discard_padding);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@ -8265,7 +8306,8 @@ long long Cluster::GetLastTime() const
|
|||||||
long Cluster::CreateBlock(
|
long Cluster::CreateBlock(
|
||||||
long long id,
|
long long id,
|
||||||
long long pos, //absolute pos of payload
|
long long pos, //absolute pos of payload
|
||||||
long long size)
|
long long size,
|
||||||
|
long long discard_padding)
|
||||||
{
|
{
|
||||||
assert((id == 0x20) || (id == 0x23)); //BlockGroup or SimpleBlock
|
assert((id == 0x20) || (id == 0x23)); //BlockGroup or SimpleBlock
|
||||||
|
|
||||||
@ -8308,15 +8350,16 @@ long Cluster::CreateBlock(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (id == 0x20) //BlockGroup ID
|
if (id == 0x20) //BlockGroup ID
|
||||||
return CreateBlockGroup(pos, size);
|
return CreateBlockGroup(pos, size, discard_padding);
|
||||||
else //SimpleBlock ID
|
else //SimpleBlock ID
|
||||||
return CreateSimpleBlock(pos, size);
|
return CreateSimpleBlock(pos, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
long Cluster::CreateBlockGroup(
|
long Cluster::CreateBlockGroup(
|
||||||
long long st,
|
long long start_offset,
|
||||||
long long sz)
|
long long size,
|
||||||
|
long long discard_padding)
|
||||||
{
|
{
|
||||||
assert(m_entries);
|
assert(m_entries);
|
||||||
assert(m_entries_size > 0);
|
assert(m_entries_size > 0);
|
||||||
@ -8325,8 +8368,8 @@ long Cluster::CreateBlockGroup(
|
|||||||
|
|
||||||
IMkvReader* const pReader = m_pSegment->m_pReader;
|
IMkvReader* const pReader = m_pSegment->m_pReader;
|
||||||
|
|
||||||
long long pos = st;
|
long long pos = start_offset;
|
||||||
const long long stop = st + sz;
|
const long long stop = start_offset + size;
|
||||||
|
|
||||||
//For WebM files, there is a bias towards previous reference times
|
//For WebM files, there is a bias towards previous reference times
|
||||||
//(in order to support alt-ref frames, which refer back to the previous
|
//(in order to support alt-ref frames, which refer back to the previous
|
||||||
@ -8407,7 +8450,8 @@ long Cluster::CreateBlockGroup(
|
|||||||
bsize,
|
bsize,
|
||||||
prev,
|
prev,
|
||||||
next,
|
next,
|
||||||
duration);
|
duration,
|
||||||
|
discard_padding);
|
||||||
|
|
||||||
if (pEntry == NULL)
|
if (pEntry == NULL)
|
||||||
return -1; //generic error
|
return -1; //generic error
|
||||||
@ -8984,7 +9028,7 @@ SimpleBlock::SimpleBlock(
|
|||||||
long long start,
|
long long start,
|
||||||
long long size) :
|
long long size) :
|
||||||
BlockEntry(pCluster, idx),
|
BlockEntry(pCluster, idx),
|
||||||
m_block(start, size)
|
m_block(start, size, 0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9014,9 +9058,10 @@ BlockGroup::BlockGroup(
|
|||||||
long long block_size,
|
long long block_size,
|
||||||
long long prev,
|
long long prev,
|
||||||
long long next,
|
long long next,
|
||||||
long long duration) :
|
long long duration,
|
||||||
|
long long discard_padding) :
|
||||||
BlockEntry(pCluster, idx),
|
BlockEntry(pCluster, idx),
|
||||||
m_block(block_start, block_size),
|
m_block(block_start, block_size, discard_padding),
|
||||||
m_prev(prev),
|
m_prev(prev),
|
||||||
m_next(next),
|
m_next(next),
|
||||||
m_duration(duration)
|
m_duration(duration)
|
||||||
@ -9082,14 +9127,15 @@ long long BlockGroup::GetDurationTimeCode() const
|
|||||||
return m_duration;
|
return m_duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
Block::Block(long long start, long long size_) :
|
Block::Block(long long start, long long size_, long long discard_padding) :
|
||||||
m_start(start),
|
m_start(start),
|
||||||
m_size(size_),
|
m_size(size_),
|
||||||
m_track(0),
|
m_track(0),
|
||||||
m_timecode(-1),
|
m_timecode(-1),
|
||||||
m_flags(0),
|
m_flags(0),
|
||||||
m_frames(NULL),
|
m_frames(NULL),
|
||||||
m_frame_count(-1)
|
m_frame_count(-1),
|
||||||
|
m_discard_padding(discard_padding)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9535,5 +9581,9 @@ long Block::Frame::Read(IMkvReader* pReader, unsigned char* buf) const
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long long Block::GetDiscardPadding() const
|
||||||
|
{
|
||||||
|
return m_discard_padding;
|
||||||
|
}
|
||||||
|
|
||||||
} //end namespace mkvparser
|
} //end namespace mkvparser
|
||||||
|
@ -83,7 +83,7 @@ public:
|
|||||||
const long long m_start;
|
const long long m_start;
|
||||||
const long long m_size;
|
const long long m_size;
|
||||||
|
|
||||||
Block(long long start, long long size);
|
Block(long long start, long long size, long long discard_padding);
|
||||||
~Block();
|
~Block();
|
||||||
|
|
||||||
long Parse(const Cluster*);
|
long Parse(const Cluster*);
|
||||||
@ -110,6 +110,8 @@ public:
|
|||||||
|
|
||||||
const Frame& GetFrame(int frame_index) const;
|
const Frame& GetFrame(int frame_index) const;
|
||||||
|
|
||||||
|
long long GetDiscardPadding() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
long long m_track; //Track::Number()
|
long long m_track; //Track::Number()
|
||||||
short m_timecode; //relative to cluster
|
short m_timecode; //relative to cluster
|
||||||
@ -118,6 +120,8 @@ private:
|
|||||||
Frame* m_frames;
|
Frame* m_frames;
|
||||||
int m_frame_count;
|
int m_frame_count;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const long long m_discard_padding;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -178,7 +182,8 @@ public:
|
|||||||
long long block_size, //size of block's payload
|
long long block_size, //size of block's payload
|
||||||
long long prev,
|
long long prev,
|
||||||
long long next,
|
long long next,
|
||||||
long long duration);
|
long long duration,
|
||||||
|
long long discard_padding);
|
||||||
|
|
||||||
long Parse();
|
long Parse();
|
||||||
|
|
||||||
@ -194,7 +199,6 @@ private:
|
|||||||
const long long m_prev;
|
const long long m_prev;
|
||||||
const long long m_next;
|
const long long m_next;
|
||||||
const long long m_duration;
|
const long long m_duration;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////
|
||||||
@ -355,6 +359,8 @@ public:
|
|||||||
const unsigned char* GetCodecPrivate(size_t&) const;
|
const unsigned char* GetCodecPrivate(size_t&) const;
|
||||||
bool GetLacing() const;
|
bool GetLacing() const;
|
||||||
unsigned long long GetDefaultDuration() const;
|
unsigned long long GetDefaultDuration() const;
|
||||||
|
unsigned long long GetCodecDelay() const;
|
||||||
|
unsigned long long GetSeekPreRoll() const;
|
||||||
|
|
||||||
const BlockEntry* GetEOS() const;
|
const BlockEntry* GetEOS() const;
|
||||||
|
|
||||||
@ -371,14 +377,12 @@ public:
|
|||||||
~Info();
|
~Info();
|
||||||
int Copy(Info&) const;
|
int Copy(Info&) const;
|
||||||
void Clear();
|
void Clear();
|
||||||
private:
|
|
||||||
Info(const Info&);
|
|
||||||
Info& operator=(const Info&);
|
|
||||||
public:
|
|
||||||
long type;
|
long type;
|
||||||
long number;
|
long number;
|
||||||
unsigned long long uid;
|
unsigned long long uid;
|
||||||
unsigned long long defaultDuration;
|
unsigned long long defaultDuration;
|
||||||
|
unsigned long long codecDelay;
|
||||||
|
unsigned long long seekPreRoll;
|
||||||
char* nameAsUTF8;
|
char* nameAsUTF8;
|
||||||
char* language;
|
char* language;
|
||||||
char* codecId;
|
char* codecId;
|
||||||
@ -387,7 +391,10 @@ public:
|
|||||||
size_t codecPrivateSize;
|
size_t codecPrivateSize;
|
||||||
bool lacing;
|
bool lacing;
|
||||||
Settings settings;
|
Settings settings;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Info(const Info&);
|
||||||
|
Info& operator=(const Info&);
|
||||||
int CopyStr(char* Info::*str, Info&) const;
|
int CopyStr(char* Info::*str, Info&) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -944,8 +951,10 @@ private:
|
|||||||
long ParseSimpleBlock(long long, long long&, long&);
|
long ParseSimpleBlock(long long, long long&, long&);
|
||||||
long ParseBlockGroup(long long, long long&, long&);
|
long ParseBlockGroup(long long, long long&, long&);
|
||||||
|
|
||||||
long CreateBlock(long long id, long long pos, long long size);
|
long CreateBlock(long long id, long long pos, long long size,
|
||||||
long CreateBlockGroup(long long, long long);
|
long long discard_padding);
|
||||||
|
long CreateBlockGroup(long long start_offset, long long size,
|
||||||
|
long long discard_padding);
|
||||||
long CreateSimpleBlock(long long, long long);
|
long CreateSimpleBlock(long long, long long);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
11
sample.cpp
11
sample.cpp
@ -233,6 +233,12 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
const double sampleRate = pAudioTrack->GetSamplingRate();
|
const double sampleRate = pAudioTrack->GetSamplingRate();
|
||||||
printf("\t\tAddio Sample Rate\t: %.3f\n", sampleRate);
|
printf("\t\tAddio Sample Rate\t: %.3f\n", sampleRate);
|
||||||
|
|
||||||
|
const long long codecDelay = pAudioTrack->GetCodecDelay();
|
||||||
|
printf("\t\tAudio Codec Delay\t\t: %lld\n", codecDelay);
|
||||||
|
|
||||||
|
const long long seekPreRoll = pAudioTrack->GetSeekPreRoll();
|
||||||
|
printf("\t\tAudio Seek Pre Roll\t\t: %lld\n", seekPreRoll);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,11 +288,12 @@ int main(int argc, char* argv[])
|
|||||||
const long long trackType = pTrack->GetType();
|
const long long trackType = pTrack->GetType();
|
||||||
const int frameCount = pBlock->GetFrameCount();
|
const int frameCount = pBlock->GetFrameCount();
|
||||||
const long long time_ns = pBlock->GetTime(pCluster);
|
const long long time_ns = pBlock->GetTime(pCluster);
|
||||||
|
const long long discard_padding = pBlock->GetDiscardPadding();
|
||||||
|
|
||||||
printf("\t\t\tBlock\t\t:%s,%s,%15lld\n",
|
printf("\t\t\tBlock\t\t:%s,%s,%15lld,%lld\n",
|
||||||
(trackType == mkvparser::Track::kVideo) ? "V" : "A",
|
(trackType == mkvparser::Track::kVideo) ? "V" : "A",
|
||||||
pBlock->IsKey() ? "I" : "P",
|
pBlock->IsKey() ? "I" : "P",
|
||||||
time_ns);
|
time_ns, discard_padding);
|
||||||
|
|
||||||
for (int i = 0; i < frameCount; ++i)
|
for (int i = 0; i < frameCount; ++i)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user