Skip to content

Commit 975eaac

Browse files
complexlogicufleisch
authored andcommitted
Fix seekhead
1 parent 6d019a8 commit 975eaac

26 files changed

Lines changed: 831 additions & 108 deletions

taglib/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,15 +230,19 @@ if(WITH_SHORTEN)
230230
endif()
231231

232232
set(tag_PRIVATE_HDRS
233+
matroska/matroskaseekhead.h
234+
matroska/matroskasegment.h
233235
matroska/ebml/ebmlbinaryelement.h
234236
matroska/ebml/ebmlelement.h
235237
matroska/ebml/ebmlmasterelement.h
236238
matroska/ebml/ebmlmkattachments.h
239+
matroska/ebml/ebmlmkseekhead.h
237240
matroska/ebml/ebmlmksegment.h
238241
matroska/ebml/ebmlmktags.h
239242
matroska/ebml/ebmlstringelement.h
240243
matroska/ebml/ebmluintelement.h
241244
matroska/ebml/ebmlutils.h
245+
matroska/ebml/ebmlvoidelement.h
242246
)
243247

244248
set(tag_HDRS ${tag_PUBLIC_HDRS} ${tag_PRIVATE_HDRS})
@@ -248,6 +252,8 @@ set(matroska_SRCS
248252
matroska/matroskaattachments.cpp
249253
matroska/matroskaelement.cpp
250254
matroska/matroskafile.cpp
255+
matroska/matroskaseekhead.cpp
256+
matroska/matroskasegment.cpp
251257
matroska/matroskasimpletag.cpp
252258
matroska/matroskatag.cpp
253259
)
@@ -257,11 +263,13 @@ set(ebml_SRCS
257263
matroska/ebml/ebmlelement.cpp
258264
matroska/ebml/ebmlmasterelement.cpp
259265
matroska/ebml/ebmlmkattachments.cpp
266+
matroska/ebml/ebmlmkseekhead.cpp
260267
matroska/ebml/ebmlmksegment.cpp
261268
matroska/ebml/ebmlmktags.cpp
262269
matroska/ebml/ebmlstringelement.cpp
263270
matroska/ebml/ebmluintelement.cpp
264271
matroska/ebml/ebmlutils.cpp
272+
matroska/ebml/ebmlvoidelement.cpp
265273
)
266274

