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:
Matthew Heaney 2012-11-13 12:44:06 -08:00
parent 0fcf5e5a40
commit 28222b4927
5 changed files with 58 additions and 5 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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,

View File

@ -118,6 +118,7 @@ enum MkvId {
kMkvEditionEntry = 0x45B9,
kMkvChapterAtom = 0xB6,
kMkvChapterUID = 0x73C4,
kMkvChapterStringUID = 0x5654,
kMkvChapterTimeStart = 0x91,
kMkvChapterTimeEnd = 0x92,
kMkvChapterDisplay = 0x80,