您的位置:首页 > 编程语言

mp4文件格式解析,为demux准备的代码

2016-02-26 11:11 441 查看
http://blog.csdn.net/wutong_login/article/details/9973215

//filename mp4_boxes.cpp

#include <iostream>

#include <fstream>

#include <string>

#include <cstring>

#include <cstdlib>

#include <cerrno>

#include "mp4_boxes.h"

#ifndef RELEASE
#define RELEASE 1
#endif

#ifndef VARIABLES
#define VARIABLES                               \

    int k = 0;                                  \

    unsigned char p[5];                         \

    int inner_size = 0;
#endif

static struct mp4_moov_box moov;

/*final box

 */
int mp4_read_mvhd_box(FILE *f, int size)  //level 3
{

    printf("\t+%s\n", "mvhd");

    VARIABLES;

    int level_4_box_size    = 0;

    mp4_mvhd_box mvhd;

    memset(&mvhd, 0, sizeof(mvhd));

    

    mvhd.size               = size;

    mvhd.type               = ('m' | 'v'<<8 | 'h'<<16 | 'd'<<24);

    mvhd.version            = read_uint8(f);                 //1
    fread(mvhd.flags, sizeof(mvhd.flags), 1, f);             //3
    mvhd.creation_time      = read_uint32_lit(f);            //4
    mvhd.modification_time  = read_uint32_lit(f);            //4
    mvhd.timescale          = read_uint32_lit(f);            //4
    mvhd.duration           = read_uint32_lit(f);            //4
    mvhd.rate               = read_uint32_lit(f);            //4
    mvhd.volume             = read_uint16_big(f);            //2
    fread(&mvhd.reserved1, sizeof(mvhd.reserved1), 1, f);    //2
    fread(&mvhd.reserved2, sizeof(mvhd.reserved2), 1, f);    //8
    fread(mvhd.matrix, sizeof(mvhd.matrix), 1, f);           //36
    fread(mvhd.pre_defined, sizeof(mvhd.pre_defined), 1, f); //24
    mvhd.next_track_id      = read_uint32_lit(f);            //4
    moov.mvhd               = mvhd;

    

    printf("\t\ttimescale: %u\n", moov.mvhd.timescale);

    printf("\t\tduration: %u\n", moov.mvhd.duration);

    printf("\t\trate: %u\n", moov.mvhd.rate );

    printf("\t\tvolume: 0x%x\n", moov.mvhd.volume);

    

    printf("\t\tmatrix:\n");

    for(int i = 0; i < 3; ++i){

        printf("\t\t");

        for(int j = 0; j < 3; ++j){

            printf(" %8u ", moov.mvhd.matrix[i*3+j]);

        }

        printf("\n");

    }

    

    printf("\t\tnext track id: %u\n", moov.mvhd.next_track_id);

   

    printf("\n");

}

/*final box

 */
struct mp4_tkhd_box mp4_read_tkhd_box(FILE *f, int size)  //level 4
{

    printf("\t\t+%s\n", "tkhd"); 

    

    VARIABLES;

    mp4_tkhd_box box;

        

    box.size              = size;

    box.type              = 0;

    box.version           = read_uint8(f);

    fread(&box.flags, sizeof(box.flags), 1, f);

    box.creation_time     = read_uint32_lit(f);

    box.modification_time = read_uint32_lit(f);

    box.track_ID          = read_uint32_lit(f);

    box.reserved1         = read_uint32_lit(f);

    box.duration          = read_uint32_lit(f);

    fread(&box.reserved2, sizeof(box.reserved2), 1, f);

    box.layer             = read_uint16_big(f);

    box.alternate_group   = read_uint16_big(f);

    box.volume            = read_uint16_big(f);

    box.reserved3         = read_uint16_big(f);

    fread(&box.matrix, sizeof(box.matrix), 1, f);

    box.width             = read_uint32_lit(f);

    box.height            = read_uint32_lit(f);

    // printf("\t\t\tflags: 0x%4x\n", box.flags[2]

    //        | box.flags[1] | box.flags[0]);

    // printf("\t\t\tcreation time: %u\n", box.creation_time);

    // printf("\t\t\tmodifaction time: %u\n",

    //        box.modification_time);
    printf("\t\t\ttrack id: %u\n", box.track_ID);

    // printf("\t\t\treserved1: 0x%x\n", box.reserved1);
    printf("\t\t\tduration: %d\n",box.duration);

    // printf("\t\t\treserved2: 0x%x, 0x%x\n",

    //        box.reserved2[0], box.reserved2[1]);
    printf("\t\t\tlayer: %d\n",box.layer);

    printf("\t\t\talternate group: %d\n", box.alternate_group);

    printf("\t\t\tvolume: 0x%x\n", box.volume);

    // printf("\t\t\treserved3: 0x%x\n", box.reserved3);
        

    printf("\t\t\tmatrix:\n");

    for(int i = 0; i < 3; ++i){

        printf("\t\t\t");

        for(int j = 0; j < 3; ++j){

            printf(" %8u ", box.matrix[i*3+j]);

        }

        printf("\n");

    }

    //////////////////////////////////////////@a mark still don't know
    printf("\t\t\twidth: %u\n",box.width);

    printf("\t\t\theight: [%u].[%u]\n",

           box.height & 0xffff0000 >> 16,

           box.height & 0xffff);

  

    printf("\n");

    

    return box;

}

/*container box

  (elst)

 */
struct mp4_edts_box mp4_read_edts_box(FILE *f, int size)

{

    printf("\t\t+%s\n", "edts");

    

    //return mp4_edts_box();
}

/*final box

 */
struct mp4_mdhd_box mp4_read_mdhd_box(FILE *f, int size)

{

    printf("\t\t\t+mdhd\n");

    struct mp4_mdhd_box box;

    VARIABLES;

        

    box.size              = size;

    box.type              = 0;

    box.version           = read_uint8(f);

    fread(&box.flags, sizeof(box.flags), 1, f);

    box.creation_time     = read_uint32_lit(f);

    box.modification_time = read_uint32_lit(f);

    box.timescale         = read_uint32_lit(f);

    box.duration          = read_uint32_lit(f);

    box.language          = read_uint16_big(f);

    box.pre_defined       = read_uint16_big(f);

    // printf("\t\t\t\t\tflags: 0x%x\n", box.flags[2]

    //        | box.flags[1] | box.flags[0]);

    // printf("\t\t\t\t\tcreation time: %u\n", box.creation_time);

    // printf("\t\t\t\t\tmodifaction time: %u\n",

    //        box.modification_time);
    printf("\t\t\t\ttimescale: %u\n", box.timescale);

    printf("\t\t\t\tduration: %u\n", box.duration);

    printf("\t\t\t\tlanguage: %u\n", box.language);

