/*
 * @(#)MPEG4Boxes.txt  1.0.1  2011-08-17
 *
 * Copyright (c) 2011 Werner Randelshofer, Immensee, Switzerland.
 * All rights reserved.
 *
 * You may not use, copy or modify this file, except in compliance with the
 * license agreement you entered into with Werner Randelshofer.
 * For details see accompanying license terms.
 */

/* This file contains the description of some
 * well known MPEG-4 data structures as
 * published in
 *   ISO/IEC 14496-12, Information technology - Coding of audio-visual objects -
 *   Part 12: ISO base media file format.
 *
 * @version 1.0.1 2011-08-17 Fixes hdlr box.
 * <br>1.0 2011-01-12 Derived from QuickTimeAtoms.txt.
 */


typedef struct {
    uint32 size;
    magic type;
} Box;

typedef struct {
    Box box;
    uint8 version;
    uint8[3] flags;
} FullBox;


magic cprtAtom "cprt";
description cprtAtom "Copyright Atom", "Copyright notice.";

magic ftypAtom "ftyp";
description ftypAtom "File Type Atom", "The file type atom identifies the file type specifications the file is compatible with. When a file is compatible with more than one specification, the file type atom lists all the compatible types and indicates the preferred brand, or best use, among the compatible types";

magic movieAtom "moov";
description movieAtom "Movie Atom", "The movie atom holds the description of the movie.";

magic compressedMovieAtom "cmov";
description compressedMovieAtom "Compressed Movie", "The compressed movie atom holds the compressed description of the movie.";

magic dataCompressionAtom "dcom";
description dataCompressionAtom "Data Compression Atom", "Describes what lossless data compression algorithm was used to compress the movie header atoms.";

magic compressedMovieDataAtom "cmvd";
description compressedMovieDataAtom "Compressed Movie Data", "Holds the compressed movie header atoms. The first 32-bit integer in the compressed movie data atom indicates the uncompressed size of the movie resource and then the compressed movie resource data follows";

magic movieDataAtom "mdat";
description movieDataAtom "Movie Data Atom", "The movie data atom contains the media data of the movie. Usually this data can be interpreted only by using information provided by the movie atom.";

magic freeAtom "free";
description freeAtom "Free Space Atom", "The free space atom marks unused space available in the file.";

magic skipAtom "skip";
description skipAtom "Skip Atom", "The skip atom marks unused space available in the file.";

magic wideAtom "wide";
description wideAtom "Reserved Space", "The wide atom marks reserved space which can be overwritten by an extended size field. The wide atom consists only of a type and size field. This occupies 8 bytes - enough space to add an extended size field to the header of the atom that follows. If an atom grows to exceed 2^32 bytes in size, and it is preceeded by a wide atom, you may create a new atom header, containing an extended size field, by overwriting the wide atom.";

magic previewAtom "pnot";
description previewAtom "Preview Atom", "The preview atom contains information that allows you to find the preview image associated with a QuickTime movie.";

magic referenceMovieAtom "rmra";
description referenceMovieAtom "Reference Movie Atom", "A movie that contains this atom references to alternate movies, i. e. movies having different data rates, allowing an application to choose the best-looking movie based on the configuration of the computer system. The reference movie atom contains one or more reference movie descriptor atoms, each of which describes an alternate movie.";

magic dataReferenceAtom "rdrf";
description dataReferenceAtom "Data Reference Atom", "A data reference atom contains the information necessary to locate a movie, or a stream or file that QuickTime canplay, typically in the form of a URL or a file alias.";

magic dataRateAtom "rmdr";
description dataRateAtom "Data Rate Atom", "A data rate atom specifies the minimum data rate required to play a movie.";
magic cpuSpeedAtom "rmcs";
description cpuSpeedAtom "CPU Speed Atom", "A CPU speed atom specifies the minimum computing power needed to display a movie. This is not a simple measurement of clock speed - it is a measurement of performance for QuickTime-related operations. Speed is expressed as a relative value between 100 and 2^31, in multiples of 100. Typical scores might range from a minimum score of 100, which would describe a computer as slow as, or slower than, a 166 MHz Pentium or 120 MHz Power PC, to a maximum score of 600 for a 500 MHz Pentium III or 400 MHz G4 PowerPC. A Computer with a graphics accelerator and a Gigahertz clock speed might score as high as 1000.";
magic versionCheckAtom "rmvc";
description versionCheckAtom "Version Check Atom", ".";
magic componentDetectAtom "rmcd";
description componentDetectAtom "Component Detect Atom", ".";
magic qualityAtom "rmqu";
description qualityAtom "Quality Atom", ".";

