61
|
1 /*
|
|
2 * The contents of this file are subject to the Mozilla Public
|
|
3 * License Version 1.1 (the "License"); you may not use this file
|
|
4 * except in compliance with the License. You may obtain a copy of
|
|
5 * the License at http://www.mozilla.org/MPL/
|
|
6 *
|
|
7 * Software distributed under the License is distributed on an "AS
|
|
8 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
9 * implied. See the License for the specific language governing
|
|
10 * rights and limitations under the License.
|
|
11 *
|
|
12 * The Original Code is MPEG4IP.
|
|
13 *
|
|
14 * The Initial Developer of the Original Code is Cisco Systems Inc.
|
|
15 * Portions created by Cisco Systems Inc. are
|
|
16 * Copyright (C) Cisco Systems Inc. 2004. All Rights Reserved.
|
|
17 *
|
|
18 * Contributor(s):
|
|
19 * Bill May (from others work).
|
|
20 */
|
|
21
|
|
22 #include "mp4common.h"
|
|
23 #include "atoms.h"
|
|
24
|
|
25 static const char name[5]={0251,'n', 'a', 'm', '\0'};
|
|
26 static const char art[5]={0251,'A', 'R', 'T', '\0'};
|
|
27 static const char wrt[5]={0251,'w', 'r', 't', '\0'};
|
|
28 static const char alb[5]={0251,'a', 'l', 'b', '\0'};
|
|
29 static const char day[5]={0251,'d', 'a', 'y', '\0'};
|
|
30 static const char too[5]={0251,'t', 'o', 'o', '\0'};
|
|
31 static const char cmt[5]={0251,'c', 'm', 't', '\0'};
|
|
32 static const char gen[5]={0251,'g', 'e', 'n', '\0'};
|
|
33 static const char grp[5]={0251,'g', 'r', 'p', '\0'};
|
|
34
|
|
35 MP4StandardAtom::MP4StandardAtom (const char *type) : MP4Atom(type)
|
|
36 {
|
|
37 /*
|
|
38 * This is a big if else loop. Make sure that you don't break it
|
|
39 * when adding new atoms, or you will set the unknown type flag
|
|
40 *
|
|
41 * Try to keep it in alphabetical order - it should only be called
|
|
42 * 1 time per atom, so it's not that urgent.
|
|
43 */
|
|
44 /*
|
|
45 * b???
|
|
46 */
|
|
47 if (ATOMID(type) == ATOMID("bitr")) {
|
|
48 AddProperty( /* 0 */
|
|
49 new MP4Integer32Property("avgBitrate"));
|
|
50
|
|
51 AddProperty( /* 1 */
|
|
52 new MP4Integer32Property("maxBitrate"));
|
|
53
|
|
54 } else if (ATOMID(type) == ATOMID("btrt")) {
|
|
55 AddProperty( new MP4Integer32Property("bufferSizeDB")); /* 0 */
|
|
56 AddProperty( new MP4Integer32Property("avgBitrate")); /* 1 */
|
|
57 AddProperty( new MP4Integer32Property("maxBitrate")); /* 2 */
|
|
58 /*
|
|
59 * c???
|
|
60 */
|
|
61 } else if (ATOMID(type) == ATOMID("co64")) {
|
|
62 AddVersionAndFlags();
|
|
63
|
|
64 MP4Integer32Property* pCount =
|
|
65 new MP4Integer32Property("entryCount");
|
|
66 AddProperty(pCount);
|
|
67
|
|
68 MP4TableProperty* pTable = new MP4TableProperty("entries", pCount);
|
|
69 AddProperty(pTable);
|
|
70
|
|
71 pTable->AddProperty(
|
|
72 new MP4Integer64Property("chunkOffset"));
|
|
73
|
|
74 } else if (ATOMID(type) == ATOMID("cpil") ||
|
|
75 ATOMID(type) == ATOMID("covr")) { /* Apple iTunes */
|
|
76 ExpectChildAtom("data", Required, OnlyOne);
|
|
77
|
|
78 } else if (ATOMID(type) == ATOMID("cprt")) {
|
|
79 AddVersionAndFlags();
|
|
80 AddProperty(
|
|
81 new MP4Integer16Property("language"));
|
|
82 AddProperty(
|
|
83 new MP4StringProperty("notice"));
|
|
84
|
|
85 } else if (ATOMID(type) == ATOMID("ctts")) {
|
|
86 AddVersionAndFlags();
|
|
87
|
|
88 MP4Integer32Property* pCount =
|
|
89 new MP4Integer32Property("entryCount");
|
|
90 AddProperty(pCount);
|
|
91
|
|
92 MP4TableProperty* pTable = new MP4TableProperty("entries", pCount);
|
|
93 AddProperty(pTable);
|
|
94
|
|
95 pTable->AddProperty(new MP4Integer32Property("sampleCount"));
|
|
96 pTable->AddProperty(new MP4Integer32Property("sampleOffset"));
|
|
97 /*
|
|
98 * d???
|
|
99 */
|
|
100 } else if (ATOMID(type) == ATOMID("dinf")) {
|
|
101 ExpectChildAtom("dref", Required, OnlyOne);
|
|
102
|
|
103 } else if (ATOMID(type) == ATOMID("dimm")) {
|
|
104 AddProperty( // bytes of immediate data
|
|
105 new MP4Integer64Property("bytes"));
|
|
106
|
|
107 } else if (ATOMID(type) == ATOMID("disk")) { /* Apple iTunes */
|
|
108 ExpectChildAtom("data", Required, OnlyOne);
|
|
109
|
|
110 } else if (ATOMID(type) == ATOMID("dmax")) {
|
|
111 AddProperty( // max packet duration
|
|
112 new MP4Integer32Property("milliSecs"));
|
|
113
|
|
114 } else if (ATOMID(type) == ATOMID("dmed")) {
|
|
115 AddProperty( // bytes sent from media data
|
|
116 new MP4Integer64Property("bytes"));
|
|
117
|
|
118 } else if (ATOMID(type) == ATOMID("drep")) {
|
|
119 AddProperty( // bytes of repeated data
|
|
120 new MP4Integer64Property("bytes"));
|
|
121 /*
|
|
122 * e???
|
|
123 */
|
|
124 } else if (ATOMID(type) == ATOMID("edts")) {
|
|
125 ExpectChildAtom("elst", Required, OnlyOne);
|
|
126
|
|
127 } else if (ATOMID(type) == ATOMID("esds")) {
|
|
128 AddVersionAndFlags();
|
|
129 AddProperty(
|
|
130 new MP4DescriptorProperty(NULL, MP4ESDescrTag, 0,
|
|
131 Required, OnlyOne));
|
|
132 /*
|
|
133 * f???
|
|
134 */
|
|
135 } else if (ATOMID(type) == ATOMID("frma")) {
|
|
136 AddProperty( /* 0 */
|
|
137 new MP4Integer32Property("data-format"));
|
|
138 /*
|
|
139 * g???
|
|
140 */
|
|
141 } else if (ATOMID(type) == ATOMID("gnre")) { // Apple iTunes
|
|
142 ExpectChildAtom("data", Optional, OnlyOne);
|
|
143
|
|
144 /*
|
|
145 * h???
|
|
146 */
|
|
147 } else if (ATOMID(type) == ATOMID("hmhd")) {
|
|
148 AddVersionAndFlags();
|
|
149
|
|
150 AddProperty(new MP4Integer16Property("maxPduSize"));
|
|
151 AddProperty(new MP4Integer16Property("avgPduSize"));
|
|
152 AddProperty(new MP4Integer32Property("maxBitRate"));
|
|
153 AddProperty(new MP4Integer32Property("avgBitRate"));
|
|
154 AddProperty(new MP4Integer32Property("slidingAvgBitRate"));
|
|
155 /*
|
|
156 * i???
|
|
157 */
|
|
158 } else if (ATOMID(type) == ATOMID("iKMS")) {
|
|
159 AddVersionAndFlags(); /* 0, 1 */
|
|
160 MP4StringProperty* pProp = new MP4StringProperty("kms_URI");
|
|
161 AddProperty(pProp); /* 2 */
|
|
162
|
|
163 } else if (ATOMID(type) == ATOMID("iSFM")) {
|
|
164 AddVersionAndFlags(); /* 0, 1 */
|
|
165 AddProperty( /* 2 */
|
|
166 new MP4BitfieldProperty("selective-encryption", 1));
|
|
167 AddProperty( /* 3 */
|
|
168 new MP4BitfieldProperty("reserved", 7));
|
|
169 AddProperty( /* 4 */
|
|
170 new MP4Integer8Property("key-indicator-length"));
|
|
171 AddProperty( /* 5 */
|
|
172 new MP4Integer8Property("IV-length"));
|
|
173
|
|
174 } else if (ATOMID(type) == ATOMID("ilst")) {
|
|
175 ExpectChildAtom("\251nam", Optional, OnlyOne); /* name */
|
|
176 ExpectChildAtom("\251ART", Optional, OnlyOne); /* artist */
|
|
177 ExpectChildAtom("\251wrt", Optional, OnlyOne); /* writer */
|
|
178 ExpectChildAtom("\251alb", Optional, OnlyOne); /* album */
|
|
179 ExpectChildAtom("\251day", Optional, OnlyOne); /* date */
|
|
180 ExpectChildAtom("\251too", Optional, OnlyOne); /* tool */
|
|
181 ExpectChildAtom("\251cmt", Optional, OnlyOne); /* comment */
|
|
182 ExpectChildAtom("\251gen", Optional, OnlyOne); /* custom genre */
|
|
183 ExpectChildAtom("trkn", Optional, OnlyOne); /* tracknumber */
|
|
184 ExpectChildAtom("disk", Optional, OnlyOne); /* disknumber */
|
|
185 ExpectChildAtom("gnre", Optional, OnlyOne); /* genre (ID3v1 index + 1) */
|
|
186 ExpectChildAtom("cpil", Optional, OnlyOne); /* compilation */
|
|
187 ExpectChildAtom("tmpo", Optional, OnlyOne); /* BPM */
|
|
188 ExpectChildAtom("covr", Optional, OnlyOne); /* cover art */
|
|
189 ExpectChildAtom("----", Optional, Many); /* ---- free form */
|
|
190
|
|
191 } else if (ATOMID(type) == ATOMID("iods")) {
|
|
192 AddVersionAndFlags();
|
|
193 AddProperty(
|
|
194 new MP4DescriptorProperty(NULL, MP4FileIODescrTag,
|
|
195 MP4FileODescrTag,
|
|
196 Required, OnlyOne));
|
|
197 /*
|
|
198 * m???
|
|
199 */
|
|
200 } else if (ATOMID(type) == ATOMID("maxr")) {
|
|
201 AddProperty(new MP4Integer32Property("granularity"));
|
|
202 AddProperty(new MP4Integer32Property("bytes"));
|
|
203
|
|
204 } else if (ATOMID(type) == ATOMID("mdia")) {
|
|
205 ExpectChildAtom("mdhd", Required, OnlyOne);
|
|
206 ExpectChildAtom("hdlr", Required, OnlyOne);
|
|
207 ExpectChildAtom("minf", Required, OnlyOne);
|
|
208
|
|
209 } else if (ATOMID(type) == ATOMID("meta")) { // iTunes
|
|
210 AddVersionAndFlags(); /* 0, 1 */
|
|
211 ExpectChildAtom("hdlr", Required, OnlyOne);
|
|
212 ExpectChildAtom("ilst", Required, OnlyOne);
|
|
213
|
|
214 } else if (ATOMID(type) == ATOMID("mfhd")) {
|
|
215 AddVersionAndFlags(); /* 0, 1 */
|
|
216 AddProperty( /* 2 */
|
|
217 new MP4Integer32Property("sequenceNumber"));
|
|
218
|
|
219 } else if (ATOMID(type) == ATOMID("minf")) {
|
|
220 ExpectChildAtom("vmhd", Optional, OnlyOne);
|
|
221 ExpectChildAtom("smhd", Optional, OnlyOne);
|
|
222 ExpectChildAtom("hmhd", Optional, OnlyOne);
|
|
223 ExpectChildAtom("nmhd", Optional, OnlyOne);
|
|
224 ExpectChildAtom("dinf", Required, OnlyOne);
|
|
225 ExpectChildAtom("stbl", Required, OnlyOne);
|
|
226
|
|
227 } else if (ATOMID(type) == ATOMID("moof")) {
|
|
228 ExpectChildAtom("mfhd", Required, OnlyOne);
|
|
229 ExpectChildAtom("traf", Optional, Many);
|
|
230
|
|
231 } else if (ATOMID(type) == ATOMID("moov")) {
|
|
232 ExpectChildAtom("mvhd", Required, OnlyOne);
|
|
233 ExpectChildAtom("iods", Required, OnlyOne);
|
|
234 ExpectChildAtom("trak", Required, Many);
|
|
235 ExpectChildAtom("udta", Optional, Many);
|
|
236 ExpectChildAtom("mvex", Optional, OnlyOne);
|
|
237
|
|
238 } else if (ATOMID(type) == ATOMID("mvex")) {
|
|
239 ExpectChildAtom("trex", Required, Many);
|
|
240
|
|
241 /*
|
|
242 * n???
|
|
243 */
|
|
244 } else if (ATOMID(type) == ATOMID("nmhd")) {
|
|
245 AddVersionAndFlags();
|
|
246
|
|
247 } else if (ATOMID(type) == ATOMID("nump")) {
|
|
248 AddProperty( // packets sent
|
|
249 new MP4Integer64Property("packets"));
|
|
250 /*
|
|
251 * p???
|
|
252 */
|
|
253 } else if (ATOMID(type) == ATOMID("payt")) {
|
|
254 AddProperty(new MP4Integer32Property("payloadNumber"));
|
|
255 AddProperty(new MP4StringProperty("rtpMap", Counted));
|
|
256
|
|
257 } else if (ATOMID(type) == ATOMID("pmax")) {
|
|
258 AddProperty( // max packet size
|
|
259 new MP4Integer32Property("bytes"));
|
|
260 /*
|
|
261 * s???
|
|
262 */
|
|
263 } else if (ATOMID(type) == ATOMID("schi")) {
|
|
264 // not sure if this is child atoms or table of boxes
|
|
265 // get clarification on spec 9.1.2.5
|
|
266 ExpectChildAtom("iKMS", Required, OnlyOne);
|
|
267 ExpectChildAtom("iSFM", Required, OnlyOne);
|
|
268
|
|
269 } else if (ATOMID(type) == ATOMID("schm")) {
|
|
270 AddVersionAndFlags(); /* 0, 1 */
|
|
271 AddProperty( /* 2 */
|
|
272 new MP4Integer32Property("scheme_type"));
|
|
273 AddProperty( /* 3 */
|
|
274 new MP4Integer32Property("scheme_version"));
|
|
275 // browser URI if flags set, TODO
|
|
276
|
|
277 } else if (ATOMID(type) == ATOMID("sinf")) {
|
|
278 ExpectChildAtom("frma", Required, OnlyOne);
|
|
279 ExpectChildAtom("schm", Required, OnlyOne);
|
|
280 ExpectChildAtom("schi", Required, OnlyOne);
|
|
281
|
|
282 } else if (ATOMID(type) == ATOMID("smhd")) {
|
|
283 AddVersionAndFlags();
|
|
284 AddReserved("reserved", 4);
|
|
285
|
|
286 } else if (ATOMID(type) == ATOMID("snro")) {
|
|
287 AddProperty(new MP4Integer32Property("offset"));
|
|
288
|
|
289 } else if (ATOMID(type) == ATOMID("stco")) {
|
|
290 AddVersionAndFlags();
|
|
291
|
|
292 MP4Integer32Property* pCount = new MP4Integer32Property("entryCount");
|
|
293 AddProperty(pCount);
|
|
294
|
|
295 MP4TableProperty* pTable = new MP4TableProperty("entries", pCount);
|
|
296 AddProperty(pTable);
|
|
297
|
|
298 pTable->AddProperty(new MP4Integer32Property("chunkOffset"));
|
|
299
|
|
300 } else if (ATOMID(type) == ATOMID("stsh")) {
|
|
301 AddVersionAndFlags();
|
|
302
|
|
303 MP4Integer32Property* pCount = new MP4Integer32Property("entryCount");
|
|
304 AddProperty(pCount);
|
|
305
|
|
306 MP4TableProperty* pTable = new MP4TableProperty("entries", pCount);
|
|
307 AddProperty(pTable);
|
|
308
|
|
309 pTable->AddProperty(new MP4Integer32Property("shadowedSampleNumber"));
|
|
310 pTable->AddProperty(new MP4Integer32Property("syncSampleNumber"));
|
|
311
|
|
312 } else if (ATOMID(type) == ATOMID("stss")) {
|
|
313 AddVersionAndFlags();
|
|
314
|
|
315 MP4Integer32Property* pCount = new MP4Integer32Property("entryCount");
|
|
316 AddProperty(pCount);
|
|
317
|
|
318 MP4TableProperty* pTable = new MP4TableProperty("entries", pCount);
|
|
319 AddProperty(pTable);
|
|
320
|
|
321 pTable->AddProperty(new MP4Integer32Property("sampleNumber"));
|
|
322
|
|
323 } else if (ATOMID(type) == ATOMID("stts")) {
|
|
324 AddVersionAndFlags();
|
|
325 MP4Integer32Property* pCount = new MP4Integer32Property("entryCount");
|
|
326 AddProperty(pCount);
|
|
327
|
|
328 MP4TableProperty* pTable = new MP4TableProperty("entries", pCount);
|
|
329 AddProperty(pTable);
|
|
330
|
|
331 pTable->AddProperty(new MP4Integer32Property("sampleCount"));
|
|
332 pTable->AddProperty(new MP4Integer32Property("sampleDelta"));
|
|
333
|
|
334 /*
|
|
335 * t???
|
|
336 */
|
|
337 } else if (ATOMID(type) == ATOMID("tims")) {
|
|
338 AddProperty(
|
|
339 new MP4Integer32Property("timeScale"));
|
|
340
|
|
341 } else if (ATOMID(type) == ATOMID("tmin")) {
|
|
342 AddProperty( // min relative xmit time
|
|
343 new MP4Integer32Property("milliSecs"));
|
|
344
|
|
345 } else if (ATOMID(type) == ATOMID("tmax")) {
|
|
346 AddProperty( // max relative xmit time
|
|
347 new MP4Integer32Property("milliSecs"));
|
|
348
|
|
349 } else if (ATOMID(type) == ATOMID("tmpo")) { // iTunes
|
|
350 ExpectChildAtom("data", Required, OnlyOne);
|
|
351
|
|
352 } else if (ATOMID(type) == ATOMID("traf")) {
|
|
353 ExpectChildAtom("tfhd", Required, OnlyOne);
|
|
354 ExpectChildAtom("trun", Optional, Many);
|
|
355
|
|
356 } else if (ATOMID(type) == ATOMID("trak")) {
|
|
357 ExpectChildAtom("tkhd", Required, OnlyOne);
|
|
358 ExpectChildAtom("tref", Optional, OnlyOne);
|
|
359 ExpectChildAtom("edts", Optional, OnlyOne);
|
|
360 ExpectChildAtom("mdia", Required, OnlyOne);
|
|
361 ExpectChildAtom("udta", Optional, Many);
|
|
362
|
|
363 } else if (ATOMID(type) == ATOMID("tref")) {
|
|
364 ExpectChildAtom("dpnd", Optional, OnlyOne);
|
|
365 ExpectChildAtom("hint", Optional, OnlyOne);
|
|
366 ExpectChildAtom("ipir", Optional, OnlyOne);
|
|
367 ExpectChildAtom("mpod", Optional, OnlyOne);
|
|
368 ExpectChildAtom("sync", Optional, OnlyOne);
|
|
369
|
|
370 } else if (ATOMID(type) == ATOMID("trex")) {
|
|
371 AddVersionAndFlags(); /* 0, 1 */
|
|
372 AddProperty( /* 2 */
|
|
373 new MP4Integer32Property("trackId"));
|
|
374 AddProperty( /* 3 */
|
|
375 new MP4Integer32Property("defaultSampleDesriptionIndex"));
|
|
376 AddProperty( /* 4 */
|
|
377 new MP4Integer32Property("defaultSampleDuration"));
|
|
378 AddProperty( /* 5 */
|
|
379 new MP4Integer32Property("defaultSampleSize"));
|
|
380 AddProperty( /* 6 */
|
|
381 new MP4Integer32Property("defaultSampleFlags"));
|
|
382
|
|
383 } else if (ATOMID(type) == ATOMID("trkn")) { // iTunes
|
|
384 ExpectChildAtom("data", Required, OnlyOne);
|
|
385
|
|
386 } else if (ATOMID(type) == ATOMID("trpy") ||
|
|
387 ATOMID(type) == ATOMID("tpyl")) {
|
|
388 AddProperty( // bytes sent including RTP headers
|
|
389 new MP4Integer64Property("bytes"));
|
|
390
|
|
391 } else if (ATOMID(type) == ATOMID("tsro")) {
|
|
392 AddProperty(
|
|
393 new MP4Integer32Property("offset"));
|
|
394
|
|
395 /*
|
|
396 * copyright???
|
|
397 */
|
|
398 } else if (ATOMID(type) == ATOMID(name) ||
|
|
399 ATOMID(type) == ATOMID(art) ||
|
|
400 ATOMID(type) == ATOMID(wrt) ||
|
|
401 ATOMID(type) == ATOMID(alb) ||
|
|
402 ATOMID(type) == ATOMID(day) ||
|
|
403 ATOMID(type) == ATOMID(too) ||
|
|
404 ATOMID(type) == ATOMID(cmt) ||
|
|
405 ATOMID(type) == ATOMID(gen) ||
|
|
406 ATOMID(type) == ATOMID(grp)) { /* Apple iTunes */
|
|
407 ExpectChildAtom("data", Required, OnlyOne);
|
|
408 /*
|
|
409 * ----
|
|
410 */
|
|
411 } else if (ATOMID(type) == ATOMID("----")) { /* Apple iTunes */
|
|
412 ExpectChildAtom("mean", Required, OnlyOne);
|
|
413 ExpectChildAtom("name", Required, OnlyOne);
|
|
414 ExpectChildAtom("data", Required, OnlyOne);
|
|
415 } else {
|
|
416 /*
|
|
417 * default - unknown type
|
|
418 */
|
|
419 SetUnknownType(true);
|
|
420 }
|
|
421
|
|
422 }
|