INTERNALS 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. January 7, 2002
  2. MP4V2 LIBRARY INTERNALS
  3. =======================
  4. This document provides an overview of the internals of the mp4v2 library
  5. to aid those who wish to modify and extend it. Before reading this document,
  6. I recommend familiarizing yourself with the MP4 (or Quicktime) file format
  7. standard and the mp4v2 library API. The API is described in a set of man pages
  8. in mpeg4ip/doc/mp4v2, or if you prefer by looking at mp4.h.
  9. All the library code is written in C++, however the library API follows uses
  10. C calling conventions hence is linkable by both C and C++ programs. The
  11. library has been compiled and used on Linux, BSD, Windows, and Mac OS X.
  12. Other than libc, the library has no external dependencies, and hence can
  13. be used independently of the mpeg4ip package if desired. The library is
  14. used for both real-time recording and playback in mpeg4ip, and its runtime
  15. performance is up to those tasks. On the IA32 architecture compiled with gcc,
  16. the stripped library is approximately 600 KB code and initialized data.
  17. It is useful to think of the mp4v2 library as consisting of four layers:
  18. infrastructure, file format, generic tracks, and type specific track helpers.
  19. A description of each layer follows, from the fundamental to the optional.
  20. Infrastructure
  21. ==============
  22. The infrastructure layer provides basic file I/O, memory allocation,
  23. error handling, string utilities, and protected arrays. The source files
  24. for this layer are mp4file_io, mp4util, and mp4array.
  25. Note that the array classes uses preprocessor macros instead of C++
  26. templates. The rationale for this is to increase portability given the
  27. sometimes incomplete support by some compilers for templates.
  28. File Format
  29. ===========
  30. The file format layer provides the translation from the on-disk MP4 file
  31. format to in-memory C++ structures and back to disk. It is intended
  32. to exactly match the MP4 specification in syntax and semantics. It
  33. represents the majority of the code.
  34. There are three key structures at the file format layer: atoms, properties,
  35. and descriptors.
  36. Atoms are the primary containers within an mp4 file. They can contain
  37. any combination of properties, other atoms, or descriptors.
  38. The mp4atom files contain the base class for all the atoms, and provide
  39. generic functions that cover most cases. Most atoms are covered in
  40. atom_standard.cpp. Atoms that have a special read, generation or
  41. write needs are contained in their subclass contained in file atom_<name>.cpp,
  42. where <name> is the four letter name of the atom defined in the MP4
  43. specification.
  44. Atoms that only specifies the properties of the atom or the possible child
  45. atoms in the case of a container atom are located in atom_standard.cpp.
  46. In more specialized cases the atom specific file provides routines to
  47. initialize, read, or write the atom.
  48. Properties are the atomic pieces of information. The basic types of
  49. properties are integers, floats, strings, and byte arrays. For integers
  50. and floats there are subclasses that represent the different storage sizes,
  51. e.g. 8, 16, 24, 32, and 64 bit integers. For strings, there is 1 property
  52. class with a number of options regarding exact storage details, e.g. null
  53. terminated, fixed length, counted.
  54. For implementation reasons, there are also two special properties, table
  55. and descriptor, that are actually containers for groups of properties.
  56. I.e by making these containers provide a property interface much code can
  57. be written in a generic fashion.
  58. The mp4property files contain all the property related classes.
  59. Descriptors are containers that derive from the MPEG conventions and use
  60. different encoding rules than the atoms derived from the QuickTime file
  61. format. This means more use of bitfields and conditional existence with
  62. an emphasis on bit efficiency at the cost of encoding/decoding complexity.
  63. Descriptors can contain other descriptors and/or properties.
  64. The mp4descriptor files contain the generic base class for descriptors.
  65. Also the mp4property files have a descriptor wrapper class that allows a
  66. descriptor to behave as if it were a property. The specific descriptors
  67. are implemented as subclasses of the base class descriptor in manner similar
  68. to that of atoms. The descriptors, ocidescriptors, and qosqualifiers files
  69. contain these implementations.
  70. Each atom/property/descriptor has a name closely related to that in the
  71. MP4 specification. The difference being that the mp4v2 library doesn't
  72. use '-' or '_' in property names and capitalizes the first letter of each
  73. word, e.g. "thisIsAPropertyName". A complete name specifies the complete
  74. container path. The names follow the C/C++ syntax for elements and array
  75. indices.
  76. Examples are:
  77. "moov.mvhd.duration"
  78. "moov.trak[2].tkhd.duration"
  79. "moov.trak[3].minf.mdia.stbl.stsz[101].sampleSize"
  80. Note "*" can be used as a wildcard for an atom name (only). This is most
  81. useful when dealing with the stsd atom which contains child atoms with
  82. various names, but shared property names.
  83. Note that internally when performance matters the code looks up a property
  84. by name once, and then stores the returned pointer to the property class.
  85. To add an atom, first you should see if an existing atom exists that
  86. can be used. If not, you need to decide if special read/write or
  87. generate properties need to be established; for example a property in the atom
  88. changes other properties (adds, or subtracts). If there are no
  89. special cases, add the atom properties to atom_standard.cpp. If there
  90. are special properties, add a new file, add a new class to atoms.h, and
  91. add the class to MP4Atom::CreateAtom in mp4atom.cpp.
  92. Generic Tracks
  93. ==============
  94. The two entities at this level are the mp4 file as a whole and the tracks
  95. which are contained with it. The mp4file and mp4track files contain the
  96. implementation.
  97. The critical work done by this layer is to map the collection of atoms,
  98. properties, and descriptors that represent a media track into a useful,
  99. and consistent set of operations. For example, reading or writing a media
  100. sample of a track is a relatively simple operation from the library API
  101. perspective. However there are numerous pieces of information in the mp4
  102. file that need to be properly used and updated to do this. This layer
  103. handles all those details.
  104. Given familiarity with the mp4 spec, the code should be straight-forward.
  105. What may not be immediately obvious are the functions to handle chunks of
  106. media samples. These exist to allow optimization of the mp4 file layout by
  107. reordering the chunks on disk to interleave the media sample chunks of
  108. multiple tracks in time order. (See MP4Optimize API doc).
  109. Type Specific Track Helpers
  110. ===========================
  111. This specialized code goes beyond the meta-information about tracks in
  112. the mp4 file to understanding and manipulating the information in the
  113. track samples. There are currently two helpers in the library:
  114. the MPEG-4 Systems Helper, and the RTP Hint Track Helper.
  115. The MPEG-4 Systems Helper is currently limited to creating the OD, BIFS,
  116. and SDP information about a minimal audio/video scene consistent with
  117. the Internet Streaming Media Alliance (ISMA) specifications. We will be
  118. evaluating how best to generalize the library's helper functions for
  119. MPEG-4 Systems without overburdening the implementation. The code for
  120. this helper is found in the isma and odcommands files.
  121. The RTP Hint Track Helper is more extensive in its support. The hint
  122. tracks contain the track packetization information needed to build
  123. RTP packets for streaming. The library can construct RTP packets based
  124. on the hint track making RTP based servers significantly easier to write.
  125. All code related to rtp hint tracks is in the rtphint files. It would also
  126. be useful to look at test/mp4broadcaster and mpeg4ip/server/mp4creator for
  127. examples of how this part of the library API can be used.
  128. Library API
  129. ===========
  130. The library API is defined and implemented in the mp4 files. The API uses
  131. C linkage conventions, and the mp4.h file adapts itself according to whether
  132. C or C++ is the compilation mode.
  133. All API calls are implemented in mp4.cpp and basically pass thru's to the
  134. MP4File member functions. This ensures that the library has internal access
  135. to the same functions as available via the API. All the calls in mp4.cpp use
  136. C++ try/catch blocks to protect against any runtime errors in the library.
  137. Upon error the library will print a diagnostic message if the verbostiy level
  138. has MP4_DETAILS_ERROR set, and return a distinguished error value, typically
  139. 0 or -1.
  140. The test and util subdirectories contain useful examples of how to
  141. use the library. Also the mp4creator and mp4live programs within
  142. mpeg4ip demonstrate more complete usage of the library API.
  143. Debugging
  144. =========
  145. Since mp4 files are fairly complicated, extensive debugging support is
  146. built into the library. Multi-level diagnostic messages are available
  147. under the control of a verbosity bitmask described in the API.
  148. Also the library provides the MP4Dump() call which provides an ASCII
  149. version of the mp4 file meta-information. The mp4dump utilitity is a
  150. wrapper executable around this function.
  151. The mp4extract program is also provided in the utilities directory
  152. which is useful for extracting a track from an mp4file and putting the
  153. media data back into it's own file. It can also extract each sample of
  154. a track into its own file it that is desired.
  155. When all else fails, mp4 files are amenable to debugging by direct
  156. examination. Since the atom names are four letter ASCII codes finding
  157. reference points in a hex dump is feasible. On UNIX, the od command
  158. is your friend: "od -t x1z -A x [-j 0xXXXXXX] foo.mp4" will print
  159. a hex and ASCII dump, with hex addresses, starting optionally from
  160. a specified offset. The library diagnostic messages can provide
  161. information on where the library is reading or writing.
  162. General caveats
  163. ===============
  164. The coding convention is to use the C++ throw operator whenever an
  165. unrecoverable error occurs. This throw is caught at the API layer
  166. in mp4.cpp and translated into an error value.
  167. Be careful about indices. Internally, we follow the C/C++ convention
  168. to use zero-based indices. However the MP4 spec uses one-based indices
  169. for things like samples and hence the library API uses this convention.