1 /*****************************************************************
2 |
3 |    AP4 - Atoms
4 |
5 |    Copyright 2002-2011 Axiomatic Systems, LLC
6 |
7 |
8 |    This file is part of Bento4/AP4 (MP4 Atom Processing Library).
9 |
10 |    Unless you have obtained Bento4 under a difference license,
11 |    this version of Bento4 is Bento4|GPL.
12 |    Bento4|GPL is free software; you can redistribute it and/or modify
13 |    it under the terms of the GNU General Public License as published by
14 |    the Free Software Foundation; either version 2, or (at your option)
15 |    any later version.
16 |
17 |    Bento4|GPL is distributed in the hope that it will be useful,
18 |    but WITHOUT ANY WARRANTY; without even the implied warranty of
19 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 |    GNU General Public License for more details.
21 |
22 |    You should have received a copy of the GNU General Public License
23 |    along with Bento4|GPL; see the file COPYING.  If not, write to the
24 |    Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 |    02111-1307, USA.
26 |
27  ****************************************************************/
28 /**
29 * @file
30 * @brief Atoms
31 */
32 
33 #ifndef _AP4_ATOM_H_
34 #define _AP4_ATOM_H_
35 
36 /*----------------------------------------------------------------------
37 |   includes
38 +---------------------------------------------------------------------*/
39 #include "Ap4Types.h"
40 #include "Ap4List.h"
41 #include "Ap4ByteStream.h"
42 #include "Ap4String.h"
43 #include "Ap4Debug.h"
44 #include "Ap4DynamicCast.h"
45 #include "Ap4Array.h"
46 
47 /*----------------------------------------------------------------------
48 |   macros
49 +---------------------------------------------------------------------*/
50 #define AP4_ATOM_TYPE(c1,c2,c3,c4)       \
51    (((static_cast<AP4_UI32>(c1))<<24) |  \
52     ((static_cast<AP4_UI32>(c2))<<16) |  \
53     ((static_cast<AP4_UI32>(c3))<< 8) |  \
54     ((static_cast<AP4_UI32>(c4))    ))
55 
56 /*----------------------------------------------------------------------
57 |   constants
58 +---------------------------------------------------------------------*/
59 const AP4_UI32 AP4_ATOM_HEADER_SIZE         = 8;
60 const AP4_UI32 AP4_ATOM_HEADER_SIZE_64      = 16;
61 const AP4_UI32 AP4_FULL_ATOM_HEADER_SIZE    = 12;
62 const AP4_UI32 AP4_FULL_ATOM_HEADER_SIZE_64 = 20;
63 const AP4_UI32 AP4_ATOM_MAX_NAME_SIZE       = 256;
64 const AP4_UI32 AP4_ATOM_MAX_URI_SIZE        = 512;
65 
66 /*----------------------------------------------------------------------
67 |   forward references
68 +---------------------------------------------------------------------*/
69 class AP4_AtomParent;
70 
71 /*----------------------------------------------------------------------
72 |   AP4_AtomInspector
73 +---------------------------------------------------------------------*/
74 /**
75  * Class used in a visitor pattern to walk all the atoms in a tree of
76  * #AP4_Atom objects.
77  */
78 class AP4_AtomInspector {
79 public:
80     // types
81     typedef enum {
82         HINT_NONE    = 0,
83         HINT_HEX     = 1,
84         HINT_BOOLEAN = 2
85     } FormatHint;
86 
87     // constructor and destructor
AP4_AtomInspector()88     AP4_AtomInspector() : m_Verbosity(0) {}
~AP4_AtomInspector()89     virtual ~AP4_AtomInspector() {}
90 
91     // methods
SetVerbosity(AP4_Ordinal verbosity)92     void        SetVerbosity(AP4_Ordinal verbosity) { m_Verbosity = verbosity; }
GetVerbosity()93     AP4_Ordinal GetVerbosity()                      { return m_Verbosity;      }
94 
95     // virtual methods
StartAtom(const char *,AP4_UI08,AP4_UI32,AP4_Size,AP4_UI64)96     virtual void StartAtom(const char* /* name        */,
97                            AP4_UI08    /* version     */,
98                            AP4_UI32    /* flags       */,
99                            AP4_Size    /* header_size */,
100                            AP4_UI64    /*size         */) {}
EndAtom()101     virtual void EndAtom() {}
StartDescriptor(const char *,AP4_Size,AP4_UI64)102     virtual void StartDescriptor(const char* /* name        */,
103                                  AP4_Size    /* header_size */,
104                                  AP4_UI64    /*size         */) {}
EndDescriptor()105     virtual void EndDescriptor() {}
106     virtual void StartArray(const char* /* name */, unsigned int element_count = 0) {}
EndArray()107     virtual void EndArray() {}
108     virtual void StartObject(const char* /* name */, unsigned int field_count = 0, bool compact = false) {}
EndObject()109     virtual void EndObject() {}
110     virtual void AddField(const char* /* name */,
111                           AP4_UI64    /* value */,
112                           FormatHint  hint = HINT_NONE) {
113         (void)hint; // gcc warning
114     }
115     virtual void AddFieldF(const char* /* name */,
116                            float       /* value */,
117                            FormatHint  hint = HINT_NONE) {
118         (void)hint; // gcc warning
119     }
120     virtual void AddField(const char* /* name */,
121                           const char* /* value */,
122                           FormatHint  hint = HINT_NONE) {
123         (void)hint; // gcc warning
124     }
125     virtual void AddField(const char*          /* name */,
126                           const unsigned char* /* bytes */,
127                           AP4_Size             /* byte_count */,
128                           FormatHint           hint = HINT_NONE) {
129         (void)hint; // gcc warning
130     }
131 
132 protected:
133     AP4_Ordinal m_Verbosity;
134 };
135 
136 /*----------------------------------------------------------------------
137 |   AP4_PrintInspector
138 +---------------------------------------------------------------------*/
139 class AP4_PrintInspector : public AP4_AtomInspector {
140 public:
141     AP4_PrintInspector(AP4_ByteStream& stream, AP4_Cardinal indent=0);
142     ~AP4_PrintInspector();
143 
144     // methods
145     void StartAtom(const char* name,
146                    AP4_UI08    version,
147                    AP4_UI32    flags,
148                    AP4_Size    header_size,
149                    AP4_UI64    size);
150     void EndAtom();
151     void StartDescriptor(const char* name,
152                          AP4_Size    header_size,
153                          AP4_UI64    size);
154     void EndDescriptor();
155     void StartArray(const char* name, unsigned int element_count);
156     void EndArray();
157     void StartObject(const char* name, unsigned int field_count, bool compact);
158     void EndObject();
159     void AddField(const char* name, AP4_UI64 value, FormatHint hint);
160     void AddFieldF(const char* name, float value, FormatHint hint);
161     void AddField(const char* name, const char* value, FormatHint hint);
162     void AddField(const char* name, const unsigned char* bytes, AP4_Size size, FormatHint hint);
163 
164 private:
165     // types
166     struct Context {
167         typedef enum {
168             TOP_LEVEL,
169             ATOM,
170             ARRAY,
171             OBJECT,
172             COMPACT_OBJECT
173         } Type;
174 
ContextContext175         Context(Type type) : m_Type(type), m_ArrayIndex(0) {}
176 
177         Type         m_Type;
178         AP4_Cardinal m_ArrayIndex;
179      };
180 
181     // methods
182     void     PushContext(Context::Type type);
183     void     PopContext();
LastContext()184     Context& LastContext() { return m_Contexts[m_Contexts.ItemCount() - 1]; }
185     void     PrintPrefix();
186     void     PrintSuffix();
187 
188     // members
189     AP4_ByteStream*    m_Stream;
190     AP4_Array<Context> m_Contexts;
191 };
192 
193 /*----------------------------------------------------------------------
194 |   AP4_JsonInspector
195 +---------------------------------------------------------------------*/
196 class AP4_JsonInspector : public AP4_AtomInspector {
197 public:
198     AP4_JsonInspector(AP4_ByteStream& stream);
199     ~AP4_JsonInspector();
200 
201     // methods
202     void StartAtom(const char* name,
203                    AP4_UI08    version,
204                    AP4_UI32    flags,
205                    AP4_Size    header_size,
206                    AP4_UI64    size);
207     void EndAtom();
208     void StartDescriptor(const char* name,
209                          AP4_Size    header_size,
210                          AP4_UI64    size);
211     void EndDescriptor();
212     void StartArray(const char* name, unsigned int element_count);
213     void EndArray();
214     void StartObject(const char* name, unsigned int field_count, bool compact);
215     void EndObject();
216     void AddField(const char* name, AP4_UI64 value, FormatHint hint);
217     void AddFieldF(const char* name, float value, FormatHint hint);
218     void AddField(const char* name, const char* value, FormatHint hint);
219     void AddField(const char* name, const unsigned char* bytes, AP4_Size size, FormatHint hint);
220 
221 private:
222     // types
223     struct Context {
224         typedef enum {
225             TOP_LEVEL,
226             ATOM,
227             ARRAY,
228             OBJECT
229         } Type;
230 
ContextContext231         Context(Type type) : m_Type(type), m_FieldCount(0), m_ChildrenCount(0) {}
232 
233         Type         m_Type;
234         AP4_Cardinal m_FieldCount;
235         AP4_Cardinal m_ChildrenCount; // to count atoms within atoms
236      };
237 
238     // methods
239     static AP4_String EscapeString(const char* string);
240     void              PushContext(Context::Type type);
241     void              PopContext();
LastContext()242     Context&          LastContext() { return m_Contexts[m_Contexts.ItemCount() - 1]; }
243     void              OnFieldAdded();
244     void              PrintFieldName(const char* name);
245 
246     // members
247     AP4_ByteStream*    m_Stream;
248     AP4_Array<Context> m_Contexts;
249     char               m_Prefix[256];
250 };
251 
252 /*----------------------------------------------------------------------
253 |   AP4_Atom
254 +---------------------------------------------------------------------*/
255 /**
256  * Abstract base class for all atom types.
257  */
258 class AP4_Atom {
259 public:
260      AP4_IMPLEMENT_DYNAMIC_CAST(AP4_Atom)
261 
262    // types
263     typedef AP4_UI32 Type;
264 
265     // class methods
266     static Type TypeFromString(const char* four_cc);
267     static AP4_Result ReadFullHeader(AP4_ByteStream& stream,
268                                      AP4_UI08&       version,
269                                      AP4_UI32&       flags);
270 
271     // constructors
272     /**
273      * Create a simple atom with a specified type and 32-bit size.
274      */
275     explicit AP4_Atom(Type type, AP4_UI32 size = AP4_ATOM_HEADER_SIZE);
276 
277     /**
278      * Create a simple atom with a specified type and 64-bit size.
279      */
280     explicit AP4_Atom(Type type, AP4_UI64 size, bool force_64=false);
281 
282     /**
283      * Create a full atom with a specified type, 32-bit size, version and flags.
284      */
285     explicit AP4_Atom(Type     type,
286                       AP4_UI32 size,
287                       AP4_UI08 version,
288                       AP4_UI32 flags);
289 
290     /**
291      * Create a full atom with a specified type, 64-bit size, version and flags.
292      */
293     explicit AP4_Atom(Type     type,
294                       AP4_UI64 size,
295                       bool     force_64,
296                       AP4_UI08 version,
297                       AP4_UI32 flags);
298 
299     // destructor
~AP4_Atom()300     virtual ~AP4_Atom() {}
301 
302     // methods
GetFlags()303     AP4_UI32           GetFlags() const { return m_Flags; }
SetFlags(AP4_UI32 flags)304     void               SetFlags(AP4_UI32 flags) { m_Flags = flags; }
GetVersion()305     AP4_UI08           GetVersion() const {return m_Version;}
SetVersion(AP4_UI08 version)306     void               SetVersion(AP4_UI08 version) { m_Version = version; }
GetType()307     Type               GetType() const { return m_Type; }
SetType(Type type)308     void               SetType(Type type) { m_Type = type; }
309     virtual AP4_Size   GetHeaderSize() const;
GetSize()310     AP4_UI64           GetSize() const { return m_Size32 == 1?m_Size64:m_Size32; }
311     void               SetSize(AP4_UI64 size, bool force_64 = false);
GetSize32()312     AP4_UI32           GetSize32() const { return m_Size32; }
SetSize32(AP4_UI32 size)313     void               SetSize32(AP4_UI32 size) { m_Size32 = size; }
GetSize64()314     AP4_UI64           GetSize64() const { return m_Size64; }
SetSize64(AP4_UI64 size)315     void               SetSize64(AP4_UI64 size) { m_Size64 = size; }
316     virtual AP4_Result Write(AP4_ByteStream& stream);
317     virtual AP4_Result WriteHeader(AP4_ByteStream& stream);
318     virtual AP4_Result WriteFields(AP4_ByteStream& stream) = 0;
319     virtual AP4_Result Inspect(AP4_AtomInspector& inspector);
320     virtual AP4_Result InspectHeader(AP4_AtomInspector& inspector);
InspectFields(AP4_AtomInspector &)321     virtual AP4_Result InspectFields(AP4_AtomInspector& /* inspector */) {
322         return AP4_SUCCESS;
323     }
324 
325     // parent/child relationship methods
SetParent(AP4_AtomParent * parent)326     virtual AP4_Result SetParent(AP4_AtomParent* parent) {
327         m_Parent = parent;
328         return AP4_SUCCESS;
329     }
GetParent()330     virtual AP4_AtomParent* GetParent() { return m_Parent; }
331     virtual AP4_Result      Detach();
332 
333     /**
334      * Create a clone of the object.
335      * This method returns a clone of the atom, or NULL if
336      * the atom cannot be cloned.
337      * Override this if your want to make an atom cloneable in a more
338      * efficient way than the default implementation.
339      */
340     virtual AP4_Atom* Clone();
341 
342  protected:
343     // members
344     Type            m_Type;
345     AP4_UI32        m_Size32;
346     AP4_UI64        m_Size64; // this is 0 if m_Size is not 1 (encoded in 32-bits)
347                               // and non-zero only if m_Size is 1 (encoded in 64-bits)
348     bool            m_IsFull;
349     AP4_UI08        m_Version;
350     AP4_UI32        m_Flags;
351     AP4_AtomParent* m_Parent;
352 };
353 
354 /*----------------------------------------------------------------------
355 |   AP4_AtomParent
356 +---------------------------------------------------------------------*/
357 /**
358  * Base class for containers of atoms.
359  * This class also implements the logic for finding descendents by name.
360  */
361 class AP4_AtomParent {
362 public:
363     AP4_IMPLEMENT_DYNAMIC_CAST(AP4_AtomParent)
364 
365     // base methods
366     virtual ~AP4_AtomParent();
GetChildren()367     AP4_List<AP4_Atom>& GetChildren() { return m_Children; }
368     AP4_Result          CopyChildren(AP4_AtomParent& destination) const;
369     virtual AP4_Result  AddChild(AP4_Atom* child, int position = -1);
370     virtual AP4_Result  RemoveChild(AP4_Atom* child);
371     virtual AP4_Result  DeleteChild(AP4_Atom::Type type, AP4_Ordinal index = 0);
372     virtual AP4_Atom*   GetChild(AP4_Atom::Type type, AP4_Ordinal index = 0) const;
373     virtual AP4_Atom*   GetChild(const AP4_UI08* uuid, AP4_Ordinal index = 0) const;
374     virtual AP4_Atom*   FindChild(const char* path,
375                                   bool        auto_create = false,
376                                   bool        auto_create_full = false);
377 
378     // methods designed to be overridden
OnChildChanged(AP4_Atom *)379     virtual void OnChildChanged(AP4_Atom* /* child */) {}
OnChildAdded(AP4_Atom *)380     virtual void OnChildAdded(AP4_Atom* /* child */)   {}
OnChildRemoved(AP4_Atom *)381     virtual void OnChildRemoved(AP4_Atom* /* child */) {}
382 
383 protected:
384     // members
385     AP4_List<AP4_Atom> m_Children;
386 };
387 
388 /*----------------------------------------------------------------------
389 |   AP4_UnknownAtom
390 +---------------------------------------------------------------------*/
391 /**
392  * Class that represents atoms for which there is no specific support.
393  * Instances of this class keep a reference to the stream from which
394  * the atom is parsed, so that it can read the atom's payload when it
395  * is serialized.
396  * If the atom is small, its payload is actually read and stored in
397  * a data buffer, so no reference to the source stream is kept
398  */
399 class AP4_UnknownAtom : public AP4_Atom {
400 public:
401     // constructor and destructor
402     AP4_UnknownAtom(AP4_Atom::Type   type,
403                     AP4_UI64         size,
404                     AP4_ByteStream&  stream);
405     AP4_UnknownAtom(AP4_Atom::Type type, const AP4_UI08* payload, AP4_Size payload_size);
406     AP4_UnknownAtom(const AP4_UnknownAtom& other);
407     ~AP4_UnknownAtom();
408 
409     // methods
410     virtual AP4_Result WriteFields(AP4_ByteStream& stream);
411     virtual AP4_Atom*  Clone();
412 
413 private:
414     // members
415     AP4_ByteStream* m_SourceStream;
416     AP4_Position    m_SourcePosition;
417     AP4_DataBuffer  m_Payload;
418 };
419 
420 /*----------------------------------------------------------------------
421 |   AP4_NullTerminatedStringAtom
422 +---------------------------------------------------------------------*/
423 /**
424  * Generic Class usd for all atoms that contain a single null-terminated
425  * string.
426  */
427 class AP4_NullTerminatedStringAtom : public AP4_Atom
428 {
429 public:
430     AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_NullTerminatedStringAtom, AP4_Atom)
431 
432     // constructors
433     AP4_NullTerminatedStringAtom(AP4_Atom::Type type, AP4_UI64 size, AP4_ByteStream& stream);
434     AP4_NullTerminatedStringAtom(AP4_Atom::Type type, const char* value);
435 
436     // accessors
GetValue()437     const AP4_String& GetValue() { return m_Value; }
438 
439     // methods
440     virtual AP4_Result InspectFields(AP4_AtomInspector& inspector);
441     virtual AP4_Result WriteFields(AP4_ByteStream& stream);
442 
443 private:
444     // members
445     AP4_String m_Value;
446 };
447 
448 /*----------------------------------------------------------------------
449 |   atom types
450 +---------------------------------------------------------------------*/
451 const AP4_Atom::Type AP4_ATOM_TYPE_UDTA = AP4_ATOM_TYPE('u','d','t','a');
452 const AP4_Atom::Type AP4_ATOM_TYPE_URL  = AP4_ATOM_TYPE('u','r','l',' ');
453 const AP4_Atom::Type AP4_ATOM_TYPE_TRAK = AP4_ATOM_TYPE('t','r','a','k');
454 const AP4_Atom::Type AP4_ATOM_TYPE_TRAF = AP4_ATOM_TYPE('t','r','a','f');
455 const AP4_Atom::Type AP4_ATOM_TYPE_TKHD = AP4_ATOM_TYPE('t','k','h','d');
456 const AP4_Atom::Type AP4_ATOM_TYPE_TFHD = AP4_ATOM_TYPE('t','f','h','d');
457 const AP4_Atom::Type AP4_ATOM_TYPE_TRUN = AP4_ATOM_TYPE('t','r','u','n');
458 const AP4_Atom::Type AP4_ATOM_TYPE_STTS = AP4_ATOM_TYPE('s','t','t','s');
459 const AP4_Atom::Type AP4_ATOM_TYPE_STSZ = AP4_ATOM_TYPE('s','t','s','z');
460 const AP4_Atom::Type AP4_ATOM_TYPE_STZ2 = AP4_ATOM_TYPE('s','t','z','2');
461 const AP4_Atom::Type AP4_ATOM_TYPE_STSS = AP4_ATOM_TYPE('s','t','s','s');
462 const AP4_Atom::Type AP4_ATOM_TYPE_STSD = AP4_ATOM_TYPE('s','t','s','d');
463 const AP4_Atom::Type AP4_ATOM_TYPE_STSC = AP4_ATOM_TYPE('s','t','s','c');
464 const AP4_Atom::Type AP4_ATOM_TYPE_STCO = AP4_ATOM_TYPE('s','t','c','o');
465 const AP4_Atom::Type AP4_ATOM_TYPE_CO64 = AP4_ATOM_TYPE('c','o','6','4');
466 const AP4_Atom::Type AP4_ATOM_TYPE_STBL = AP4_ATOM_TYPE('s','t','b','l');
467 const AP4_Atom::Type AP4_ATOM_TYPE_SINF = AP4_ATOM_TYPE('s','i','n','f');
468 const AP4_Atom::Type AP4_ATOM_TYPE_SCHM = AP4_ATOM_TYPE('s','c','h','m');
469 const AP4_Atom::Type AP4_ATOM_TYPE_SCHI = AP4_ATOM_TYPE('s','c','h','i');
470 const AP4_Atom::Type AP4_ATOM_TYPE_MVHD = AP4_ATOM_TYPE('m','v','h','d');
471 const AP4_Atom::Type AP4_ATOM_TYPE_MEHD = AP4_ATOM_TYPE('m','e','h','d');
472 const AP4_Atom::Type AP4_ATOM_TYPE_MP4S = AP4_ATOM_TYPE('m','p','4','s');
473 const AP4_Atom::Type AP4_ATOM_TYPE_MP4A = AP4_ATOM_TYPE('m','p','4','a');
474 const AP4_Atom::Type AP4_ATOM_TYPE_MP4V = AP4_ATOM_TYPE('m','p','4','v');
475 const AP4_Atom::Type AP4_ATOM_TYPE_AVC1 = AP4_ATOM_TYPE('a','v','c','1');
476 const AP4_Atom::Type AP4_ATOM_TYPE_AVC2 = AP4_ATOM_TYPE('a','v','c','2');
477 const AP4_Atom::Type AP4_ATOM_TYPE_AVC3 = AP4_ATOM_TYPE('a','v','c','3');
478 const AP4_Atom::Type AP4_ATOM_TYPE_AVC4 = AP4_ATOM_TYPE('a','v','c','4');
479 const AP4_Atom::Type AP4_ATOM_TYPE_DVAV = AP4_ATOM_TYPE('d','v','a','v');
480 const AP4_Atom::Type AP4_ATOM_TYPE_DVA1 = AP4_ATOM_TYPE('d','v','a','1');
481 const AP4_Atom::Type AP4_ATOM_TYPE_HEV1 = AP4_ATOM_TYPE('h','e','v','1');
482 const AP4_Atom::Type AP4_ATOM_TYPE_HVC1 = AP4_ATOM_TYPE('h','v','c','1');
483 const AP4_Atom::Type AP4_ATOM_TYPE_DVHE = AP4_ATOM_TYPE('d','v','h','e');
484 const AP4_Atom::Type AP4_ATOM_TYPE_DVH1 = AP4_ATOM_TYPE('d','v','h','1');
485 const AP4_Atom::Type AP4_ATOM_TYPE_VP08 = AP4_ATOM_TYPE('v','p','0','8');
486 const AP4_Atom::Type AP4_ATOM_TYPE_VP09 = AP4_ATOM_TYPE('v','p','0','9');
487 const AP4_Atom::Type AP4_ATOM_TYPE_VP10 = AP4_ATOM_TYPE('v','p','1','0');
488 const AP4_Atom::Type AP4_ATOM_TYPE_AV01 = AP4_ATOM_TYPE('a','v','0','1');
489 const AP4_Atom::Type AP4_ATOM_TYPE_ALAC = AP4_ATOM_TYPE('a','l','a','c');
490 const AP4_Atom::Type AP4_ATOM_TYPE_ENCA = AP4_ATOM_TYPE('e','n','c','a');
491 const AP4_Atom::Type AP4_ATOM_TYPE_ENCV = AP4_ATOM_TYPE('e','n','c','v');
492 const AP4_Atom::Type AP4_ATOM_TYPE_MOOV = AP4_ATOM_TYPE('m','o','o','v');
493 const AP4_Atom::Type AP4_ATOM_TYPE_MOOF = AP4_ATOM_TYPE('m','o','o','f');
494 const AP4_Atom::Type AP4_ATOM_TYPE_MVEX = AP4_ATOM_TYPE('m','v','e','x');
495 const AP4_Atom::Type AP4_ATOM_TYPE_TREX = AP4_ATOM_TYPE('t','r','e','x');
496 const AP4_Atom::Type AP4_ATOM_TYPE_MINF = AP4_ATOM_TYPE('m','i','n','f');
497 const AP4_Atom::Type AP4_ATOM_TYPE_META = AP4_ATOM_TYPE('m','e','t','a');
498 const AP4_Atom::Type AP4_ATOM_TYPE_MDHD = AP4_ATOM_TYPE('m','d','h','d');
499 const AP4_Atom::Type AP4_ATOM_TYPE_MFHD = AP4_ATOM_TYPE('m','f','h','d');
500 const AP4_Atom::Type AP4_ATOM_TYPE_ILST = AP4_ATOM_TYPE('i','l','s','t');
501 const AP4_Atom::Type AP4_ATOM_TYPE_HDLR = AP4_ATOM_TYPE('h','d','l','r');
502 const AP4_Atom::Type AP4_ATOM_TYPE_FTYP = AP4_ATOM_TYPE('f','t','y','p');
503 const AP4_Atom::Type AP4_ATOM_TYPE_IODS = AP4_ATOM_TYPE('i','o','d','s');
504 const AP4_Atom::Type AP4_ATOM_TYPE_ESDS = AP4_ATOM_TYPE('e','s','d','s');
505 const AP4_Atom::Type AP4_ATOM_TYPE_EDTS = AP4_ATOM_TYPE('e','d','t','s');
506 const AP4_Atom::Type AP4_ATOM_TYPE_DRMS = AP4_ATOM_TYPE('d','r','m','s');
507 const AP4_Atom::Type AP4_ATOM_TYPE_DRMI = AP4_ATOM_TYPE('d','r','m','i');
508 const AP4_Atom::Type AP4_ATOM_TYPE_DREF = AP4_ATOM_TYPE('d','r','e','f');
509 const AP4_Atom::Type AP4_ATOM_TYPE_DINF = AP4_ATOM_TYPE('d','i','n','f');
510 const AP4_Atom::Type AP4_ATOM_TYPE_CTTS = AP4_ATOM_TYPE('c','t','t','s');
511 const AP4_Atom::Type AP4_ATOM_TYPE_MDIA = AP4_ATOM_TYPE('m','d','i','a');
512 const AP4_Atom::Type AP4_ATOM_TYPE_ELST = AP4_ATOM_TYPE('e','l','s','t');
513 const AP4_Atom::Type AP4_ATOM_TYPE_VMHD = AP4_ATOM_TYPE('v','m','h','d');
514 const AP4_Atom::Type AP4_ATOM_TYPE_SMHD = AP4_ATOM_TYPE('s','m','h','d');
515 const AP4_Atom::Type AP4_ATOM_TYPE_NMHD = AP4_ATOM_TYPE('n','m','h','d');
516 const AP4_Atom::Type AP4_ATOM_TYPE_STHD = AP4_ATOM_TYPE('s','t','h','d');
517 const AP4_Atom::Type AP4_ATOM_TYPE_HMHD = AP4_ATOM_TYPE('h','m','h','d');
518 const AP4_Atom::Type AP4_ATOM_TYPE_FRMA = AP4_ATOM_TYPE('f','r','m','a');
519 const AP4_Atom::Type AP4_ATOM_TYPE_MDAT = AP4_ATOM_TYPE('m','d','a','t');
520 const AP4_Atom::Type AP4_ATOM_TYPE_FREE = AP4_ATOM_TYPE('f','r','e','e');
521 const AP4_Atom::Type AP4_ATOM_TYPE_TIMS = AP4_ATOM_TYPE('t','i','m','s');
522 const AP4_Atom::Type AP4_ATOM_TYPE_RTP_ = AP4_ATOM_TYPE('r','t','p',' ');
523 const AP4_Atom::Type AP4_ATOM_TYPE_HNTI = AP4_ATOM_TYPE('h','n','t','i');
524 const AP4_Atom::Type AP4_ATOM_TYPE_SDP_ = AP4_ATOM_TYPE('s','d','p',' ');
525 const AP4_Atom::Type AP4_ATOM_TYPE_IKMS = AP4_ATOM_TYPE('i','K','M','S');
526 const AP4_Atom::Type AP4_ATOM_TYPE_ISFM = AP4_ATOM_TYPE('i','S','F','M');
527 const AP4_Atom::Type AP4_ATOM_TYPE_ISLT = AP4_ATOM_TYPE('i','S','L','T');
528 const AP4_Atom::Type AP4_ATOM_TYPE_TREF = AP4_ATOM_TYPE('t','r','e','f');
529 const AP4_Atom::Type AP4_ATOM_TYPE_HINT = AP4_ATOM_TYPE('h','i','n','t');
530 const AP4_Atom::Type AP4_ATOM_TYPE_CDSC = AP4_ATOM_TYPE('c','d','s','c');
531 const AP4_Atom::Type AP4_ATOM_TYPE_MPOD = AP4_ATOM_TYPE('m','p','o','d');
532 const AP4_Atom::Type AP4_ATOM_TYPE_IPIR = AP4_ATOM_TYPE('i','p','i','r');
533 const AP4_Atom::Type AP4_ATOM_TYPE_CHAP = AP4_ATOM_TYPE('c','h','a','p');
534 const AP4_Atom::Type AP4_ATOM_TYPE_ALIS = AP4_ATOM_TYPE('a','l','i','s');
535 const AP4_Atom::Type AP4_ATOM_TYPE_SYNC = AP4_ATOM_TYPE('s','y','n','c');
536 const AP4_Atom::Type AP4_ATOM_TYPE_DPND = AP4_ATOM_TYPE('d','p','n','d');
537 const AP4_Atom::Type AP4_ATOM_TYPE_ODRM = AP4_ATOM_TYPE('o','d','r','m');
538 const AP4_Atom::Type AP4_ATOM_TYPE_ODKM = AP4_ATOM_TYPE('o','d','k','m');
539 const AP4_Atom::Type AP4_ATOM_TYPE_OHDR = AP4_ATOM_TYPE('o','h','d','r');
540 const AP4_Atom::Type AP4_ATOM_TYPE_ODDA = AP4_ATOM_TYPE('o','d','d','a');
541 const AP4_Atom::Type AP4_ATOM_TYPE_ODHE = AP4_ATOM_TYPE('o','d','h','e');
542 const AP4_Atom::Type AP4_ATOM_TYPE_ODAF = AP4_ATOM_TYPE('o','d','a','f');
543 const AP4_Atom::Type AP4_ATOM_TYPE_GRPI = AP4_ATOM_TYPE('g','r','p','i');
544 const AP4_Atom::Type AP4_ATOM_TYPE_IPRO = AP4_ATOM_TYPE('i','p','r','o');
545 const AP4_Atom::Type AP4_ATOM_TYPE_MDRI = AP4_ATOM_TYPE('m','d','r','i');
546 const AP4_Atom::Type AP4_ATOM_TYPE_AVCC = AP4_ATOM_TYPE('a','v','c','C');
547 const AP4_Atom::Type AP4_ATOM_TYPE_HVCC = AP4_ATOM_TYPE('h','v','c','C');
548 const AP4_Atom::Type AP4_ATOM_TYPE_DVCC = AP4_ATOM_TYPE('d','v','c','C');
549 const AP4_Atom::Type AP4_ATOM_TYPE_VPCC = AP4_ATOM_TYPE('v','p','c','C');
550 const AP4_Atom::Type AP4_ATOM_TYPE_DVVC = AP4_ATOM_TYPE('d','v','v','C');
551 const AP4_Atom::Type AP4_ATOM_TYPE_HVCE = AP4_ATOM_TYPE('h','v','c','E');
552 const AP4_Atom::Type AP4_ATOM_TYPE_AVCE = AP4_ATOM_TYPE('a','v','c','E');
553 const AP4_Atom::Type AP4_ATOM_TYPE_AV1C = AP4_ATOM_TYPE('a','v','1','C');
554 const AP4_Atom::Type AP4_ATOM_TYPE_WAVE = AP4_ATOM_TYPE('w','a','v','e');
555 const AP4_Atom::Type AP4_ATOM_TYPE_WIDE = AP4_ATOM_TYPE('w','i','d','e');
556 const AP4_Atom::Type AP4_ATOM_TYPE_UUID = AP4_ATOM_TYPE('u','u','i','d');
557 const AP4_Atom::Type AP4_ATOM_TYPE_8ID_ = AP4_ATOM_TYPE('8','i','d',' ');
558 const AP4_Atom::Type AP4_ATOM_TYPE_8BDL = AP4_ATOM_TYPE('8','b','d','l');
559 const AP4_Atom::Type AP4_ATOM_TYPE_AC_3 = AP4_ATOM_TYPE('a','c','-','3');
560 const AP4_Atom::Type AP4_ATOM_TYPE_EC_3 = AP4_ATOM_TYPE('e','c','-','3');
561 const AP4_Atom::Type AP4_ATOM_TYPE_AC_4 = AP4_ATOM_TYPE('a','c','-','4');
562 const AP4_Atom::Type AP4_ATOM_TYPE_DTSC = AP4_ATOM_TYPE('d','t','s','c');
563 const AP4_Atom::Type AP4_ATOM_TYPE_DTSH = AP4_ATOM_TYPE('d','t','s','h');
564 const AP4_Atom::Type AP4_ATOM_TYPE_DTSL = AP4_ATOM_TYPE('d','t','s','l');
565 const AP4_Atom::Type AP4_ATOM_TYPE_DTSE = AP4_ATOM_TYPE('d','t','s','e');
566 const AP4_Atom::Type AP4_ATOM_TYPE_FLAC = AP4_ATOM_TYPE('f','L','a','C');
567 const AP4_Atom::Type AP4_ATOM_TYPE_OPUS = AP4_ATOM_TYPE('O','p','u','s');
568 const AP4_Atom::Type AP4_ATOM_TYPE_MFRA = AP4_ATOM_TYPE('m','f','r','a');
569 const AP4_Atom::Type AP4_ATOM_TYPE_TFRA = AP4_ATOM_TYPE('t','f','r','a');
570 const AP4_Atom::Type AP4_ATOM_TYPE_MFRO = AP4_ATOM_TYPE('m','f','r','o');
571 const AP4_Atom::Type AP4_ATOM_TYPE_TFDT = AP4_ATOM_TYPE('t','f','d','t');
572 const AP4_Atom::Type AP4_ATOM_TYPE_TENC = AP4_ATOM_TYPE('t','e','n','c');
573 const AP4_Atom::Type AP4_ATOM_TYPE_SENC = AP4_ATOM_TYPE('s','e','n','c');
574 const AP4_Atom::Type AP4_ATOM_TYPE_SAIO = AP4_ATOM_TYPE('s','a','i','o');
575 const AP4_Atom::Type AP4_ATOM_TYPE_SAIZ = AP4_ATOM_TYPE('s','a','i','z');
576 const AP4_Atom::Type AP4_ATOM_TYPE_PDIN = AP4_ATOM_TYPE('p','d','i','n');
577 const AP4_Atom::Type AP4_ATOM_TYPE_BLOC = AP4_ATOM_TYPE('b','l','o','c');
578 const AP4_Atom::Type AP4_ATOM_TYPE_AINF = AP4_ATOM_TYPE('a','i','n','f');
579 const AP4_Atom::Type AP4_ATOM_TYPE_PSSH = AP4_ATOM_TYPE('p','s','s','h');
580 const AP4_Atom::Type AP4_ATOM_TYPE_MARL = AP4_ATOM_TYPE('m','a','r','l');
581 const AP4_Atom::Type AP4_ATOM_TYPE_MKID = AP4_ATOM_TYPE('m','k','i','d');
582 const AP4_Atom::Type AP4_ATOM_TYPE_PRFT = AP4_ATOM_TYPE('p','r','f','t');
583 const AP4_Atom::Type AP4_ATOM_TYPE_STPP = AP4_ATOM_TYPE('s','t','p','p');
584 const AP4_Atom::Type AP4_ATOM_TYPE_DAC3 = AP4_ATOM_TYPE('d','a','c','3');
585 const AP4_Atom::Type AP4_ATOM_TYPE_DEC3 = AP4_ATOM_TYPE('d','e','c','3');
586 const AP4_Atom::Type AP4_ATOM_TYPE_DAC4 = AP4_ATOM_TYPE('d','a','c','4');
587 const AP4_Atom::Type AP4_ATOM_TYPE_SIDX = AP4_ATOM_TYPE('s','i','d','x');
588 const AP4_Atom::Type AP4_ATOM_TYPE_SSIX = AP4_ATOM_TYPE('s','s','i','x');
589 const AP4_Atom::Type AP4_ATOM_TYPE_SBGP = AP4_ATOM_TYPE('s','b','g','p');
590 const AP4_Atom::Type AP4_ATOM_TYPE_SGPD = AP4_ATOM_TYPE('s','g','p','d');
591 
592 /*----------------------------------------------------------------------
593 |   AP4_AtomListInspector
594 +---------------------------------------------------------------------*/
595 class AP4_AtomListInspector : public AP4_List<AP4_Atom>::Item::Operator
596 {
597  public:
AP4_AtomListInspector(AP4_AtomInspector & inspector)598     AP4_AtomListInspector(AP4_AtomInspector& inspector) :
599         m_Inspector(inspector) {}
Action(AP4_Atom * atom)600     AP4_Result Action(AP4_Atom* atom) const {
601         atom->Inspect(m_Inspector);
602         return AP4_SUCCESS;
603     }
604 
605  private:
606     AP4_AtomInspector& m_Inspector;
607 };
608 
609 /*----------------------------------------------------------------------
610 |   AP4_AtomListWriter
611 +---------------------------------------------------------------------*/
612 class AP4_AtomListWriter : public AP4_List<AP4_Atom>::Item::Operator
613 {
614  public:
AP4_AtomListWriter(AP4_ByteStream & stream)615     AP4_AtomListWriter(AP4_ByteStream& stream) :
616         m_Stream(stream) {}
617     AP4_Result Action(AP4_Atom* atom) const;
618 
619  private:
620     AP4_ByteStream& m_Stream;
621 };
622 
623 /*----------------------------------------------------------------------
624 |   AP4_AtomFinder
625 +---------------------------------------------------------------------*/
626 class AP4_AtomFinder : public AP4_List<AP4_Atom>::Item::Finder
627 {
628  public:
629     AP4_AtomFinder(AP4_Atom::Type type, AP4_Ordinal index = 0) :
m_Type(type)630        m_Type(type), m_Index(index) {}
Test(AP4_Atom * atom)631     AP4_Result Test(AP4_Atom* atom) const {
632         if (atom->GetType() == m_Type) {
633             if (m_Index-- == 0) {
634                 return AP4_SUCCESS;
635             } else {
636                 return AP4_FAILURE;
637             }
638         } else {
639             return AP4_FAILURE;
640         }
641     }
642  private:
643     AP4_Atom::Type      m_Type;
644     mutable AP4_Ordinal m_Index;
645 };
646 
647 /*----------------------------------------------------------------------
648 |   AP4_AtomSizeAdder
649 +---------------------------------------------------------------------*/
650 class AP4_AtomSizeAdder : public AP4_List<AP4_Atom>::Item::Operator {
651 public:
AP4_AtomSizeAdder(AP4_UI64 & size)652     AP4_AtomSizeAdder(AP4_UI64& size) : m_Size(size) {}
653 
654 private:
Action(AP4_Atom * atom)655     AP4_Result Action(AP4_Atom* atom) const {
656         m_Size += atom->GetSize();
657         return AP4_SUCCESS;
658     }
659     AP4_UI64& m_Size;
660 };
661 
662 #endif // _AP4_ATOM_H_
663