2929
3030using namespace TagLib ;
3131
32- Matroska::Cues::Cues () :
33- Element(static_cast <ID>(EBML::Element::Id::MkCues))
32+ Matroska::Cues::Cues (offset_t segmentDataOffset) :
33+ Element(static_cast <ID>(EBML::Element::Id::MkCues)),
34+ segmentDataOffset(segmentDataOffset)
3435{
36+ setNeedsRender (false );
3537}
3638
3739ByteVector Matroska::Cues::renderInternal ()
3840{
41+ auto beforeSize = sizeRenderedOrWritten ();
3942 EBML::MkCues cues;
43+ cues.setMinRenderSize (beforeSize);
4044 for (const auto &cuePoint : cuePoints) {
4145 auto cuePointElement = EBML::make_unique_element<EBML::Element::Id::MkCuePoint>();
4246 auto timestamp = EBML::make_unique_element<EBML::Element::Id::MkCueTime>();
@@ -57,7 +61,33 @@ ByteVector Matroska::Cues::renderInternal()
5761 clusterPosition->setValue (cueTrack->getClusterPosition ());
5862 cueTrackElement->appendElement (std::move (clusterPosition));
5963
60- // Todo - other elements
64+ // Relative position, optional
65+ if (cueTrack->getRelativePosition ().has_value ()) {
66+ auto relativePosition = EBML::make_unique_element<EBML::Element::Id::MkCueRelativePosition>();
67+ relativePosition->setValue (cueTrack->getRelativePosition ().value ());
68+ cueTrackElement->appendElement (std::move (relativePosition));
69+ }
70+
71+ // Duration, optional
72+ if (cueTrack->getDuration ().has_value ()) {
73+ auto duration = EBML::make_unique_element<EBML::Element::Id::MkCueDuration>();
74+ duration->setValue (cueTrack->getDuration ().value ());
75+ cueTrackElement->appendElement (std::move (duration));
76+ }
77+
78+ // Block number, optional
79+ if (cueTrack->getBlockNumber ().has_value ()) {
80+ auto blockNumber = EBML::make_unique_element<EBML::Element::Id::MkCueBlockNumber>();
81+ blockNumber->setValue (cueTrack->getBlockNumber ().value ());
82+ cueTrackElement->appendElement (std::move (blockNumber));
83+ }
84+
85+ // Codec state, not in version 1
86+ if (cueTrack->getCodecState ().has_value ()) {
87+ auto codecState = EBML::make_unique_element<EBML::Element::Id::MkCueCodecState>();
88+ codecState->setValue (cueTrack->getCodecState ().value ());
89+ cueTrackElement->appendElement (std::move (codecState));
90+ }
6191
6292 // Reference times
6393 auto referenceTimes = cueTrack->referenceTimes ();
@@ -72,29 +102,33 @@ ByteVector Matroska::Cues::renderInternal()
72102 }
73103 cuePointElement->appendElement (std::move (cueTrackElement));
74104 }
105+ cues.appendElement (std::move (cuePointElement));
75106 }
76107 return cues.render ();
77108}
78109
79- bool Matroska::Cues::render ( )
110+ void Matroska::Cues::write (TagLib::File& file )
80111{
81- if (!needsRender)
82- return true ;
83-
84- setData (renderInternal ());
85- needsRender = false ;
86- return true ;
112+ if (!data ().isEmpty ())
113+ Element::write (file);
87114}
88115
89116bool Matroska::Cues::sizeChanged (Element &caller, offset_t delta)
90117{
91- offset_t offset = caller.offset ();
92- for (auto &cuePoint : cuePoints)
93- needsRender |= cuePoint->adjustOffset (offset, delta);
118+ // Adjust own offset
119+ if (!Element::sizeChanged (caller, delta))
120+ return false ;
121+
122+ offset_t offset = caller.offset () - segmentDataOffset;
123+ for (auto &cuePoint : cuePoints) {
124+ if (cuePoint->adjustOffset (offset, delta)) {
125+ setNeedsRender (true );
126+ }
127+ }
94128 return true ;
95129}
96130
97- bool Matroska::Cues::isValid (TagLib::File &file, offset_t segmentDataOffset ) const
131+ bool Matroska::Cues::isValid (TagLib::File &file) const
98132{
99133 for (const auto &cuePoint : cuePoints) {
100134 if (!cuePoint->isValid (file, segmentDataOffset))
@@ -150,8 +184,8 @@ bool Matroska::CueTrack::isValid(TagLib::File &file, offset_t segmentDataOffset)
150184 debug (" No cluster found at position" );
151185 return false ;
152186 }
153- if (codecState) {
154- file.seek (segmentDataOffset + codecState);
187+ if (codecState. has_value () && codecState. value () != 0 ) {
188+ file.seek (segmentDataOffset + codecState. value () );
155189 if (EBML::Element::readId (file) != static_cast <unsigned int >(EBML::Element::Id::MkCodecState)) {
156190 debug (" No codec state found at position" );
157191 return false ;
@@ -160,8 +194,18 @@ bool Matroska::CueTrack::isValid(TagLib::File &file, offset_t segmentDataOffset)
160194 return true ;
161195}
162196
163- bool Matroska::CueTrack::adjustOffset (offset_t , offset_t )
197+ bool Matroska::CueTrack::adjustOffset (offset_t offset , offset_t delta )
164198{
165- // TODO implement
166- return false ;
199+ bool ret = false ;
200+ if (clusterPosition > offset) {
201+ clusterPosition += delta;
202+ ret = true ;
203+ }
204+ offset_t codecStateValue;
205+ if (codecState.has_value () && (codecStateValue = codecState.value ()) != 0 &&
206+ codecStateValue > offset) {
207+ codecState = codecStateValue + delta;
208+ ret = true ;
209+ }
210+ return ret;
167211}
0 commit comments