    // printf("\t\t\t\tpre-defined: %u\n", box.pre_defined);

    
//    printf("\n");

    return box;

}

/*filnal box

 */
struct mp4_hdlr_box mp4_read_hdlr_box(FILE *f, int size)

{

    printf("\t\t\t%s\n", "+hdlr");

    struct mp4_hdlr_box box;

   

    VARIABLES;

    

    box.size            = size;

    box.type            = 'h'|'d'<<8|'l'<<16|'r'<<24;

    box.version         = read_uint8(f);

    fread(&box.flags, sizeof(box.flags), 1, f);

    box.pre_defined     = read_uint32_lit(f);

    fread(&box.handler_type, sizeof(box.handler_type), 1, f);

    box.handler_type[4] = 0;

    fread(&box.reserved, sizeof(box.reserved), 1, f);

    fread(&inner_size, 1, 1, f);

    box.name            = new char[inner_size + 1];

    for(int i = 0; i < inner_size; ++i)

        fread(&box.name[i], sizeof(unsigned char), 1, f);

    

    // printf("\t\t\t\tflags: 0x%x\n",

    //        box.flags[2] | box.flags[1] | box.flags[0]);

    // printf("\t\t\t\tpre-defined: %d\n", box.pre_defined);
    printf("\t\t\t\thandler type: %s\n", box.handler_type);

    // printf("\t\t\t\treserved: 0x%x, 0x%x, 0x%x\n",

    //        box.reserved[0], box.reserved[1], box.reserved[2]);
    printf("\t\t\t\tname: %s\n", box.name);  //I have no idea what

                                             //is this using for

    // printf("\n");
    return box;

}

/*final box

 */
struct mp4_vmhd_box * mp4_read_vmhd_box(FILE *f, int size)

{

    printf("\t\t\t\t+%s\n", "vmhd");

    VARIABLES;

    mp4_vmhd_box *box  = new mp4_vmhd_box;

    

    box->size          = size;

    box->type          = 0;

    box->version       = read_uint8(f);

    fread(&(box->flags), sizeof(box->flags), 1, f);

    box->graphics_mode = read_uint32_lit(f);

    fread(&(box->opcolor), sizeof(box->opcolor), 1, f);

        

    // printf("\t\t\t\t\tflags: 0x%x\n", box.flags[2]

    //        | box.flags[1] | box.flags[0]);
    printf("\t\t\t\t\tgraphics mode: %u\n", box->graphics_mode);

    printf("\t\t\t\t\topcolor: %u,%u,%u,%u\n",

           box->opcolor[0],  box->opcolor[1],

           box->opcolor[2],  box->opcolor[3]);

    

    //printf("\n");
}

/*final box

 */
struct mp4_smhd_box *mp4_read_smhd_box(FILE *f, int size)

{

    printf("\t\t\t\t+%s\n", "smhd");

    mp4_smhd_box box;

    

    box.size             = size;

    box.type             = 's'|'m'<<8|'h'<<16|'d'<<24;

    box.version          = read_uint8(f);

    fread(&box.flags, sizeof(box.flags), 1, f);

    box.balance          = read_uint16_big(f);

    box.reserved         = read_uint16_big(f);        

    // printf("\t\t\t\t\tflags: 0x%x\n", box.flags[2]

    //        | box.flags[1] | box.flags[0]);
    printf("\t\t\t\t\tbalance: %d,%d\n",

           box.balance & 0xff00 >> 8, box.balance & 0xff);

    // printf("\t\t\t\t\treserved: 0x%x\n", box.reserved);

        

    //  printf("\n");
    mp4_smhd_box *newbox = new mp4_smhd_box;

    *newbox              = box;

    return newbox;

}

struct mp4_stts_box mp4_read_stts_box(FILE *f, int size)  //level 8
{

    printf("\t\t\t\t\t+%s\n", "stts");

    mp4_stts_box box;

    box.size                 = size;

    box.version              = read_uint8(f);

    fread(box.flags, sizeof(box.flags), 1, f);

    box.number_of_entries    = read_uint32_lit(f);

    // printf("\t\t\t\t\t\tflags: %u\n",

    //        box.flags[0]|box.flags[1]|box.flags[2]);
    printf("\t\t\t\t\t\tnumber of entries: %u\n",box.number_of_entries);

     

    printf("\t\t\t\t\t\tentries:\n\t\t\t\t\t\t");

    box.time_to_sample_table = new uint32_t[box.number_of_entries];

    for(int i = 0; i < box.number_of_entries; ++i){

        box.time_to_sample_table[i] = read_uint32_lit(f);

        //  printf("%5u ", box.time_to_sample_table[i]);

        // if(i%16 == 0) printf("\n");
    }

    //delete [] box.time_to_sample_table;
    

    printf("\n");

    return box;

}

/*final box*/
struct mp4_avcC_box *mp4_read_avcC_box(FILE *f)

{

    struct mp4_avcC_box *ptr       = new mp4_avcC_box;

    

    ptr->size                      = read_uint32_lit(f);

    printf("avcC_size:%u\n",ptr->size);

    

    ptr->type                      = read_uint32_lit(f);

    if( ptr->type                  ==  ('a'<<24|'v'<<16|'c'<<8|'C')){

        printf("type:avcC\n");

    }

    

    ptr->configurationVersion      = read_uint8(f);

    printf("configurationVersion:%u\n", ptr->configurationVersion);

    ptr->AVCProfileIndication      = read_uint8(f);

    printf("AVCProfileIndication: %x\n", ptr->AVCProfileIndication);

    ptr->profile_compatibility     = read_uint8(f);

    ptr->AVCLevelIndication        = read_uint8(f);

    ptr->lengthSizeMinusOne        = 0x3 & read_uint8(f);  //2 bit
    printf("lengthSizeMinusOne:%u\n", ptr->lengthSizeMinusOne);

    ptr->numOfSequenceParameterSet = 0x1F & read_uint8(f);  //5bit
    printf("numOfSequenceParameterSet:%x\n", ptr->numOfSequenceParameterSet);

    ptr->sps                       = new mp4_avcC_box::SPS[ptr->numOfSequenceParameterSet];

    

    for( int i = 0; i < ptr->numOfSequenceParameterSet; ++i ){

        ptr->sps[i].sequenceParameterSetLength = read_uint16_lit(f);

        printf("sequenceParameterSetLength: %u\n", ptr->sps[i].sequenceParameterSetLength);

        

        ptr->sps[i].sequenceParameterSetNALUnit =

            new uint8_t[ptr->sps[i].sequenceParameterSetLength];

        fread((ptr->sps[i].sequenceParameterSetNALUnit),

              (ptr->sps[i].sequenceParameterSetLength), 1, f);

        

        for(int j = 0; j < ptr->sps[i].sequenceParameterSetLength; ++j){

            printf("%x", ptr->sps[i].sequenceParameterSetNALUnit[j]);

        }

        printf("============\n");

    }

