File Coverage

blib/lib/Parse/Matroska/Definitions.pm
Criterion Covered Total %
statement 43 43 100.0
branch 3 4 75.0
condition n/a
subroutine 10 10 100.0
pod 4 4 100.0
total 60 61 98.3


line stmt bran cond sub pod time code
1 1     1   14 use 5.008;
  1         3  
  1         32  
2 1     1   5 use strict;
  1         2  
  1         24  
3 1     1   5 use warnings;
  1         1  
  1         54  
4              
5             # ABSTRACT: internal EBML grammar definitions
6             package Parse::Matroska::Definitions;
7             {
8             $Parse::Matroska::Definitions::VERSION = '0.003';
9             }
10              
11 1     1   544 use Parse::Matroska::Utils qw{uniq uncamelize};
  1         2  
  1         49  
12              
13 1     1   4 use Exporter;
  1         1  
  1         146  
14             our @ISA = qw{Exporter};
15             our @EXPORT_OK = qw{elem_by_hexid %EBML_DEFINITION %MATROSKA_DEFINITION};
16              
17              
18             @Parse::Matroska::Definitions::global_elem_list = ();
19             %Parse::Matroska::Definitions::global_elem_dict = ();
20              
21              
22             our %EBML_DEFINITION = define_ebml();
23             our %MATROSKA_DEFINITION = define_matroska();
24              
25             sub elem_by_hexid {
26 25     25 1 28 my ($elid) = @_;
27 25         79 return $Parse::Matroska::Definitions::global_elem_dict{$elid};
28             }
29              
30             ################################################
31             ### Helper functions for document definition ###
32             ################################################
33              
34             # used by elem when setting the 'valname' key
35 1         1303 use constant TYPE_MAP => {
36             uint => 'uint64_t',
37             str => 'struct bstr',
38             binary => 'struct bstr',
39             ebml_id => 'uint32_t',
40             float => 'double',
41             sint => 'int64_t',
42 1     1   4 };
  1         1  