267275
set(mpeg_SRCS

taglib/matroska/ebml/ebmlelement.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919
***************************************************************************/
2020

2121
#include "ebmlelement.h"
22+
#include "ebmlvoidelement.h"
2223
#include "ebmlmasterelement.h"
2324
#include "ebmlbinaryelement.h"
25+
#include "ebmlmkseekhead.h"
2426
#include "ebmlmksegment.h"
2527
#include "ebmlmktags.h"
2628
#include "ebmlmkattachments.h"
@@ -68,6 +70,7 @@ EBML::Element* EBML::Element::factory(File &file)
6870
case ElementIDs::MkTagTargets:
6971
case ElementIDs::MkSimpleTag:
7072
case ElementIDs::MkAttachedFile:
73+
case ElementIDs::MkSeek:
7174
return new MasterElement(id, sizeLength, dataSize, offset);
7275

7376
case ElementIDs::MkTagName:
@@ -82,10 +85,18 @@ EBML::Element* EBML::Element::factory(File &file)
8285

8386
case ElementIDs::MkTagTargetTypeValue:
8487
case ElementIDs::MkAttachedFileUID:
88+
case ElementIDs::MkSeekPosition:
8589
return new UIntElement(id, sizeLength, dataSize);
8690

8791
case ElementIDs::MkAttachedFileData:
92+
case ElementIDs::MkSeekID:
8893
return new BinaryElement(id, sizeLength, dataSize);
94+
95+
case ElementIDs::MkSeekHead:
96+
return new MkSeekHead(sizeLength, dataSize, offset);
97+
98+
case ElementIDs::VoidElement:
99+
return new VoidElement(sizeLength, dataSize);
89100

90101
default:
91102
return new Element(id, sizeLength, dataSize);

taglib/matroska/ebml/ebmlelement.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ namespace TagLib {
4343
void skipData(File &file);
4444
Id getId() const { return id; }
4545
offset_t headSize() const;
46+
offset_t getSize() const { return headSize() + dataSize; }
4647
int getSizeLength() const { return sizeLength; }
4748
int64_t getDataSize() const { return dataSize; }
4849
ByteVector renderId();
@@ -58,6 +59,7 @@ namespace TagLib {
5859

5960
namespace ElementIDs {
6061
inline constexpr Element::Id EBMLHeader = 0x1A45DFA3;
62+
inline constexpr Element::Id VoidElement = 0xEC;
6163
inline constexpr Element::Id MkSegment = 0x18538067;
6264
inline constexpr Element::Id MkTags = 0x1254C367;
6365
inline constexpr Element::Id MkTag = 0x7373;
@@ -76,6 +78,10 @@ namespace TagLib {
7678
inline constexpr Element::Id MkAttachedFileMediaType = 0x4660;
7779
inline constexpr Element::Id MkAttachedFileData = 0x465C;
7880
inline constexpr Element::Id MkAttachedFileUID = 0x46AE;
81+
inline constexpr Element::Id MkSeekHead = 0x114D9B74;
82+
inline constexpr Element::Id MkSeek = 0x4DBB;
83+
inline constexpr Element::Id MkSeekID = 0x53AB;
84+
inline constexpr Element::Id MkSeekPosition = 0x53AC;
7985

8086
}
8187
}

taglib/matroska/ebml/ebmlmasterelement.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
***************************************************************************/
2020

2121
#include "ebmlmasterelement.h"
22+
#include "ebmlvoidelement.h"
2223
#include "ebmlutils.h"
2324
#include "matroskafile.h"
2425

@@ -55,5 +56,10 @@ ByteVector EBML::MasterElement::render()
5556
dataSize = data.size();
5657
buffer.append(renderVINT(dataSize, 0));
5758
buffer.append(data);
59+
if (minRenderSize) {
60+
auto bufferSize = buffer.size();
61+
if(minRenderSize >= (bufferSize + MIN_VOID_ELEMENT_SIZE))
62+
buffer.append(VoidElement::renderSize(minRenderSize - bufferSize));
63+
}
5864
return buffer;
5965
}

taglib/matroska/ebml/ebmlmasterelement.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,23 @@ namespace TagLib {
4141
{}
4242
~MasterElement() override;
4343
offset_t getOffset() const { return offset; }
44-
offset_t getSize() const { return headSize() + dataSize; }
4544
bool read(File &file) override;
4645
ByteVector render() override;
4746
void appendElement(Element *element) { elements.append(element); }
4847
List<Element*>::Iterator begin () { return elements.begin(); }
4948
List<Element*>::Iterator end () { return elements.end(); }
5049
List<Element*>::ConstIterator cbegin () const { return elements.cbegin(); }
5150
List<Element*>::ConstIterator cend () const { return elements.cend(); }
51+
offset_t getPadding() const { return padding; }
52+
void setPadding(offset_t padding) { this->padding = padding; }
53+
offset_t getMinRenderSize() const { return minRenderSize; }
54+
void setMinRenderSize(offset_t minRenderSize) { this->minRenderSize = minRenderSize; }
55+
5256

5357
protected:
5458
offset_t offset;
59+
offset_t padding = 0;
60+
offset_t minRenderSize = 0;
5561
List<Element*> elements;
5662
};
5763

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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 "ebmlmkseekhead.h"
22+
#include "matroskaseekhead.h"
23+
#include "ebmluintelement.h"
24+
#include "ebmlbinaryelement.h"
25+
26+
using namespace TagLib;
27+
28+
Matroska::SeekHead* EBML::MkSeekHead::parse()
29+
{
30+
auto seekHead = new Matroska::SeekHead();
31+
seekHead->setOffset(offset);
32+
seekHead->setSize(getSize() + padding);
33+
34+
for(auto element : elements) {
35+
if(element->getId() != ElementIDs::MkSeek)
36+
continue;
37+
auto seekElement = static_cast<MasterElement*>(element);
38+
Matroska::Element::ID entryId = 0;
39+
offset_t offset = 0;
40+
for(auto seekElementChild : *seekElement) {
41+
Id id = seekElementChild->getId();
42+
if(id == ElementIDs::MkSeekID && !entryId) {
43+
auto data = static_cast<BinaryElement*>(seekElementChild)->getValue();
44+
if(data.size() == 4)
45+
entryId = data.toUInt(true);
46+
}
47+
else if(id == ElementIDs::MkSeekPosition && !offset)
48+
offset = static_cast<UIntElement*>(seekElementChild)->getValue();
49+
}
50+
if(entryId && offset)
51+
seekHead->addEntry(entryId, offset);
52+
else {
53+
delete seekHead;
54+
return nullptr;
55+
}
56+
}
57+
58+
return seekHead;
59+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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 "taglib.h"
23+
24+
#ifndef TAGLIB_EBMLMKSEEKHEAD_H
25+
#define TAGLIB_EBMLMKSEEKHEAD_H
26+
#ifndef DO_NOT_DOCUMENT
27+
28+
namespace TagLib {
29+
namespace Matroska {
30+
class SeekHead;
31+
}
32+
namespace EBML {
33+
class MkSeekHead : public MasterElement
34+
{
35+
public:
36+
MkSeekHead(int sizeLength, offset_t dataSize, offset_t offset)
37+
: MasterElement(ElementIDs::MkSeekHead, sizeLength, dataSize, offset)
38+
{}
39+
MkSeekHead()
40+
: MasterElement(ElementIDs::MkSeekHead, 0, 0, 0)
41+
{}
42+
43+
Matroska::SeekHead* parse();
44+
45+
};
46+
}
47+
}
48+
#endif
49+
#endif

taglib/matroska/ebml/ebmlmksegment.cpp

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,13 @@
2121
#include "ebmlmksegment.h"
2222
#include "ebmlmktags.h"
2323
#include "ebmlmkattachments.h"
24+
#include "ebmlmkseekhead.h"
2425
#include "ebmlutils.h"
2526
#include "matroskafile.h"
2627
#include "matroskatag.h"
2728
#include "matroskaattachments.h"
29+
#include "matroskaseekhead.h"
30+
#include "matroskasegment.h"
2831
#include "tutils.h"
2932
#include "tbytevector.h"
3033
#include "tdebug.h"
@@ -35,16 +38,24 @@ EBML::MkSegment::~MkSegment()
3538
{
3639
delete tags;
3740
delete attachments;
41+
delete seekHead;
3842
}
3943

4044
bool EBML::MkSegment::read(File &file)
4145
{
4246
offset_t maxOffset = file.tell() + dataSize;
4347
EBML::Element *element = nullptr;
44-
48+
int i = 0;
49+
int seekHeadIndex = -1;
4550
while((element = findNextElement(file, maxOffset))) {
4651
Id id = element->getId();
47-
if(id == ElementIDs::MkTags) {
52+
if(id == ElementIDs::MkSeekHead) {
53+
seekHeadIndex = i;
54+
seekHead = static_cast<MkSeekHead*>(element);
55+
if(!seekHead->read(file))
56+
return false;
57+
}
58+
else if(id == ElementIDs::MkTags) {
4859
tags = static_cast<MkTags*>(element);
4960
if(!tags->read(file))
5061
return false;
@@ -55,9 +66,15 @@ bool EBML::MkSegment::read(File &file)
5566
return false;
5667
}
5768
else {
69+
if(id == ElementIDs::VoidElement
70+
&& seekHead
71+
&& seekHeadIndex == (i - 1))
72+
seekHead->setPadding(element->getSize());
73+
5874
element->skipData(file);
5975
delete element;
6076
}
77+
i++;
6178
}
6279
return true;
6380
}
@@ -71,3 +88,13 @@ Matroska::Attachments* EBML::MkSegment::parseAttachments()
7188
{
7289
return attachments ? attachments->parse() : nullptr;
7390
}
91+
92+
Matroska::SeekHead* EBML::MkSegment::parseSeekHead()
93+
{
94+
return seekHead ? seekHead->parse() : nullptr;
95+
}
96+
97+
Matroska::Segment* EBML::MkSegment::parseSegment()
98+
{
99+
return new Matroska::Segment(sizeLength, dataSize, offset + idSize(id));
100+
}

taglib/matroska/ebml/ebmlmksegment.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,13 @@ namespace TagLib {
3030
namespace Matroska {
3131
class Tag;
3232
class Attachments;
33+
class SeekHead;
34+
class Segment;
3335
}
3436
namespace EBML {
3537
class MkTags;
3638
class MkAttachments;
39+
class MkSeekHead;
3740
class MkSegment : public MasterElement
3841
{
3942
public:
@@ -44,10 +47,14 @@ namespace TagLib {
4447
bool read(File &file) override;
4548
Matroska::Tag* parseTag();
4649
Matroska::Attachments* parseAttachments();
50+
Matroska::SeekHead* parseSeekHead();
51+
Matroska::Segment* parseSegment();
4752

4853
private:
54+
offset_t dataOffset = 0;
4955
MkTags *tags = nullptr;
5056
MkAttachments *attachments = nullptr;
57+
MkSeekHead *seekHead = nullptr;
5158

5259
};
5360
}

taglib/matroska/ebml/ebmlmktags.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Matroska::Tag* EBML::MkTags::parse()
3636
auto mTag = new Matroska::Tag();
3737
mTag->setOffset(offset);
3838
mTag->setSize(getSize());
39+
mTag->setID(id);
3940

4041
// Loop through each <Tag> element
4142
for(auto tagsChild : elements) {

0 commit comments

Comments
 (0)