    ptr->numOfPictureParameterSets = read_uint8(f);

    printf("numOfPictureParameterSets:%u\n", ptr->numOfPictureParameterSets);

    ptr->pps                       = new mp4_avcC_box::PPS[ptr->numOfPictureParameterSets];

    for( int i = 0; i < ptr->numOfPictureParameterSets; ++i){

        ptr->pps[i].pictureParameterSetLength = read_uint16_lit(f);

        printf("%d\n", ptr->pps[i].pictureParameterSetLength);

        

        ptr->pps[i].pictureParameterSetNALUnit

                                   = new uint8_t[ptr->pps[i].pictureParameterSetLength];

        

        fread(ptr->pps[i].pictureParameterSetNALUnit,

              ptr->pps[i].pictureParameterSetLength, 1, f);

        

        for(int j = 0; j < ptr->pps[i].pictureParameterSetLength; ++j){

            printf("%x", ptr->pps[i].pictureParameterSetNALUnit[j]);

        }

        printf("============\n");

    }

    

    return ptr;

}

/*final box

  @a special contain a avcC box

 */
struct mp4_avc1_box* mp4_read_avc1_box(FILE *f, int size)  //level 9
{

    mp4_avc1_box *ptr = new mp4_avc1_box;

    

    ptr->size                   = size;

    ptr->type                   = (('a'<<24)|('v'<<16)|('c'<<8)|('1'));

    

    fread(ptr->reserved, sizeof(ptr->reserved), 1, f);  //6
    ptr->data_reference_index   = read_uint16_lit(f);   //2
    ptr->pre_defined            = read_uint16_big(f);   //2
    ptr->reserved1              = read_uint16_big(f);   //2
    fread(ptr->pre_defined1, sizeof(ptr->pre_defined1), 1, f);  //3*4
    ptr->width                  = read_uint16_lit(f);   //2
    ptr->height                 = read_uint16_lit(f);   //2
    ptr->horiz_res              = read_uint32_lit(f);   //4
    ptr->vert_res               = read_uint32_lit(f);   //4
    ptr->reserved2              = read_uint32_lit(f);   //4
    ptr->frames_count           = read_uint16_lit(f);   //2
    fread(ptr->compressor_name, sizeof(ptr->compressor_name), 1, f);  //33
    ptr->bit_depth              = read_uint8(f);        //1
    ptr->pre_defined2           = read_uint16_big(f);   //2

    //avcC --AVCDecoderConfigurationRecord
    printf("-------------------------------------\n");

    printf("data_reference_index:%x\n", ptr->data_reference_index);

    printf("width:%u\n", ptr->width);

    printf("height:%u\n", ptr->height);

    printf("frames_count:%x\n", ptr->frames_count);

    printf("bit_depth:%u\n", ptr->bit_depth);

    printf("pre_defined2: %x\n", ptr->pre_defined2);

    

    ptr->avcC = mp4_read_avcC_box(f);

    

    printf("-------------------------------------\n");

    return ptr;

}

/*final box

 */
struct mp4_mp4a_box * mp4_read_mp4a_box(FILE*f, int size)  //level 9
{

    printf("\t\t\t\t\t\t+mp4a\n");

    return 0;

}

/*container box

  (mp4a,avc1)

 */
struct mp4_stsd_box mp4_read_stsd_box(FILE *f, int size)  //level 8
{

    printf("\t\t\t\t\t+%s\n", "stsd");

    mp4_stsd_box box;

    box.size               = size;

    box.version            = read_uint8(f);

    fread(box.flags, sizeof(box.flags), 1, f);

    box.number_of_entries  = read_uint32_lit(f);

    // printf("\t\t\t\t\t\tflags: %u\n",

    //        box.flags[0]|box.flags[1]|box.flags[2]);
    printf("\t\t\t\t\t\tnumber of entries: %u\n", box.number_of_entries);

    

    box.sample_description = new Sample_description[box.number_of_entries];

    for(int i =0; i < box.number_of_entries; ++i){

        box.sample_description[i].size = read_uint32_lit(f);

        box.sample_description[i].type = read_uint32_lit(f);

        

        if( box.sample_description[i].type == (('m'<<24)|('p'<<16)|('4'<<8)|('a'))){

            box.sample_description[i].mp4a

                = mp4_read_mp4a_box(f, box.sample_description[i].size);

            box.sample_description[i].avc1 = 0;

            

        }else if(box.sample_description[i].type

                 == (('a'<<24)|('v'<<16)|('c'<<8)|('1'))){

            box.sample_description[i].avc1

                = mp4_read_avc1_box(f, box.sample_description[i].size);

            box.sample_description[i].mp4a = 0;

        } 

    }

    return box;

}

/*final box

 */
struct mp4_stss_box mp4_read_stss_box(FILE *f, int size)  //level 8
{

    printf("\t\t\t\t\t+%s\n", "stss");

    mp4_stss_box box;

    box.size              = size;

    box.version           = read_uint8(f);

    fread(box.flags, sizeof(box.flags), 1, f);

    box.number_of_entries = read_uint32_lit(f);

    

    // printf("\t\t\t\t\t\t\tflags: %u\n",

    //        box.flags[0]|box.flags[1]|box.flags[2]);
    printf("\t\t\t\t\t\tnumber of entries: %u\n",box.number_of_entries);

    printf("\t\t\t\t\t\tentries:\n");

    box.sync_sample_table = new uint32_t[box.number_of_entries];

    for(int i =0; i < box.number_of_entries; ++i){

        box.sync_sample_table[i] = read_uint32_lit(f);

        printf("%6u ", box.sync_sample_table[i]);

        if( (i+1)%12 == 0) printf("\n");

    }

    // delete box.sync_sample_table;
    printf("\n");

    return box;

}

/*final box

 */
struct mp4_stsc_box mp4_read_stsc_box(FILE *f, int size)  //level 8
{

    printf("\t\t\t\t\t+%s\n", "stsc");

    mp4_stsc_box box;

    

    box.version    = read_uint8(f);

    fread(&box.flags, sizeof(box.flags), 1, f);

    box.map_amount = read_uint32_lit(f);

   

    printf("\t\t\t\t\t\tmap-amount: %u\n", box.map_amount);

    

    box.scmap      = new mp4_list_t[box.map_amount];

    printf("\t\t\t\t\t\tfirst trunk:\tsamples-per-thunk:\tsample-description-ID\n");

