ZigZag Sin
登 陆
上一篇:mvhd Box 下一篇:tkhd Box

trak Box

Time
2022-2-21 11:39 阅读 322

具体 Box 分析

Trak Box

官方介绍定义

image-20211218162912212

传送门:MP4 文档 P16页

介绍

这个 Box 根据官方定义发现也挺简单的,就一个 Header 和 Data ,也可以相当于一个分隔符,类似 Moov Box,在 Data 里面就包含了很多子 Box,根据里面的子 Box 信息,我们可以看到这是 Video Track 还是 Audio Track。Trak Box这里自身只是一个分界符,属于 Container Box,所以它只有 Box Header。

字段分析:

名称大小(byte)意义说明
Box length4Box 整体的大小包含 Header 和 Data部分
Box type4”trak”的ASCII码,表明是 trak Boxbox 属性值,通常是固定值
Box DataBox length - 8具体数据数据里面包含的是子Box

工具分析:

用16进制工具查看:

image-20211218163550425

再用 MP4 info查看

image-20211218163941507

发现子 Box 里面有 tkhd box 和 mdia box,这里就直接看下面代码定义部分。

代码定义:

// BaseBox.h  

enum BOX_TYPE{
    FTYP,
    MOOV,
        MVHD,
        TRAK,
    	// 添加2个新的Box类型
    		TKHD,
            MDIA,
        LODS,
    UUID,
    MDAT,
    ERROR
};

struct BoxHeader{
    
    // ...
    // 其他不变
    
    BOX_TYPE GetType() {
        if(_h_type[0]=='f'&&_h_type[1]=='t'&&_h_type[2]=='y'&&_h_type[3]=='p') return FTYP;
        else if (_h_type[0]=='m'&&_h_type[1]=='o'&&_h_type[2]=='o'&&_h_type[3]=='v') return MOOV;
        else if (_h_type[0]=='m'&&_h_type[1]=='v'&&_h_type[2]=='h'&&_h_type[3]=='d') return MVHD;
        else if (_h_type[0]=='t'&&_h_type[1]=='r'&&_h_type[2]=='a'&&_h_type[3]=='k') return TRAK;        
        else if (_h_type[0]=='t'&&_h_type[1]=='k'&&_h_type[2]=='h'&&_h_type[3]=='d') return TKHD;
        else if (_h_type[0]=='m'&&_h_type[1]=='d'&&_h_type[2]=='i'&&_h_type[3]=='a') return MDIA;
        return ERROR;
    }
};


// ...
// 其他 Box 的定义

class TimeTrakBox : public BaseBox{
public:
    TimeTrakBox(BoxHeader h);
    TimeTrakBox(BoxHeader h, Timebyte * d): BaseBox(h, d){};
    void AnalyzeBoxHeader(BoxHeader header, size_t offset) override; // 这里要解析data数据的子box所以要重写方法
};

实现

// TimeTrakBox.cpp

TimeTrakBox::TimeTrakBox(BoxHeader h) : BaseBox(h) {
    if (h.GetSize()) {
        data = new Timebyte[h.GetSize()];
    }
}

void TimeTrakBox::AnalyzeBoxHeader(BoxHeader header, size_t offset) {
    if (header.GetType() == TKHD) {
		printf("===========================\n");
        header.to_string();
    }
    if (header.GetType() == MDIA) {
        printf("===========================\n");
        header.to_string();
    }

}

Trak Box 我们定义好了,这里我们回到 Moov Box 去修改一下它的解析 Data 的代码

// TimeMoovBox.cpp

// ...
// 其他不变

void TimeMoovBox::AnalyzeBoxHeader(BoxHeader header, size_t offset) {
    if (header.GetType() == MVHD) {
        TimeMvhdBox* timeMvhdBox = new TimeMvhdBox(header, data + offset + 8);
        timeMvhdBox->PrintDataInfo();
        PushBox(timeMvhdBox);
    }
    if (header.GetType() == TRAK) {
        printf("===========================\n");
        header.to_string();
        TimeTrakBox* timeTrakBox = new TimeTrakBox(header, data + offset + 8);
        timeTrakBox->Analyze();
        PushBox(timeTrakBox);
    }
}

最后把我们运行测试的代码再简单修改一下

void TimeMP4::LodingBox() {
    if(!file) return;
    
    while (!feof(file)) {
        BoxHeader header;
        unsigned int len;
        fread(header._h_size, 1, 4, file);
        fread(header._h_type, 1, 4, file);
        if(header.GetSize() == 1) {
            len = 16;
        }else if(header.GetSize() == 0) {
            break;
        }
        len = 8;

        if(header.GetType() == FTYP) {
            ftyBox = new TimeFTYBox(header);
            fread(ftyBox->GetData(),1,header.GetSize()-len, file);
            
        }}else if(header.GetType() == MOOV) {
            moovBox = new TimeMoovBox(header);
            fread(moovBox->GetData(),1,header.GetSize()-len, file);

        }else {
            if(header.GetSize() >> 31) {
#ifdef _WINDOWS
                _fseeki64(file, header.GetSize()-len, 1);
#endif
#ifdef __APPLE__
                fread(nullptr, 1, header.GetSize()-len, file);
#endif
            }else {
                fseek(file, header.GetSize()-len, 1);
            }
        }

    }
}

void TimeMP4::test() {
    if(ftyBox) {
        ftyBox->PrintDataInfo();
    }
    if(moovBox) {
        moovBox->Analyze();
    }
}

最后运行测试

image-20211218165519804

上一篇:mvhd Box 下一篇:tkhd Box
给我买个键盘吧。。。求打赏。。。
欢迎加群,一起交流~~~