56 static const string context(
"parsing \"Cues\"-element");
58 std::uint64_t cuesElementSize = 0, cuePointElementSize, cueTrackPositionsElementSize, cueReferenceElementSize, pos, relPos, statePos;
59 EbmlElement *cueRelativePositionElement, *cueClusterPositionElement;
62 cuePointElement->parse(diag);
63 switch (cuePointElement->id()) {
68 cuePointElementSize = 0;
71 cuePointChild->parse(diag);
72 switch (cuePointChild->id()) {
77 cuePointChild->makeBuffer();
78 cuePointElementSize += cuePointChild->totalSize();
81 cueTrackPositionsElementSize = relPos = 0;
82 cueRelativePositionElement = cueClusterPositionElement =
nullptr;
84 cueTrackPositionsChild = cueTrackPositionsChild->
nextSibling()) {
86 cueTrackPositionsChild->parse(diag);
87 switch (cueTrackPositionsChild->id()) {
91 cueTrackPositionsChild->makeBuffer();
92 cueTrackPositionsElementSize += cueTrackPositionsChild->totalSize();
95 relPos = (cueRelativePositionElement = cueTrackPositionsChild)->readUInteger();
98 pos = (cueClusterPositionElement = cueTrackPositionsChild)->readUInteger();
100 m_offsets.emplace(cueTrackPositionsChild, pos);
101 m_cueElementByOriginalOffset.emplace(pos, cueTrackPositionsChild);
104 statePos = cueTrackPositionsChild->readUInteger();
106 m_offsets.emplace(cueTrackPositionsChild, statePos);
107 m_cueElementByOriginalOffset.emplace(statePos, cueTrackPositionsChild);
110 cueReferenceElementSize = 0;
112 cueReferenceChild = cueReferenceChild->
nextSibling()) {
114 cueReferenceChild->parse(diag);
115 switch (cueReferenceChild->id()) {
121 cueReferenceChild->makeBuffer();
122 cueReferenceElementSize += cueReferenceChild->totalSize();
126 statePos = cueReferenceChild->readUInteger();
128 m_offsets.emplace(cueReferenceChild, statePos);
129 m_cueElementByOriginalOffset.emplace(statePos, cueReferenceChild);
133 "\"CueReference\"-element contains a element which is not known to the parser. It will be ignored.", context);
136 cueTrackPositionsElementSize
138 m_sizes.emplace(cueTrackPositionsChild, cueReferenceElementSize);
142 "\"CueTrackPositions\"-element contains a element which is not known to the parser. It will be ignored.", context);
145 if (!cueClusterPositionElement) {
147 DiagLevel::Critical,
"\"CueTrackPositions\"-element does not contain mandatory \"CueClusterPosition\"-element.", context);
148 }
else if (cueRelativePositionElement) {
150 m_relativeOffsets.emplace(piecewise_construct, forward_as_tuple(cueRelativePositionElement), forward_as_tuple(pos, relPos));
151 m_cueRelativePositionElementByOriginalOffsets.emplace(
152 piecewise_construct, forward_as_tuple(pos, relPos), forward_as_tuple(cueRelativePositionElement));
156 m_sizes.emplace(cuePointChild, cueTrackPositionsElementSize);
160 "\"CuePoint\"-element contains a element which is not a \"CueTime\"- or a \"CueTrackPositions\"-element. It will be ignored.",
165 m_sizes.emplace(cuePointElement, cuePointElementSize);
169 DiagLevel::Warning,
"\"Cues\"-element contains a element which is not a \"CuePoint\"-element. It will be ignored.", context);
172 m_sizes.emplace(m_cuesElement =
cuesElement, cuesElementSize);
181 auto updated =
false;
183 for (
auto cueElementRange = m_cueElementByOriginalOffset.equal_range(originalOffset); cueElementRange.first != cueElementRange.second;
184 ++cueElementRange.first) {
185 auto *
const cueElement = cueElementRange.first->second;
186 const auto offsetIterator = m_offsets.find(cueElement);
187 if (offsetIterator == m_offsets.end()) {
190 auto &offset = offsetIterator->second;
191 if (offset.currentValue() != newOffset) {
195 offset.update(newOffset);
206 std::uint64_t referenceOffset, std::uint64_t originalRelativeOffset, std::uint64_t newRelativeOffset)
208 auto updated =
false;
210 for (
auto cueElementRange = m_cueRelativePositionElementByOriginalOffsets.equal_range(std::make_pair(referenceOffset, originalRelativeOffset));
211 cueElementRange.first != cueElementRange.second; ++cueElementRange.first) {
212 auto *
const cueRelativePositionElement = cueElementRange.first->second;
213 const auto offsetIterator = m_relativeOffsets.find(cueRelativePositionElement);
214 if (offsetIterator == m_relativeOffsets.end()) {
217 auto &offset = offsetIterator->second;
218 if (offset.currentValue() != newRelativeOffset) {
219 updated = updateSize(cueRelativePositionElement->parent(),
222 offset.update(newRelativeOffset);
264 static const string context(
"making \"Cues\"-element");
265 if (!m_cuesElement) {
266 diag.emplace_back(
DiagLevel::Warning,
"No cues written; the cues of the source file could not be parsed correctly.", context);
275 stream.write(buff, 4);
277 stream.write(buff, len);
280 cuePointElement->parse(diag);
281 switch (cuePointElement->id()) {
289 stream.write(buff, len);
291 cuePointChild->parse(diag);
292 switch (cuePointChild->id()) {
298 cuePointChild->copyBuffer(stream);
299 cuePointChild->discardBuffer();
305 stream.write(buff, len);
307 cueTrackPositionsChild = cueTrackPositionsChild->
nextSibling()) {
308 cueTrackPositionsChild->parse(diag);
309 switch (cueTrackPositionsChild->id()) {
314 cueTrackPositionsChild->copyBuffer(stream);
315 cueTrackPositionsChild->discardBuffer();
318 if (
const auto relativeOffset = m_relativeOffsets.find(cueTrackPositionsChild);
319 relativeOffset != m_relativeOffsets.end()) {
329 stream, cueTrackPositionsChild->id(), m_offsets.at(cueTrackPositionsChild).currentValue());
335 stream.write(buff, len);
337 cueReferenceChild = cueReferenceChild->
nextSibling()) {
338 cueReferenceChild->parse(diag);
339 switch (cueReferenceChild->id()) {
346 cueReferenceChild->copyBuffer(stream);
347 cueReferenceChild->discardBuffer();
348 cueReferenceChild->copyEntirely(stream, diag,
nullptr);
354 stream, cueReferenceChild->id(), m_offsets.at(cueReferenceChild).currentValue());
358 "\"CueReference\"-element contains a element which is not known to the parser. It will be ignored.",
365 "\"CueTrackPositions\"-element contains a element which is not known to the parser. It will be ignored.",
372 "\"CuePoint\"-element contains a element which is not a \"CueTime\"- or a \"CueTrackPositions\"-element. It will be "
380 DiagLevel::Warning,
"\"Cues\"-element contains a element which is not a \"CuePoint\"-element. It will be ignored.", context);
383 }
catch (
const out_of_range &) {
385 DiagLevel::Critical,
"Unable to write the file index because the index of the original file could not be parsed correctly.", context);