File: Ap4Atom.h

package info (click to toggle)
kodi-inputstream-adaptive 2.6.14%2Bds1-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 4,036 kB
  • sloc: cpp: 53,019; ansic: 492; makefile: 10
file content (583 lines) | stat: -rw-r--r-- 25,414 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
/*****************************************************************
|
|    AP4 - Atoms 
|
|    Copyright 2002-2011 Axiomatic Systems, LLC
|
|
|    This file is part of Bento4/AP4 (MP4 Atom Processing Library).
|
|    Unless you have obtained Bento4 under a difference license,
|    this version of Bento4 is Bento4|GPL.
|    Bento4|GPL is free software; you can redistribute it and/or modify
|    it under the terms of the GNU General Public License as published by
|    the Free Software Foundation; either version 2, or (at your option)
|    any later version.
|
|    Bento4|GPL is distributed in the hope that it will be useful,
|    but WITHOUT ANY WARRANTY; without even the implied warranty of
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
|    GNU General Public License for more details.
|
|    You should have received a copy of the GNU General Public License
|    along with Bento4|GPL; see the file COPYING.  If not, write to the
|    Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|    02111-1307, USA.
|
 ****************************************************************/
/**
* @file 
* @brief Atoms
*/

#ifndef _AP4_ATOM_H_
#define _AP4_ATOM_H_

/*----------------------------------------------------------------------
|   includes
+---------------------------------------------------------------------*/
#include "Ap4Types.h"
#include "Ap4List.h"
#include "Ap4ByteStream.h"
#include "Ap4String.h"
#include "Ap4Debug.h"
#include "Ap4DynamicCast.h"
#include "Ap4Array.h"

/*----------------------------------------------------------------------
|   macros
+---------------------------------------------------------------------*/
#define AP4_ATOM_TYPE(c1,c2,c3,c4)       \
   (((static_cast<AP4_UI32>(c1))<<24) |  \
    ((static_cast<AP4_UI32>(c2))<<16) |  \
    ((static_cast<AP4_UI32>(c3))<< 8) |  \
    ((static_cast<AP4_UI32>(c4))    ))

/*----------------------------------------------------------------------
|   constants
+---------------------------------------------------------------------*/
const AP4_UI32 AP4_ATOM_HEADER_SIZE         = 8;
const AP4_UI32 AP4_ATOM_HEADER_SIZE_64      = 16;
const AP4_UI32 AP4_FULL_ATOM_HEADER_SIZE    = 12;
const AP4_UI32 AP4_FULL_ATOM_HEADER_SIZE_64 = 20;
const AP4_UI32 AP4_ATOM_MAX_NAME_SIZE       = 256;
const AP4_UI32 AP4_ATOM_MAX_URI_SIZE        = 512;

/*----------------------------------------------------------------------
|   forward references
+---------------------------------------------------------------------*/
class AP4_AtomParent;

/*----------------------------------------------------------------------
|   AP4_AtomInspector
+---------------------------------------------------------------------*/
/**
 * Class used in a visitor pattern to walk all the atoms in a tree of
 * #AP4_Atom objects. 
 */
class AP4_AtomInspector {
public:
    // types
    typedef enum {
        HINT_NONE       = 0,
        HINT_HEX        = 1,
        HINT_BOOLEAN    = 2
    } FormatHint;

    // constructor and destructor
    AP4_AtomInspector() : m_Verbosity(0) {}
    virtual ~AP4_AtomInspector() {}

    // methods
    void        SetVerbosity(AP4_Ordinal verbosity) { m_Verbosity = verbosity; }
    AP4_Ordinal GetVerbosity()                      { return m_Verbosity;      }
    