magic referenceMovieDescriptorAtom "rmda";
description referenceMovieDescriptorAtom "Reference Movie Descriptor Atom", "Describes where a particular movie can be found, and optionally what the system requirements are to play that movie, as well as an optonal quality rating for that movie.";

magic trackAtom "trak";
description trackAtom "Track Atom", "Track atoms define a single track of a movie. A movie may consist of one or more tracks. Each track is independent of the other tracks in the movie and carries its own temporal and spatial information.";

magic editAtom "edts";
description editAtom "Edit Atom", "Edit atoms define the portions of the media that are to be used to build up a track for a movie.";

magic mediaAtom "mdia";
description mediaAtom "Media Atom",  "Media atoms define the data for a movie track. It specifies the component that is to interpret the media data, and it also specifies the data references.";

magic mediaInformationAtom "minf";
description mediaInformationAtom "Media Information Atom", "Media information atoms store handler-specific information for the media data that constitutes a track. The media handler uses this information to map from media time to media data. These atoms are formatted differently based on the type of media data stored in the atom. The format and content of media information atoms are dictated by the media handler that is responsible for interpreting the media data stream. Another media handler would not know how to interpret this information.";

magic dataInformationAtom "dinf";
description dataInformationAtom "Data Information Atom", "The handler reference atom (hdlr) contains information specifying the data handler component that provides access to the media data. The handler uses the data information atom to specify where the data is stored.";

magic sampleTableAtom "stbl";
description sampleTableAtom "Sample Table Atom", "The sample table atom contains information for converting from media time to sample number to sample location. This atom also indicates how to interpret the sample (for example, whether to decompress the video sample and, if so, how).";

magic userDefinedDataAtom "udta";
description userDefinedDataAtom "User Defined Data Atom", "This atom holds user-defined data.";

magic clippingAtom "clip";
description clippinAtom "Clipping Atom", "Clipping atoms specify the clipping regions for movies and tracks.";

magic trackMatteAtom "matt";
description trackMatteAtom "Track Matte Atom", "Track matte atoms specify the mattes for tracks. A track matte is a pixel map that defines the blending of visual track data.";

magic movieHeaderAtom "mvhd";
description movieHeaderAtom "Movie Header Atom", "The movie header atom defines the time scale and duration information of the entire movie, as well as its display characteristics.";

magic windowLocationAtom "WLOC";
description windowLocationAtom "Window Location Atom", "Default window location for movie.";

magic trackApertureModeDimensions "tapt";
description trackApertureModeDimensions "Track Aperture Mode Dimensions", "";

magic trackCleanApertureModeDimensions "clef";
description trackCleanApertureModeDimensions "Track Clean Aperture Dimensions", "";

magic trackProductionApertureDimensions "prof";
description trackProductionApertureDimensions "Track Production Aperture Dimensions", "";

magic trackEncodePixelsModeDimensions "enof";
description trackEncodePixelsModeDimensions "Track Encode Pixels Dimensions", "";

magic playSelectionAtom "SelO";
description playSelectionAtom "Play Selection Atom", "";

magic playAllFramesAtom "AllF";
description playAllFramesAtom "Play All Frames Atom", "";

typedef struct {
    int version; // 4 bytes version/flags = byte hex version + 24-bit hex flags
                 // (current = 0)
    short languageCode; //  1/8 byte ISO language padding = 1-bit value set to 0
           //-> 1 7/8 bytes content language = 3 * 5-bits ISO 639-2 language code less 0x60
           //  - example code for english = 0x15C7
    byte unknown;
    cstring copyright;
} cprtAtom;

