User Tools

Site Tools


tech:multimedia:iso_mp4_parser

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

tech:multimedia:iso_mp4_parser [2011/12/29 07:18]
admin
tech:multimedia:iso_mp4_parser [2014/11/10 08:22]
Line 1: Line 1:
-/*** +
- *  +
- * iso.cxx, an iso media file parser by C.L Lee (Gmail: cl.li1980) +
- *  +
- * Last modified on Aug.24, 2010 +
- * +
- * This is a piece of free code that you can freely use, copy, modify and distribute in both open and proprietary applications +
- * +
-*/ +
-  +
-  +
-#include <​iostream>​ +
-#include <​fstream>​ +
-using namespace std; +
-  +
-/*  +
- Basic ISO 14496-12 Box Class +
-*/ +
-class CBox +
-+
-protected:​ +
-    unsigned int size; +
-    unsigned long long largesize;​ +
-    unsigned int boxtype; +
-    unsigned char usertype[16];​ +
-    bool extended; +
-    unsigned long long start; +
-    unsigned long long end; +
-  +
-    char *comments;​ +
-    bool parsed; ​    +
-    int nested; +
-  +
-public: +
-    static CBox* Create(unsigned int type, int nest = 0, unsigned char *extended_type = 0); +
-    static void Destroy(CBox *box); +
-    static inline unsigned int MakeInt(unsigned char *buf) {return (buf[0]<<​24)|(buf[1]<<​16)|(buf[2]<<​8)|buf[3];​} +
-    static inline char * FourCC(unsigned int type, char *fourCC)  +
-    { +
-        fourCC[0] = (type>>​24)&​0xff;​ +
-        fourCC[1] = (type>>​16)&​0xff;​ +
-        fourCC[2] = (type>>​8)&​0xff;​ +
-        fourCC[3] = type&​0xff;​ +
-        fourCC[4] = 0; +
-        return fourCC; +
-    } +
-  +
-    virtual bool Parse(ifstream &in) +
-    { +
-        this->​start = in.tellg();​ +
-  +
-        /* read size */ +
-        unsigned char s1[4], s2[4]; +
-        in.read((char *)s1, 4); +
-        if (this->​boxtype == 0) +
-        { +
-            in.read((char *)s2, 4); /* for unknown box */ +
-            this->​boxtype = CBox::​MakeInt(s2);​ +
-        } +
-        else +
-            in.seekg(4, ios_base::​cur);​ /* skip type */ +
-        if (!in.good()) +
-            return false; +
-        this->​size = CBox::​MakeInt(s1);​ +
-        this->​end = this->​start + this->​size;​ +
-  +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        if (!this->​parsed) +
-        { +
-            cerr << "​ERROR:​ list not parsed"​ << endl; +
-            return; +
-        }     +
-  +
-        /* Dump basic box information*/ ​        +
-        char type[5]; +
-        for (int i = 0; i < this->​nested;​ i++) out << "​\t";​ +
-        out << "BOX " << CBox::​FourCC(this->​boxtype,​ type) << " @ " << this->​start << " with size " << this->​size;​ +
-        out << " (" << this->​comments << "​)"​ << endl; +
-  +
-        return; +
-    } +
-  +
-protected:​ +
-    CBox(unsigned int type, int nest = 0, unsigned char *extended_type = 0) +
-    { +
-        size = 0; +
-        largesize = 0; +
-        boxtype = type; +
-        if (extended_type) +
-        { +
-            for (int i = 0; i < 16; i++) usertype[i] = extended_type[i];​ +
-            extended = true; +
-        } +
-        else +
-        { +
-            extended = false; +
-        } +
-  +
-        start = end = 0; +
-  +
-        parsed = false; +
-        nested = nest; +
-        comments = (char *)"​\0";​ +
-    } +
-    virtual ~CBox() +
-    { +
-    } +
-}; +
-  +
-class CFullBox : public CBox +
-+
-protected:​ +
-    unsigned char version; +
-    unsigned int flag; +
-public: +
-    CFullBox(unsigned int type, int nest) : CBox(type, nest), version(0), flag(0) {} +
-    virtual ~CFullBox() {} +
-    virtual bool Parse(ifstream &​in) ​    +
-    { +
-        if (!CBox::​Parse(in)) +
-            return false; +
-        char buf[4]; +
-        in.read(buf,​ 4); +
-        version = buf[0]; +
-        flag = (buf[1] << 16) | (buf[2] << 8) | buf[3]; +
-  +
-        return true; +
-    } +
-}; +
-  +
-/* +
- ​Unknown Box +
- ​Actually there is no "​Unknown Box" defined in 14496-12, this is just for extension +
-*/ +
-class CUnknownBox : public CBox +
-+
-public: +
-    CUnknownBox(int nest = 0):CBox(0, nest) +
-    { +
-        comments = "​Unknown Box, can not be parsed";​ +
-    } +
-    virtual ~CUnknownBox() +
-    {} +
-  +
-    virtual bool Parse(ifstream &in) +
-    { +
-        if (!CBox::​Parse(in)) +
-            return false; +
-        /* skip */ +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-        this->​parsed = true; +
-  +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        CBox::​Dump(out);​ +
-        return; +
-    } +
-}; +
-  +
-/* +
-  Container Box +
-  Actually there is no "​Container Box" defined in 14496-12, this is an abstract class to descript containers +
-*/ +
-  +
-class CContainerBox : public CBox +
-+
-protected:​ +
-    int subboxes; +
-    CBox** list; +
-public: +
-    CContainerBox(unsigned int type, int nest):​CBox(type,​ nest), +
-    subboxes(0),​ list(NULL)  +
-    {  +
-        comments = (char *) "​Container Box";​ +
-    } +
-    virtual ~CContainerBox() +
-    {  +
-        if (this->​subboxes) +
-        { +
-            for (int i = 0; i < this->​subboxes;​ i++) +
-                CBox::​Destroy(this->​list[i]);​ +
-            delete [] this->​list;​ +
-        } +
-    } +
-    virtual bool Parse(ifstream &in) +
-    { +
-        unsigned char buf[4]; +
-        unsigned long long pos; +
-  +
-        if (!CBox::​Parse(in)) +
-            return false; +
-  +
-        /* count subboxes */ +
-        pos = in.tellg();​ +
-        do +
-        { +
-            in.read((char *)buf, 4); +
-            in.seekg(CBox::​MakeInt(buf)-4,​ ios_base::​cur);​ +
-            this->​subboxes++;​ +
-        } while(in.tellg() < this->​end);​ +
-        in.seekg(pos,​ ios_base::​beg);​ /* go back */ +
-        if (this->​subboxes) +
-            this->​list = new CBox*[this->​subboxes];​ +
-  +
-        /* parse subboxes */ +
-        for (int i = 0; i < this->​subboxes;​ i++) +
-        { +
-            pos = in.tellg();​ +
-            in.seekg(4, ios_base::​cur);​ +
-            in.read((char *)buf, 4); /* prefetch type value */; +
-            this->​list[i] = CBox::​Create(CBox::​MakeInt(buf),​ this->​nested+1);​ +
-            in.seekg(pos,​ ios_base::​beg);​ /* go back */  +
-            if (!this->​list[i]->​Parse(in)) +
-            { +
-                CBox::​Destroy(this->​list[i]);​ +
-                cerr << "Error Parsing Container"​ << endl; +
-                return false; +
-            } +
-        } +
-        this->​parsed = true; +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        CBox::​Dump(out);​ +
-        for (int i = 0; i < this->​subboxes;​ i++) +
-            this->​list[i]->​Dump(out);​ +
-        return; +
-    } +
-  +
-}; +
-  +
-/*  +
- File Type Box +
- The box identifies the specifications to which this file complies. +
-*/ +
-class CFileTypeBox : public CBox +
-+
-protected:​ +
-    unsigned int major_brand;​ +
-    unsigned int minor_version;​ +
-    unsigned int *brands_list;​ +
-    int nlist; +
-  +
-public: +
-    CFileTypeBox(int nest = 0):​CBox(CBox::​MakeInt((unsigned char *)"​ftyp"​),​ nest), +
-    major_brand(0),​ minor_version(0),​ brands_list(NULL) +
-    { +
-        comments = "File Type Box";​ +
-    } +
-  +
-    virtual ~CFileTypeBox() +
-    { +
-        if (this->​nlist) delete []this->​brands_list;​ +
-    } +
-  +
-    virtual bool Parse(ifstream &in) +
-    { +
-        if (!CBox::​Parse(in)) +
-            return false; +
-  +
-        unsigned char buf[4]; +
-        in.read((char *)buf, 4); +
-        this->​major_brand = CBox::​MakeInt(buf);​ +
-        in.read((char *)buf, 4); +
-        this->​minor_version = CBox::​MakeInt(buf);​ +
-  +
-        this->​nlist = (this->​end - in.tellg())/​sizeof(unsigned int); +
-        if (this->​nlist) +
-        { +
-            this->​brands_list = new unsigned int[this->​nlist];​ +
-            for (int i = 0; i < this->​nlist;​ i++) +
-            { +
-                in.read((char *)buf, 4); +
-                this->​brands_list[i] = CBox::​MakeInt(buf);​ +
-            } +
-        } +
-  +
-        this->​parsed = true; +
-    } +
-  +
-    virtual void Dump(ostream &out) +
-    { +
-        char s[5]; +
-  +
-        CBox::​Dump(out);​ +
-        for (int i = 0; i < this->​nested;​ i++) out << "​\t";​ +
-        out << "{ "; +
-        out << CBox::​FourCC(this->​major_brand,​ s) << ", "; +
-        out << "​version:​ " << this->​minor_version << ", "; +
-        out << "​(";​ +
-        for (int i = 0; i < this->​nlist;​ i++) +
-            out << CBox::​FourCC(this->​brands_list[i],​ s) << ", "; +
-        out << "​)";​ +
-        out << " }" << endl; +
-        return; +
-    }     +
-}; +
-  +
-/* +
- Media Data Box +
-*/ +
-class CMediaDataBox : public CBox +
-+
-public: +
-    CMediaDataBox(int nest = 0):​CBox(CBox::​MakeInt((unsigned char*)"​mdat"​),​ nest) +
-    { +
-        comments = "Media Data Box";​ +
-    } +
-    virtual ~CMediaDataBox() {} +
-    virtual bool Parse(ifstream &in) +
-    { +
-        if (!CBox::​Parse(in)) +
-            return false; +
-        /* skip */ +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-        this->​parsed = true; +
-  +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        CBox::​Dump(out);​ +
-        return; ​    +
-    }     +
-}; +
-  +
-/* +
- Free Space Box +
-*/ +
-class CFreeSpaceBox : public CBox +
-+
-public: +
-    CFreeSpaceBox(int nest = 0):​CBox(CBox::​MakeInt((unsigned char*)"​free"​),​ nest) +
-    { +
-        comments = "Free Space Box";​ +
-    } +
-    virtual ~CFreeSpaceBox() {} +
-    virtual bool Parse(ifstream &in) +
-    { +
-        if (!CBox::​Parse(in)) +
-            return false; +
-        /* skip */ +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-        this->​parsed = true; +
-  +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        CBox::​Dump(out);​ +
-        return; ​    +
-    }     +
-}; +
-  +
-/* +
- Movie Header Box +
-*/ +
-class CMovieHeaderBox : public CFullBox +
-+
-protected:​ +
-    unsigned int scale; +
-    unsigned long long duration; +
-public: +
-    CMovieHeaderBox(int nest = 0):​CFullBox(CBox::​MakeInt((unsigned char*)"​mvhd"​),​ nest), +
-    scale(0),​duration(0) +
-    { +
-        comments = "Movie Header Box";​ +
-    } +
-    virtual ~CMovieHeaderBox() {} +
-    virtual bool Parse(ifstream &in) +
-    { +
-        unsigned char buf[4]; +
-        if (!CFullBox::​Parse(in)) +
-            return false; +
-        if (this->​version == 1) +
-        { +
-            in.seekg(16,​ ios_base::​cur);​ +
-            in.read((char *)buf, 4); /*< get time scale */ +
-            scale = CBox::​MakeInt(buf);​ +
-            /* get duratioin */ +
-            in.read((char *)buf, 4);  +
-            duration = (unsigned long long)CBox::​MakeInt(buf) << 32; +
-            in.read((char *)buf, 4); +
-            duration |= CBox::​MakeInt(buf);​ +
-        } +
-        else +
-        { +
-            in.seekg(8, ios_base::​cur);​ +
-            in.read((char *)buf, 4); /*< get time scale */ +
-            scale = CBox::​MakeInt(buf);​ +
-            in.read((char *)buf, 4); /*< get duratioin */ +
-            duration = CBox::​MakeInt(buf); ​            +
-        } +
-        /* skip */ +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-  +
-        this->​parsed = true; +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        CBox::​Dump(out);​ +
-        for (int i = 0; i < this->​nested;​ i++) out << "​\t";​ +
-  +
-        unsigned char h, m, s; +
-        unsigned int ms = this->​duration*1000/​this->​scale;​ +
-        h = ms/​3600000;​ +
-        m = (ms%3600000)/​60000;​ +
-        s = (ms%60000)/​1000;​ +
-        ms = ms%1000; +
-        out << "{ "; +
-        out << "Time Scale : " << this->​scale << ", Duration : " << this->​duration;​ +
-        out << "​(";​ +
-        out << (unsigned int)h << ":"​ << (unsigned int)m << ":"​ << (unsigned int)s << ":"​ << ms; +
-        out << "​)";​ +
-        out << " }" << endl; +
-  +
-        return; ​    +
-    }     +
-}; +
-  +
-/* +
- Track Header Box +
- The box specifies the characteristics of a single track +
-*/ +
-class CTrackHeaderBox : public CFullBox +
-+
-protected:​ +
-    unsigned int trackid; +
-    unsigned long long duration; +
-    short layer; +
-    unsigned int width; +
-    unsigned int height; +
-public: +
-    CTrackHeaderBox(int nest = 0):​CFullBox(CBox::​MakeInt((unsigned char*)"​tkhd"​),​ nest), +
-    trackid(0), duration(0),​ layer(0), width(0), height(0) +
-    { +
-        comments = (char *) "Track Header Box";​ +
-    } +
-    virtual ~CTrackHeaderBox() {} +
-    virtual bool Parse(ifstream &in) +
-    { +
-        unsigned char buf[4]; +
-        if (!CFullBox::​Parse(in)) +
-            return false; +
-        if (this->​version == 1) +
-        { +
-            in.seekg(16,​ ios_base::​cur);​ +
-            in.read((char *)buf, 4); /*< get trackid */ +
-            trackid = CBox::​MakeInt(buf);​ +
-            in.read((char *)buf, 4);  +
-            /* get duratioin */ +
-            in.read((char *)buf, 4); +
-            duration = (unsigned long long)CBox::​MakeInt(buf) << 32; +
-            in.read((char *)buf, 4); +
-            duration |= CBox::​MakeInt(buf);​ +
-        } +
-        else +
-        { +
-            in.seekg(8, ios_base::​cur);​ +
-            in.read((char *)buf, 4); /*< get trackid */ +
-            trackid = CBox::​MakeInt(buf);​ +
-            in.read((char *)buf, 4); +
-            in.read((char *)buf, 4); /*< get duratioin */ +
-            duration = CBox::​MakeInt(buf); ​            +
-        } +
-        in.seekg(8, ios_base::​cur);​ +
-        in.read((char *)buf, 2); +
-        layer = (buf[0]<<​8)|buf[1];​ +
-        in.seekg(42,​ ios_base::​cur);​ +
-        in.read((char *)buf, 4); +
-        width = CBox::​MakeInt(buf);​ +
-        in.read((char *)buf, 4); +
-        height = CBox::​MakeInt(buf);​ +
-        /* skip */ +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-  +
-        this->​parsed = true; +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        CFullBox::​Dump(out);​ +
-        for (int i = 0; i < this->​nested;​ i++) out << "​\t";​ +
-  +
-        unsigned short w1 = this->​width >> 16; +
-        unsigned short w2 = this->​width&​0xffff;​ +
-        unsigned short h1 = this->​height >> 16; +
-        unsigned short h2 = this->​height&​0xffff; ​       +
-        out << "{ "; +
-        out << "Track Id : " << this->​trackid << ", Duration : " << this->​duration << ", "; +
-        out << "​Layer:​ " << this->​layer << ", " << w1 << "​."​ << w2 << "​x"​ << h1 << "​."​ <<​h2;​ +
-        out << " }" << endl; +
-  +
-        return; ​    +
-    } +
-  +
-}; +
-  +
-/* +
- Media Header Box +
-*/ +
-class CMediaHeaderBox : public CFullBox +
-+
-protected:​ +
-    unsigned int scale; +
-    unsigned long long duration; +
-public: +
-    CMediaHeaderBox(int nest = 0):​CFullBox(CBox::​MakeInt((unsigned char*)"​mdhd"​),​ nest), +
-    scale(0),​duration(0) +
-    { +
-        comments = "Media Header Box";​ +
-    } +
-    virtual ~CMediaHeaderBox() {} +
-    virtual bool Parse(ifstream &in) +
-    { +
-        unsigned char buf[4]; +
-        if (!CFullBox::​Parse(in)) +
-            return false; +
-        if (this->​version == 1) +
-        { +
-            in.seekg(16,​ ios_base::​cur);​ +
-            in.read((char *)buf, 4); /*< get time scale */ +
-            scale = CBox::​MakeInt(buf);​ +
-            /* get duratioin */ +
-            in.read((char *)buf, 4);  +
-            duration = (unsigned long long)CBox::​MakeInt(buf) << 32; +
-            in.read((char *)buf, 4); +
-            duration |= CBox::​MakeInt(buf);​ +
-        } +
-        else +
-        { +
-            in.seekg(8, ios_base::​cur);​ +
-            in.read((char *)buf, 4); /*< get time scale */ +
-            scale = CBox::​MakeInt(buf);​ +
-            in.read((char *)buf, 4); /*< get duratioin */ +
-            duration = CBox::​MakeInt(buf); ​            +
-        } +
-        /* skip */ +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-  +
-        this->​parsed = true; +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        CFullBox::​Dump(out);​ +
-        for (int i = 0; i < this->​nested;​ i++) out << "​\t";​ +
-  +
-        unsigned char h, m, s; +
-        unsigned int ms = this->​duration*1000/​this->​scale;​ +
-        h = ms/​3600000;​ +
-        m = (ms%3600000)/​60000;​ +
-        s = (ms%60000)/​1000;​ +
-        ms = ms%1000; +
-        out << "{ "; +
-        out << "Time Scale : " << this->​scale << ", Duration : " << this->​duration;​ +
-        out << "​(";​ +
-        out << (unsigned int)h << ":"​ << (unsigned int)m << ":"​ << (unsigned int)s << ":"​ << ms; +
-        out << "​)";​ +
-        out << " }" << endl; +
-  +
-        return; ​    +
-    }  +
-  +
-}; +
-  +
-/* +
- ​Handler Reference Box +
-*/ +
-class CHandlerRefBox : public CFullBox +
-+
-protected:​ +
-    unsigned int handler; +
-    char *string; +
-public: +
-    CHandlerRefBox(int nest = 0):​CFullBox(CBox::​MakeInt((unsigned char*)"​hdlr"​),​ nest), +
-    handler(0), string(NULL) +
-    { +
-        comments = (char *) "​Handler Reference Box";​ +
-    } +
-    virtual ~CHandlerRefBox() +
-    { +
-        if (this->​string) delete[] string; +
-    } +
-    virtual bool Parse(ifstream &in) +
-    { +
-        unsigned char buf[4]; +
-        if (!CFullBox::​Parse(in)) +
-            return false; +
-  +
-        in.read((char *)buf, 4); +
-        in.read((char *)buf, 4); +
-        this->​handler = CBox::​MakeInt(buf);​ +
-        in.seekg(12,​ ios_base::​cur);​ +
-  +
-        /* count chars */ +
-        int len = 0; +
-        int pos = in.tellg();​ +
-        while(in.get()) len++; +
-        in.seekg(pos,​ ios_base::​beg);​ +
-  +
-        /* read string */ +
-        char *p = this->​string = new char[len+1];​ +
-        while(*p++ = in.get());​ +
-  +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-        this->​parsed = true; +
-  +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        CFullBox::​Dump(out);​ +
-        for (int i = 0; i < this->​nested;​ i++) out << "​\t";​ +
-  +
-        char s[5]; +
-        out << "{ "; +
-        out << "​handler : " << CBox::​FourCC(this->​handler,​ s) << ", '"​ << this->​string << "'";​ +
-        out << " }" << endl; +
-    } +
-}; +
-  +
-/* +
- Video Media Header Box  +
- ​Contains general presentation information,​ independant of coding, for video media +
-*/ +
-class CVideoMediaHeaderBox : public CFullBox +
-+
-public: +
-    CVideoMediaHeaderBox(int nest = 0):​CFullBox(CBox::​MakeInt((unsigned char*)"​vmhd"​),​ nest) +
-    { +
-        comments = "Video Media Header Box";​ +
-    } +
-    virtual ~CVideoMediaHeaderBox() +
-    {} +
-  +
-    virtual bool Parse(ifstream &in) +
-    { +
-        if (!CBox::​Parse(in)) +
-            return false; +
-        /* skip */ +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-        this->​parsed = true; +
-  +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        CFullBox::​Dump(out);​ +
-        return; +
-    } +
-}; +
-  +
-/* +
- Sound Media Header Box +
- ​Contains general presentation information,​ independant of coding, for audio media +
-*/ +
-class CSoundMediaHeaderBox : public CFullBox +
-+
-public: +
-    CSoundMediaHeaderBox(int nest = 0):​CFullBox(CBox::​MakeInt((unsigned char*)"​smhd"​),​ nest) +
-    { +
-        comments = "Sound Media Header Box";​ +
-    } +
-    virtual ~CSoundMediaHeaderBox() +
-    {} +
-  +
-    virtual bool Parse(ifstream &in) +
-    { +
-        if (!CFullBox::​Parse(in)) +
-            return false; +
-        /* skip */ +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-        this->​parsed = true; +
-  +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        CFullBox::​Dump(out);​ +
-        return; +
-    } +
-}; +
-  +
-/* +
- Hint Media Header Box +
- The hint media header contains general information,​ independent of the protocol, for hint tracks +
-*/ +
-  +
-class CHintMediaHeaderBox : public CFullBox +
-+
-public: +
-    CHintMediaHeaderBox(int nest = 0):​CFullBox(CBox::​MakeInt((unsigned char*)"​hmhd"​),​ nest) +
-    { +
-        comments = "Hint Media Header Box";​ +
-    } +
-    virtual ~CHintMediaHeaderBox() +
-    {} +
-  +
-    virtual bool Parse(ifstream &in) +
-    { +
-        if (!CFullBox::​Parse(in)) +
-            return false; +
-        /* skip */ +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-        this->​parsed = true; +
-  +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        CFullBox::​Dump(out);​ +
-        return; +
-    } +
-}; +
-  +
-/* +
- Data Reference Box +
-*/ +
-class CDataRefBox : public CFullBox +
-+
-protected:​ +
-    unsigned int entry_count;​ +
-    CBox **entries;​ +
-public: +
-    CDataRefBox(int nest = 0):​CFullBox(CBox::​MakeInt((unsigned char*)"​dref"​),​ nest), +
-    entry_count(0),​ entries(NULL) +
-    { +
-        comments = "Data Reference Box";​ +
-    } +
-    virtual ~CDataRefBox() +
-    { +
-        if (this->​entry_count) +
-        { +
-            for (int i = 0; i < this->​entry_count;​ i++) +
-                CBox::​Destroy(this->​entries[i]);​ +
-            delete [] this->​entries;​ +
-        } +
-    } +
-  +
-    virtual bool Parse(ifstream &in) +
-    { +
-        if (!CFullBox::​Parse(in)) +
-            return false; +
-  +
-        unsigned char buf[4]; +
-        in.read((char *)buf, 4); +
-        this->​entry_count = CBox::​MakeInt(buf);​ +
-        if (this->​entry_count) this->​entries = new CBox* [this->​entry_count];​ +
-        for (int i = 0; i < this->​entry_count;​ i++) +
-        { +
-            unsigned long long pos; +
-            pos = in.tellg();​ +
-            in.read((char *)buf, 4); +
-            in.read((char *)buf, 4); /*< prefetch the type */ +
-            this->​entries[i] = CBox::​Create(CBox::​MakeInt(buf),​ this->​nested+1);​ +
-            in.seekg(pos,​ ios_base::​beg);​ +
-  +
-            if (!this->​entries[i]->​Parse(in)) return false; +
-        } +
-  +
-        /* skip */ +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-        this->​parsed = true; +
-  +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        CFullBox::​Dump(out);​ +
-        for (int i = 0; i < this->​nested;​ i++) out << "​\t";​ +
-  +
-        out << "{ "; +
-        out << this->​entry_count << " Entries";​ +
-        out << " }" << endl; +
-  +
-        for (int i = 0; i < this->​entry_count;​ i++) +
-            this->​entries[i]->​Dump(out);​ +
-  +
-        return; +
-    } +
-}; +
-  +
-/* +
- URL Reference Box +
-*/ +
-class CDataEntryURLBox : public CFullBox +
-+
-public: +
-    CDataEntryURLBox(int nest = 0):​CFullBox(CBox::​MakeInt((unsigned char*)"​url "), nest) +
-    { +
-        comments = "URL Reference Box";​ +
-    } +
-    virtual ~CDataEntryURLBox() +
-    {} +
-  +
-    virtual bool Parse(ifstream &in) +
-    { +
-        if (!CFullBox::​Parse(in)) +
-            return false; +
-        /* skip */ +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-        this->​parsed = true; +
-  +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        CFullBox::​Dump(out);​ +
-        return; +
-    } +
-}; +
-  +
-/* +
- URN Reference Box +
-*/ +
-class CDataEntryURNBox : public CFullBox +
-+
-public: +
-    CDataEntryURNBox(int nest = 0):​CFullBox(CBox::​MakeInt((unsigned char*)"​urn "), nest) +
-    { +
-        comments = "URN Reference Box";​ +
-    } +
-    virtual ~CDataEntryURNBox() +
-    {} +
-  +
-    virtual bool Parse(ifstream &in) +
-    { +
-        if (!CFullBox::​Parse(in)) +
-            return false; +
-        /* skip */ +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-        this->​parsed = true; +
-  +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        CFullBox::​Dump(out);​ +
-        return; +
-    } +
-}; +
-  +
-/* +
-  Movie Fragment Box +
-*/ +
-class CMovieFragmentBox : public CFullBox +
-+
-protected:​ +
-    int seq; +
-public: +
-    CMovieFragmentBox(int nest = 0):​CFullBox(CBox::​MakeInt((unsigned char*)"​mfhd"​),​ nest) +
-    { +
-        comments = "Movie Fragment Box";​ +
-        seq = -1; +
-    } +
-    virtual ~CMovieFragmentBox() +
-    {} +
-    virtual bool Parse(ifstream &in) +
-    { +
-        char buf[4]; +
-  +
-        if (!CFullBox::​Parse(in)) return false; +
-  +
-        in.read(buf,​ 4); +
-        this->​seq = CBox::​MakeInt((unsigned char *)buf); +
-  +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-        this->​parsed = true; +
-  +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        CFullBox::​Dump(out);​ +
-  +
-        for (int i = 0; i < this->​nested;​ i++) out << "​\t";​ +
-  +
-        out << "{ "; +
-        out << "​No."​ << this->​seq;​ +
-        out << " }" << endl; +
-  +
-        return; +
-    }    +
-}; +
-  +
-/* +
-  Track Fragment Header Box +
-*/ +
-class CTrackFragmentHeaderBox : public CFullBox +
-+
-protected:​ +
-    int track_ID; +
-public: +
-    CTrackFragmentHeaderBox(int nest = 0):​CFullBox(CBox::​MakeInt((unsigned char*)"​tfhd"​),​ nest) +
-    { +
-        comments = "Track Fragment Header Box";​ +
-        track_ID = -1; +
-    } +
-    virtual ~CTrackFragmentHeaderBox() +
-    {} +
-    virtual bool Parse(ifstream &in) +
-    { +
-        char buf[4]; +
-  +
-        if (!CFullBox::​Parse(in)) return false; +
-  +
-        in.read(buf,​ 4); +
-        this->​track_ID = CBox::​MakeInt((unsigned char *)buf); +
-  +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-        this->​parsed = true; +
-  +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        CFullBox::​Dump(out);​ +
-  +
-        for (int i = 0; i < this->​nested;​ i++) out << "​\t";​ +
-  +
-        out << "{ "; +
-        out << "Track ID:" << this->​track_ID;​ +
-        out << " }" << endl; +
-  +
-        return; +
-    }    +
-}; +
-  +
-  +
-/* +
- ​Sample Entry Box, abstrac box +
-*/ +
-class CSampleEntryBox : public CBox +
-+
-protected:​ +
-    unsigned short data_ref_id;​ +
-public: +
-    CSampleEntryBox(unsigned int type, int nest) : CBox(type, nest), data_ref_id(0) {} +
-    virtual ~CSampleEntryBox() {} +
-  +
-    virtual bool Parse(ifstream &in) +
-    { +
-        if (!CBox::​Parse(in)) +
-            return false; +
-        in.seekg(6, ios_base::​cur);​ +
-  +
-        unsigned char buf[2]; +
-        in.read((char *)buf, 2); +
-        this->​data_ref_id = (buf[0] << 16) | buf[1]; +
-  +
-        return true; +
-    } +
-  +
-    virtual void Dump(ostream &out) +
-    { +
-        CBox::​Dump(out);​ +
-        return; +
-    } +
-}; +
-  +
-/* +
-  Visual Sample Entry Box +
-*/ +
-class CVisualSampleEntryBox : public CSampleEntryBox +
-+
-protected:​ +
-    unsigned short width; +
-    unsigned short height; +
-    unsigned short frame_count;​ +
-public: +
-    CVisualSampleEntryBox(unsigned int type, int nest) : CSampleEntryBox(type,​ nest), +
-    width(0), height(0), frame_count(0) +
-    { +
-        comments = "​Visual Sample Entry Box";​ +
-    } +
-    virtual ~CVisualSampleEntryBox() {} +
-  +
-    virtual bool Parse(ifstream &in) +
-    { +
-        if (!CSampleEntryBox::​Parse(in)) +
-            return false; +
-  +
-        unsigned char buf[4]; +
-        in.seekg(16,​ ios_base::​cur);​ +
-        in.read((char *)buf, 2); +
-        this->​width = (buf[0] << 8) | buf[1]; +
-        in.read((char *)buf, 2); +
-        this->​height = (buf[0] << 8) | buf[1]; +
-        in.read((char *)buf, 4); +
-        in.read((char *)buf, 4); +
-        in.read((char *)buf, 4); +
-        in.read((char *)buf, 2); +
-        this->​frame_count = (buf[0] << 8) | buf[1]; +
-  +
-        in.seekg(36,​ ios_base::​cur);​ +
-  +
-        return true; +
-    } +
-  +
-    virtual void Dump(ostream &out) +
-    { +
-        CBox::​Dump(out);​ +
-  +
-        for (int i = 0; i < this->​nested;​ i++) out << "​\t";​ +
-  +
-        out << "{ "; +
-        out << this->​width << "​x"​ << this->​height << ", " << this->​frame_count << " frames per sample.";​ +
-        out << " }" << endl; +
-  +
-        return; +
-    } +
-}; +
-  +
-/*  +
- AVC Configuration Box (14496-15)  +
-*/ +
-class CAVCConfigurationBox : public ​ CBox +
-+
-protected:​ +
-    unsigned int profile; +
-    unsigned int level; +
-    unsigned int lNAL; +
-    unsigned int nSPS; +
-    unsigned int nPPS; +
-public: +
-    CAVCConfigurationBox(int nest = 0):​CBox(CBox::​MakeInt((unsigned char*)"​avcC"​),​ nest) +
-    { +
-        comments = "AVC Configuration Box";​ +
-    } +
-    virtual ~CAVCConfigurationBox() +
-    {} +
-  +
-    virtual bool Parse(ifstream &in) +
-    { +
-        if (!CBox::​Parse(in)) +
-            return false; +
-        in.get(); +
-        this->​profile ​ = in.get(); +
-        in.get(); +
-        this->​level = in.get(); +
-        this->​lNAL = (in.get()&​0x3)+1;​ +
-        this->​nSPS = in.get()&​0x1f;​ +
-        for (int i = 0; i < this->​nSPS;​ i++) +
-        { +
-            int size = (in.get()<<​8)|(in.get());​ +
-            in.seekg(size,​ ios_base::​cur);​ +
-        } +
-        this->​nPPS = in.get(); +
-        for (int i = 0; i < this->​nPPS;​ i++) +
-        { +
-            int size = (in.get()<<​8)|(in.get());​ +
-            in.seekg(size,​ ios_base::​cur);​ +
-        }         +
-        /* skip */ +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-        this->​parsed = true; +
-  +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        CBox::​Dump(out);​ +
-  +
-        for (int i = 0; i < this->​nested;​ i++) out << "​\t";​ +
-  +
-        out << "{ "; +
-        out << "​Profile:​ " << this->​profile << ", Level: " << this->​level << ", size of NAL length: " << this->​lNAL;​ +
-        out << ", SPS x " << this->​nSPS << ", PPS x " << this->​nPPS;​ +
-        out << " }" << endl; +
-        return; +
-    } +
-}; +
-  +
-/*  +
- AVC Sample Entry Box (14496-15)  +
-*/ +
-class CAVCSampleEntryBox : public ​ CVisualSampleEntryBox +
-+
-protected:​ +
-    CAVCConfigurationBox config; +
-public: +
-    CAVCSampleEntryBox(int nest = 0):​CVisualSampleEntryBox(CBox::​MakeInt((unsigned char*)"​avc1"​),​ nest), +
-    config(nest+1) +
-    { +
-        comments = "​Visual Sample Entry Box: AVC, 14496-15)";​ +
-    } +
-    virtual ~CAVCSampleEntryBox() +
-    {} +
-  +
-    virtual bool Parse(ifstream &in) +
-    { +
-        if (!CVisualSampleEntryBox::​Parse(in)) +
-            return false; +
-        if (!config.Parse(in)) +
-            return false; +
-  +
-        /* skip */ +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-        this->​parsed = true; +
-  +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        CVisualSampleEntryBox::​Dump(out);​ +
-  +
-        config.Dump(out);​ +
-  +
-        return; +
-    } +
-}; +
-  +
-/* +
-  Audio Sample Entry Box +
-*/ +
-class CAudioSampleEntryBox : public CSampleEntryBox +
-+
-protected:​ +
-    unsigned short channelcount;​ +
-    unsigned short samplesize;​ +
-    unsigned int samplerate;​ +
-public: +
-    CAudioSampleEntryBox(unsigned int type, int nest) : CSampleEntryBox(type,​ nest), +
-    channelcount(0),​ samplesize(0),​ samplerate(0) +
-    { +
-        comments = "Audio Sample Entry Box";​ +
-    } +
-    virtual ~CAudioSampleEntryBox() {} +
-  +
-    virtual bool Parse(ifstream &in) +
-    { +
-        if (!CSampleEntryBox::​Parse(in)) +
-            return false; +
-  +
-        unsigned char buf[4]; +
-        in.seekg(8, ios_base::​cur);​ +
-        in.read((char *)buf, 2); +
-        this->​channelcount= (buf[0] << 8) | buf[1]; +
-        in.read((char *)buf, 2); +
-        this->​samplesize= (buf[0] << 8) | buf[1]; +
-        in.read((char *)buf, 4); +
-        in.read((char *)buf, 4); +
-        this->​samplerate= CBox::​MakeInt(buf);​ +
-  +
-        in.seekg(this->​end,​ ios_base::​beg); ​       +
-        this->​parsed = true; +
-  +
-        return true; +
-    } +
-  +
-    virtual void Dump(ostream &out) +
-    { +
-        CBox::​Dump(out);​ +
-  +
-        for (int i = 0; i < this->​nested;​ i++) out << "​\t";​ +
-  +
-        unsigned short r1 = this->​samplerate >> 16; +
-        out << "{ "; +
-        out << this->​channelcount << " channels, sample size: " << this->​samplesize << ", sample rate: " << r1; +
-        out << " }" << endl; +
-  +
-        return; +
-    } +
-}; +
-  +
-/* +
- ​Sample Description Box +
- The sample description table gives detailed information about the coding type used, and any initialization +
-    information needed for that coding +
-*/ +
-class CSampleDescriptionBox : public CFullBox +
-+
-protected:​ +
-    unsigned int entry_count;​ +
-    CBox** subboxes; +
-public: +
-    CSampleDescriptionBox(int nest = 0):​CFullBox(CBox::​MakeInt((unsigned char*)"​stsd"​),​ nest), +
-    entry_count(0),​ subboxes(NULL) +
-    { +
-        comments = "​Sample Description Box";​ +
-    } +
-    virtual ~CSampleDescriptionBox() +
-    { +
-        if (this->​entry_count) +
-        { +
-             for (int i = 0; i < this->​entry_count;​ i++) +
-                CBox::​Destroy(this->​subboxes[i]);​ +
-            delete [] this->​subboxes; ​           +
-        } +
-  +
-    } +
-  +
-    virtual bool Parse(ifstream &in) +
-    { +
-        if (!CFullBox::​Parse(in)) +
-            return false; +
-  +
-        unsigned char buf[4]; +
-        in.read((char *)buf, 4); +
-        this->​entry_count = CBox::​MakeInt(buf);​ +
-        this->​subboxes = new CBox*[this->​entry_count];​ +
-  +
-        /* poll subboxes */ +
-        for (int i = 0; i < this->​entry_count;​ i++) +
-        { +
-            unsigned long long pos = in.tellg();​ +
-            in.seekg(4, ios_base::​cur);​ +
-            in.read((char *)buf, 4); /*< prefetch */ +
-            in.seekg(pos,​ ios_base::​beg);​ +
-            this->​subboxes[i] = CBox::​Create(CBox::​MakeInt(buf),​ this->​nested+1);​ +
-            if (!this->​subboxes[i]->​Parse(in)) +
-                return false; +
-        } +
-  +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-        this->​parsed = true; +
-  +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        CFullBox::​Dump(out);​ +
-        for (int i = 0; i < this->​nested;​ i++) out << "​\t";​ +
-        out << "{ " << this->​entry_count << " Entries }" << endl; +
-  +
-        for (int i = 0; i < this->​entry_count;​ i++) +
-            this->​subboxes[i]->​Dump(out);​ +
-  +
-        return; +
-    } +
-}; +
-  +
-/* +
- ​Decoding Time to Sample Box +
-*/ +
-class CTimeToSampleBox : public CFullBox +
-+
-protected:​ +
-    unsigned int entry_count;​ +
-    class CEntry +
-    { +
-    public: +
-        unsigned int sample_count;​ +
-        unsigned int sample_delta;​ +
-    } **entries;​ +
-public: +
-    CTimeToSampleBox(int nest = 0):​CFullBox(CBox::​MakeInt((unsigned char*)"​stts"​),​ nest), +
-    entry_count(0),​ entries(NULL) +
-    { +
-        comments = (char *) "​Decoding Time to Sample Box";​ +
-    } +
-    virtual ~CTimeToSampleBox()  +
-    { +
-        if (this->​entry_count) +
-        { +
-            for (int i = 0; i < this->​entry_count;​ i++) delete this->​entries[i];​ +
-            delete [] this->​entries;​ +
-        } +
-    } +
-    virtual bool Parse(ifstream &in) +
-    { +
-        if (!CFullBox::​Parse(in)) +
-            return false; +
-  +
-        unsigned char buf[4]; +
-        in.read((char *)buf, 4); +
-        this->​entry_count = CBox::​MakeInt(buf);​ +
-        if (this->​entry_count) this->​entries = new CEntry* [this->​entry_count];​ +
-        for (int i = 0; i < this->​entry_count;​ i++) +
-        { +
-            this->​entries[i] = new CEntry; +
-            in.read((char *)buf, 4); +
-            this->​entries[i]->​sample_count = CBox::​MakeInt(buf);​ +
-            in.read((char *)buf, 4); +
-            this->​entries[i]->​sample_delta = CBox::​MakeInt(buf);​ +
-        } +
-  +
-        /* skip */ +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-        this->​parsed = true; +
-  +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        int i; +
-  +
-        CFullBox::​Dump(out);​ +
-        for (i = 0; i < this->​nested;​ i++) out << "​\t";​ +
-        out << "{ "; +
-        if (this->​entry_count) +
-        { +
-            for (i = 0; i < 5; i++) +
-            { +
-                if (i >= this->​entry_count) break; +
-                out << this->​entries[i]->​sample_count << ":"​ << this->​entries[i]->​sample_delta << ", "; +
-            } +
-            if (i < this->​entry_count) out << ​ "..., " << this->​entry_count - i << " left";​ +
-        } +
-        out << " }" << endl; +
-        return; +
-    }     +
-}; +
-  +
-/* +
- Sync Sample Box +
-*/ +
-class CSyncSampleBox : public CFullBox +
-+
-protected:​ +
-    unsigned int entry_count;​ +
-    unsigned int *entries; +
-public: +
-    CSyncSampleBox(int nest = 0):​CFullBox(CBox::​MakeInt((unsigned char*)"​stss"​),​ nest) +
-    { +
-        comments = (char *) "Sync Sample Box";​ +
-    } +
-    virtual ~CSyncSampleBox()  +
-    { +
-        if (this->​entry_count) delete []entries;​ +
-    } +
-    virtual bool Parse(ifstream &in) +
-    { +
-        if (!CFullBox::​Parse(in)) +
-            return false; +
-  +
-        unsigned char buf[4]; +
-        in.read((char *)buf, 4); +
-        this->​entry_count = CBox::​MakeInt(buf); ​     +
-        if (this->​entry_count) this->​entries = new unsigned int[this->​entry_count]; ​        +
-        for (int i = 0; i < this->​entry_count;​ i++) +
-        { +
-            in.read((char *)buf, 4); +
-            this->​entries[i] = CBox::​MakeInt(buf);​ +
-        } +
-  +
-        /* skip */ +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-        this->​parsed = true; +
-  +
-  +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        int i; +
-  +
-        CFullBox::​Dump(out);​ +
-        for (i = 0; i < this->​nested;​ i++) out << "​\t";​ +
-        out << "{ "; +
-        if (this->​entry_count) +
-        { +
-            for (i = 0; i < 5; i++) +
-            { +
-                if (i >= this->​entry_count) break; +
-                out << this->​entries[i] << ", "; +
-            } +
-            if (i < this->​entry_count) out << ​ "..., " << this->​entry_count - i << " left";​ +
-        } +
-        out << " }" << endl;         +
-        return; +
-    }     +
-}; +
-  +
-/* +
- ​Independent and Disposable Samples Box +
-*/ +
-class CSampleDependencyTypeBox : public CFullBox +
-+
-protected:​ +
-    unsigned int entry_count;​ +
-    unsigned char *entries; ​    +
-public: +
-    CSampleDependencyTypeBox(int nest = 0):​CFullBox(CBox::​MakeInt((unsigned char*)"​sdtp"​),​ nest) +
-    { +
-        comments = (char *) "​Independent and Disposable Samples Box";​ +
-    } +
-    virtual ~CSampleDependencyTypeBox()  +
-    { +
-        if (this->​entry_count) delete []entries;​ +
-    } +
-    virtual bool Parse(ifstream &in) +
-    { +
-        if (!CFullBox::​Parse(in)) +
-            return false; +
-  +
-        unsigned long long pos = in.tellg();​ +
-        this->​entry_count = this->​end - pos; +
-        this->​entries = new unsigned char[this->​entry_count];​ +
-        for (int i = 0; i < this->​entry_count;​ i++) this->​entries[i] = in.get(); +
-  +
-        /* skip */ +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-        this->​parsed = true; +
-  +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        int i; +
-  +
-        CFullBox::​Dump(out);​ +
-        for (i = 0; i < this->​nested;​ i++) out << "​\t";​ +
-        out << "{ "; +
-        if (this->​entry_count) +
-        { +
-            for (i = 0; i < 5; i++) +
-            { +
-                if (i >= this->​entry_count) break; +
-                if ((this->​entries[i]&​0x30) == 0x10) out << "​N";​ +
-                else if ((this->​entries[i]&​0x30) == 0x20) out << "​I";​ +
-                else out << "​X";​ +
-                out <<"​|";​ +
-                if ((this->​entries[i]&​0xc) == 4) out << "​R";​ +
-                else if ((this->​entries[i]&​0xc) == 8) out << "​N";​ +
-                else out << "​X";​ +
-                out <<"​|";​ +
-                if ((this->​entries[i]&​0x3) == 1) out << "​D";​ +
-                else if ((this->​entries[i]&​0x3) == 2) out << "​N";​ +
-                else out << "​X"; ​    +
-                out <<",​ "; +
-            } +
-            if (i < this->​entry_count) out << ​ "..., " << this->​entry_count - i << " left";​ +
-        } +
-        out << " }" << endl;   +
-    }     +
-}; +
-  +
-/* +
- ​Sample to Chunk Box +
-*/ +
-class CSampleToChunkBox : public CFullBox +
-+
-protected:​ +
-    unsigned int entry_count;​ +
-    class CEntry +
-    { +
-    public: +
-        unsigned int first_chunk;​ +
-        unsigned int samples_per_chunk;​ +
-        unsigned int sd_id; +
-    } **entries;​ +
-public: +
-    CSampleToChunkBox(int nest = 0):​CFullBox(CBox::​MakeInt((unsigned char*)"​stsc"​),​ nest), +
-    entry_count(0),​ entries(NULL) +
-    { +
-        comments = (char *) "​Sample to Chunk Box";​ +
-    } +
-    virtual ~CSampleToChunkBox() +
-    { +
-        if (this->​entry_count) +
-        { +
-            for (int i = 0; i < this->​entry_count;​ i++) delete this->​entries[i];​ +
-            delete [] this->​entries;​ +
-        }     +
-    } +
-    virtual bool Parse(ifstream &in) +
-    { +
-        if (!CFullBox::​Parse(in)) +
-            return false; +
-  +
-        unsigned char buf[4]; +
-        in.read((char *)buf, 4); +
-        this->​entry_count = CBox::​MakeInt(buf);​ +
-        if (this->​entry_count) this->​entries = new CEntry* [this->​entry_count];​ +
-        for (int i = 0; i < this->​entry_count;​ i++) +
-        { +
-            this->​entries[i] = new CEntry; +
-            in.read((char *)buf, 4); +
-            this->​entries[i]->​first_chunk = CBox::​MakeInt(buf);​ +
-            in.read((char *)buf, 4); +
-            this->​entries[i]->​samples_per_chunk = CBox::​MakeInt(buf);​ +
-            in.read((char *)buf, 4); +
-            this->​entries[i]->​sd_id = CBox::​MakeInt(buf); ​            +
-        } +
-  +
-        /* skip */ +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-        this->​parsed = true; +
-  +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        int i; +
-  +
-        CFullBox::​Dump(out);​ +
-        for (i = 0; i < this->​nested;​ i++) out << "​\t";​ +
-        out << "{ "; +
-        if (this->​entry_count) +
-        { +
-            for (i = 0; i < 5; i++) +
-            { +
-                if (i >= this->​entry_count) break; +
-                out << "​(1st:"​ << ​ this->​entries[i]->​first_chunk;​ +
-                out << ",​s:"​ << this->​entries[i]->​samples_per_chunk;​ +
-                out << ",​sdid:"​ << this->​entries[i]->​sd_id << "), "; +
-            } +
-            if (i < this->​entry_count) out << ​ "..., " << this->​entry_count - i << " left";​ +
-        } +
-        out << " }" << endl;         +
-        return; +
-    }     +
-}; +
-  +
-/* +
- ​Sample Size Box +
-*/ +
-class CSampleSizeBox : public CFullBox +
-+
-protected:​ +
-    unsigned int sample_size;​ +
-    unsigned int sample_count;​ +
-    unsigned int *entries; +
-public: +
-    CSampleSizeBox(int nest = 0):​CFullBox(CBox::​MakeInt((unsigned char*)"​stsz"​),​ nest), +
-    sample_size(0),​ sample_count(0),​ entries(NULL) +
-    { +
-        comments = (char *) "​Sample Size Box";​ +
-    } +
-    virtual ~CSampleSizeBox()  +
-    { +
-        if (this->​sample_count) +
-        { +
-            delete [] this->​entries;​ +
-        } +
-    } +
-    virtual bool Parse(ifstream &in) +
-    { +
-        if (!CFullBox::​Parse(in)) +
-            return false; +
-  +
-        unsigned char buf[4]; +
-        in.read((char *)buf, 4); +
-        this->​sample_size = CBox::​MakeInt(buf);​ +
-        if (this->​sample_size == 0) +
-        { +
-            in.read((char *)buf, 4); +
-            this->​sample_count = CBox::​MakeInt(buf);​ +
-            if (this->​sample_count) this->​entries = new unsigned int [this->​sample_count];​ +
-            for (int i = 0; i < this->​sample_count;​ i++) +
-            { +
-                in.read((char *)buf, 4); +
-                this->​entries[i] = CBox::​MakeInt(buf);​ +
-            } +
-        } +
-  +
-        /* skip */ +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-        this->​parsed = true; +
-  +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        int i; +
-        CFullBox::​Dump(out);​ +
-  +
-        for (i = 0; i < this->​nested;​ i++) out << "​\t";​ +
-        out << "{ "; +
-        if (this->​sample_size == 0) +
-        { +
-            for (i = 0; i < 5; i++) +
-            { +
-                if (i >= this->​sample_count) break; +
-                out << this->​entries[i] << ", "; +
-            } +
-            if (i < this->​sample_count) out << ​ "..., " << this->​sample_count - i << " left";​ +
-        } +
-        else +
-            out << this->​sample_size;​ +
-        out << " }" << endl;     +
-  +
-        return; +
-    }     +
-}; +
-  +
-/* +
- Chunk Offset Box +
-*/ +
-class CChunkOffsetBox : public CFullBox +
-+
-protected:​ +
-    unsigned int entry_count;​ +
-    unsigned int *entries; ​      +
-public: +
-    CChunkOffsetBox(int nest = 0):​CFullBox(CBox::​MakeInt((unsigned char*)"​stco"​),​ nest), +
-    entry_count(0),​ entries(NULL) +
-    { +
-        comments = (char *) "Chunk Offset Box";​ +
-    } +
-    virtual ~CChunkOffsetBox()  +
-    { +
-        if (this->​entry_count) delete []entries;​ +
-    } +
-    virtual bool Parse(ifstream &in) +
-    { +
-        if (!CFullBox::​Parse(in)) +
-            return false; +
-  +
-        unsigned char buf[4]; +
-        in.read((char *)buf, 4); +
-        this->​entry_count = CBox::​MakeInt(buf);​ +
-        if (this->​entry_count) this->​entries = new unsigned int[this->​entry_count];​ +
-  +
-        for (int i = 0; i < this->​entry_count;​ i++)  +
-        { +
-            in.read((char *)buf, 4); +
-            this->​entries[i] = CBox::​MakeInt(buf);​ +
-        } +
-  +
-        /* skip */ +
-        in.seekg(this->​end,​ ios_base::​beg);​ +
-        this->​parsed = true; +
-  +
-        return true; +
-    } +
-    virtual void Dump(ostream &out) +
-    { +
-        int i; +
-        CFullBox::​Dump(out);​ +
-  +
-        for (i = 0; i < this->​nested;​ i++) out << "​\t";​ +
-        out << "{ "; +
-        if (this->​entry_count) +
-        { +
-            for (i = 0; i < 5; i++) +
-            { +
-                if (i >= this->​entry_count) break; +
-                out << this->​entries[i] << ", "; +
-            } +
-            if (i < this->​entry_count) out << ​ "..., " << this->​entry_count - i << " left";​ +
-        } +
-        out << " }" << endl;     +
-  +
-        return; +
-    }     +
-}; +
-  +
-CBox* CBox::​Create(unsigned int type, int nest, unsigned char *extended_type) +
-+
-    switch (type) +
-    { +
-        case 0x66747970 /* '​f''​t''​y''​p'​*/:​  +
-            return new CFileTypeBox(nest);​ +
-        case 0x6d646174 /* '​m''​d''​a''​t'​ */: +
-            return new CMediaDataBox(nest);​ +
-        case 0x66726565 /* '​f''​r''​e''​e'​ */: +
-            return new CFreeSpaceBox(nest);​ +
-        case 0x6d766864 /* '​m''​v''​h''​d'​ */: +
-            return new CMovieHeaderBox(nest);​ +
-        case 0x746b6864 /* '​t''​k''​h''​d'​ */: +
-            return new CTrackHeaderBox(nest);​ +
-        case 0x6d646864 /* '​m''​d''​h''​d'​ */: +
-            return new CMediaHeaderBox(nest);​ +
-        case 0x68646c72 /* '​h''​d''​l''​r'​ */: +
-            return new CHandlerRefBox(nest);​ +
-        case 0x766d6864 /* '​v''​m''​h''​d'​ */: +
-            return new CVideoMediaHeaderBox(nest);​ +
-        case 0x736d6864 /* '​s''​m''​h''​d'​ */: +
-            return new CSoundMediaHeaderBox(nest);​ +
-        case 0x686d6864 /* '​h''​m''​h''​d'​ */: +
-            return new CHintMediaHeaderBox(nest);​ +
-        case 0x64726566 /* '​d''​r''​e''​f'​ */: +
-            return new CDataRefBox(nest);​ +
-        case 0x73747364 /* '​s''​t''​s''​d'​ */: +
-            return new CSampleDescriptionBox(nest);​ +
-        case 0x73747473 /* '​s''​t''​t''​s'​ */: +
-            return new CTimeToSampleBox(nest);​ +
-        case 0x73747373 /* '​s''​t''​s''​s'​ */: +
-            return new CSyncSampleBox(nest);​ +
-        case 0x73647470 /* '​s''​d''​t''​p'​ */: +
-            return new CSampleDependencyTypeBox(nest);​ +
-        case 0x73747363 /* '​s''​t''​s''​c'​ */: +
-            return new CSampleToChunkBox(nest);​ +
-        case 0x7374737a /* '​s''​t''​s''​z'​ */: +
-            return new CSampleSizeBox(nest);​ +
-        case 0x7374636f /* '​s''​t''​c''​o'​ */: +
-            return new CChunkOffsetBox(nest);​ +
-        case 0x61766331 /* '​a''​v''​c''​1'​ */: +
-            return new CAVCSampleEntryBox(nest);​ +
-        case 0x6d703461 /* '​m''​p''​4''​a'​ */: +
-            return new CAudioSampleEntryBox(type,​ nest); +
-        case 0x75726c20 /* '​u''​r''​l''​ ' */: +
-            return new CDataEntryURLBox(nest);​ +
-        case 0x75726e20 /* '​u''​r''​n''​ ' */: +
-            return new CDataEntryURNBox(nest);​ +
-        case 0x6d666864 /* '​m''​f''​h''​d'​ */: +
-            return new CMovieFragmentBox(nest);​ +
-        case 0x74666864 /* '​t''​f''​h''​d'​ */: +
-            return new CTrackFragmentHeaderBox(nest);​ +
-        case 0x6d6f6f76 /* '​m''​o''​o''​v'​ */: +
-        case 0x7472616b /* '​t''​r''​a''​k'​ */: +
-        case 0x74726566 /* '​t''​r''​e''​f'​ */: +
-        case 0x65647473 /* '​e''​d''​t''​s'​ */:   +
-        case 0x6d646961 /* '​m''​d''​i''​a'​ */:  +
-        case 0x6d696e66 /* '​m''​i''​n''​f'​ */: +
-        case 0x64696e66 /* '​d''​i''​n''​f'​ */: +
-        case 0x7374626c /* '​s''​t''​b''​l'​ */: +
-        case 0x6d6f6f66 /* '​m''​o''​o''​f'​ */: +
-        case 0x74726166 /* '​t''​r''​a''​f'​ */: +
-            return new CContainerBox(type,​ nest); +
-        default: +
-            return new CUnknownBox(nest);​ +
-    } +
-+
-  +
-void CBox::​Destroy(CBox* box) +
-+
-    delete box; +
-+
-  +
-int main(int argc, char** argv) +
-+
-    ifstream in; +
-    int ret; +
-    CBox *isobox; +
-  +
-    if (argc < 2) +
-    { +
-        cout << argv[0] << " filename"​ << endl; +
-        return 0; +
-    } +
-  +
-    in.open(argv[1],​ ios::​binary);​ +
-    while (1) +
-    { +
-        unsigned char buf[4]; +
-        unsigned long long pos = in.tellg();​ +
-        in.seekg(4, ios_base::​cur);​ +
-        in.read((char *)buf, 4); /* prefetch type value */; +
-        if (in.eof()) +
-            break; ​        +
-        isobox = CBox::​Create(CBox::​MakeInt(buf));​ +
-        in.seekg(pos,​ ios_base::​beg);​ /* go back */  +
-        if (isobox->​Parse(in)) +
-        { +
-            isobox->​Dump(cout);​ +
-            CBox::​Destroy(isobox);​ +
-        } +
-        else +
-        { +
-            cerr << "Error During Parsing"​ << endl; +
-            CBox::​Destroy(isobox);​ +
-            ret = -1; +
-            break; +
-        } +
-    } +
-  +
-  +
-    return ret; +
-}+
tech/multimedia/iso_mp4_parser.txt · Last modified: 2014/11/10 08:22 (external edit)