    for(int i = 0; i < box.map_amount; ++i){

        box.scmap[i].first_chunk_num = read_uint32_lit(f);

        box.scmap[i].sample_amount_in_cur_table = read_uint32_lit(f);

        box.scmap[i].sample_description_id = read_uint32_lit(f);

        

        printf("\t\t\t\t\t\t%13d", box.scmap[i].first_chunk_num);

        printf("\t%13d", box.scmap[i].sample_amount_in_cur_table);

        printf("\t%13d\n", box.scmap[i].sample_description_id);

    }

    //delete box.scmap;
    return box;

}

/*final box

 */
struct mp4_stsz_box mp4_read_stsz_box(FILE *f, int size)  //level 8
{

    printf("\t\t\t\t\t+%s\n", "stsz");

    mp4_stsz_box box;

    box.size                 = size;

    box.version              = read_uint8(f);

    fread(box.flags, sizeof(box.flags), 1, f);

    box.samples_size_intotal = read_uint32_lit(f);

    

    if(box.samples_size_intotal == 0){

        box.table_size = read_uint32_lit(f);

        box.sample_size_table = new uint32_t[box.table_size];

        // printf("\t\t\t\t\t\tflags: 0x%x\n",

        //        box.flags[0]|box.flags[1]|box.flags[2]);
        printf("\t\t\t\t\t\tall samples amount: %u\n", box.samples_size_intotal);

        printf("\t\t\t\t\t\tsample table size: %u\n", box.table_size);

        

        printf("\t\t\t\t\t\tsmple_size_table:\n");

        for(int i = 0; i < box.table_size; ++i){

            box.sample_size_table[i] = read_uint32_lit(f);

            

            printf("%8u ", box.sample_size_table[i]);

            if((i+1) % 10 == 0) printf("\n");

        }

        printf("\n");

    }

    

    return box;

}

/*final box

 */
struct mp4_stco_box mp4_read_stco_box(FILE *f, int size)

{

    printf("\t\t\t\t\t+%s\n", "stco");

    mp4_stco_box box;

    box.version                      = read_uint8(f);

    fread(box.flags, sizeof(box.flags), 1, f);

    box.chunk_offset_amount          = read_uint32_lit(f);

    printf("\t\t\t\t\t\tflags: 0x %x\n",

           box.flags[0]|box.flags[1]|box.flags[2]);

    printf("\t\t\t\t\t\tchunk offest amount: %u\n",

           box.chunk_offset_amount);

    printf("\t\t\t\t\t\tchunk offset:\n");

    box.chunk_offset_from_file_begin = new uint32_t[box.chunk_offset_amount];

    for(int i = 0 ; i < box.chunk_offset_amount; ++i){

        box.chunk_offset_from_file_begin[i] = read_uint32_lit(f);

        printf("%8x ", box.chunk_offset_from_file_begin[i]);

        if((i+1) % 10 == 0) printf("\n");

    }
//    delete [] box.chunk_offset_from_file_begin;

    return box;

}

/*container box

  (stsd, stts, stsz|stz2, stsc, stco|co64, ctts, stss)
*/
struct mp4_stbl_box mp4_read_stbl_box(FILE *f, int size)

{

    printf("\t\t\t\t+stbl\n");

    

    mp4_stbl_box box;

    

    VARIABLES;

    int box_size          = 0;

    int cur_pos           = ftell(f) ;

    do{

        fseek(f, cur_pos, SEEK_SET);

        

        box_size          = read_uint32_lit(f);

        fread(p, 4, 1, f);

        p[4]              = 0;

        

        std::string name  = (char*)p;

        if(name == "stsd") {

            box.stsd      = mp4_read_stsd_box(f, box_size);

            //根据不同的编码方案和存储数据的文件数目,

            //每个media可以有一个到多个sample description。

            //sample-to-chunk atom通过这个索引表,

            //找到合适medai中每个sample的description。
            

        } else if(name == "stts"){

            box.stts      = mp4_read_stts_box(f, box_size);

            //Time-to-sample atoms存储了media sample的duration 信息,

            //提供了时间对具体data sample的映射方法,通过这个atom,

            //你可以找到任何时间的sample,类型是'stts'。
            

        } else if(name == "stss"){

            box.stss      = mp4_read_stss_box(f, box_size);

            //sync sample atom确定media中的关键帧。
        } else if(name == "stsc"){

            box.stsc      = mp4_read_stsc_box(f, box_size);

            //@a http://www.52rd.com/Blog/Detail_RD.Blog_wqyuwss_7922.html

            //@a http://www.52rd.com/Blog/Detail_RD.Blog_wqyuwss_7923.html
            

        } else if(name == "stsz" || name == "stz2"){

            box.stsz      = mp4_read_stsz_box(f, box_size);

            //@a http://www.52rd.com/Blog/Detail_RD.Blog_wqyuwss_7924.html
            

        } else if(name == "stco" || name == "c064"){

            box.stco      = mp4_read_stco_box(f, box_size);

            //@a http://www.52rd.com/Blog/Detail_RD.Blog_wqyuwss_7925.html
            

        } else if(name == "ctts") {

            //@a undefined
        } else {

            //printf("\t\t====size: %u\n", box_size);
            printf("\t\t\t\t\t+%s===============mark undifined\n", p);

        }

        

        cur_pos    += box_size;

        inner_size += box_size;

    } while(inner_size+8 != size);

    

    //printf("\n");
    return box;

}

/*container box

  ()

 */
struct mp4_dinf_box mp4_read_dinf_box(FILE *f, int size)

{

    printf("\t\t\t\t+dinf\n");

    struct mp4_dinf_box box;

    return box;

}

/*container box

  (vmhd, smhd, hmhd, nmhd)
*/
struct mp4_minf_box mp4_read_minf_box(FILE *f, int size)

{

    struct mp4_minf_box box;

    

    printf("\t\t\t+%s\n", "minf");

    VARIABLES;

    int level_5_box_size = 0;

    int cur_pos          = ftell(f) ;

    

    do{

        fseek(f, cur_pos, SEEK_SET);

        

        level_5_box_size = read_uint32_lit(f);

        fread(p, 4, 1, f);

        p[4] = 0;

        

        std::string name = (char*)p;

        if(name == "vmhd") {

            box.vmhd = mp4_read_vmhd_box(f, level_5_box_size);

            //@a http://www.52rd.com/Blog/Detail_RD.Blog_wqyuwss_7913.html
            

        } else if(name == "dinf") {

            box.dinf = mp4_read_dinf_box(f, level_5_box_size);

            //@a http://www.52rd.com/Blog/Detail_RD.Blog_wqyuwss_7915.html
            

        } else if(name == "stbl") {

            box.stbl = mp4_read_stbl_box(f, level_5_box_size);

            //@a unfind
            

        }else if(name == "smhd"){

            box.smhd = mp4_read_smhd_box(f, level_5_box_size);

            //@a http://www.52rd.com/Blog/Detail_RD.Blog_wqyuwss_7914.html
            

        } else {

            printf("\t\t====size: %u\n", level_5_box_size);

            printf("\t\t====type: %s\n", p);

        }

        

        cur_pos    += level_5_box_size;

        inner_size += level_5_box_size;

    } while(inner_size+8 != size);

    