typedef struct {
    magic brand;
    bcd4 versionYear;
    bcd2 versionMonth;
    bcd2 versionMinor;
    magic[] compatibleBrands;
} ftypAtom;

typedef struct {
    magic compressionMethod;
} dataCompressionAtom;

typedef struct {
    mactimestamp modificationDate;
    short versionNumber;
    magic atomType;
    short atomIndex;
} previewAtom;

// Enumeration for data reference flags
set {
    SelfContained = 0x1 // movie is self contained
} DataReferenceFlags;
typedef struct {
    int set DataReferenceFlags flags;
    magic dataReferenceType;
    int dataReferenceSize;
    string dataReference;
} dataReferenceAtom;

typedef struct {
    byte[4] flags;
    int bitsPerSecond;
} dataRateAtom;

typedef struct {
    byte[4] flags;
    int cpuSpeed;
} cpuSpeedAtom;

typedef struct {
    byte version;
    byte[3] flags;
    mactimestamp creationTime;
    mactimestamp modificationTime;
    int timeScale;
    int duration;
    fixed16d16 preferredRate;
    fixed8d8 preferredVolume;
    byte[10] reserved;
    fixed16d16 matrixA;
    fixed16d16 matrixB;
    fixed2d30 matrixU;
    fixed16d16 matrixC;
    fixed16d16 matrixD;
    fixed2d30 matrixV;
    fixed16d16 matrixX;
    fixed16d16 matrixY;
    fixed2d30 matrixW;
    int previewTime;
    int previewDuration;
    int posterTime;
    int selectionTime;
    int selectionDuration;
    int currentTime;
    int nextTrackId;
} movieHeaderAtom;


magic trackHeaderAtom "tkhd";
description trackHeaderAtom "Track Header Atom", "The track header atom describes the characteristics of a single track within a movie, including temporal, spatial, and volume information.";

// Enumeration for track header flags
set {
    TrackEnable = 0x1, // enabled track
    TrackInMovie = 0x2, // track in playback
    TrackInPreview = 0x4, // track in preview
    TrackInPoster = 0x8 // track in poster
} TrackHeaderFlags;


typedef struct {
    byte version;
    byte flag0;
    byte flag1;
    byte set TrackHeaderFlags flag2;
    mactimestamp creationTime;
    mactimestamp modificationTime;
    int trackId;
    byte[4] reserved;
    int duration;
    byte[8] reserved;
    short layer;
    short alternateGroup;
    fixed8d8 volume;
    byte[2] reserved;
    fixed16d16 matrixA;
    fixed16d16 matrixB;
    fixed2d30 matrixU;
    fixed16d16 matrixC;
    fixed16d16 matrixD;
    fixed2d30 matrixV;
    fixed16d16 matrixX;
    fixed16d16 matrixY;
    fixed2d30 matrixW;
    fixed16d16 trackWidth;
    fixed16d16 trackHeight;
} trackHeaderAtom;


magic mediaHeaderAtom "mdhd";
description mediaHeaderAtom "Media Header Atom", "The media header atom specifies the characteristics of the media that is used to store data for the movie track defined in its associated track atom.";

typedef struct {
    byte version;
    byte[3] flags;
    mactimestamp creationTime;
    mactimestamp modificationTime;
    int timeScale;
    int duration;
    short language;
    short quality;
} mediaHeaderAtom;


magic handlerReferenceAtom "hdlr";
description handlerReferenceAtom "Handler Reference Atom", "The handler reference atom specifies the component that is to interpret a media's data. This component is called a media handler.";

typedef struct {
    byte version;
    byte[3] flags;
    magic componentType;
    magic componentSubtype;
    magic componentManufacturer;
    int componentFlags;
    int componentFlagsMask;
    cstring componentName;
    ubyte[] extraData;
} handlerReferenceAtom;

magic movieAlbumAtom "©alb";
description movieAlbumAtom "Movie Album Atom", "";
typedef struct {
    pstring album;
} movieAlbumAtom;

magic movieArtistAtom "©ART";
description movieArtistAtom "Movie Artist Atom", "";
typedef struct {
    pstring artist;
} movieArtistAtom;