    // virtual methods
    virtual void StartAtom(const char* /* name        */,
                           AP4_UI08    /* version     */,
                           AP4_UI32    /* flags       */,
                           AP4_Size    /* header_size */,
                           AP4_UI64    /*size         */) {}
    virtual void EndAtom() {}
    virtual void StartDescriptor(const char* /* name        */,
                                 AP4_Size    /* header_size */,
                                 AP4_UI64    /*size         */) {}
    virtual void EndDescriptor() {}
    virtual void AddField(const char* /* name */, 
                          AP4_UI64    /* value */, 
                          FormatHint  hint = HINT_NONE) {
        (void)hint; // gcc warning
    }
    virtual void AddFieldF(const char* /* name */, 
                           float       /* value */, 
                           FormatHint  hint = HINT_NONE) {
        (void)hint; // gcc warning
    }
    virtual void AddField(const char* /* name */, 
                          const char* /* value */, 
                          FormatHint  hint = HINT_NONE) {
        (void)hint; // gcc warning 
    }
    virtual void AddField(const char*          /* name */, 
                          const unsigned char* /* bytes */, 
                          AP4_Size             /* byte_count */, 
                          FormatHint           hint = HINT_NONE) {
        (void)hint; // gcc warning 
    }
    
protected:
    AP4_Ordinal m_Verbosity;
};

/*----------------------------------------------------------------------
|   AP4_PrintInspector
+---------------------------------------------------------------------*/
class AP4_PrintInspector : public AP4_AtomInspector {
public:
    AP4_PrintInspector(AP4_ByteStream& stream, AP4_Cardinal indent=0);
    ~AP4_PrintInspector();

    // methods
    void StartAtom(const char* name,
                   AP4_UI08    version,
                   AP4_UI32    flags,
                   AP4_Size    header_size,
                   AP4_UI64    size);
    void EndAtom();
    void StartDescriptor(const char* name,
                         AP4_Size    header_size,
                         AP4_UI64    size);
    void EndDescriptor();
    void AddField(const char* name, AP4_UI64 value, FormatHint hint);
    void AddFieldF(const char* name, float value, FormatHint hint);
    void AddField(const char* name, const char* value, FormatHint hint);
    void AddField(const char* name, const unsigned char* bytes, AP4_Size size, FormatHint hint);

private:
    // members
    AP4_ByteStream* m_Stream;
    AP4_Cardinal    m_Indent;
};

/*----------------------------------------------------------------------
|   AP4_JsonInspector
+---------------------------------------------------------------------*/
class AP4_JsonInspector : public AP4_AtomInspector {
public:
    AP4_JsonInspector(AP4_ByteStream& stream);
    ~AP4_JsonInspector();

    // methods
    void StartAtom(const char* name,
                   AP4_UI08    version,
                   AP4_UI32    flags,
                   AP4_Size    header_size,
                   AP4_UI64    size);
    void EndAtom();
    void StartDescriptor(const char* name,
                         AP4_Size    header_size,
                         AP4_UI64    size);
    void EndDescriptor();
    void AddField(const char* name, AP4_UI64 value, FormatHint hint);
    void AddFieldF(const char* name, float value, FormatHint hint);
    void AddField(const char* name, const char* value, FormatHint hint);
    void AddField(const char* name, const unsigned char* bytes, AP4_Size size, FormatHint hint);

private:
    // members
    AP4_ByteStream*         m_Stream;
    AP4_Cardinal            m_Depth;
    AP4_Array<AP4_Cardinal> m_Items;
};

/*----------------------------------------------------------------------
|   AP4_Atom
+---------------------------------------------------------------------*/
/**
 * Abstract base class for all atom types.
 */
class AP4_Atom {
public:
     AP4_IMPLEMENT_DYNAMIC_CAST(AP4_Atom)

   // types
    typedef AP4_UI32 Type;

    // class methods
    static Type TypeFromString(const char* four_cc);
    static AP4_Result ReadFullHeader(AP4_ByteStream& stream, 
                                     AP4_UI08&       version, 
                                     AP4_UI32&       flags);

    // constructors
    /**
     * Create a simple atom with a specified type and 32-bit size.
     */
    explicit AP4_Atom(Type type, AP4_UI32 size = AP4_ATOM_HEADER_SIZE);

    /**
     * Create a simple atom with a specified type and 64-bit size.
     */
    explicit AP4_Atom(Type type, AP4_UI64 size, bool force_64=false);

    /**
     * Create a full atom with a specified type, 32-bit size, version and flags.
     */
    explicit AP4_Atom(Type     type, 
                      AP4_UI32 size,
                      AP4_UI08 version, 
                      AP4_UI32 flags);

