Пример #1
0
MP4Ac3Atom::MP4Ac3Atom(MP4File &file)
        : MP4Atom(file, "ac-3")
{
    AddReserved(*this, "reserved1", 6); /* 0 */

    AddProperty( /* 1 */
        new MP4Integer16Property(*this,"dataReferenceIndex"));

    AddReserved(*this,"reserved2", 8); /* 2 */

    AddProperty( /* 3 */
        new MP4Integer16Property(*this,"channelCount"));

    AddProperty( /* 4 */
        new MP4Integer16Property(*this,"sampleSize"));

    AddReserved(*this,"reserved3", 4); /* 5 */

    AddProperty( /* 6 */
        new MP4Integer16Property(*this,"samplingRate"));

    AddReserved(*this,"reserved4", 2); /* 7 */

    ExpectChildAtom("dac3", Required, OnlyOne);
}
Пример #2
0
MP4SoundAtom::MP4SoundAtom(const char *atomid) 
	: MP4Atom(atomid) 
{
	AddReserved("reserved1", 6); /* 0 */

	AddProperty( /* 1 */
		new MP4Integer16Property("dataReferenceIndex"));
	AddProperty( /* 2 */
		    new MP4Integer16Property("soundVersion"));
	AddReserved( "reserved2", 6); /* 3 */
	
	AddProperty( /* 4 */
		    new MP4Integer16Property("channels"));
	AddProperty( /* 5 */
		    new MP4Integer16Property("sampleSize"));
	AddProperty( /* 6 */
		    new MP4Integer16Property("packetSize"));
	AddProperty( /* 7 */
		    new MP4Integer32Property("timeScale"));

	if (ATOMID(atomid) == ATOMID("mp4a")) {
	  AddReserved("reserved3", 2); /* 8 */
	  ExpectChildAtom("esds", Required, OnlyOne);
	  ExpectChildAtom("wave", Optional, OnlyOne);
	} else if (ATOMID(atomid) == ATOMID("alac")) {
	  AddReserved("reserved3", 2); /* 8 */
	  ExpectChildAtom("alac", Optional, Optional);
	  //AddProperty( new MP4BytesProperty("alacInfo", 36));
	}
}
Пример #3
0
MP4VideoAtom::MP4VideoAtom (const char *type)
        : MP4Atom(type)
{
    AddReserved("reserved1", 6); /* 0 */

    AddProperty( /* 1 */
        new MP4Integer16Property("dataReferenceIndex"));

    AddReserved("reserved2", 16); /* 2 */

    AddProperty( /* 3 */
        new MP4Integer16Property("width"));
    AddProperty( /* 4 */
        new MP4Integer16Property("height"));

    AddReserved("reserved3", 14); /* 5 */

    MP4StringProperty* pProp =
        new MP4StringProperty("compressorName");
    pProp->SetFixedLength(32);
    pProp->SetCountedFormat(true);
    pProp->SetValue("");
    AddProperty(pProp); /* 6 */

    AddProperty(/* 7 */
        new MP4Integer16Property("depth"));
    AddProperty(/* 8 */
        new MP4Integer16Property("colorTableId"));
    ExpectChildAtom("smi ", Optional, OnlyOne);
}
Пример #4
0
MP4Mp4vAtom::MP4Mp4vAtom(MP4File &file)
        : MP4Atom(file, "mp4v")
{
    AddReserved(*this, "reserved1", 6); /* 0 */

    AddProperty( /* 1 */
        new MP4Integer16Property(*this, "dataReferenceIndex"));

    AddReserved(*this, "reserved2", 16); /* 2 */

    AddProperty( /* 3 */
        new MP4Integer16Property(*this, "width"));
    AddProperty( /* 4 */
        new MP4Integer16Property(*this, "height"));

    AddReserved(*this, "reserved3", 14); /* 5 */

    MP4StringProperty* pProp =
        new MP4StringProperty(*this, "compressorName");
    pProp->SetFixedLength(32);
    pProp->SetCountedFormat(true);
    pProp->SetValue("");
    AddProperty(pProp); /* 6 */

    AddReserved(*this, "reserved4", 4); /* 7 */

    ExpectChildAtom("colr", Optional, OnlyOne);
    ExpectChildAtom("esds", Required, OnlyOne);
    ExpectChildAtom("pasp", Optional, OnlyOne);
}
Пример #5
0
MP4AvspAtom::MP4AvspAtom() 
	: MP4Atom("avsp")
{
	AddReserved("reserved1", 6); /* 0 */

	AddProperty( /* 1 */
		new MP4Integer16Property("dataReferenceIndex"));

	AddReserved("reserved2", 16); /* 2 */

	AddProperty( /* 3 */
		new MP4Integer16Property("width"));
	AddProperty( /* 4 */
		new MP4Integer16Property("height"));

	AddReserved("reserved3", 14); /* 5 */

	MP4StringProperty* pProp = 
		new MP4StringProperty("compressorName");
	pProp->SetFixedLength(32);
	pProp->SetValue("AVS-M Parameters");
	AddProperty(pProp); /* 6 */

	AddReserved("reserved4", 4); /* 7 */

	ExpectChildAtom("avsc", Required, OnlyOne);
	ExpectChildAtom("btrt", Optional, OnlyOne);
	// for now ExpectChildAtom("m4ds", Optional, OnlyOne);
}
Пример #6
0
void MP4TextAtom::AddPropertiesStsdType()
{

    AddReserved("reserved1", 6); /* 0 */

    AddProperty(new MP4Integer16Property("dataReferenceIndex"));/* 1 */

    AddProperty(new MP4Integer32Property("displayFlags")); /* 2 */
    AddProperty(new MP4Integer32Property("textJustification")); /* 3 */

    AddProperty(new MP4Integer16Property("bgColorRed")); /* 4 */
    AddProperty(new MP4Integer16Property("bgColorGreen")); /* 5 */
    AddProperty(new MP4Integer16Property("bgColorBlue")); /* 6 */

    AddProperty(new MP4Integer16Property("defTextBoxTop")); /* 7 */
    AddProperty(new MP4Integer16Property("defTextBoxLeft")); /* 8 */
    AddProperty(new MP4Integer16Property("defTextBoxBottom")); /* 9 */
    AddProperty(new MP4Integer16Property("defTextBoxRight")); /* 10 */

    AddReserved("reserved2", 8); /* 11 */

    AddProperty(new MP4Integer16Property("fontNumber")); /* 12 */
    AddProperty(new MP4Integer16Property("fontFace")); /* 13 */

    AddReserved("reserved3", 1); /* 14 */
    AddReserved("reserved4", 2); /* 15 */

    AddProperty(new MP4Integer16Property("foreColorRed")); /* 16 */
    AddProperty(new MP4Integer16Property("foreColorGreen")); /* 17 */
    AddProperty(new MP4Integer16Property("foreColorBlue")); /* 18 */

}
Пример #7
0
MP4EncvAtom::MP4EncvAtom() 
	: MP4Atom("encv")
{
	AddReserved("reserved1", 6); /* 0 */

	AddProperty( /* 1 */
		new MP4Integer16Property("dataReferenceIndex"));

	AddReserved("reserved2", 16); /* 2 */

	AddProperty( /* 3 */
		new MP4Integer16Property("width"));
	AddProperty( /* 4 */
		new MP4Integer16Property("height"));

	AddReserved("reserved3", 14); /* 5 */

	MP4StringProperty* pProp = 
		new MP4StringProperty("compressorName");
	pProp->SetFixedLength(32);
	pProp->SetValue("");
	AddProperty(pProp); /* 6 */
	AddReserved("reserved4", 4); /* 7 */

	ExpectChildAtom("esds", Required, OnlyOne);
	ExpectChildAtom("sinf", Required, OnlyOne);
	ExpectChildAtom("avcC", Optional, OnlyOne);
}	
Пример #8
0
MP4HdlrAtom::MP4HdlrAtom() 
    : MP4Atom("hdlr")
{
    AddVersionAndFlags(); /* 0, 1 */
    AddReserved("reserved1", 4); /* 2 */
    MP4StringProperty* pProp = new MP4StringProperty("handlerType");
    pProp->SetFixedLength(4);
    AddProperty(pProp); /* 3 */
    AddReserved("reserved2", 12); /* 4 */
    AddProperty( /* 5 */
        new MP4StringProperty("name"));
}
Пример #9
0
void MP4TkhdAtom::AddProperties(uint8_t version)
{
    if (version == 1) {
        AddProperty( /* 2 */
            new MP4Integer64Property("creationTime"));
        AddProperty( /* 3 */
            new MP4Integer64Property("modificationTime"));
    } else { // version == 0
        AddProperty( /* 2 */
            new MP4Integer32Property("creationTime"));
        AddProperty( /* 3 */
            new MP4Integer32Property("modificationTime"));
    }

    AddProperty( /* 4 */
        new MP4Integer32Property("trackId"));
    AddReserved("reserved1", 4); /* 5 */

    if (version == 1) {
        AddProperty( /* 6 */
            new MP4Integer64Property("duration"));
    } else {
        AddProperty( /* 6 */
            new MP4Integer32Property("duration"));
    }

    AddReserved("reserved2", 8); /* 7 */

    AddProperty( /* 8 */
        new MP4Integer16Property("layer"));
    AddProperty( /* 9 */
        new MP4Integer16Property("alternate_group"));

    MP4Float32Property* pProp;

    pProp = new MP4Float32Property("volume");
    pProp->SetFixed16Format();
    AddProperty(pProp); /* 10 */

    AddReserved("reserved3", 2); /* 11 */

    AddProperty(new MP4BytesProperty("matrix", 36)); /* 12 */

    pProp = new MP4Float32Property("width");
    pProp->SetFixed32Format();
    AddProperty(pProp); /* 13 */

    pProp = new MP4Float32Property("height");
    pProp->SetFixed32Format();
    AddProperty(pProp); /* 14 */
}
Пример #10
0
void MP4MdhdAtom::AddProperties(u_int8_t version) 
{
	if (version == 1) {
		AddProperty(
			new MP4Integer64Property("creationTime"));
		AddProperty(
			new MP4Integer64Property("modificationTime"));
	} else {
		AddProperty(
			new MP4Integer32Property("creationTime"));
		AddProperty(
			new MP4Integer32Property("modificationTime"));
	}

	AddProperty(
		new MP4Integer32Property("timeScale"));

	if (version == 1) {
		AddProperty(
			new MP4Integer64Property("duration"));
	} else {
		AddProperty(
			new MP4Integer32Property("duration"));
	}

	AddProperty(
		new MP4Integer16Property("language"));
	AddReserved("reserved", 2);
}
Пример #11
0
// MP4ChplAtom is for Nero chapter list atom which is a child of udta
MP4ChplAtom::MP4ChplAtom ()
        : MP4Atom("chpl")
{
    // it is not completely clear if version, flags, reserved and chaptercount
    // have the right sizes but
    // one thing is clear: chaptercount is not only 8-bit it is at least 16-bit

    // add the version
    AddVersionAndFlags();

    // add reserved bytes
    AddReserved("reserved", 1);

    // define the chaptercount
    MP4Integer32Property * counter = new MP4Integer32Property("chaptercount");
    AddProperty(counter);

    // define the chapterlist
    MP4TableProperty * list = new MP4TableProperty("chapters", counter);

    // the start time as 100 nanoseconds units
    list->AddProperty(new MP4Integer64Property("starttime"));

    // the chapter name as UTF-8
    list->AddProperty(new MP4StringProperty("title", true));

    // add the chapterslist
    AddProperty(list);
}
Пример #12
0
MP4AmrAtom::MP4AmrAtom(const char *type) 
    : MP4Atom(type) 
{
    AddReserved("reserved1", 6); /* 0 */

    AddProperty( /* 1 */
        new MP4Integer16Property("dataReferenceIndex"));

    AddReserved("reserved2", 16); /* 2 */

    AddProperty( /* 3 */
        new MP4Integer16Property("timeScale"));

    AddReserved("reserved3", 2); /* 4 */

    ExpectChildAtom("damr", Required, OnlyOne);
}
Пример #13
0
MP4HrefAtom::MP4HrefAtom() 
	: MP4Atom("href") 
{
	AddReserved("reserved1", 6); /* 0 */

	AddProperty( /* 1 */
		new MP4Integer16Property("dataReferenceIndex"));
}
Пример #14
0
MP4Mp4aAtom::MP4Mp4aAtom() 
	: MP4Atom("mp4a") 
{
	AddReserved("reserved1", 6); /* 0 */

	AddProperty( /* 1 */
		new MP4Integer16Property("dataReferenceIndex"));

	AddReserved("reserved2", 16); /* 2 */

	AddProperty( /* 3 */
		new MP4Integer16Property("timeScale"));

	AddReserved("reserved3", 2); /* 4 */

	ExpectChildAtom("esds", Required, OnlyOne);
}
Пример #15
0
MP4DataAtom::MP4DataAtom()
    : MP4Atom("data")
{
	AddVersionAndFlags(); /* 0, 1 */
    AddReserved("reserved2", 4); /* 2 */

    AddProperty(
        new MP4BytesProperty("metadata")); /* 3 */
}
Пример #16
0
MP4Mp4sAtom::MP4Mp4sAtom() 
    : MP4Atom("mp4s") 
{
    AddReserved("reserved1", 6);
    AddProperty(
        new MP4Integer16Property("dataReferenceIndex"));

    ExpectChildAtom("esds", Required, OnlyOne);
}
Пример #17
0
MP4HrefAtom::MP4HrefAtom()
        : MP4Atom("href")
{
    AddReserved("reserved1", 6); /* 0 */

    AddProperty( /* 1 */
        new MP4Integer16Property("dataReferenceIndex"));
    ExpectChildAtom("burl", Optional, OnlyOne);
}
Пример #18
0
void MP4TkhdAtom::AddProperties(u_int8_t version) 
{
    if (version == 1) {
        AddProperty( /* 2 */
            new MP4Integer64Property("creationTime"));
        AddProperty( /* 3 */
            new MP4Integer64Property("modificationTime"));
    } else { // version == 0
        AddProperty( /* 2 */
            new MP4Integer32Property("creationTime"));
        AddProperty( /* 3 */
            new MP4Integer32Property("modificationTime"));
    }

    AddProperty( /* 4 */
        new MP4Integer32Property("trackId"));
    AddReserved("reserved1", 4); /* 5 */

    if (version == 1) {
        AddProperty( /* 6 */
            new MP4Integer64Property("duration"));
    } else {
        AddProperty( /* 6 */
            new MP4Integer32Property("duration"));
    }

    AddReserved("reserved2", 12); /* 7 */

    MP4Float32Property* pProp;

    pProp = new MP4Float32Property("volume");
    pProp->SetFixed16Format();
    AddProperty(pProp); /* 8 */

    AddReserved("reserved3", 38); /* 9 */

    pProp = new MP4Float32Property("width");
    pProp->SetFixed32Format();
    AddProperty(pProp); /* 10 */

    pProp = new MP4Float32Property("height");
    pProp->SetFixed32Format();
    AddProperty(pProp); /* 11 */
}
Пример #19
0
MP4GminAtom::MP4GminAtom()
    : MP4Atom("gmin")
{

    AddVersionAndFlags(); /* 0, 1 */

    AddProperty(new MP4Integer16Property("graphicsMode")); /* 2 */
    AddProperty(new MP4Integer16Property("opColorRed")); /* 3 */
    AddProperty(new MP4Integer16Property("opColorGreen")); /* 4 */
    AddProperty(new MP4Integer16Property("opColorBlue")); /* 5 */
    AddProperty(new MP4Integer16Property("balance")); /* 6 */
    AddReserved("reserved", 2); /* 7 */

}
Пример #20
0
void MP4Meta2Atom::Read ()
{
  MP4Atom *parent = GetParentAtom();
  if (ATOMID(parent->GetType()) == ATOMID("udta")) {
    // add data property
    AddReserved("reserved2", 4); /* 0 */

    AddProperty(
        new MP4BytesProperty("metadata")); /* 1 */
    ((MP4BytesProperty*)m_pProperties[1])->SetValueSize(m_size - 4);
  } else {
    ExpectChildAtom("data", Required, OnlyOne);
  }
  MP4Atom::Read();
}
Пример #21
0
MP4Stz2Atom::MP4Stz2Atom() 
	: MP4Atom("stz2") 
{
	AddVersionAndFlags(); /* 0, 1 */

	AddReserved("reserved", 3); /* 2 */

	AddProperty( /* 3 */
		new MP4Integer8Property("fieldSize")); 

	MP4Integer32Property* pCount = 
		new MP4Integer32Property("sampleCount"); 
	AddProperty(pCount); /* 4 */

}
Пример #22
0
void MP4SoundAtom::AddProperties (uint8_t version)
{
  if (version > 0) {
    AddProperty( /* 8 */
		new MP4Integer32Property("samplesPerPacket"));
    AddProperty( /* 9 */
		new MP4Integer32Property("bytesPerPacket"));
    AddProperty( /* 10 */
		new MP4Integer32Property("bytesPerFrame"));
    AddProperty( /* 11 */
		new MP4Integer32Property("bytesPerSample"));
  }
  if (version == 2) {
    AddReserved("reserved4", 20);
  }
}
Пример #23
0
void MP4RtpAtom::AddPropertiesStsdType()
{
    AddReserved("reserved1", 6); /* 0 */

    AddProperty( /* 1 */
        new MP4Integer16Property("dataReferenceIndex"));

    AddProperty( /* 2 */
        new MP4Integer16Property("hintTrackVersion"));
    AddProperty( /* 3 */
        new MP4Integer16Property("highestCompatibleVersion"));
    AddProperty( /* 4 */
        new MP4Integer32Property("maxPacketSize"));

    ExpectChildAtom("tims", Required, OnlyOne);
    ExpectChildAtom("tsro", Optional, OnlyOne);
    ExpectChildAtom("snro", Optional, OnlyOne);
}
Пример #24
0
void MP4MvhdAtom::AddProperties(u_int8_t version) 
{
    if (version == 1) {
        AddProperty( /* 2 */
            new MP4Integer64Property("creationTime"));
        AddProperty( /* 3 */
            new MP4Integer64Property("modificationTime"));
    } else {
        AddProperty( /* 2 */
            new MP4Integer32Property("creationTime"));
        AddProperty( /* 3 */
            new MP4Integer32Property("modificationTime"));
    }

    AddProperty( /* 4 */
        new MP4Integer32Property("timeScale"));

    if (version == 1) {
        AddProperty( /* 5 */
            new MP4Integer64Property("duration"));
    } else {
        AddProperty( /* 5 */
            new MP4Integer32Property("duration"));
    }

    MP4Float32Property* pProp;

    pProp = new MP4Float32Property("rate");
    pProp->SetFixed32Format();
    AddProperty(pProp); /* 6 */

    pProp = new MP4Float32Property("volume");
    pProp->SetFixed16Format();
    AddProperty(pProp); /* 7 */

    AddReserved("reserved1", 70); /* 8 */

    AddProperty( /* 9 */
        new MP4Integer32Property("nextTrackId"));
}
Пример #25
0
MP4VmhdAtom::MP4VmhdAtom() 
	: MP4Atom("vmhd") 
{
	AddVersionAndFlags();
	AddReserved("reserved", 8);
}
Пример #26
0
MP4StandardAtom::MP4StandardAtom (const char *type) : MP4Atom(type)
{
    /*
     * This is a big if else loop.  Make sure that you don't break it
     * when adding new atoms, or you will set the unknown type flag
     *
     * Try to keep it in alphabetical order - it should only be called
     * 1 time per atom, so it's not that urgent.
     */
    /*
     * b???
     */
    if (ATOMID(type) == ATOMID("bitr")) {
        AddProperty( /* 0 */
            new MP4Integer32Property("avgBitrate"));

        AddProperty( /* 1 */
            new MP4Integer32Property("maxBitrate"));

    } else if (ATOMID(type) == ATOMID("btrt")) {
        AddProperty( new MP4Integer32Property("bufferSizeDB")); /* 0 */
        AddProperty( new MP4Integer32Property("avgBitrate"));   /* 1 */
        AddProperty( new MP4Integer32Property("maxBitrate"));   /* 2 */
        /*
         * c???
         */
    } else if (ATOMID(type) == ATOMID("co64")) {
        AddVersionAndFlags();

        MP4Integer32Property* pCount =
            new MP4Integer32Property("entryCount");
        AddProperty(pCount);

        MP4TableProperty* pTable = new MP4TableProperty("entries", pCount);
        AddProperty(pTable);

        pTable->AddProperty(
            new MP4Integer64Property("chunkOffset"));

    } else if (ATOMID(type) == ATOMID("cpil")) {
        ExpectChildAtom("data", Required, OnlyOne);
    } else if (ATOMID(type) == ATOMID("covr")) { /* Apple iTunes */
        ExpectChildAtom("data", Required, Many);
    } else if (ATOMID(type) == ATOMID("cprt")) {
        AddVersionAndFlags();
        AddProperty(
            new MP4Integer16Property("language"));
        AddProperty(
            new MP4StringProperty("notice"));

    } else if (ATOMID(type) == ATOMID("ctts")) {
        AddVersionAndFlags();

        MP4Integer32Property* pCount =
            new MP4Integer32Property("entryCount");
        AddProperty(pCount);

        MP4TableProperty* pTable = new MP4TableProperty("entries", pCount);
        AddProperty(pTable);

        pTable->AddProperty(new MP4Integer32Property("sampleCount"));
        pTable->AddProperty(new MP4Integer32Property("sampleOffset"));
        /*
         * d???
         */
    } else if (ATOMID(type) == ATOMID("dinf")) {
        ExpectChildAtom("dref", Required, OnlyOne);

    } else if (ATOMID(type) == ATOMID("dimm")) {
        AddProperty( // bytes of immediate data
            new MP4Integer64Property("bytes"));

    } else if (ATOMID(type) == ATOMID("disk")) { /* Apple iTunes */
        ExpectChildAtom("data", Required, OnlyOne);

    } else if (ATOMID(type) == ATOMID("dmax")) {
        AddProperty( // max packet duration
            new MP4Integer32Property("milliSecs"));

    } else if (ATOMID(type) == ATOMID("dmed")) {
        AddProperty( // bytes sent from media data
            new MP4Integer64Property("bytes"));

    } else if (ATOMID(type) == ATOMID("drep")) {
        AddProperty( // bytes of repeated data
            new MP4Integer64Property("bytes"));
        /*
         * e???
         */
    } else if (ATOMID(type) == ATOMID("edts")) {
        ExpectChildAtom("elst", Required, OnlyOne);

    } else if (ATOMID(type) == ATOMID("esds")) {
        AddVersionAndFlags();
        AddProperty(
            new MP4DescriptorProperty(NULL, MP4ESDescrTag, 0,
                                      Required, OnlyOne));
        /*
         * f???
         */
    } else if (ATOMID(type) == ATOMID("frma")) {
        AddProperty( /* 0 */
            new MP4Integer32Property("data-format"));
        /*
         * g???
         */
    } else if (ATOMID(type) == ATOMID("gnre")) { // Apple iTunes
        ExpectChildAtom("data", Optional, OnlyOne);

        /*
         * h???
         */
    } else if (ATOMID(type) == ATOMID("hmhd")) {
        AddVersionAndFlags();

        AddProperty(new MP4Integer16Property("maxPduSize"));
        AddProperty(new MP4Integer16Property("avgPduSize"));
        AddProperty(new MP4Integer32Property("maxBitRate"));
        AddProperty(new MP4Integer32Property("avgBitRate"));
        AddProperty(new MP4Integer32Property("slidingAvgBitRate"));
        /*
         * i???
         */
    } else if (ATOMID(type) == ATOMID("iKMS")) {
        AddVersionAndFlags(); /* 0, 1 */
        MP4StringProperty* pProp = new MP4StringProperty("kms_URI");
        AddProperty(pProp); /* 2 */

    } else if (ATOMID(type) == ATOMID("iSFM")) {
        AddVersionAndFlags(); /* 0, 1 */
        AddProperty( /* 2 */
            new MP4BitfieldProperty("selective-encryption", 1));
        AddProperty( /* 3 */
            new MP4BitfieldProperty("reserved", 7));
        AddProperty( /* 4 */
            new MP4Integer8Property("key-indicator-length"));
        AddProperty( /* 5 */
            new MP4Integer8Property("IV-length"));

    } else if (ATOMID(type) == ATOMID("ilst")) {
        ExpectChildAtom("\251nam", Optional, OnlyOne); /* name */
        ExpectChildAtom("\251ART", Optional, OnlyOne); /* artist */
        ExpectChildAtom("\251wrt", Optional, OnlyOne); /* writer */
        ExpectChildAtom("\251alb", Optional, OnlyOne); /* album */
        ExpectChildAtom("\251day", Optional, OnlyOne); /* date */
        ExpectChildAtom("\251too", Optional, OnlyOne); /* tool */
        ExpectChildAtom("\251cmt", Optional, OnlyOne); /* comment */
        ExpectChildAtom("\251gen", Optional, OnlyOne); /* custom genre */
        ExpectChildAtom("trkn", Optional, OnlyOne); /* tracknumber */
        ExpectChildAtom("disk", Optional, OnlyOne); /* disknumber */
        ExpectChildAtom("gnre", Optional, OnlyOne); /* genre (ID3v1 index + 1) */
        ExpectChildAtom("cpil", Optional, OnlyOne); /* compilation */
        ExpectChildAtom("tmpo", Optional, OnlyOne); /* BPM */
        ExpectChildAtom("covr", Optional, OnlyOne); /* cover art */
        ExpectChildAtom("----", Optional, Many); /* ---- free form */

    }  else if (ATOMID(type) == ATOMID("imif")) {
        AddVersionAndFlags();
        AddProperty(new MP4DescriptorProperty("ipmp_desc", MP4IPMPDescrTag,
                                              MP4IPMPDescrTag, Required, Many));
    } else if (ATOMID(type) == ATOMID("iods")) {
        AddVersionAndFlags();
        AddProperty(
            new MP4DescriptorProperty(NULL, MP4FileIODescrTag,
                                      MP4FileODescrTag,
                                      Required, OnlyOne));
        /*
         * m???
         */
    } else if (ATOMID(type) == ATOMID("maxr")) {
        AddProperty(new MP4Integer32Property("granularity"));
        AddProperty(new MP4Integer32Property("bytes"));

    } else if (ATOMID(type) == ATOMID("mdia")) {
        ExpectChildAtom("mdhd", Required, OnlyOne);
        ExpectChildAtom("hdlr", Required, OnlyOne);
        ExpectChildAtom("minf", Required, OnlyOne);

    } else if (ATOMID(type) == ATOMID("meta")) { // iTunes
        AddVersionAndFlags(); /* 0, 1 */
        ExpectChildAtom("hdlr", Required, OnlyOne);
        ExpectChildAtom("ilst", Required, OnlyOne);

    } else if (ATOMID(type) == ATOMID("mfhd")) {
        AddVersionAndFlags();    /* 0, 1 */
        AddProperty( /* 2 */
            new MP4Integer32Property("sequenceNumber"));

    } else if (ATOMID(type) == ATOMID("minf")) {
        ExpectChildAtom("vmhd", Optional, OnlyOne);
        ExpectChildAtom("smhd", Optional, OnlyOne);
        ExpectChildAtom("hmhd", Optional, OnlyOne);
        ExpectChildAtom("nmhd", Optional, OnlyOne);
        ExpectChildAtom("dinf", Required, OnlyOne);
        ExpectChildAtom("stbl", Required, OnlyOne);

    } else if (ATOMID(type) == ATOMID("moof")) {
        ExpectChildAtom("mfhd", Required, OnlyOne);
        ExpectChildAtom("traf", Optional, Many);

    } else if (ATOMID(type) == ATOMID("moov")) {
        ExpectChildAtom("mvhd", Required, OnlyOne);
        ExpectChildAtom("iods", Optional, OnlyOne);
        ExpectChildAtom("trak", Required, Many);
        ExpectChildAtom("udta", Optional, Many);
        ExpectChildAtom("mvex", Optional, OnlyOne);

    } else if (ATOMID(type) == ATOMID("mvex")) {
        ExpectChildAtom("trex", Required, Many);

        /*
         * n???
         */
    } else if (ATOMID(type) == ATOMID("nmhd")) {
        AddVersionAndFlags();

    } else if (ATOMID(type) == ATOMID("nump")) {
        AddProperty( // packets sent
            new MP4Integer64Property("packets"));
        /*
          * o???
          */
    } else if (ATOMID(type) == ATOMID("odkm")) {
        AddVersionAndFlags();
        ExpectChildAtom("ohdr", Required, OnlyOne);
        /*
         * p???
         */
    } else if (ATOMID(type) == ATOMID("payt")) {
        AddProperty(new MP4Integer32Property("payloadNumber"));
        AddProperty(new MP4StringProperty("rtpMap", Counted));

    } else if (ATOMID(type) == ATOMID("pmax")) {
        AddProperty( // max packet size
            new MP4Integer32Property("bytes"));
        /*
         * s???
         */
    } else if (ATOMID(type) == ATOMID("schi")) {
        // not sure if this is child atoms or table of boxes
        // get clarification on spec 9.1.2.5
        ExpectChildAtom("odkm", Optional, OnlyOne);
        ExpectChildAtom("iKMS", Optional, OnlyOne);
        ExpectChildAtom("iSFM", Optional, OnlyOne);

    } else if (ATOMID(type) == ATOMID("schm")) {
        AddVersionAndFlags(); /* 0, 1 */
        AddProperty( /* 2 */
            new MP4Integer32Property("scheme_type"));
        AddProperty( /* 3 */
            new MP4Integer32Property("scheme_version"));
        // browser URI if flags set, TODO

    } else if (ATOMID(type) == ATOMID("sinf")) {
        ExpectChildAtom("frma", Required, OnlyOne);
        ExpectChildAtom("imif", Optional, OnlyOne);
        ExpectChildAtom("schm", Optional, OnlyOne);
        ExpectChildAtom("schi", Optional, OnlyOne);

    } else if (ATOMID(type) == ATOMID("smhd")) {
        AddVersionAndFlags();
        AddReserved("reserved", 4);

    } else if (ATOMID(type) == ATOMID("snro")) {
        AddProperty(new MP4Integer32Property("offset"));

    } else if (ATOMID(type) == ATOMID("stco")) {
        AddVersionAndFlags();

        MP4Integer32Property* pCount = new MP4Integer32Property("entryCount");
        AddProperty(pCount);

        MP4TableProperty* pTable = new MP4TableProperty("entries", pCount);
        AddProperty(pTable);

        pTable->AddProperty(new MP4Integer32Property("chunkOffset"));

    } else if (ATOMID(type) == ATOMID("stsh")) {
        AddVersionAndFlags();

        MP4Integer32Property* pCount = new MP4Integer32Property("entryCount");
        AddProperty(pCount);

        MP4TableProperty* pTable = new MP4TableProperty("entries", pCount);
        AddProperty(pTable);

        pTable->AddProperty(new MP4Integer32Property("shadowedSampleNumber"));
        pTable->AddProperty(new MP4Integer32Property("syncSampleNumber"));

    } else if (ATOMID(type) == ATOMID("stss")) {
        AddVersionAndFlags();

        MP4Integer32Property* pCount = new MP4Integer32Property("entryCount");
        AddProperty(pCount);

        MP4TableProperty* pTable = new MP4TableProperty("entries", pCount);
        AddProperty(pTable);

        pTable->AddProperty(new MP4Integer32Property("sampleNumber"));

    } else if (ATOMID(type) == ATOMID("stts")) {
        AddVersionAndFlags();
        MP4Integer32Property* pCount = new MP4Integer32Property("entryCount");
        AddProperty(pCount);

        MP4TableProperty* pTable = new MP4TableProperty("entries", pCount);
        AddProperty(pTable);

        pTable->AddProperty(new MP4Integer32Property("sampleCount"));
        pTable->AddProperty(new MP4Integer32Property("sampleDelta"));

        /*
         * t???
         */
    } else if (ATOMID(type) == ATOMID("tims")) {
        AddProperty(
            new MP4Integer32Property("timeScale"));

    } else if (ATOMID(type) == ATOMID("tmin")) {
        AddProperty( // min relative xmit time
            new MP4Integer32Property("milliSecs"));

    } else if (ATOMID(type) == ATOMID("tmax")) {
        AddProperty( // max relative xmit time
            new MP4Integer32Property("milliSecs"));

    } else if (ATOMID(type) == ATOMID("tmpo")) { // iTunes
        ExpectChildAtom("data", Required, OnlyOne);

    } else if (ATOMID(type) == ATOMID("traf")) {
        ExpectChildAtom("tfhd", Required, OnlyOne);
        ExpectChildAtom("trun", Optional, Many);

    } else if (ATOMID(type) == ATOMID("trak")) {
        ExpectChildAtom("tkhd", Required, OnlyOne);
        ExpectChildAtom("tref", Optional, OnlyOne);
        ExpectChildAtom("edts", Optional, OnlyOne);
        ExpectChildAtom("mdia", Required, OnlyOne);
        ExpectChildAtom("udta", Optional, Many);

    } else if (ATOMID(type) == ATOMID("tref")) {
        ExpectChildAtom("dpnd", Optional, OnlyOne);
        ExpectChildAtom("hint", Optional, OnlyOne);
        ExpectChildAtom("ipir", Optional, OnlyOne);
        ExpectChildAtom("mpod", Optional, OnlyOne);
        ExpectChildAtom("sync", Optional, OnlyOne);

    } else if (ATOMID(type) == ATOMID("trex")) {
        AddVersionAndFlags();    /* 0, 1 */
        AddProperty( /* 2 */
            new MP4Integer32Property("trackId"));
        AddProperty( /* 3 */
            new MP4Integer32Property("defaultSampleDesriptionIndex"));
        AddProperty( /* 4 */
            new MP4Integer32Property("defaultSampleDuration"));
        AddProperty( /* 5 */
            new MP4Integer32Property("defaultSampleSize"));
        AddProperty( /* 6 */
            new MP4Integer32Property("defaultSampleFlags"));

    } else if (ATOMID(type) == ATOMID("trkn")) { // iTunes
        ExpectChildAtom("data", Required, OnlyOne);

    } else if (ATOMID(type) == ATOMID("trpy") ||
               ATOMID(type) == ATOMID("tpyl")) {
        AddProperty( // bytes sent including RTP headers
            new MP4Integer64Property("bytes"));

    } else if (ATOMID(type) == ATOMID("tsro")) {
        AddProperty(
            new MP4Integer32Property("offset"));
    } else if (ATOMID(type) == ATOMID("wave")) {
        ExpectChildAtom("esds", Required, OnlyOne);
        /*
         * copyright???
         */
    } else if (ATOMID(type) == ATOMID(art) ||
               ATOMID(type) == ATOMID(wrt) ||
               ATOMID(type) == ATOMID(alb) ||
               ATOMID(type) == ATOMID(day) ||
               ATOMID(type) == ATOMID(too) ||
               ATOMID(type) == ATOMID(gen) ||
               ATOMID(type) == ATOMID(grp)) { /* Apple iTunes */
        ExpectChildAtom("data", Required, OnlyOne);
        /*
         * ----
         */
    } else if (ATOMID(type) == ATOMID("----")) { /* Apple iTunes */
        ExpectChildAtom("mean", Required, OnlyOne);
        ExpectChildAtom("name", Required, OnlyOne);
        ExpectChildAtom("data", Required, OnlyOne);
    } else {
        /*
         * default - unknown type
         */
        SetUnknownType(true);
    }

}