43              
44             # this will be localized to "MATROSKA" or "EBML" on the elem declarations
45             our $ELEM_DEFINE_TYPE = undef;
46              
47             sub elem {
48 116     116 1 302 my %e = (name => shift, elid => shift, valtype => shift);
49              
50             # strip * from name, set 'multiple' if there was one
51 116         253 $e{multiple} = scalar $e{name} =~ s/\*$//;
52              
53             # ELEM_DEFINE_TYPE is either MATROSKA or EBML
54 116         257 $e{definename} = "${ELEM_DEFINE_TYPE}_ID_".uc($e{name});
55 116         251 $e{fieldname} = uncamelize $e{name};
56 116         233 $e{structname} = "ebml_$e{fieldname}";
57              
58 116 100       194 if (ref $e{valtype} eq 'HASH') {
59 27         54 $e{subelements} = $e{valtype};
60 27         26 $e{subids} = uniq map { $_->{elid} } values %{$e{subelements}};
  112         248  
  27         80  
61 27         47 $e{valtype} = 'sub';
62 27         34 $e{ebmltype} = 'EBML_TYPE_SUBELEMENTS';
63 27         51 $e{valname} = "struct $e{structname}";
64             } else {
65 89         219 $e{ebmltype} = "EBML_TYPE_\U$e{valtype}";
66 89 50       226 die "Unrecognized value type $e{valtype}" unless
67             defined ($e{valname} = TYPE_MAP->{$e{valtype}});
68             }
69 116         142 my $e = \%e;
70 116         146 push @Parse::Matroska::Definitions::global_elem_list, $e;
71 116         221 $Parse::Matroska::Definitions::global_elem_dict{$e{elid}} = $e;
72 116         410 return ($e{elid}, $e);
73             }
74              
75             #############################################
76             ### EBML and Matroska document definitons ###
77             #############################################
78              
79             sub define_ebml {
80 1     1 1 1 local $ELEM_DEFINE_TYPE = 'EBML';
81             return (
82 1         2 elem('EBML', '1a45dfa3', {
83             elem('EBMLVersion', '4286', 'uint'),
84             elem('EBMLReadVersion', '42f7', 'uint'),
85             elem('EBMLMaxIDLength', '42f2', 'uint'),
86             elem('EBMLMaxSizeLength', '42f3', 'uint'),
87             elem('DocType', '4282', 'str'),
88             elem('DocTypeVersion', '4287', 'uint'),
89             elem('DocTypeReadVersion', '4285', 'uint'),
90             }),
91              
92             elem('CRC32', 'bf', 'binary'),
93             elem('Void', 'ec', 'binary'),
94             );
95             }
96              
97              
98             sub define_matroska {
99 1     1 1 1 local $ELEM_DEFINE_TYPE = 'MATROSKA';
100             return (
101 1         7 elem('Segment', '18538067', {
102             elem('SeekHead*', '114d9b74', {
103             elem('Seek*', '4dbb', {
104             elem('SeekID', '53ab', 'ebml_id'),
105             elem('SeekPosition', '53ac', 'uint'),
106             }),
107             }),
108              
109             elem('Info*', '1549a966', {
110             elem('SegmentUID', '73a4', 'binary'),
111             elem('PrevUID', '3cb923', 'binary'),
112             elem('NextUID', '3eb923', 'binary'),
113             elem('TimecodeScale', '2ad7b1', 'uint'),
114             elem('DateUTC', '4461', 'sint'),
115             elem('Title', '7ba9', 'str'),
116             elem('MuxingApp', '4d80', 'str'),
117             elem('WritingApp', '5741', 'str'),
118             elem('Duration', '4489', 'float'),
119             }),
120              
121             elem('Cluster*', '1f43b675', {
122             elem('Timecode', 'e7', 'uint'),
123             elem('BlockGroup*', 'a0', {
124             elem('Block', 'a1', 'binary'),
125             elem('BlockDuration', '9b', 'uint'),
126             elem('ReferenceBlock*', 'fb', 'sint'),
127             }),
128             elem('SimpleBlock*', 'a3', 'binary'),
129             }),
130              
131             elem('Tracks*', '1654ae6b', {
132             elem('TrackEntry*', 'ae', {
133             elem('TrackNumber', 'd7', 'uint'),
134             elem('TrackUID', '73c5', 'uint'),
135             elem('TrackType', '83', 'uint'),
136             elem('FlagEnabled', 'b9', 'uint'),
137             elem('FlagDefault', '88', 'uint'),
138             elem('FlagForced', '55aa', 'uint'),
139             elem('FlagLacing', '9c', 'uint'),
140             elem('MinCache', '6de7', 'uint'),
141             elem('MaxCache', '6df8', 'uint'),
142             elem('DefaultDuration', '23e383', 'uint'),
143             elem('TrackTimecodeScale', '23314f', 'float'),
144             elem('MaxBlockAdditionID', '55ee', 'uint'),
145             elem('Name', '536e', 'str'),
146             elem('Language', '22b59c', 'str'),
147             elem('CodecID', '86', 'str'),
148             elem('CodecPrivate', '63a2', 'binary'),
149             elem('CodecName', '258688', 'str'),
150             elem('CodecDecodeAll', 'aa', 'uint'),
151             elem('Video', 'e0', {
152             elem('FlagInterlaced', '9a', 'uint'),
153             elem('PixelWidth', 'b0', 'uint'),
154             elem('PixelHeight', 'ba', 'uint'),
155             elem('DisplayWidth', '54b0', 'uint'),
156             elem('DisplayHeight', '54ba', 'uint'),
157             elem('DisplayUnit', '54b2', 'uint'),
158             elem('FrameRate', '2383e3', 'float'),
159             }),
160             elem('Audio', 'e1', {
161             elem('SamplingFrequency', 'b5', 'float'),
162             elem('OutputSamplingFrequency', '78b5', 'float'),
163             elem('Channels', '9f', 'uint'),
164             elem('BitDepth', '6264', 'uint'),
165             }),
166             elem('ContentEncodings', '6d80', {
167             elem('ContentEncoding*', '6240', {
168             elem('ContentEncodingOrder', '5031', 'uint'),
169             elem('ContentEncodingScope', '5032', 'uint'),
170             elem('ContentEncodingType', '5033', 'uint'),
171             elem('ContentCompression', '5034', {
172             elem('ContentCompAlgo', '4254', 'uint'),
173             elem('ContentCompSettings', '4255', 'binary'),
174             }),
175             }),
176             }),
177             }),
178             }),
179              
180             elem('Cues', '1c53bb6b', {
181             elem('CuePoint*', 'bb', {
182             elem('CueTime', 'b3', 'uint'),
183             elem('CueTrackPositions*', 'b7', {
184             elem('CueTrack', 'f7', 'uint'),
185             elem('CueClusterPosition', 'f1', 'uint'),
186             }),
187             }),
188             }),
189              
190             elem('Attachments', '1941a469', {
191             elem('AttachedFile*', '61a7', {
192             elem('FileDescription', '467e', 'str'),
193             elem('FileName', '466e', 'str'),
194             elem('FileMimeType', '4660', 'str'),
195             elem('FileData', '465c', 'binary'),
196             elem('FileUID', '46ae', 'uint'),
197             }),
198             }),
199              
200             elem('Chapters', '1043a770', {
201             elem('EditionEntry*', '45b9', {
202             elem('EditionUID', '45bc', 'uint'),
203             elem('EditionFlagHidden', '45bd', 'uint'),
204             elem('EditionFlagDefault', '45db', 'uint'),
205             elem('EditionFlagOrdered', '45dd', 'uint'),
206             elem('ChapterAtom*', 'b6', {
207             elem('ChapterUID', '73c4', 'uint'),
208             elem('ChapterTimeStart', '91', 'uint'),
209             elem('ChapterTimeEnd', '92', 'uint'),
210             elem('ChapterFlagHidden', '98', 'uint'),
211             elem('ChapterFlagEnabled', '4598', 'uint'),
212             elem('ChapterSegmentUID', '6e67', 'binary'),
213             elem('ChapterSegmentEditionUID', '6ebc', 'uint'),
214             elem('ChapterDisplay*', '80', {
215             elem('ChapString', '85', 'str'),
216             elem('ChapLanguage*', '437c', 'str'),
217             elem('ChapCountry*', '437e', 'str'),
218             }),
219             }),
220             }),
221             }),
222             elem('Tags*', '1254c367', {
223             elem('Tag*', '7373', {
224             elem('Targets', '63c0', {
225             elem('TargetTypeValue', '68ca', 'uint'),
226             elem('TargetTrackUID', '63c5', 'uint'),
227             elem('TargetEditionUID', '63c9', 'uint'),
228             elem('TargetChapterUID', '63c4', 'uint'),
229             elem('TargetAttachmentUID', '63c6', 'uint'),
230             }),
231             elem('SimpleTag*', '67c8', {
232             elem('TagName', '45a3', 'str'),
233             elem('TagLanguage', '447a', 'str'),
234             elem('TagString', '4487', 'str'),
235             }),
236             }),
237             }),
238             }),
239             );
240             }
241              
242             1;
243              
244             __END__