    /**
     * Create a full atom with a specified type, 64-bit size, version and flags.
     */
    explicit AP4_Atom(Type     type, 
                      AP4_UI64 size,
                      bool     force_64,
                      AP4_UI08 version, 
                      AP4_UI32 flags);

    // destructor
    virtual ~AP4_Atom() {}
    
    // methods
    AP4_UI32           GetFlags() const { return m_Flags; }
    void               SetFlags(AP4_UI32 flags) { m_Flags = flags; }
    Type               GetType() const { return m_Type; }
    void               SetType(Type type) { m_Type = type; }
    virtual AP4_Size   GetHeaderSize() const;
    AP4_UI64           GetSize() const { return m_Size32 == 1?m_Size64:m_Size32; }
    void               SetSize(AP4_UI64 size, bool force_64 = false);
    AP4_UI32           GetSize32() const { return m_Size32; }
    void               SetSize32(AP4_UI32 size) { m_Size32 = size; }
    AP4_UI64           GetSize64() const { return m_Size64; }
    void               SetSize64(AP4_UI64 size) { m_Size64 = size; }
    virtual AP4_Result Write(AP4_ByteStream& stream);
    virtual AP4_Result WriteHeader(AP4_ByteStream& stream);
    virtual AP4_Result WriteFields(AP4_ByteStream& stream) = 0;
    virtual AP4_Result Inspect(AP4_AtomInspector& inspector);
    virtual AP4_Result InspectHeader(AP4_AtomInspector& inspector);
    virtual AP4_Result InspectFields(AP4_AtomInspector& /* inspector */) {
        return AP4_SUCCESS; 
    }

    // parent/child relationship methods
    virtual AP4_Result SetParent(AP4_AtomParent* parent) {
        m_Parent = parent;
        return AP4_SUCCESS;
    }
    virtual AP4_AtomParent* GetParent() { return m_Parent; }
    virtual AP4_Result      Detach();

    /**
     * Create a clone of the object.
     * This method returns a clone of the atom, or NULL if
     * the atom cannot be cloned.
     * Override this if your want to make an atom cloneable in a more
     * efficient way than the default implementation.
     */ 
    virtual AP4_Atom* Clone();

 protected:
    // members
    Type            m_Type;
    AP4_UI32        m_Size32; 
    AP4_UI64        m_Size64; // this is 0 if m_Size is not 1 (encoded in 32-bits)
                              // and non-zero only if m_Size is 1 (encoded in 64-bits)
    bool            m_IsFull;
    AP4_UI08        m_Version;
    AP4_UI32        m_Flags;
    AP4_AtomParent* m_Parent;
};

/*----------------------------------------------------------------------
|   AP4_AtomParent
+---------------------------------------------------------------------*/
/**
 * Base class for containers of atoms.
 * This class also implements the logic for finding descendents by name.
 */
class AP4_AtomParent {
public:
    AP4_IMPLEMENT_DYNAMIC_CAST(AP4_AtomParent)

    // base methods
    virtual ~AP4_AtomParent();
    AP4_List<AP4_Atom>& GetChildren() { return m_Children; }
    virtual AP4_Result  AddChild(AP4_Atom* child, int position = -1);
    virtual AP4_Result  RemoveChild(AP4_Atom* child);
    virtual AP4_Result  DeleteChild(AP4_Atom::Type type, AP4_Ordinal index = 0);
    virtual AP4_Atom*   GetChild(AP4_Atom::Type type, AP4_Ordinal index = 0) const;
    virtual AP4_Atom*   GetChild(const AP4_UI08* uuid, AP4_Ordinal index = 0) const;
    virtual AP4_Atom*   FindChild(const char* path, 
                                  bool        auto_create = false,
                                  bool        auto_create_full = false);

    // methods designed to be overridden
    virtual void OnChildChanged(AP4_Atom* /* child */) {}
    virtual void OnChildAdded(AP4_Atom* /* child */)   {}
    virtual void OnChildRemoved(AP4_Atom* /* child */) {}

protected:
    // members
    AP4_List<AP4_Atom> m_Children;
};

