1
0

atom_standard.cpp 16 KB

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