Skip to content

Commit f948436

Browse files
complexlogicufleisch
authored andcommitted
Initial cues work
1 parent 975eaac commit f948436

4 files changed

Lines changed: 412 additions & 0 deletions

File tree

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/***************************************************************************
2+
* This library is free software; you can redistribute it and/or modify *
3+
* it under the terms of the GNU Lesser General Public License version *
4+
* 2.1 as published by the Free Software Foundation. *
5+
* *
6+
* This library is distributed in the hope that it will be useful, but *
7+
* WITHOUT ANY WARRANTY; without even the implied warranty of *
8+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
9+
* Lesser General Public License for more details. *
10+
* *
11+
* You should have received a copy of the GNU Lesser General Public *
12+
* License along with this library; if not, write to the Free Software *
13+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
14+
* 02110-1301 USA *
15+
* *
16+
* Alternatively, this file is available under the Mozilla Public *
17+
* License Version 1.1. You may obtain a copy of the License at *
18+
* http://www.mozilla.org/MPL/ *
19+
***************************************************************************/
20+
21+
#include "ebmlmkcues.h"
22+
#include "ebmluintelement.h"
23+
#include "ebmlstringelement.h"
24+
#include "ebmlutils.h"
25+
#include "matroskafile.h"
26+
#include "matroskacues.h"
27+
#include "tdebug.h"
28+
#include "tutils.h"
29+
30+
using namespace TagLib;
31+
32+
Matroska::Cues* EBML::MkCues::parse()
33+
{
34+
auto cues = new Matroska::Cues();
35+
cues->setOffset(offset);
36+
cues->setSize(getSize());
37+
cues->setID(id);
38+
39+
for (auto cuesChild : elements) {
40+
if (cuesChild->getId() != ElementIDs::MkCuePoint)
41+
continue;
42+
auto cuePointElement = static_cast<MasterElement*>(cuesChild);
43+
auto cuePoint = new Matroska::CuePoint();
44+
45+
for (auto cuePointChild : *cuePointElement) {
46+
Id id = cuePointChild->getId();
47+
if (id == ElementIDs::MkCueTime)
48+
cuePoint->setTime(static_cast<UIntElement*>(cuePointChild)->getValue());
49+
else if (id == ElementIDs::MkCueTrackPositions) {
50+
auto cueTrack = new Matroska::CueTrack();
51+
auto cueTrackElement = static_cast<MasterElement*>(cuePointChild);
52+
for (auto cueTrackChild : *cueTrackElement) {
53+
Id trackId = cueTrackChild->getId();
54+
if (trackId == ElementIDs::MkCueTrack)
55+
cueTrack->setTrackNumber(static_cast<UIntElement*>(cueTrackChild)->getValue());
56+
else if (trackId == ElementIDs::MkCueClusterPosition)
57+
cueTrack->setClusterPosition(static_cast<UIntElement*>(cueTrackChild)->getValue());
58+
else if (trackId == ElementIDs::MkCueRelativePosition)
59+
cueTrack->setRelativePosition(static_cast<UIntElement*>(cueTrackChild)->getValue());
60+
else if (trackId == ElementIDs::MkCueDuration)
61+
cueTrack->setDuration(static_cast<UIntElement*>(cueTrackChild)->getValue());
62+
else if (trackId == ElementIDs::MkCueBlockNumber)
63+
cueTrack->setBlockNumber(static_cast<UIntElement*>(cueTrackChild)->getValue());
64+
else if (trackId == ElementIDs::MkCueCodecState)
65+
cueTrack->setCodecState(static_cast<UIntElement*>(cueTrackChild)->getValue());
66+
else if (trackId == ElementIDs::MkCueReference) {
67+
auto cueReference = static_cast<MasterElement*>(cueTrackChild);
68+
for (auto cueReferenceChild : *cueReference) {
69+
if (cueReferenceChild->getId() != ElementIDs::MkCueReference)
70+
continue;
71+
cueTrack->addReferenceTime(static_cast<UIntElement*>(cueReferenceChild)->getValue());
72+
}
73+
}
74+
}
75+
cuePoint->addCueTrack(cueTrack);
76+
}
77+
}
78+
cues->addCuePoint(cuePoint);
79+
}
80+
return cues;
81+
}