/*----------------------------------------------------------------------
|   AP4_UnknownAtom
+---------------------------------------------------------------------*/
/**
 * Class that represents atoms for which there is no specific support.
 * Instances of this class keep a reference to the stream from which 
 * the atom is parsed, so that it can read the atom's payload when it
 * is serialized.
 * If the atom is small, its payload is actually read and stored in 
 * a data buffer, so no reference to the source stream is kept
 */
class AP4_UnknownAtom : public AP4_Atom {
public:
    // constructor and destructor
    AP4_UnknownAtom(AP4_Atom::Type   type, 
                    AP4_UI64         size, 
                    AP4_ByteStream&  stream);
    AP4_UnknownAtom(AP4_Atom::Type type, const AP4_UI08* payload, AP4_Size payload_size);
    AP4_UnknownAtom(const AP4_UnknownAtom& other);
    ~AP4_UnknownAtom();

    // methods
    virtual AP4_Result WriteFields(AP4_ByteStream& stream);
    virtual AP4_Atom*  Clone();

private:
    // members
    AP4_ByteStream* m_SourceStream;
    AP4_Position    m_SourcePosition;
    AP4_DataBuffer  m_Payload;
};

/*----------------------------------------------------------------------
|   AP4_NullTerminatedStringAtom
+---------------------------------------------------------------------*/
/**
 * Generic Class usd for all atoms that contain a single null-terminated
 * string.
 */
class AP4_NullTerminatedStringAtom : public AP4_Atom
{
public:
    AP4_IMPLEMENT_DYNAMIC_CAST_D(AP4_NullTerminatedStringAtom, AP4_Atom)

    // constructors
    AP4_NullTerminatedStringAtom(AP4_Atom::Type type, AP4_UI64 size, AP4_ByteStream& stream);
    AP4_NullTerminatedStringAtom(AP4_Atom::Type type, const char* value);

    // accessors
    const AP4_String& GetValue() { return m_Value; }
    
    // methods
    virtual AP4_Result InspectFields(AP4_AtomInspector& inspector);
    virtual AP4_Result WriteFields(AP4_ByteStream& stream);

private:
    // members
    AP4_String m_Value;
};

