Add support for WebVTT cue identifier line
Modified the mkvmuxer to write the ChapterStringUID sub-element of the Chapter Atom element. Modified the mkvparser to read the ChapterStringUID sub-element of the chapter atom. Modified the vttdemux app to write the Cue Identifier line of the WebVTT cue. Change-Id: I06fe386f44897ada3fe10cbf89096df104dcf779
This commit is contained in:
parent
0fcf5e5a40
commit
28222b4927
@ -1126,7 +1126,7 @@ bool Chapter::ExpandDisplaysArray() {
|
||||
|
||||
uint64 Chapter::WriteAtom(IMkvWriter* writer) const {
|
||||
uint64 payload_size =
|
||||
// TODO(matthewjheaney): resolve ID issue
|
||||
EbmlElementSize(kMkvChapterStringUID, id_) +
|
||||
EbmlElementSize(kMkvChapterUID, uid_) +
|
||||
EbmlElementSize(kMkvChapterTimeStart, start_timecode_) +
|
||||
EbmlElementSize(kMkvChapterTimeEnd, end_timecode_);
|
||||
@ -1148,6 +1148,9 @@ uint64 Chapter::WriteAtom(IMkvWriter* writer) const {
|
||||
if (!WriteEbmlMasterElement(writer, kMkvChapterAtom, payload_size))
|
||||
return 0;
|
||||
|
||||
if (!WriteEbmlElement(writer, kMkvChapterStringUID, id_))
|
||||
return 0;
|
||||
|
||||
if (!WriteEbmlElement(writer, kMkvChapterUID, uid_))
|
||||
return 0;
|
||||
|
||||
|
@ -4514,6 +4514,18 @@ Chapters::Atom::~Atom()
|
||||
}
|
||||
|
||||
|
||||
unsigned long long Chapters::Atom::GetUID() const
|
||||
{
|
||||
return m_uid;
|
||||
}
|
||||
|
||||
|
||||
const char* Chapters::Atom::GetStringUID() const
|
||||
{
|
||||
return m_string_uid;
|
||||
}
|
||||
|
||||
|
||||
long long Chapters::Atom::GetStartTimecode() const
|
||||
{
|
||||
return m_start_timecode;
|
||||
@ -4558,6 +4570,7 @@ const Chapters::Display* Chapters::Atom::GetDisplay(int index) const
|
||||
|
||||
void Chapters::Atom::Init()
|
||||
{
|
||||
m_string_uid = NULL;
|
||||
m_uid = 0;
|
||||
m_start_timecode = -1;
|
||||
m_stop_timecode = -1;
|
||||
@ -4570,6 +4583,7 @@ void Chapters::Atom::Init()
|
||||
|
||||
void Chapters::Atom::ShallowCopy(Atom& rhs) const
|
||||
{
|
||||
rhs.m_string_uid = m_string_uid;
|
||||
rhs.m_uid = m_uid;
|
||||
rhs.m_start_timecode = m_start_timecode;
|
||||
rhs.m_stop_timecode = m_stop_timecode;
|
||||
@ -4582,6 +4596,9 @@ void Chapters::Atom::ShallowCopy(Atom& rhs) const
|
||||
|
||||
void Chapters::Atom::Clear()
|
||||
{
|
||||
delete[] m_string_uid;
|
||||
m_string_uid = NULL;
|
||||
|
||||
while (m_displays_count > 0)
|
||||
{
|
||||
Display& d = m_displays[--m_displays_count];
|
||||
@ -4626,6 +4643,13 @@ long Chapters::Atom::Parse(
|
||||
if (status < 0) // error
|
||||
return status;
|
||||
}
|
||||
else if (id == 0x1654) // StringUID ID
|
||||
{
|
||||
status = UnserializeString(pReader, pos, size, m_string_uid);
|
||||
|
||||
if (status < 0) // error
|
||||
return status;
|
||||
}
|
||||
else if (id == 0x33C4) // UID ID
|
||||
{
|
||||
const long long val = UnserializeUInt(pReader, pos, size);
|
||||
|
@ -567,10 +567,15 @@ public:
|
||||
~Atom();
|
||||
Atom& operator=(const Atom&);
|
||||
public:
|
||||
unsigned long long GetUID() const;
|
||||
const char* GetStringUID() const;
|
||||
|
||||
long long GetStartTimecode() const;
|
||||
long long GetStopTimecode() const;
|
||||
|
||||
long long GetStartTime(const Chapters*) const;
|
||||
long long GetStopTime(const Chapters*) const;
|
||||
|
||||
int GetDisplayCount() const;
|
||||
const Display* GetDisplay(int index) const;
|
||||
private:
|
||||
@ -583,8 +588,8 @@ public:
|
||||
long ParseDisplay(IMkvReader*, long long pos, long long size);
|
||||
bool ExpandDisplaysArray();
|
||||
|
||||
char* m_string_uid;
|
||||
unsigned long long m_uid;
|
||||
// TODO(matthewjheaney): Cue Identifier (string)
|
||||
long long m_start_timecode;
|
||||
long long m_stop_timecode;
|
||||
|
||||
|
26
vttdemux.cc
26
vttdemux.cc
@ -146,6 +146,12 @@ bool WriteChaptersCue(
|
||||
const mkvparser::Chapters::Atom* atom,
|
||||
const mkvparser::Chapters::Display* display);
|
||||
|
||||
// Write the Cue Identifier line of the WebVTT cue, if it's present.
|
||||
// Returns false on error.
|
||||
bool WriteChaptersCueIdentifier(
|
||||
FILE* file,
|
||||
const mkvparser::Chapters::Atom* atom);
|
||||
|
||||
// Use the timecodes from the chapters |atom| to write just the
|
||||
// timings line of the WebVTT cue. Returns false on error.
|
||||
bool WriteChaptersCueTimings(
|
||||
@ -722,9 +728,8 @@ bool vttdemux::WriteChaptersCue(
|
||||
// the cue timings, followed by the payload of the cue. We write
|
||||
// each part of the cue in sequence.
|
||||
|
||||
// TODO(matthewjheaney): write cue identifier
|
||||
// if (!WriteChaptersCueIdentifier(f, atom))
|
||||
// return false;
|
||||
if (!WriteChaptersCueIdentifier(f, atom))
|
||||
return false;
|
||||
|
||||
if (!WriteChaptersCueTimings(f, chapters, atom))
|
||||
return false;
|
||||
@ -735,6 +740,21 @@ bool vttdemux::WriteChaptersCue(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool vttdemux::WriteChaptersCueIdentifier(
|
||||
FILE* f,
|
||||
const mkvparser::Chapters::Atom* atom) {
|
||||
|
||||
const char* const identifier = atom->GetStringUID();
|
||||
|
||||
if (identifier == NULL)
|
||||
return true; // nothing else to do
|
||||
|
||||
if (fprintf(f, "%s\n", identifier) < 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool vttdemux::WriteChaptersCueTimings(
|
||||
FILE* f,
|
||||
const mkvparser::Chapters* chapters,
|
||||
|
@ -118,6 +118,7 @@ enum MkvId {
|
||||
kMkvEditionEntry = 0x45B9,
|
||||
kMkvChapterAtom = 0xB6,
|
||||
kMkvChapterUID = 0x73C4,
|
||||
kMkvChapterStringUID = 0x5654,
|
||||
kMkvChapterTimeStart = 0x91,
|
||||
kMkvChapterTimeEnd = 0x92,
|
||||
kMkvChapterDisplay = 0x80,
|
||||
|
Loading…
Reference in New Issue
Block a user