taglib/matroska/ebml/ebmlmkcues.h

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/***************************************************************************
2+
* This library is free software; you can redistribute it and/or modify *
3+
* it under the terms of the GNU Lesser General Public License version *
4+
* 2.1 as published by the Free Software Foundation. *
5+
* *
6+
* This library is distributed in the hope that it will be useful, but *
7+
* WITHOUT ANY WARRANTY; without even the implied warranty of *
8+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
9+
* Lesser General Public License for more details. *
10+
* *
11+
* You should have received a copy of the GNU Lesser General Public *
12+
* License along with this library; if not, write to the Free Software *
13+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
14+
* 02110-1301 USA *
15+
* *
16+
* Alternatively, this file is available under the Mozilla Public *
17+
* License Version 1.1. You may obtain a copy of the License at *
18+
* http://www.mozilla.org/MPL/ *
19+
***************************************************************************/
20+
21+
#include "ebmlmasterelement.h"
22+
#include "ebmlutils.h"
23+
#include "taglib.h"
24+
25+
#ifndef TAGLIB_EBMLMKCUES_H
26+
#define TAGLIB_EBMLMKCUES_H
27+
#ifndef DO_NOT_DOCUMENT
28+
29+
namespace TagLib {
30+
namespace Matroska {
31+
class Cues;
32+
}
33+
//class Matroska::Tag;
34+
namespace EBML {
35+
class MkCues : public MasterElement
36+
{
37+
public:
38+
MkCues(int sizeLength, offset_t dataSize, offset_t offset)
39+
: MasterElement(ElementIDs::MkCues, sizeLength, dataSize, offset)
40+
{}
41+
MkCues()
42+
: MasterElement(ElementIDs::MkCues, 0, 0, 0)
43+
{}
44+
45+
Matroska::Cues* parse();
46+
47+
};
48+
}
49+
}
50+
#endif
51+
#endif