/*----------------------------------------------------------------------
|   atom types
+---------------------------------------------------------------------*/
const AP4_Atom::Type AP4_ATOM_TYPE_UDTA = AP4_ATOM_TYPE('u','d','t','a');
const AP4_Atom::Type AP4_ATOM_TYPE_URL  = AP4_ATOM_TYPE('u','r','l',' ');
const AP4_Atom::Type AP4_ATOM_TYPE_TRAK = AP4_ATOM_TYPE('t','r','a','k');
const AP4_Atom::Type AP4_ATOM_TYPE_TRAF = AP4_ATOM_TYPE('t','r','a','f');
const AP4_Atom::Type AP4_ATOM_TYPE_TKHD = AP4_ATOM_TYPE('t','k','h','d');
const AP4_Atom::Type AP4_ATOM_TYPE_TFHD = AP4_ATOM_TYPE('t','f','h','d');
const AP4_Atom::Type AP4_ATOM_TYPE_TRUN = AP4_ATOM_TYPE('t','r','u','n');
const AP4_Atom::Type AP4_ATOM_TYPE_STTS = AP4_ATOM_TYPE('s','t','t','s');
const AP4_Atom::Type AP4_ATOM_TYPE_STSZ = AP4_ATOM_TYPE('s','t','s','z');
const AP4_Atom::Type AP4_ATOM_TYPE_STZ2 = AP4_ATOM_TYPE('s','t','z','2');
const AP4_Atom::Type AP4_ATOM_TYPE_STSS = AP4_ATOM_TYPE('s','t','s','s');
const AP4_Atom::Type AP4_ATOM_TYPE_STSD = AP4_ATOM_TYPE('s','t','s','d');
const AP4_Atom::Type AP4_ATOM_TYPE_STSC = AP4_ATOM_TYPE('s','t','s','c');
const AP4_Atom::Type AP4_ATOM_TYPE_STCO = AP4_ATOM_TYPE('s','t','c','o');
const AP4_Atom::Type AP4_ATOM_TYPE_CO64 = AP4_ATOM_TYPE('c','o','6','4');
const AP4_Atom::Type AP4_ATOM_TYPE_STBL = AP4_ATOM_TYPE('s','t','b','l');
const AP4_Atom::Type AP4_ATOM_TYPE_SINF = AP4_ATOM_TYPE('s','i','n','f');
const AP4_Atom::Type AP4_ATOM_TYPE_SCHM = AP4_ATOM_TYPE('s','c','h','m');
const AP4_Atom::Type AP4_ATOM_TYPE_SCHI = AP4_ATOM_TYPE('s','c','h','i');
const AP4_Atom::Type AP4_ATOM_TYPE_MVHD = AP4_ATOM_TYPE('m','v','h','d');
const AP4_Atom::Type AP4_ATOM_TYPE_MEHD = AP4_ATOM_TYPE('m','e','h','d');
const AP4_Atom::Type AP4_ATOM_TYPE_MP4S = AP4_ATOM_TYPE('m','p','4','s');
const AP4_Atom::Type AP4_ATOM_TYPE_MP4A = AP4_ATOM_TYPE('m','p','4','a');
const AP4_Atom::Type AP4_ATOM_TYPE_MP4V = AP4_ATOM_TYPE('m','p','4','v');
const AP4_Atom::Type AP4_ATOM_TYPE_AVC1 = AP4_ATOM_TYPE('a','v','c','1');
const AP4_Atom::Type AP4_ATOM_TYPE_AVC2 = AP4_ATOM_TYPE('a','v','c','2');
const AP4_Atom::Type AP4_ATOM_TYPE_AVC3 = AP4_ATOM_TYPE('a','v','c','3');
const AP4_Atom::Type AP4_ATOM_TYPE_AVC4 = AP4_ATOM_TYPE('a','v','c','4');
const AP4_Atom::Type AP4_ATOM_TYPE_HEV1 = AP4_ATOM_TYPE('h','e','v','1');
const AP4_Atom::Type AP4_ATOM_TYPE_HVC1 = AP4_ATOM_TYPE('h','v','c','1');
const AP4_Atom::Type AP4_ATOM_TYPE_ALAC = AP4_ATOM_TYPE('a','l','a','c');
const AP4_Atom::Type AP4_ATOM_TYPE_ENCA = AP4_ATOM_TYPE('e','n','c','a');
const AP4_Atom::Type AP4_ATOM_TYPE_ENCV = AP4_ATOM_TYPE('e','n','c','v');
const AP4_Atom::Type AP4_ATOM_TYPE_MOOV = AP4_ATOM_TYPE('m','o','o','v');
const AP4_Atom::Type AP4_ATOM_TYPE_MOOF = AP4_ATOM_TYPE('m','o','o','f');
const AP4_Atom::Type AP4_ATOM_TYPE_MVEX = AP4_ATOM_TYPE('m','v','e','x');
const AP4_Atom::Type AP4_ATOM_TYPE_TREX = AP4_ATOM_TYPE('t','r','e','x');
const AP4_Atom::Type AP4_ATOM_TYPE_MINF = AP4_ATOM_TYPE('m','i','n','f');
const AP4_Atom::Type AP4_ATOM_TYPE_META = AP4_ATOM_TYPE('m','e','t','a');
const AP4_Atom::Type AP4_ATOM_TYPE_MDHD = AP4_ATOM_TYPE('m','d','h','d');
const AP4_Atom::Type AP4_ATOM_TYPE_MFHD = AP4_ATOM_TYPE('m','f','h','d');
const AP4_Atom::Type AP4_ATOM_TYPE_ILST = AP4_ATOM_TYPE('i','l','s','t');
const AP4_Atom::Type AP4_ATOM_TYPE_HDLR = AP4_ATOM_TYPE('h','d','l','r');
const AP4_Atom::Type AP4_ATOM_TYPE_FTYP = AP4_ATOM_TYPE('f','t','y','p');
const AP4_Atom::Type AP4_ATOM_TYPE_IODS = AP4_ATOM_TYPE('i','o','d','s');
const AP4_Atom::Type AP4_ATOM_TYPE_ESDS = AP4_ATOM_TYPE('e','s','d','s');
const AP4_Atom::Type AP4_ATOM_TYPE_EDTS = AP4_ATOM_TYPE('e','d','t','s');
const AP4_Atom::Type AP4_ATOM_TYPE_DRMS = AP4_ATOM_TYPE('d','r','m','s');
const AP4_Atom::Type AP4_ATOM_TYPE_DRMI = AP4_ATOM_TYPE('d','r','m','i');
const AP4_Atom::Type AP4_ATOM_TYPE_DREF = AP4_ATOM_TYPE('d','r','e','f');
const AP4_Atom::Type AP4_ATOM_TYPE_DINF = AP4_ATOM_TYPE('d','i','n','f');
const AP4_Atom::Type AP4_ATOM_TYPE_CTTS = AP4_ATOM_TYPE('c','t','t','s');
const AP4_Atom::Type AP4_ATOM_TYPE_MDIA = AP4_ATOM_TYPE('m','d','i','a');
const AP4_Atom::Type AP4_ATOM_TYPE_ELST = AP4_ATOM_TYPE('e','l','s','t');
const AP4_Atom::Type AP4_ATOM_TYPE_VMHD = AP4_ATOM_TYPE('v','m','h','d');
const AP4_Atom::Type AP4_ATOM_TYPE_SMHD = AP4_ATOM_TYPE('s','m','h','d');
const AP4_Atom::Type AP4_ATOM_TYPE_NMHD = AP4_ATOM_TYPE('n','m','h','d');
const AP4_Atom::Type AP4_ATOM_TYPE_STHD = AP4_ATOM_TYPE('s','t','h','d');
const AP4_Atom::Type AP4_ATOM_TYPE_HMHD = AP4_ATOM_TYPE('h','m','h','d');
const AP4_Atom::Type AP4_ATOM_TYPE_FRMA = AP4_ATOM_TYPE('f','r','m','a');
const AP4_Atom::Type AP4_ATOM_TYPE_MDAT = AP4_ATOM_TYPE('m','d','a','t');
const AP4_Atom::Type AP4_ATOM_TYPE_FREE = AP4_ATOM_TYPE('f','r','e','e');
const AP4_Atom::Type AP4_ATOM_TYPE_TIMS = AP4_ATOM_TYPE('t','i','m','s');
const AP4_Atom::Type AP4_ATOM_TYPE_RTP_ = AP4_ATOM_TYPE('r','t','p',' ');
const AP4_Atom::Type AP4_ATOM_TYPE_HNTI = AP4_ATOM_TYPE('h','n','t','i');
const AP4_Atom::Type AP4_ATOM_TYPE_SDP_ = AP4_ATOM_TYPE('s','d','p',' ');
const AP4_Atom::Type AP4_ATOM_TYPE_IKMS = AP4_ATOM_TYPE('i','K','M','S');
const AP4_Atom::Type AP4_ATOM_TYPE_ISFM = AP4_ATOM_TYPE('i','S','F','M');
const AP4_Atom::Type AP4_ATOM_TYPE_ISLT = AP4_ATOM_TYPE('i','S','L','T');
const AP4_Atom::Type AP4_ATOM_TYPE_TREF = AP4_ATOM_TYPE('t','r','e','f');
const AP4_Atom::Type AP4_ATOM_TYPE_HINT = AP4_ATOM_TYPE('h','i','n','t');
const AP4_Atom::Type AP4_ATOM_TYPE_CDSC = AP4_ATOM_TYPE('c','d','s','c');
const AP4_Atom::Type AP4_ATOM_TYPE_MPOD = AP4_ATOM_TYPE('m','p','o','d');
const AP4_Atom::Type AP4_ATOM_TYPE_IPIR = AP4_ATOM_TYPE('i','p','i','r');
const AP4_Atom::Type AP4_ATOM_TYPE_CHAP = AP4_ATOM_TYPE('c','h','a','p');
const AP4_Atom::Type AP4_ATOM_TYPE_ALIS = AP4_ATOM_TYPE('a','l','i','s');
const AP4_Atom::Type AP4_ATOM_TYPE_SYNC = AP4_ATOM_TYPE('s','y','n','c');
const AP4_Atom::Type AP4_ATOM_TYPE_DPND = AP4_ATOM_TYPE('d','p','n','d');
const AP4_Atom::Type AP4_ATOM_TYPE_ODRM = AP4_ATOM_TYPE('o','d','r','m');
const AP4_Atom::Type AP4_ATOM_TYPE_ODKM = AP4_ATOM_TYPE('o','d','k','m');
const AP4_Atom::Type AP4_ATOM_TYPE_OHDR = AP4_ATOM_TYPE('o','h','d','r');
const AP4_Atom::Type AP4_ATOM_TYPE_ODDA = AP4_ATOM_TYPE('o','d','d','a');
const AP4_Atom::Type AP4_ATOM_TYPE_ODHE = AP4_ATOM_TYPE('o','d','h','e');
const AP4_Atom::Type AP4_ATOM_TYPE_ODAF = AP4_ATOM_TYPE('o','d','a','f');
const AP4_Atom::Type AP4_ATOM_TYPE_GRPI = AP4_ATOM_TYPE('g','r','p','i');
const AP4_Atom::Type AP4_ATOM_TYPE_IPRO = AP4_ATOM_TYPE('i','p','r','o');
const AP4_Atom::Type AP4_ATOM_TYPE_MDRI = AP4_ATOM_TYPE('m','d','r','i');
const AP4_Atom::Type AP4_ATOM_TYPE_AVCC = AP4_ATOM_TYPE('a','v','c','C');
const AP4_Atom::Type AP4_ATOM_TYPE_HVCC = AP4_ATOM_TYPE('h','v','c','C');
const AP4_Atom::Type AP4_ATOM_TYPE_WAVE = AP4_ATOM_TYPE('w','a','v','e');
const AP4_Atom::Type AP4_ATOM_TYPE_WIDE = AP4_ATOM_TYPE('w','i','d','e');
const AP4_Atom::Type AP4_ATOM_TYPE_UUID = AP4_ATOM_TYPE('u','u','i','d');
const AP4_Atom::Type AP4_ATOM_TYPE_8ID_ = AP4_ATOM_TYPE('8','i','d',' ');
const AP4_Atom::Type AP4_ATOM_TYPE_8BDL = AP4_ATOM_TYPE('8','b','d','l');
const AP4_Atom::Type AP4_ATOM_TYPE_AC_3 = AP4_ATOM_TYPE('a','c','-','3');
const AP4_Atom::Type AP4_ATOM_TYPE_EC_3 = AP4_ATOM_TYPE('e','c','-','3');
const AP4_Atom::Type AP4_ATOM_TYPE_DTSC = AP4_ATOM_TYPE('d','t','s','c');
const AP4_Atom::Type AP4_ATOM_TYPE_DTSH = AP4_ATOM_TYPE('d','t','s','h');
const AP4_Atom::Type AP4_ATOM_TYPE_DTSL = AP4_ATOM_TYPE('d','t','s','l');
const AP4_Atom::Type AP4_ATOM_TYPE_DTSE = AP4_ATOM_TYPE('d','t','s','e');
const AP4_Atom::Type AP4_ATOM_TYPE_MFRA = AP4_ATOM_TYPE('m','f','r','a');
const AP4_Atom::Type AP4_ATOM_TYPE_TFRA = AP4_ATOM_TYPE('t','f','r','a');
const AP4_Atom::Type AP4_ATOM_TYPE_MFRO = AP4_ATOM_TYPE('m','f','r','o');
const AP4_Atom::Type AP4_ATOM_TYPE_TFDT = AP4_ATOM_TYPE('t','f','d','t');
const AP4_Atom::Type AP4_ATOM_TYPE_TENC = AP4_ATOM_TYPE('t','e','n','c');
const AP4_Atom::Type AP4_ATOM_TYPE_SENC = AP4_ATOM_TYPE('s','e','n','c');
const AP4_Atom::Type AP4_ATOM_TYPE_SAIO = AP4_ATOM_TYPE('s','a','i','o');
const AP4_Atom::Type AP4_ATOM_TYPE_SAIZ = AP4_ATOM_TYPE('s','a','i','z');
const AP4_Atom::Type AP4_ATOM_TYPE_PDIN = AP4_ATOM_TYPE('p','d','i','n');
const AP4_Atom::Type AP4_ATOM_TYPE_BLOC = AP4_ATOM_TYPE('b','l','o','c');
const AP4_Atom::Type AP4_ATOM_TYPE_AINF = AP4_ATOM_TYPE('a','i','n','f');
const AP4_Atom::Type AP4_ATOM_TYPE_PSSH = AP4_ATOM_TYPE('p','s','s','h');
const AP4_Atom::Type AP4_ATOM_TYPE_MARL = AP4_ATOM_TYPE('m','a','r','l');
const AP4_Atom::Type AP4_ATOM_TYPE_MKID = AP4_ATOM_TYPE('m','k','i','d');
const AP4_Atom::Type AP4_ATOM_TYPE_PRFT = AP4_ATOM_TYPE('p','r','f','t');
const AP4_Atom::Type AP4_ATOM_TYPE_STPP = AP4_ATOM_TYPE('s','t','p','p');
const AP4_Atom::Type AP4_ATOM_TYPE_DEC3 = AP4_ATOM_TYPE('d','e','c','3');
const AP4_Atom::Type AP4_ATOM_TYPE_DAC3 = AP4_ATOM_TYPE('d','a','c','3');
const AP4_Atom::Type AP4_ATOM_TYPE_SIDX = AP4_ATOM_TYPE('s','i','d','x');
const AP4_Atom::Type AP4_ATOM_TYPE_SSIX = AP4_ATOM_TYPE('s','s','i','x');
const AP4_Atom::Type AP4_ATOM_TYPE_SBGP = AP4_ATOM_TYPE('s','b','g','p');
const AP4_Atom::Type AP4_ATOM_TYPE_SGPD = AP4_ATOM_TYPE('s','g','p','d');
const AP4_Atom::Type AP4_ATOM_TYPE_VPCC = AP4_ATOM_TYPE('v','p','c','C');

/*----------------------------------------------------------------------
|   AP4_AtomListInspector
+---------------------------------------------------------------------*/
class AP4_AtomListInspector : public AP4_List<AP4_Atom>::Item::Operator
{
 public:
    AP4_AtomListInspector(AP4_AtomInspector& inspector) :
        m_Inspector(inspector) {}
    AP4_Result Action(AP4_Atom* atom) const {
        atom->Inspect(m_Inspector);
        return AP4_SUCCESS;
    }

 private:
    AP4_AtomInspector& m_Inspector;
};

/*----------------------------------------------------------------------
|   AP4_AtomListWriter
+---------------------------------------------------------------------*/
class AP4_AtomListWriter : public AP4_List<AP4_Atom>::Item::Operator
{
 public:
    AP4_AtomListWriter(AP4_ByteStream& stream) :
        m_Stream(stream) {}
    AP4_Result Action(AP4_Atom* atom) const;

 private:
    AP4_ByteStream& m_Stream;
};

/*----------------------------------------------------------------------
|   AP4_AtomFinder
+---------------------------------------------------------------------*/
class AP4_AtomFinder : public AP4_List<AP4_Atom>::Item::Finder
{
 public:
    AP4_AtomFinder(AP4_Atom::Type type, AP4_Ordinal index = 0) : 
       m_Type(type), m_Index(index) {}
    AP4_Result Test(AP4_Atom* atom) const {
        if (atom->GetType() == m_Type) {
            if (m_Index-- == 0) {
                return AP4_SUCCESS;
            } else {
                return AP4_FAILURE;
            }
        } else {
            return AP4_FAILURE;
        }
    }
 private:
    AP4_Atom::Type      m_Type;
    mutable AP4_Ordinal m_Index;
};

/*----------------------------------------------------------------------
|   AP4_AtomSizeAdder
+---------------------------------------------------------------------*/
class AP4_AtomSizeAdder : public AP4_List<AP4_Atom>::Item::Operator {
public:
    AP4_AtomSizeAdder(AP4_UI64& size) : m_Size(size) {}

private:
    AP4_Result Action(AP4_Atom* atom) const {
        m_Size += atom->GetSize();
        return AP4_SUCCESS;
    }
    AP4_UI64& m_Size;
};

#endif // _AP4_ATOM_H_