    printf("\n");

    return box;

}

/*container box

  (mdhd, hdlr, minf)
*/
struct mp4_mdia_box mp4_read_mdia_box(FILE *f, int size)

{

    printf("\t\t+%s\n", "mdia");

    

    mp4_mdia_box box;

    box.size              = size;

    box.type              = 'm' | 'd'<<8 | 'i'<<16 | 'a'<<24;

    VARIABLES;

    int box_size          = 0;

    int cur_pos           = ftell(f) ;

    do{

        fseek(f, cur_pos, SEEK_SET);

        

        box_size          = read_uint32_lit(f);

        fread(p, 4, 1, f);

        p[4]              = 0;

        

        std::string name  = (char*)p;

        if(name == "mdhd") {

            box.mdhd      = mp4_read_mdhd_box(f, box_size);

            //@a http://www.52rd.com/Blog/Detail_RD.Blog_wqyuwss_7908.html
            

        } else if(name == "hdlr") {

            box.hdlr      = mp4_read_hdlr_box(f, box_size);

            //@a http://www.52rd.com/Blog/Detail_RD.Blog_wqyuwss_7909.html
            

        }else if(name == "minf"){

            box.minf      = mp4_read_minf_box(f, box_size);

            //@a http://www.52rd.com/Blog/Detail_RD.Blog_wqyuwss_7910.html
            

        } else {

            //printf("\t\t====size: %u\n", box_size);
            printf("\t\t====type: %s\n", p);

        }

        

        cur_pos    += box_size;

        inner_size += box_size;

    } while(inner_size+8 != size);

    printf("\n");

    

    return box;

}

/*container box

 */
struct  mp4_udta_box mp4_read_udta_box(FILE *f, int size)

{

    printf("\t\t+%s\n", "udta");

    return mp4_udta_box();

}

/* container box

   (tkhd, mdia)
*/
int mp4_read_trak_box(FILE *f, int size)

{

    printf("\t+%s\n", "trak");

    

    struct mp4_trak_box *trak  = new struct mp4_trak_box;

    VARIABLES;

    int box_size               = 0;

    int cur_pos                = ftell(f) ;

    do{

        fseek(f, cur_pos, SEEK_SET);

        box_size               = read_uint32_lit(f);

        fread(p, 4, 1, f);

        p[4]                   = 0;

        std::string name       = (char*)p;

        if(name == "tkhd") {

            trak->tkhd         = mp4_read_tkhd_box(f, box_size);

            //@a http://www.52rd.com/Blog/Detail_RD.Blog_wqyuwss_7903.html
            

        } else if(name == "edts") {

            trak->edts         = mp4_read_edts_box(f, box_size);

            //@a http://www.52rd.com/Blog/Detail_RD.Blog_wqyuwss_7904.html
            

        }else if(name == "mdia"){

            trak->mdia         = mp4_read_mdia_box(f, box_size);

            //@a http://www.52rd.com/Blog/Detail_RD.Blog_wqyuwss_7907.html

        } else if(name == "udta"){

            trak->udta         = mp4_read_udta_box(f, box_size);

            //same as the level 3 box, @a special
            

        } else {

            //printf("\t====size: %u\n", box_size);
            printf("\t\t+%s===========\n", p);

        }

        

        cur_pos    += box_size;

        inner_size += box_size;

    } while(inner_size+8 != size);

    moov.trak.push_back(trak);

}

/*final box

 */
int mp4_read_iods_box(FILE *f, int size)  //level 3
{

    printf("\t+iods-------------------------undefined\n\n");

}

/*container box

  (mvhd, trak)
*/
int mp4_read_moov_box(FILE* f, int size)   //level 2
{

    printf("+%s\n",  "moov");

    

    moov.size             = size;

    moov.type             = 'm'|'o'<<8|'o'<<16|'v'<<24;

    VARIABLES;

    int level_2_box_size  = 0;

    

    int cur_pos           = ftell(f);

    do{

        fseek(f, cur_pos, SEEK_SET);

        

        level_2_box_size  = read_uint32_lit(f);

        

        fread(&k, sizeof(k), 1, f);  //read byte
        indian_a.size     = k;

        memcpy(p, indian_a.byte, sizeof(indian_a.byte));

        p[4]              = 0;

        

        std::string name  = (char*)p;

        if(name == "mvhd"){

            mp4_read_mvhd_box(f, level_2_box_size);

            //@a http://www.52rd.com/Blog/Detail_RD.Blog_wqyuwss_7901.html
            

        } else if(name == "trak") {

            mp4_read_trak_box(f, level_2_box_size);

            //@a http://www.52rd.com/Blog/Detail_RD.Blog_wqyuwss_7902.html
            

        } else if(name == "iods"){

            mp4_read_iods_box(f, level_2_box_size);

            

        } else if(name == "udta"){

            mp4_read_udta_box(f, level_2_box_size);

            //@a mark parse it, unknow what it is    
        

        } else {

            printf("====%s\n\n", p);

        }

        

        cur_pos    += level_2_box_size;

        inner_size += level_2_box_size;

    }while( inner_size+8 != size);

}

/*final box

 */
int mp4_read_ftyp_box(FILE *f, int size)  //level 2
{

    printf("+ftyp\n");

    

    size -= 8;

    char *ch = new char[size+1];

    for(int i = 0; i < size; ++i) {

        fread(&ch[i], sizeof(char), 1, f);

    }

    ch[size] = 0;

    

    printf("\tftyp: %s\n",  ch);

    delete [] ch;

}

/*@a special final box

 */
int mp4_read_mdat_box(FILE *f, int size)

{

    printf("\t+%s\n", "mdat");

    printf("\t\tthis is the real media data\n");

}

/*container box

  (ftyp, free, mdat, moov)
*/
int mp4_read_root_box(FILE *f) //level 1
{

    int k                 = 0;

    unsigned char p[5];

    

    int level_1_box_size  = read_uint32_lit(f);

    

    fread(&k, sizeof(k), 1, f);  //read byte
    indian_a.size         = k;

    memcpy(p, indian_a.byte, sizeof(indian_a.byte));

    p[4]                  = 0;

    

    std::string name      = (char*)p;

    if(name == "moov"){

        mp4_read_moov_box(f, level_1_box_size);

        //@a http://www.52rd.com/Blog/Detail_RD.Blog_wqyuwss_7900.html
        

    }else if(name == "ftyp"){

        mp4_read_ftyp_box(f, level_1_box_size);

        

    } else if(level_1_box_size == 0){  //till the end of file
        return 1;

        

    }  else if(name == "mdat"){

        mp4_read_mdat_box(f, level_1_box_size);

    } else if(name == "free"){

        printf("+free\n");

        

    } else {

        //printf("==%u\n", level_1_box_size);
        printf("%s==mark undifined\n", p);

    }

    

    return level_1_box_size;

}

