FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
python-ebml/tags.py at master · python-ffmpegio/python-ebml · GitHub
Uh oh!
There was an error while loading.
Please reload this page
.
python-ffmpegio
/
python-ebml
Public
forked from
QBobWatson/python-ebml
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Pull requests
0
Actions
Projects
Security and quality
0
Insights
Additional navigation options
Code
Pull requests
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
python-ebml
/
tags.py
Copy path
More file actions
More file actions
Latest commit
History
History
History
322 lines (286 loc) · 12.6 KB
Breadcrumbs
python-ebml
/
tags.py
Copy path
File metadata and controls
322 lines (286 loc) · 12.6 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
"""
Matroska tag processing.
"""
from
collections
.
abc
import
Mapping
__all__
=
[
'Tag'
,
'TagDict'
,
'MATROSKA_TAGS'
,
'INTERNAL_ID'
]
class
Tag
:
"""Class representing a specific EBML tag.
This class encodes all of the defining data of an EBML tag, originating from
Matroska's specdata.xml file. It serves mainly as an attribute dictionary
for the tag properties, but it also keeps track of parent-child
relationships.
Note that many different tags will correspond to the same Element class.
Attributes that are always defined:
+ ebml_id: The EBML ID of this tag, an integer.
+ name: The name of this tag, a string.
+ cls: The Element subclass to instantiate in self.__call__().
+ parent: The parent Tag instance. For level-zero tags this is None, and
for global tags it is "*".
+ mandatory: Whether this Tag must appear as a child of its parent. Used
in consistency checking. This is always False if the child has a default
value.
+ multiple: Whether this Tag may appear multiple times. Used in
consistency checking.
+ webm: Whether this Tag is part of webm. Unused by this module.
+ minver, maxver: The range of versions of the Matroska EBML specification
in which this tag appears. Unused by this module.
Attributes with default values:
+ header_size_min: Becomes the Element attribute of the same name.
+ data_size_min: Becomes the Element attribute of the same name.
Attributes that are sometimes defined:
+ min_val: For numeric types, valid values are greater than this value.
The inequality is strict for floats.
+ max_val: For numeric types, valid values are smaller than this value.
The inequality is strict for floats.
+ default: Default value. This may be a Tag instance, in which case it is
a sibling tag from which to inherit the default value.
+ recursive: Whether the tag can be a child of itself.
+ values: For Enum types, a dict whose keys are integers and whose values
are string representations of that value. For BitField types, a list of
strings whose ith element is the string representation of the ith bit.
Properties:
+ required_children: Iterator for required children.
+ unique_children: Iterator for unique children.
"""
#pylint: disable=too-many-instance-attributes
def
__init__
(
self
,
ebml_id
,
name
,
cls
,
parent
,
mandatory
,
multiple
,
webm
,
minver
,
maxver
,
**
kwargs
):
#pylint: disable=too-many-arguments
self
.
ebml_id
=
ebml_id
self
.
name
=
name
self
.
cls
=
cls
if
parent
is
None
or
parent
==
"*"
:
self
.
parent
=
parent
else
:
self
.
parent
=
MATROSKA_TAGS
[
parent
]
self
.
parent
.
children
.
append
(
self
)
self
.
_mandatory
=
mandatory
self
.
multiple
=
multiple
# Defaults
self
.
header_size_min
=
0
self
.
data_size_min
=
0
# Unused
self
.
webm
=
webm
self
.
minver
=
minver
self
.
maxver
=
maxver
# The rest
for
name
,
val
in
kwargs
.
items
():
setattr
(
self
,
name
,
val
)
self
.
children
=
[]
@
property
def
required_children
(
self
):
"Iterate over required children."
return
(
child
for
child
in
self
.
children
if
child
.
mandatory
)
@
property
def
unique_children
(
self
):
"Iterate over unique children."
return
(
child
for
child
in
self
.
children
if
not
child
.
multiple
)
@
property
def
mandatory
(
self
):
"Override mandatory property for tags with default values."
return
False
if
hasattr
(
self
,
'default'
)
else
self
.
_mandatory
def
__eq__
(
self
,
other
):
return
isinstance
(
other
,
Tag
)
and
self
.
ebml_id
==
other
.
ebml_id
def
__ne__
(
self
,
other
):
return
not
self
==
other
def
__hash__
(
self
):
return
self
.
ebml_id
def
__call__
(
self
,
header
):
"""Create a new Element instance for this tag.
Args:
+ header: as in Element.__init__().
"""
return
self
.
cls
(
header
,
name
=
self
.
name
)
def
is_child
(
self
,
tag
):
"Decide if this tag is allowed to be contained in tag."
if
tag
is
None
:
# Level zero
return
self
.
parent
is
None
or
self
.
parent
==
"*"
else
:
if
self
.
parent
==
tag
or
self
.
parent
==
"*"
:
return
True
return
hasattr
(
self
,
'recursive'
)
and
tag
==
self
class
TagDict
(
Mapping
):
"""Dictionary for storing Tag instances.
This dictionary does not support __setitem__(); instead Tag instances must
be added using insert(). They are stored under both their name and ID.
The tags are loaded on demand to prevent circular import dependencies.
"""
def
__init__
(
self
):
self
.
_dict
=
{}
self
.
_initialized
=
False
def
__getitem__
(
self
,
key
):
self
.
delayed_init
()
try
:
return
self
.
_dict
[
key
]
except
KeyError
:
if
isinstance
(
key
,
int
):
return
Tag
(
key
,
'Unknown'
,
'ElementUnsupported'
,
"*"
,
False
,
True
,
True
,
1
,
4
)
raise
def
__len__
(
self
):
self
.
delayed_init
()
return
len
(
self
.
_dict
)
def
__iter__
(
self
):
self
.
delayed_init
()
return
iter
(
self
.
_dict
)
def
__contains__
(
self
,
item
):
self
.
delayed_init
()
return
self
.
_dict
.
__contains__
(
item
)
def
keys
(
self
):
self
.
delayed_init
()
return
self
.
_dict
.
keys
()
def
items
(
self
):
self
.
delayed_init
()
return
self
.
_dict
.
items
()
def
values
(
self
):
self
.
delayed_init
()
return
self
.
_dict
.
values
()
def
get
(
self
,
key
,
default
=
None
):
self
.
delayed_init
()
return
self
.
_dict
.
get
(
key
,
default
)
def
insert
(
self
,
tag
):
"""Store tag in self under its name and ebml_id.
This is roughly equivalent to:
self[tag.ebml_id] = tag
self[tag.name] = tag
Args:
+ tag: A Tag instance.
Returns:
tag
Raises:
+ EbmlException, if tag is not an instance of Tag.
"""
if
isinstance
(
tag
,
Tag
):
self
.
_dict
[
tag
.
ebml_id
]
=
tag
self
.
_dict
[
tag
.
name
]
=
tag
else
:
raise
ValueError
(
"Tried to insert() a non-Tag instance {!r}"
.
format
(
tag
))
def
remove
(
self
,
ebml_id
):
"Remove a tag. For testing purposes."
tag
=
self
.
_dict
[
ebml_id
]
del
self
.
_dict
[
ebml_id
]
del
self
.
_dict
[
tag
.
name
]
def
level0s
(
self
):
"Iterate over Tag instances with parent equal to None."
for
ebml_id
,
val
in
self
.
items
():
if
isinstance
(
ebml_id
,
int
)
and
val
.
parent
is
None
:
yield
val
def
delayed_init
(
self
):
"Initialize the Tags."
#pylint: disable=too-many-statements,too-many-locals,unused-variable
if
self
.
_initialized
:
return
self
.
_initialized
=
True
from
.
tagdata
import
MATROSKA_TAG_DATA
from
.
element
import
ElementUnsupported
,
ElementPlaceholder
, \
ElementVoid
,
ElementMaster
,
ElementMasterDefer
from
.
atomic
import
ElementAtomic
,
ElementRaw
,
ElementUnsigned
, \
ElementSigned
,
ElementBoolean
,
ElementEnum
,
ElementBitField
, \
ElementFloat
,
ElementString
,
ElementUnicode
,
ElementDate
,
ElementID
from
.
data_elements
import
ElementEBML
,
ElementSegment
,
ElementSeek
, \
ElementInfo
,
ElementTrackEntry
,
ElementVideo
,
ElementAudio
, \
ElementAttachedFile
,
ElementTag
,
ElementTargets
,
ElementSimpleTag
, \
ElementEditionEntry
,
ElementChapterAtom
# For internal use
MATROSKA_TAG_DATA
.
append
(
dict
(
ebml_id
=
INTERNAL_ID
,
name
=
'LibInternal'
,
cls_name
=
'ElementPlaceholder'
,
parent
=
'*'
,
mandatory
=
False
,
multiple
=
True
,
webm
=
True
,
minver
=
1
,
maxver
=
4
))
MATROSKA_TAG_DATA
.
append
(
dict
(
ebml_id
=
INTERNAL_ID
,
name
=
'LibInternal2'
,
cls_name
=
'ElementPlaceholder'
,
parent
=
'*'
,
mandatory
=
False
,
multiple
=
True
,
webm
=
True
,
minver
=
1
,
maxver
=
4
))
for
tag_data
in
MATROSKA_TAG_DATA
:
cls_name
=
tag_data
[
'cls_name'
]
del
tag_data
[
'cls_name'
]
tag_data
[
'cls'
]
=
locals
()[
cls_name
]
self
.
insert
(
Tag
(
**
tag_data
))
# Override some automatically generated values
self
[
'EBML'
].
cls
=
ElementEBML
self
[
'Void'
].
cls
=
ElementVoid
self
[
'SignedElement'
].
cls
=
ElementID
self
[
'Segment'
].
cls
=
ElementSegment
self
[
'Segment'
].
header_size_min
=
8
self
[
'Seek'
].
cls
=
ElementSeek
self
[
'SeekID'
].
cls
=
ElementID
self
[
'SeekPosition'
].
data_size_min
=
8
self
[
'Info'
].
cls
=
ElementInfo
self
[
'Title'
].
data_size_min
=
100
self
[
'EditionEntry'
].
cls
=
ElementEditionEntry
self
[
'ChapterAtom'
].
cls
=
ElementChapterAtom
self
[
'ChapterTranslateCodec'
].
cls
=
ElementEnum
self
[
'ChapterTranslateCodec'
].
values
\
=
{
0
:
'Matroska Script'
,
1
:
'DVD-menu'
}
self
[
'SimpleBlock'
].
cls
=
ElementUnsupported
self
[
'Block'
].
cls
=
ElementUnsupported
self
[
'BlockVirtual'
].
cls
=
ElementUnsupported
self
[
'BlockAdditional'
].
cls
=
ElementUnsupported
self
[
'CodecState'
].
cls
=
ElementUnsupported
self
[
'EncryptedBlock'
].
cls
=
ElementUnsupported
self
[
'TrackEntry'
].
cls
=
ElementTrackEntry
self
[
'TrackType'
].
cls
=
ElementEnum
self
[
'TrackType'
].
values
\
=
{
0x1
:
'video'
,
0x2
:
'audio'
,
0x3
:
'complex'
,
0x10
:
'logo'
,
0x11
:
'subtitle'
,
0x12
:
'buttons'
,
0x20
:
'control'
}
self
[
'TrackTranslateCodec'
].
cls
=
ElementEnum
self
[
'TrackTranslateCodec'
].
values
\
=
{
0
:
'Matroska Script'
,
1
:
'DVD-menu'
}
self
[
'Video'
].
cls
=
ElementVideo
self
[
'StereoMode'
].
cls
=
ElementEnum
self
[
'StereoMode'
].
values
\
=
{
0
:
'mono'
,
1
:
'side-by-side (left)'
,
2
:
'top-bottom (right)'
,
3
:
'top-bottom (left)'
,
4
:
'checkerboard (right)'
,
5
:
'checkerboard (left)'
,
6
:
'row interleaved (right)'
,
7
:
'row interleaved (left)'
,
8
:
'col interleaved (right)'
,
9
:
'col interleaved (left)'
,
10
:
'anaglyph (cyan/red)'
,
11
:
'side-by-side (right)'
,
12
:
'anaglyph (green/magenta)'
,
13
:
'both (left)'
,
14
:
'both (right)'
}
self
[
'DisplayWidth'
].
default
=
self
[
'PixelWidth'
]
self
[
'DisplayHeight'
].
default
=
self
[
'PixelHeight'
]
self
[
'DisplayUnit'
].
cls
=
ElementEnum
self
[
'DisplayUnit'
].
values
\
=
{
0
:
'pixels'
,
1
:
'centimeters'
,
2
:
'inches'
,
3
:
'Display Aspect Ratio'
}
self
[
'AspectRatioType'
].
cls
=
ElementEnum
self
[
'AspectRatioType'
].
values
\
=
{
0
:
'free resizing'
,
1
:
'keep aspect ratio'
,
2
:
'fixed'
}
self
[
'Audio'
].
cls
=
ElementAudio
self
[
'OutputSamplingFrequency'
].
default
\
=
self
[
'SamplingFrequency'
]
self
[
'TrackPlaneType'
].
cls
=
ElementEnum
self
[
'TrackPlaneType'
].
values
\
=
{
0
:
'left eye'
,
1
:
'right eye'
,
2
:
'background'
}
self
[
'ContentEncodingScope'
].
cls
=
ElementBitField
self
[
'ContentEncodingScope'
].
values
\
=
[
'all-frame-contents'
,
'track-private-data'
,
'the-next-ContentEncoding'
]
self
[
'ContentEncodingType'
].
cls
=
ElementEnum
self
[
'ContentEncodingType'
].
values
\
=
{
0
:
'compression'
,
1
:
'encryption'
}
self
[
'ContentCompAlgo'
].
cls
=
ElementEnum
self
[
'ContentCompAlgo'
].
values
\
=
{
0
:
'zlib'
,
1
:
'bzlib'
,
2
:
'lzo1x'
,
3
:
'Header Stripping'
}
self
[
'ContentEncAlgo'
].
cls
=
ElementEnum
self
[
'ContentEncAlgo'
].
values
\
=
{
0
:
'signed only'
,
1
:
'DES'
,
2
:
'3DES'
,
3
:
'Twofish'
,
4
:
'Blowfish'
,
5
:
'AES'
}
self
[
'ContentSigAlgo'
].
cls
=
ElementEnum
self
[
'ContentSigAlgo'
].
values
\
=
{
0
:
'signed only'
,
1
:
'RSA'
}
self
[
'ContentSigHashAlgo'
].
cls
=
ElementEnum
self
[
'ContentSigHashAlgo'
].
values
\
=
{
0
:
'signed only'
,
1
:
'SHA1-160'
,
2
:
'MD5'
}
self
[
'Cues'
].
cls
=
ElementMasterDefer
self
[
'Attachments'
].
header_size_min
=
4
self
[
'AttachedFile'
].
cls
=
ElementAttachedFile
self
[
'AttachedFile'
].
header_size_min
=
4
self
[
'FileUID'
].
cls
=
ElementRaw
self
[
'Tag'
].
cls
=
ElementTag
self
[
'Targets'
].
cls
=
ElementTargets
self
[
'SimpleTag'
].
cls
=
ElementSimpleTag
# This dictionary contains the tags that the parser recognizes. The tags are
# Tag instances and the keys are the tag IDs and names.
MATROSKA_TAGS
=
TagDict
()
INTERNAL_ID
=
66
Back
|
FazBrowse Home
|
New Git URL