magic copyrightStatementAtom "©cpy";
typedef struct {
    pstring copyright;
} copyrightStatementAtom;

magic copyrightCommentsAtom "©cmt";
typedef struct {
    pstring comments;
} copyrightCommentsAtom;

magic creationDateAtom "©day";
description creationDateAtom "Movie Creation Date Atom", "";
typedef struct {
    pstring date;
} creationDateAtom;

magic movieDescriptionAtom "©des";
typedef struct {
    pstring description;
} movieDescriptionAtom;

magic movieDirectorAtom "©dir";
typedef struct {
    pstring director;
} movieDirectorAtom;

magic copyrightDisclaimerAtom "©dis";
typedef struct {
    pstring disclaimer;
} copyrightDisclaimerAtom;

magic editComment1Atom "©ed1";
typedef struct {
    pstring edit;
} editComment1Atom;

magic editComment2Atom "©ed2";
typedef struct {
    pstring edit;
} editComment2Atom;

magic editComment3Atom "©ed3";

typedef struct {
    pstring edit;
} editComment3Atom;

magic editComment4Atom "©ed4";

typedef struct {
    pstring edit;
} editComment4Atom;

magic editComment5Atom "©ed5";

typedef struct {
    pstring edit;
} editComment5Atom;

magic editComment6Atom "©ed6";

typedef struct {
    pstring edit;
} editComment7Atom;

magic editComment7Atom "©ed7";

typedef struct {
    pstring edit;
} editComment7Atom;

magic editComment8Atom "©ed8";
typedef struct {
    pstring edit;
} editComment8Atom;

magic editComment9Atom "©ed9";
typedef struct {
    pstring edit;
} editComment9Atom;

magic movieEncodingSoftwareAtom "©enc";
description movieEncodingSoftwareAtom "Movie Encoding Software Atom", "";
typedef struct {
    pstring encodingSoftware;
} movieEncodingSoftwareAtom;

magic formatAtom "©fmt";
typedef struct {
    pstring format;
} formatAtom;

magic movieInfoAtom "©inf";

typedef struct {
    pstring info;
} movieInfoAtom;

magic movieProducerAtom "©prd";
typedef struct {
    pstring producer;
} movieProducerAtom;

magic moviePerformersAtom "©prf";
typedef struct {
    pstring performer;
} moviePerformersAtom;

magic movieRequirementsAtom "©req";
typedef struct {
    pstring requirements;
} movieRequirementsAtom;

magic movieNameAtom "©nam";
description movieNameAtom "Movie Name Atom", "";
typedef struct {
    pstring name;
} movieNameAtom;

magic movieSourceCreditsAtom "©src";
typedef struct {
    pstring source;
} movieSourceCreditsAtom;

magic copyrightSoftwareAtom "©swr";
typedef struct {
    pstring software;
} copyrightSoftwareAtom;

magic movieTrackNumberAtom "©trk";
description movieTrackNumberAtom "Movie Track Number Atom", "";
typedef struct {
    pstring trackNumber;
} movieTrackNumberAtom;

magic movieWriterAtom "©wrt";
typedef struct {
    pstring writer;
} movieWriterAtom;

magic clippingRegionAtom "crgn";

typedef struct {
    short regionSize;
    short[4] regionBoundaryBox;
    byte[] clippingRegionData;
} clippingRegionAtom;

magic compressedMatteAtom "kmat";
description compressedMatteAtom "Compressed Matte Atom", "The compressed matte atom specifies the image description structure associated with a particular matte atom.";

typedef struct {
    byte versions;
    byte[3] flags;
    byte[] matteImageDescriptionStructureAndMatteData;
} compressedMatteAtom;

magic editListAtom "elst";
description editListAtom "Edit List Atom", "Edit list atoms specify how to map from a time in a movie to a time in a media, and ultimatively to media data";

typedef struct {
    byte version;
    byte[3] flags;
    int numberOfEntries;
    editListTable editListTable[numberOfEntries];
} editListAtom;

typedef struct {
    int trackDuration;
    int mediaTime;
    fixed16d16 mediaRate;
} editListTable;