void print_trak(const struct mp4_trak_box * trak)

{

    printf("trak\n");

    

    printf("\t+%s\n", "tkhd");

    printf("\t\ttrack id: %u\n", trak->tkhd.track_ID);

    printf("\t\tduration: %d\n", trak->tkhd.duration);

    printf("\t\t\tlayer: %d\n",trak->tkhd.layer);

    printf("\t\t\talternate group: %d\n", trak->tkhd.alternate_group);

    printf("\t\t\tvolume: 0x%x\n", trak->tkhd.volume);

    printf("\t\t\tmatrix:\n");

    for(int i = 0; i < 3; ++i){

        printf("\t\t\t");

        for(int j = 0; j < 3; ++j){

            printf(" %8u ", trak->tkhd.matrix[i*3+j]);

        }

        printf("\n");

    }

    printf("\t\t\twidth: %u\n",trak->tkhd.width);

    printf("\t\t\theight: [%u].[%u]\n",

           trak->tkhd.height & 0xffff0000 >> 16,

           trak->tkhd.height & 0xffff);

    

    printf("\t+%s\n", "mdia");

    

    printf("\t\t\t\t\t\t+stsd\n");

    printf("\t\t\t\t\t\t\tnumber of entries: %u\n",

           trak->mdia.minf.stbl.stsd.number_of_entries);

    

    // printf("\t\t\t\t\t\t+stts: time to sample\n");

    // printf("\t\t\t\t\t\t\tentries:\n\t\t\t\t\t\t\t");

    // for(int i =0; i < trak->mdia.minf.stbl.stts.number_of_entries; ++i){

    //     printf("%15u ", trak->mdia.minf.stbl.stts.time_to_sample_table[i]);

    // }

    // printf("\n");

    // printf("\t\t\t\t\t+stss:关键帧\n");

    // printf("\t\t\t\t\t\t\tentries:\n\t\t\t\t\t\t\t");

    // for(int i =0; i < trak->mdia.minf.stbl.stss.number_of_entries; ++i){

    //     printf("%15u ", trak->mdia.minf.stbl.stss.sync_sample_table[i]);

    // }

    // printf("\n");

    printf("\t\t\t\t\t\t+stsc:sample to chunk table\n");

    printf("\t\t\t\t\t\tfirst trunk:\tsamples-per-thunk:\tsample-description-ID\n");

    for(int i = 0; i < trak->mdia.minf.stbl.stsc.map_amount; ++i){

        printf("\t\t\t\t\t\t%13d", trak->mdia.minf.stbl.stsc.scmap[i].first_chunk_num);

        printf("\t%13d", trak->mdia.minf.stbl.stsc.scmap[i].sample_amount_in_cur_table);

        printf("\t%13d\n", trak->mdia.minf.stbl.stsc.scmap[i].sample_description_id);

    }   printf("\n");

    printf("\t\t\t\t\t\t+%s\n", "stsz");

    printf("\t\t\t\t\t\t\tsmple_size_table:\n\t\t\t\t\t\t");

    for(int i = 0; i < trak->mdia.minf.stbl.stsz.table_size; ++i){

        printf("%8u ", trak->mdia.minf.stbl.stsz.sample_size_table[i]);

    }   printf("\n");

    printf("\t\t\t\t\t\t+stco\n");

    printf("\t\t\t\t\t\tchunk offset:\n\t\t\t\t\t");

    for(int i = 0 ; i < trak->mdia.minf.stbl.stco.chunk_offset_amount; ++i){

        printf("%8u ",trak->mdia.minf.stbl.stco.chunk_offset_from_file_begin[i]);

    }

}

uint32_t get_sample_num_in_cur_chunk(const struct mp4_stsc_box & box,

                                     const uint32_t chunk_index)  //begin from 0
{

    int sample_num_in_cur_chunk_ = 0;

    

    for(int i = 0; i < box.map_amount; ++i) {

        if(i+1 == box.map_amount){

            //std::cout<<"chunk_index:"<<chunk_index<<std::endl;
                

            sample_num_in_cur_chunk_

                = box.scmap[i].sample_amount_in_cur_table;

        }

        if(chunk_index+1 >= box.scmap[i].first_chunk_num

           && chunk_index+1 < box.scmap[i+1].first_chunk_num){

            sample_num_in_cur_chunk_

                =  box.scmap[i].sample_amount_in_cur_table;

            

                 break;

        }

    }

    

    //std::cout<<"sample_num_in_cur_chunk_:"<< sample_num_in_cur_chunk_;
    

    return sample_num_in_cur_chunk_;

}

/*@a return index from 0*/

uint32_t get_sample_index(const struct mp4_stsc_box &box,

                          const uint32_t chunk_index)  //[1,end)
{

    /*chunk   samples   id

      1         8        1

      2         7        1

      46        6        1

    */

    uint32_t me     = chunk_index;

    uint32_t sindex = 0;

    

    for(int i = 0; i < box.map_amount; ++i) {

        uint32_t chunk_amount = 0;

        uint32_t curr         = box.scmap[i].first_chunk_num;

        

        if(i+1 == box.map_amount){ //end() , we can't have next one to index
            chunk_amount = me - curr;  //do not add ONE
            sindex       += box.scmap[i].sample_amount_in_cur_table * chunk_amount;

            break;

        }

        uint32_t next    = box.scmap[i + 1].first_chunk_num;

        if(me > curr){

            if(me < next){

                chunk_amount = me - curr;  //do not add ONE
                sindex       += box.scmap[i].sample_amount_in_cur_table * chunk_amount;

                break;

            }else{

                chunk_amount = next - curr;  //do not add ONE
                sindex       += box.scmap[i].sample_amount_in_cur_table * chunk_amount;

            }

        } else if(me == curr){

            break;

        }

    }

    return sindex;

}

uint32_t get_sample_size(const struct mp4_stsz_box &box,

                         const uint32_t chunk_index)  //[0, end)
{

    for(int i = 0; i < box.table_size; ++i) {

        if(chunk_index == i)

            return box.sample_size_table[i];

    }

}

void copy_chunk_data(FILE *fin, 

                     const struct mp4_stbl_box &box,

                     const uint32_t chunk_index,  //[0, end)
                     FILE *fout)

