142 lines
3.4 KiB
C++
142 lines
3.4 KiB
C++
#include "segmentinfo.hpp"
|
|
#include "imkvreader.hpp"
|
|
#include "ebmlreadhelpers.hpp"
|
|
#include "segment.hpp"
|
|
|
|
#include <stddef.h>
|
|
#include <assert.h>
|
|
|
|
namespace mkvparser
|
|
{
|
|
|
|
SegmentInfo::SegmentInfo(Segment* pSegment, const EBMLElement& elemInfo)
|
|
: m_pSegment(pSegment)
|
|
, m_elemInfo(elemInfo)
|
|
, m_timecodeScale(1000000)
|
|
, m_duration(-1.0)
|
|
, m_pMuxingAppAsUTF8(NULL)
|
|
, m_pWritingAppAsUTF8(NULL)
|
|
, m_pTitleAsUTF8(NULL)
|
|
{
|
|
}
|
|
|
|
SegmentInfo::~SegmentInfo()
|
|
{
|
|
mem::Free(m_pMuxingAppAsUTF8);
|
|
m_pMuxingAppAsUTF8 = NULL;
|
|
|
|
mem::Free(m_pWritingAppAsUTF8);
|
|
m_pWritingAppAsUTF8 = NULL;
|
|
|
|
mem::Free(m_pTitleAsUTF8);
|
|
m_pTitleAsUTF8 = NULL;
|
|
}
|
|
|
|
|
|
long SegmentInfo::Parse()
|
|
{
|
|
assert(m_pMuxingAppAsUTF8 == NULL);
|
|
assert(m_pWritingAppAsUTF8 == NULL);
|
|
assert(m_pTitleAsUTF8 == NULL);
|
|
|
|
IMkvReader* const pReader = m_pSegment->GetReader();
|
|
|
|
long long pos = m_elemInfo.GetPayloadPos();
|
|
const long long stop = m_elemInfo.GetEndPos();
|
|
|
|
m_timecodeScale = 1000000;
|
|
m_duration = -1;
|
|
|
|
while (pos < stop)
|
|
{
|
|
long long id, size;
|
|
|
|
const long status = ParseElementHeader(
|
|
pReader,
|
|
pos,
|
|
stop,
|
|
id,
|
|
size);
|
|
|
|
if (status < 0) //error
|
|
return status;
|
|
|
|
if (id == 0x0AD7B1) //Timecode Scale
|
|
{
|
|
m_timecodeScale = UnserializeUInt(pReader, pos, size);
|
|
|
|
if (m_timecodeScale <= 0)
|
|
return E_FILE_FORMAT_INVALID;
|
|
}
|
|
else if (id == 0x0489) //Segment duration
|
|
{
|
|
const long status = UnserializeFloat(
|
|
pReader,
|
|
pos,
|
|
size,
|
|
m_duration);
|
|
|
|
if (status < 0)
|
|
return status;
|
|
|
|
if (m_duration < 0)
|
|
return E_FILE_FORMAT_INVALID;
|
|
}
|
|
else if (id == 0x0D80) //MuxingApp
|
|
{
|
|
const long status = UnserializeString(
|
|
pReader,
|
|
pos,
|
|
size,
|
|
m_pMuxingAppAsUTF8);
|
|
|
|
if (status)
|
|
return status;
|
|
}
|
|
else if (id == 0x1741) //WritingApp
|
|
{
|
|
const long status = UnserializeString(
|
|
pReader,
|
|
pos,
|
|
size,
|
|
m_pWritingAppAsUTF8);
|
|
|
|
if (status)
|
|
return status;
|
|
}
|
|
else if (id == 0x3BA9) //Title
|
|
{
|
|
const long status = UnserializeString(
|
|
pReader,
|
|
pos,
|
|
size,
|
|
m_pTitleAsUTF8);
|
|
|
|
if (status)
|
|
return status;
|
|
}
|
|
|
|
pos += size;
|
|
assert(pos <= stop);
|
|
}
|
|
|
|
assert(pos == stop);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
long long SegmentInfo::GetDuration() const
|
|
{
|
|
if (m_duration < 0)
|
|
return -1;
|
|
|
|
assert(m_timecodeScale >= 1);
|
|
|
|
const double dd = double(m_duration) * double(m_timecodeScale);
|
|
const long long d = static_cast<long long>(dd);
|
|
|
|
return d;
|
|
}
|
|
|
|
} // namespace mkvparser
|