magic videoMediaInformationHeaderAtom "vmhd";
description videoMediaInformationHeaderAtom "Video Media Information Header Atom", "Video media information atoms are the highest-level atoms in video media. A number of other atoms define specific characteristics of the video media data.";

set {
    videoFlagNoLeanAhead=1 // I am not shure if this is the correct value for this flag
} vmhdFlags;

enum {
    Copy = 0x0,  
    DitherCopy = 0x40,  
    Blend = 0x20, // uses opcolor  
    Transparent = 0x24, // uses opcolor  
    StraightAlpha = 0x100,  
    PremulWhiteAlpha = 0x101,  
    PremulBlackAlpha = 0x102,  
    StraightAlphaBlend = 0x104, // uses opclor  
    Composition = 0x103  
} GraphicsModes;

typedef struct {
    byte version;
    byte flag1;
    byte flag2;
    byte set vmhdFlags flag3;
    short enum GraphicsModes graphicsMode;
    ushort[3] opcolor;
} videoMediaInformationHeaderAtom;

magic soundMediaInformationHeaderAtom "smhd";
description soundMediaInformationHeaderAtom "Sound Media Information Header Atom", "The sound media information header atom stores the sound media information.";

typedef struct {
    ubyte version;  // A 1-byte specification of the version of this sound media information header atom.
    byte[3] flags; // A 3-byte space for sound media information flags. Set this field to 0.
    short balance;  // A 16-bit integer that specifies the sound balance of this
                    // sound media. Sound balance is the setting that controls
                    // the mix of sound between the two speakers of a computer.
                    // This field is normally set to 0.
                    // Balance values are represented as 16-bit, fixed-point
                    // numbers that range from -1.0 to +1.0. The high-order 8
                    // bits contain the integer portion of the value; the
                    // low-order 8 bits contain the fractional part. Negative
                    // values weight the balance toward the left speaker;
                    // positive values emphasize the right channel. Setting the
                    // balance to 0 corresponds to a neutral setting.
    short reserved; // Reserved for use by Apple. Set this field to 0.
} soundMediaInformationHeaderAtom;

magic dataReferenceAtom "dref";
description dataReferenceAtom "Data Reference Atom", "The data reference atom encompasses the data references.";

typedef struct {
    ubyte version;
    ubyte[3] flags;
    int numberOfEntries;
    dataReferenceEntry dataReference[numberOfEntries];
} dataReferenceAtom;

set {
    dataRefSelfReference=1 // I am not shure if this is the correct value for this flag
} drefEntryFlags;

typedef struct {
    int size;
    magic type;
    byte version;
    ubyte flag1;
    ubyte flag2;
    ubyte set drefEntryFlags flag3;
    ubyte[size - 12] data;
} dataReferenceEntry;

magic SampleDescriptionBox "stsd";
description SampleDescriptionBox  "Sample Description Box",
"The sample description table gives detailed information about the coding type used, and any initialization information needed for that coding.";

magic VisualSampleDescriptionBox "stsd (vmhd)";
description VisualSampleDescriptionBox  "Visual Sample Description Box",
    "The visual sample description contains information that defines how to interpret video media data.";

magic AudioSampleDescriptionBox "stsd (smhd)";
description AudioSampleDescriptionBox  "Audio Sample Description Box",
    "The audio sample description contains information that defines how to interpret sound media data.";

typedef struct {
    byte version;
    byte[3] flags;
    int numberOfEntries;
    SampleDescriptionEntry table[numberOfEntries];
} SampleDescriptionBox;

typedef struct {
    int size;
    magic type;
    byte[6] reserved; // six bytes that must be zero
    short dataReferenceIndex; // A 16-bit integer that contains the index of the data reference to use to retrieve data associated with samples that use this sample description. Data references are stored in data reference atoms. 
    ubyte[size - 16] data;
} SampleDescriptionEntry;

typedef struct {
    uint8 version;
    uint8[3] flags;
    int entryCount;
    VisualSampleEntry table[entryCount];
} VisualSampleDescriptionBox;