{

    fseek(fin, box.stco.chunk_offset_from_file_begin[chunk_index],

          SEEK_SET);

    

    uint32_t sample_num_in_cur_chunk_

        = get_sample_num_in_cur_chunk(box.stsc, chunk_index);  //@a mark
    uint32_t sample_index_

        = get_sample_index(box.stsc, chunk_index+1);

    printf("%x\tindex=%u\t",

           box.stco.chunk_offset_from_file_begin[chunk_index],

           sample_index_);

    for(int i = 0; i < sample_num_in_cur_chunk_; ++i) {

        uint32_t sample_size_ = get_sample_size(box.stsz, sample_index_+i);

        std::cout<<sample_size_<<std::endl;

        uint32_t NALU_size  = 0;

        uint32_t NALU_total = 0;

        

        while(NALU_total < sample_size_){

            NALU_size           = read_uint32_lit(fin);

            NALU_total          += NALU_size+4;

            printf("\tNALU_size:%x\n", NALU_size);

            

            char *ptr           = new char [NALU_size];

            fread(ptr, NALU_size, 1, fin);

            

            static uint32_t one = 1 << 24;

            fwrite(&one, sizeof(one), 1, fout);

            fwrite(ptr, NALU_size, 1, fout);

            

            delete [] ptr;

            NALU_size           = 0;

        }

    }

}

void make_file(FILE *fin, const struct mp4_trak_box * trak, std::string name)

{

    

    int chunk_offset_amount    = trak->mdia.minf.stbl.stco.chunk_offset_amount;

    
#if RELEASE

    struct mp4_avc1_box * avc1 =

        trak->mdia.minf.stbl.stsd.sample_description[0].avc1;

    

    name                       += "x";

    FILE *fout                 = fopen(name.c_str(), "w");

    if(!fout){

        std::string tmp        = "fopen_" + name ;

        perror(tmp.c_str());

    }

    

    if(avc1 != 0){

        uint32_t one           = 1 << 24;

        fwrite(&one, sizeof(one), 1, fout);

        

        struct mp4_avcC_box * avcC = avc1->avcC;

        fwrite(avcC->sps[0].sequenceParameterSetNALUnit,

               avcC->sps[0].sequenceParameterSetLength, 1, fout);

        fwrite(&one, sizeof(one), 1, fout);

        fwrite(avcC->pps[0].pictureParameterSetNALUnit,

               avcC->pps[0].pictureParameterSetLength, 1, fout);

    }

    for(int chunk_index = 0 ; chunk_index < chunk_offset_amount;

        ++chunk_index) {

        copy_chunk_data(fin, trak->mdia.minf.stbl, chunk_index, fout);

    }

    

    fclose(fout);
#else

    

    system(std::string("rm -rf " + name).c_str());

    system(std::string("mkdir "  + name).c_str());

    

    for(int chunk_index = 0 ; chunk_index < chunk_offset_amount;

        ++chunk_index) {

        char char_num[10];

        sprintf(char_num, "%u", chunk_index);

        

        FILE *fout =

            fopen(std::string(name + "/" + name + char_num).c_str(), "w");

        

        if(fout == (FILE*)0){

            printf("error\n");

            std::exit(-1);

        }

        

        copy_chunk_data(fin, trak->mdia.minf.stbl, chunk_index, fout);

        fclose(fout);

    }
#endif

}

int main(){

    std::ios_base::sync_with_stdio(true);

    std::string luo   = "luohunshidai01_001.mp4";

    std::string _600  = "6004501011.mp4";

    
//    FILE *fin       = fopen(luo.c_str(), "r");
    FILE *fin         = fopen(_600.c_str(), "r");

    //FILE *f_video   = fopen("video", "w+");

    //FILE *f_audio   = fopen("audio", "w+");
    

    if(fin == (FILE*)0){

        printf("failed to open\n");

        return 0;

    }

    

    //level 0
    int cur_pos       = ftell(fin);

    for(; !feof(fin); ) {

        fseek(fin, cur_pos, SEEK_SET);

        printf("----------------------------------------level 0\n");

        cur_pos += mp4_read_root_box(fin);

    }

    //print_trak(moov.trak[0]);

    //print_trak(moov.trak[1]);

    make_file(fin, moov.trak[0], ("video"));
//    make_file(fin, moov.trak[1], ("audio"));

    return 0;

}

//filename mp4_boxes.h

#ifndef MP4_BOXES_H

#define MP4_BOXES_H

#include <vector>

#include <inttypes.h>

static union ____indian_swap{

    unsigned char byte[4];

    unsigned int size;

}indian_a , indian_b;

unsigned read_uint16_big(FILE *f)

{

    unsigned short k = 0;

    fread(&k, sizeof(k), 1, f);

    return k;

}

uint16_t read_uint16_lit(FILE *f)

{

    uint16_t k;

    fread(&k, sizeof(k), 1, f);

    return ((k&0xff00) >> 8)|((k&0xff) << 8);

}

unsigned char read_uint8(FILE *f)

{

    unsigned char x;

    fread(&x, sizeof(x), 1, f);

    return x;

}

int read_uint32_lit(FILE *f){

    int k = 0;

    fread(&k, sizeof(k), 1, f);

    indian_a.size = k;

    for(int i = 0, j = 3; i < 4; i++, j--)

        indian_b.byte[i] = indian_a.byte[j];

    

    return indian_b.size;

}

#ifndef MP4_BASE_BOX
#define MP4_BASE_BOX                            \

    uint32_t type;                              \

    uint32_t  size;
#endif

#ifndef MP4_FULL_BOX
#define MP4_FULL_BOX                            \

    MP4_BASE_BOX;                               \

    uint8_t version;                            \

    uint8_t flags[3]
#endif

#ifndef MP4_SAMPLE_ENTRY_FIELDS
#define MP4_SAMPLE_ENTRY_FIELDS                    \

    MP4_BASE_BOX;                                \

    char reserved[6];                            \

    uint16_t data_reference_index;
#endif

#ifndef VISUAL_SAMPLE_ENTRY_FIELDS
#define VISUAL_SAMPLE_ENTRY_FIELDS                \

    MP4_SAMPLE_ENTRY_FIELDS;                    \

    uint16_t      pre_defined;                  \

    uint16_t      reserved1;                    \

    uint32_t      pre_defined1[3];              \

    uint16_t      width;                        \

    uint16_t      height;                       \

    uint32_t      horiz_res;                    \

    uint32_t      vert_res;                     \

    uint32_t      reserved2;                    \

    /**/uint16_t  frames_count;                 \

    /*以下是AVCDecoderConfigurationRecord*/     \

    /**/char      compressor_name[33];          \

    /**/uint16_t  bit_depth;                    \

    /**/int16_t   pre_defined2
#endif

struct mp4_box{

    MP4_BASE_BOX;

};