taglib/matroska/matroskacues.cpp

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/***************************************************************************
2+
* This library is free software; you can redistribute it and/or modify *
3+
* it under the terms of the GNU Lesser General Public License version *
4+
* 2.1 as published by the Free Software Foundation. *
5+
* *
6+
* This library is distributed in the hope that it will be useful, but *
7+
* WITHOUT ANY WARRANTY; without even the implied warranty of *
8+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
9+
* Lesser General Public License for more details. *
10+
* *
11+
* You should have received a copy of the GNU Lesser General Public *
12+
* License along with this library; if not, write to the Free Software *
13+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
14+
* 02110-1301 USA *
15+
* *
16+
* Alternatively, this file is available under the Mozilla Public *
17+
* License Version 1.1. You may obtain a copy of the License at *
18+
* http://www.mozilla.org/MPL/ *
19+
***************************************************************************/
20+
21+
#include "matroskacues.h"
22+
#include "ebmlelement.h"
23+
#include "ebmlmkcues.h"
24+
#include "ebmlmasterelement.h"
25+
#include "ebmluintelement.h"
26+
#include "tlist.h"
27+
#include "tdebug.h"
28+
#include "tfile.h"
29+
30+
using namespace TagLib;
31+
32+
Matroska::Cues::Cues()
33+
: Element(ElementIDs::MkCues)
34+
{
35+
cuePoints.setAutoDelete(true);
36+
}
37+
38+
ByteVector Matroska::Cues::renderInternal()
39+
{
40+
EBML::MkCues cues;
41+
for (auto &cuePoint : cuePoints) {
42+
auto cuePointElement = new EBML::MasterElement(EBML::ElementIDs::MkCuePoint);
43+
auto timestamp = new EBML::UIntElement(EBML::ElementIDs::MkCueTime);
44+
timestamp->setValue(cuePoint->getTime());
45+
cuePointElement->appendElement(timestamp);
46+
47+
auto trackList = cuePoint->cueTrackList();
48+
for (auto &cueTrack : trackList) {
49+
auto cueTrackElement = new EBML::MasterElement(EBML::ElementIDs::MkCueTrackPositions);
50+
51+
// Track number
52+
auto trackNumber = new EBML::UIntElement(EBML::ElementIDs::MkCueTrack);
53+
trackNumber->setValue(cueTrack->getTrackNumber());
54+
cueTrackElement->appendElement(trackNumber);
55+
56+
// Cluster position
57+
auto clusterPosition = new EBML::UIntElement(EBML::ElementIDs::MkCueClusterPosition);
58+
clusterPosition->setValue(cueTrack->getClusterPosition());
59+
cueTrackElement->appendElement(clusterPosition);
60+
61+
// Todo - other elements
62+
63+
64+
// Reference times
65+
auto referenceTimes = cueTrack->referenceTimes();
66+
if (!referenceTimes.isEmpty()) {
67+
auto cueReference = new EBML::MasterElement(EBML::ElementIDs::MkCueReference);
68+
for (auto reference : referenceTimes) {
69+
auto refTime = new EBML::UIntElement(EBML::ElementIDs::MkCueRefTime);
70+
refTime->setValue(reference);
71+
cueReference->appendElement(refTime);
72+
}
73+
cueTrackElement->appendElement(cueReference);
74+
}
75+
cuePointElement->appendElement(cueTrackElement);
76+
}
77+
}
78+
return cues.render();
79+
}
80+
81+
bool Matroska::Cues::render()
82+
{
83+
if (!needsRender)
84+
return true;
85+
86+
87+
setData(cues.render());
88+
needsRender = false;
89+
return true;
90+
}
91+
92+
bool Matroska::Cues::sizeChanged(Element &caller, offset_t delta)
93+
{
94+
offset_t offset = caller.offset();
95+
for (auto cuePoint : cuePoints)
96+
needsRender |= cuePoint->adjustOffset(offset, delta);
97+
return true;
98+
}
99+
100+
bool Matroska::Cues::isValid(TagLib::File &file, offset_t segmentDataOffset) const
101+
{
102+
for (const auto cuePoint : cuePoints) {
103+
if (!cuePoint->isValid(file, segmentDataOffset))
104+
return false;
105+
}
106+
return true;
107+
}
108+
109+
Matroska::CuePoint::CuePoint()
110+
{
111+
cueTracks.setAutoDelete(true);
112+
}
113+
114+
bool Matroska::CuePoint::isValid(TagLib::File &file, offset_t segmentDataOffset) const
115+
{
116+
for (const auto track : cueTracks) {
117+
if (!track->isValid(file, segmentDataOffset))
118+
return false;
119+
}
120+
return true;
121+
}
122+
123+
bool Matroska::CuePoint::adjustOffset(offset_t offset, offset_t delta)
124+
{
125+
bool ret = false;
126+
for (auto cueTrack : cueTracks)
127+
ret |= cueTrack->adjustOffset(offset, delta);
128+
129+
return ret;
130+
}
131+
132+
bool Matroska::CueTrack::isValid(TagLib::File &file, offset_t segmentDataOffset) const
133+
{
134+
if (!trackNumber) {
135+
debug("Cue track number not set");
136+
return false;
137+
}
138+
if (!clusterPosition) {
139+
debug("Cue track cluster position not set");
140+
return false;
141+
}
142+
file.seek(segmentDataOffset + clusterPosition);
143+
if (EBML::Element::readId(file) != EBML::ElementIDs::MkCluster) {
144+
debug("No cluster found at position");
145+
return false;
146+
}
147+
if (codecState) {
148+
file.seek(segmentDataOffset + codecState);
149+
if (EBML::Element::readId(file) != EBML::ElementIDs::MkCodecState) {
150+
debug("No codec state found at position");
151+
return false;
152+
}
153+
}
154+
return true;
155+
}
156+
157+
bool Matroska::CueTrack::adjustOffset(offset_t offset, offset_t delta)
158+
{
159+
return false;
160+
}
161+

0 commit comments

Comments
 (0)