typedef struct {
    Box box;
    uint8[6] reserved; // six bytes that must be zero
    uint16 dataReferenceIndex; // A 16-bit integer that contains the index of the data reference to use to retrieve data associated with samples that use this sample description. Data references are stored in data reference atoms.
} SampleEntry;

enum {
    _72dpi = 0x00480000
} VisualSampleEntryResolution;

typedef struct {
    SampleEntry entry;
    uint16 predefined;
    uint16 reserved;
    uint32[3] predefined;
    uint16 width;
    uint16 height;
    uint32 enum VisualSampleEntryResolution horizResolution;
    uint32 enum VisualSampleEntryResolution vertResolution;
    uint32 reserved;
    uint16 frameCount;
    pstring32 compressorname;
    uint8 depth;
    int16 predefined3; // should always be -1
    uint8 undocumentedByte[predefined3!=-1];
    SampleDescriptionExtension[] extendedData;
} VisualSampleEntry;

typedef struct {
    uint dataSize;
    magic type;
    ubyte[dataSize - 8] data;
} SampleDescriptionExtension;

typedef struct {
    byte version; // A 1-byte specification of the version of this sample description atom.
    byte[3] flags; // A 3-byte space for sample description flags. Set this field to 0.
    int numberOfEntries; // A 32-bit integer containing the number of sample descriptions that follow.
    soundSampleDescriptionEntry sampleDescriptionTable[numberOfEntries];
} AudioSampleDescriptionBox;

typedef struct {
} AudioSampleDescriptionBoxV1;



typedef struct {
    int size; // A 32-bit integer indicating the number of bytes in the sample description.
    magic type;         // A 32-bit integer indicating the format of the stored data.
        // This depends on the media type, but is usually either the
        // compression format or the media type.
    byte[6] reserved; // six bytes that must be zero
    short dataReferenceIndex; // A 16-bit integer that contains the index of the data reference to use to retrieve data associated with samples that use this sample description. Data references are stored in data reference atoms.
    soundSampleDescription data;
} soundSampleDescriptionEntry;

enum {
    version0 = 0, // compressionId must be 0 for version 0 sound sample description.
    uncompressedAudio = -1,
    compressedAudio = -2,
} soundSampleCompressionId;


typedef struct {
    ushort version;     // A 16-bit integer that holds the sample description
                        // version (currently 0 or 1).
    ushort revisionLevel;// A 16-bit integer that must be set to 0.
    uint vendor;        // A 32-bit integer that must be set to 0.
    ushort numberOfChannels;
                        // A 16-bit integer that indicates the number of sound
                        // channels used by the sound sample. Set to 1 for
                        // monaural sounds, 2 for stereo sounds.
                        // Higher numbers of channels are not supported.
    ushort sampleSize;  // A 16-bit integer that specifies the number of bits in
                        // each uncompressed sound sample. Allowable values are
                        // 8 or 16. Formats using more than 16 bits per sample
                        // set this field to 16 and use sound description
                        // version 1.
    short enum soundSampleCompressionId compressionId;// A 16-bit integer that must be set to 0 for version 0
                        // sound descriptions. This may be set to –2 for some
                        // version 1 sound descriptions; see “Redefined Sample
                        // Tables” (page 115).
    ushort packetSize;  // A 16-bit integer that must be set to 0.
    fixed16d16 sampleRate;// A 32-bit unsigned fixed-point number (16.16) that
                        // indicates the rate at which the sound samples were
                        // obtained. The integer portion of this number should
                        // match the media’s time scale. Many older version 0
                        // files have values of 22254.5454 or 11127.2727, but
                        // most files have integer values, such as 44100. Sample
                        // rates greater than 2^16 are not supported.
  soundSampleDescriptionV1[version] v1; // Additional fields for version 1
  soundSampleDescriptionExtension[] extendedData;
} soundSampleDescription;

typedef struct {
    uint samplesPerPacket;
                        // This field is only present if version == 1.
                        // A 32-bit integer.
                        // The number of uncompressed frames generated by a
                        // compressed frame (an uncompressed frame is one sample
                        // from each channel). This is also the frame duration,
                        // expressed in the media’s timescale, where the
                        // timescale is equal to the sample rate. For
                        // uncompressed formats, this field is always 1.
    uint bytesPerPacket;
                        // This field is only present if version == 1.
                        // A 32-bit integer.
                        // For uncompressed audio, the number of bytes in a
                        // sample for a single channel. This replaces the older
                        // sampleSize field, which is set to 16.
                        // This value is calculated by dividing the frame size
                        // by the number of channels. The same calculation is
                        // performed to calculate the value of this field for
                        // compressed audio, but the result of the calculation
                        // is not generally meaningful for compressed audio.
    uint bytesPerFrame;
                        // This field is only present if version == 1.
                        // A 32-bit integer.
                        // The number of bytes in a frame: for uncompressed
                        // audio, an uncompressed frame; for compressed audio, a
                        // compressed frame. This can be calculated by
                        // multiplying the bytes per packet field by the number
                        // of channels.
    uint bytesPerSample;
                        // This field is only present if version == 1.
                        // A 32-bit integer.
                        // The size of an uncompressed sample in bytes. This is
                        // set to 1 for 8-bit audio, 2 for all other cases, even
                        // if the sample size is greater than 2 bytes.
} soundSampleDescriptionV1;

typedef struct {
    uint dataSize;
    magic type;
    ubyte[dataSize - 8] data;
} soundSampleDescriptionExtension;



magic timeToSampleAtom "stts";
description timeToSampleAtom "Time-to-Sample Atom", "Time-to-sample atoms store duration information for the samples in a media, providing a mapping from a time in a media to the corresponding data sample.";

typedef struct {
    byte version;
    byte[3] flags;
    int numberOfEntries;
    timeToSampleTable timeToSampleTable[numberOfEntries];
} timeToSampleAtom;

typedef struct {
    int sampleCount;
    int sampleDuration;
} timeToSampleTable;

magic syncSampleAtom "stss";
description syncSampleAtom "Sync Sample Atom", "The sync sample atom identifies the key frames in the media. In a media that contains compressed data, key frames define starting points for portions of a temporally compressed sequence. The key frame is self-contained - that is, it is independent of preceding frames. Subsequent frames may depend on the key frame.";

typedef struct {
    byte version;
    byte[3] flags;
    int numberOfEntries;
    syncSampleTable syncSampleTable[numberOfEntries];
} syncSampleAtom;

typedef struct {
    int number;
} syncSampleTable;

magic sampleToChunkAtom "stsc";
description sampleToChunkAtom "Sample-to-Chunk Atom", "As samples are added to a media, they are collected into chunks that allow optimized data access. A chunk may contain one or more samples. Chunks in a media may have different sizes, and the samples within a chunk may have different sizes.";

typedef struct {
    byte version;
    byte[3] flags;
    int numberOfEntries;
    sampleToChunkTable sampleToChunkTable[numberOfEntries];
} sampleToChunkAtom;

typedef struct {
    int firstChunk;
    int samplesPerChunk;
    int sampleDescription;
} sampleToChunkTable;

magic sampleSizeAtom "stsz";
description sampleSizeAtom "Sample Size Atom", "Sample size atoms identify the size of each sample in the media.";

typedef struct {
    byte version;
    byte[3] flags;
    int sampleSize;
    int numberOfEntries;
    sampleSizeTable sampleSizeTable[numberOfEntries];
} sampleSizeAtom;

typedef struct {
    int size;
} sampleSizeTable;

magic chunkOffsetAtom "stco";
description chunkOffsetAtom "Chunk Offset Atom", "Chunk offset atoms identify the location of each chunk of data in the media's data stream, relative to the beginning of the file.";

typedef struct {
    byte version;
    byte[3] flags;
    uint numberOfEntries;
    chunkOffsetTable chunkOffsetTable[numberOfEntries];
} chunkOffsetAtom;

typedef struct {
    uint offset;
} chunkOffsetTable;

magic chunkOffset64Atom "co64";
description chunkOffset64Atom "Chunk Offset 64-bit Atom", "Chunk offset atoms identify the location of each chunk of data in the media's data stream, relative to the beginning of the file.";

typedef struct {
    byte version;
    byte[3] flags;
    uint numberOfEntries;
    chunkOffset64Table chunkOffsetTable[numberOfEntries];
} chunkOffset64Atom;

typedef struct {
    long offset;
} chunkOffset64Table;

magic shadowSyncAtom "stsh";
description shadowSyncAtom "Shadow Sync Atom", "Shadow sync atoms contain self-contained samples that are alternates for existing frame difference samples. Shadow sync atoms are used to optimiye random access operations on a movie. Scrubbing is an example of such a random access operation. These atoms are used to enhance playback performance.";

typedef struct {
    byte version;
    byte[3] flags;
    uint numberOfEntries;
    shadowSyncTable shadowSyncTable[numberOfEntries];
} shadowSyncAtom;

typedef struct {
    int frameDifferenceSampleNumber;
    int syncSampleNumber;
} shadowSyncTable;

typedef struct {
    short x;
    short y;
} windowLocationAtom;


// Atoms from MPEG-4: ISO/IEC 14496-12:2008(E)

magic cttsAtom "ctts";
description cttsAtom "Composition Time to Sample Atom",
"This atom provides the offset between decoding time and composition time. "+
"The offsets are expressed as signed numbers such that CT(n) = DT(n) + CTTS(n) "+
"where CTTS(n) is the (uncompressed) table entry for sample n."+
"The composition time to sample table is optional and must only be present if "+
"DT and CT differ for any samples. Hint tracks do not use this box.";

typedef struct {
    uint sampleCount;
    int sampleOffset; // signed!
} cttsEntry;

typedef struct {
    byte version;
    byte[3] flags;
    uint numberOfEntries;
    cttsEntry entry[numberOfEntries];
} cttsAtom;


magic sdtpAtom "sdtp";
description sdtpAtom "Independent And Disposable Samples Atom",
"This optional table answers three questions about sample dependency: "+
"<ol>"+
"<li>does this sample depend on others (is it an I-picture)?</li>"+
"<li>do no other samples depend on this one?</li>"+
"<li>does this sample contain multiple (redundant) encodings of the data at "+
"this time-instant (possibly with different dependencies)?</li>"+
"</ol>";
/*
"In the absence of this table: "+
"<ol>"+
"<li>the sync sample table answers the first question; in most video codecs, "+
"I-pictures are also sync points,</li>"+
"<li>the dependency of other samples on this one is unknown.</li>"+
"<li>the existence of redundant coding is unknown.</li>"+
"</ol>";
*/
enum {
    unknown = 0,
    isDependent = 1,
    isIndependent = 2,
    reserved = 3,
} sdtpSampleDependsOn;

enum {
    unknown = 0,
    hasDependents = 1,
    noDependents = 2,
    reserved = 3,
} sdtpSampleIsDependedOn;

enum {
    unknown = 0,
    hasRedundancy = 1,
    noRedundancy = 2,
    reserved = 3,
} sdtpSampleHasRedundancy;

typedef struct {
    uint2 reserved;
    uint2 enum sdtpSampleDependsOn sampleDependsOn;
    uint2 enum sdtpSampleIsDependedOn sampleIsDependedOn;
    uint2 enum sdtpSampleHasRedundancy sampleHasRedundancy;
} sdtpSample;

typedef struct {
    byte version;
    byte[3] flags;
    sdtpSample sample[];
} sdtpAtom;



// Atoms from Apple Atom Inspector

magic cslgAtom "cslg";
description cslgAtom "Composition Shift Info Atom",
"";

typedef struct {
    byte version;
    byte[3] flags;
    int shift;
    int leastDelta;
    int greatestDelta;
    uint displayStartTime;
    uint displayEndTime;
} cslgAtom;


magic stpsAtom "stps";
description stpsAtom "Partial Sync Samples Atom",
"";

typedef struct {
    uint sample;
} stpsEntry;

typedef struct {
    byte version;
    byte[3] flags;
    uint numberOfEntries;
    stpsEntry entry[numberOfEntries];
} stpsAtom;