struct mp4_avcC_box{

    uint32_t      size;

    uint32_t      type;

    uint8_t       configurationVersion;      //=1
    uint8_t       AVCProfileIndication;

    uint8_t       profile_compatibility;

    uint8_t       AVCLevelIndication;

    

    uint8_t       lengthSizeMinusOne;        // & 0x3,  ==2 bit
    uint8_t       numOfSequenceParameterSet; // & 0x1F  ==5bit
    struct SPS{

        uint16_t  sequenceParameterSetLength;

        uint8_t   *sequenceParameterSetNALUnit;

    }             *sps;

    uint8_t       numOfPictureParameterSets;

    struct PPS{

        uint16_t  pictureParameterSetLength;

        uint8_t   *pictureParameterSetNALUnit;

    }             *pps; 

};

struct mp4_avc1_box {

    VISUAL_SAMPLE_ENTRY_FIELDS;

    struct mp4_avcC_box *avcC;

    struct mp4_btrt_box *btrt;

    /*ext descriptors */

    struct mp4_m4ds_box *m4ds;

};

struct mp4_tkhd_box {

    MP4_FULL_BOX;

    uint32_t creation_time;

    uint32_t modification_time;

    uint32_t track_ID;

    uint32_t reserved1;

    uint32_t duration;

    uint32_t reserved2[2];

    uint16_t layer;

    uint16_t alternate_group;

    uint16_t volume;

    uint16_t reserved3;

    uint32_t matrix[9];

    uint32_t width;

    uint32_t height;

};

struct editList{

    uint32_t trak_duration;

    uint32_t duration;

    uint32_t rate;

};

struct mp4_elst_box{

    MP4_FULL_BOX;

    uint32_t amount;

    editList *edit_list;

};

struct mp4_mdhd_box {

    MP4_FULL_BOX;

    uint32_t creation_time;

    uint32_t modification_time;

    uint32_t timescale;

    uint32_t duration;

    uint16_t language;

    uint16_t pre_defined;

};

struct mp4_vmhd_box{

    MP4_FULL_BOX;

    uint32_t graphics_mode;

    uint8_t opcolor[4];  //==============take care
};

struct mp4_dref_box{

    MP4_FULL_BOX;

    uint32_t entry_count;

    //there are many urls

    //======================================
};

struct mp4_list_t{

    uint32_t first_chunk_num;

    uint32_t sample_amount_in_cur_table;

    uint32_t sample_description_id;

};

struct mp4_stsc_box{  //Sample-to-Chunk Atoms
    MP4_FULL_BOX;

    uint32_t map_amount;

    mp4_list_t *scmap; //sample-to-trunk表的结构
};

struct mp4_stsz_box{  //sample size
    MP4_FULL_BOX;

    uint32_t samples_size_intotal;

    uint32_t table_size;  // 全部sample的数目。如果所有的sample有相同的长度,这个字段就是这个值。

                                // 否则,这个字段的值就是0。那些长度存在sample size表中
    uint32_t *sample_size_table;  //多个sample的大小相加就是整个电影的长度
};

struct mp4_stco_box{  //Chunk Offset
    MP4_FULL_BOX;

    uint32_t chunk_offset_amount;

    uint32_t *chunk_offset_from_file_begin;

};

struct mp4_stss_box{  //Sync Sample 
    MP4_FULL_BOX;

    uint32_t number_of_entries;

    uint32_t *sync_sample_table;

};

struct mp4_stts_box{  //Time-to-Sample
    MP4_FULL_BOX;

    uint32_t number_of_entries;

    uint32_t *time_to_sample_table;

};

#ifndef MP4_SAMPLE_ENTRY_FIELDS
#define MP4_SAMPLE_ENTRY_FIELDS                    \

    MP4_BASE_BOX;                                \

    char     reserved[6];                       \

    uint16_t data_reference_index;
#endif

struct mp4_mp4a_box{

};

struct Sample_description{

    uint32_t            size;

    uint32_t            type;

    struct mp4_avc1_box *avc1;

    struct mp4_mp4a_box *mp4a;

    //利用这个索引可以检索与当前sample description关联的数据。

    //数据引用存储在data reference atoms。
};

struct mp4_stsd_box{

    MP4_FULL_BOX;                           //12 bytes
    uint32_t            number_of_entries;  //4 bytes
    Sample_description *sample_description;

};

struct mp4_smhd_box{  //sound media header box
    MP4_FULL_BOX;

    uint16_t            balance;

    uint16_t            reserved;

};

struct mp4_hdlr_box {

    MP4_FULL_BOX;

    uint32_t       pre_defined;

    uint8_t        handler_type[5];

    uint32_t       reserved[3];

    char           *name;  //end with '\0'
};

/* 14496-12 8.2, media data container */
struct mp4_mdat_box {

    MP4_BASE_BOX;

    uint64_t data_size;

    char     *data;

};

struct mp4_mvhd_box{

    MP4_FULL_BOX;                //12
    uint32_t creation_time;      //4
    uint32_t modification_time;  //4
    uint32_t timescale;          //4
    uint32_t duration;           //4
    uint32_t rate;               //4
    uint16_t volume;             //2
    uint16_t reserved1;          //2
    uint32_t reserved2[2];       //8
    uint32_t matrix[9];          //36
    uint32_t pre_defined[6];     //24
    uint32_t next_track_id;      //4
};

struct mp4_iods_box{

};

struct mp4_udta_box{

};

struct mp4_dinf_box{

};

struct mp4_stbl_box{

    struct mp4_stsd_box stsd;

    struct mp4_stts_box stts;

    struct mp4_stss_box stss;

    struct mp4_stsc_box stsc;

    struct mp4_stsz_box stsz;

    struct mp4_stco_box stco;

};

struct mp4_minf_box{

    MP4_BASE_BOX;

    struct mp4_vmhd_box *vmhd;

    struct mp4_smhd_box *smhd;

    struct mp4_hdlr_box hdlr;

    struct mp4_dinf_box dinf;

    struct mp4_stbl_box stbl;

};

struct mp4_mdia_box{

    MP4_BASE_BOX;

    struct mp4_mdhd_box mdhd;

    struct mp4_hdlr_box hdlr;

    struct mp4_minf_box minf;

};

struct mp4_edts_box{

};

struct mp4_trak_box{

    struct mp4_tkhd_box tkhd;

    struct mp4_mdia_box mdia;

    struct mp4_edts_box edts;

    struct mp4_udta_box udta;

};

struct mp4_moov_box{

    MP4_BASE_BOX;

    struct mp4_mvhd_box mvhd;

    struct mp4_iods_box iods;

    std::vector<struct mp4_trak_box *>

                        trak;

    struct mp4_udta_box udta;

};

#endif  //MP4_BOXES_H
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: