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

moov Box

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

具体 Box 分析

moov Box

官方介绍定义

moov box

image-20211217102850330

传送门:MP4 文档 P14 页

介绍

Moov Box 这个 Box 是我们前文提到的 Container Box,Moov Box 里面的 Data 包含其他的子 Box。在 MP4 文件中必须有但是只有一个的 Moov Box,我们看到上面官方的定义介绍,这个 Box 本身是很简单的,里面没有携带具体 Box 的信息,看下面的结构图,Box Data 区里面的就是各个的 Trak(Video,Audio ......),所以这个 Box 更像是一个分界标识。

字段分析:

名称大小(byte)意义说明
Box length4Box 整体的大小包含 Header 和 Data部分
Box type4”moov”的ASCII码,表明是 moov Boxbox 属性值,通常是固定值
dataBox length - 8具体数据这个Box是Container Box,里面还有好几层子Bo

工具分析:

  • 我们用 MP4 info 打开这个 MP4文件,如图:

image-20211217175357740

​ 我们发现 Moov Box 在最后面,前面还有 uuid box 和 mdat box,这里 uuid box 不是必须的,也不是重要的,这里就不花篇幅进行解析介绍了。还有就是 mdat box,这个 box 里面放的都是音视频的原数据,这里我们先不解析,等把 moov box解析完成后,再回过头去看 mdat box。

  • 这我们再用 16 进制查看,找到 moov box 的位置

image-20211217180205871

​ 上图黑框标志出来的是 box size,红框标注出来的是 moov 的 type 值,也就是对应的是 “moov” ascii码。我们再看到

箭头指向的偏移地址,这里我们验算一遍这个偏移量:

image-20211217180306552

image-20211217180329517

image-20211217180348176

ftyp 的大小 0x18 ,uuid 的大小 0x28,mdat 的大小 0x03<<24|0x68<<16|0x87<<8|0xCD

这里计算后的大小,正好就是 moov box 的偏移量:

image-20211217180715256

接下来我们根据上图16进制查看器展现出来的值进行分析:

定义实际值(16进制)具体值(10进制 / ASCII)字段位置
Box length(4 byte)0x00 0x10 0x8A 0x771084023Header
Box type(4 byte)0x6D 0x6F 0x6F 0x76"moov"Header
Box data(Box length - 4 byte)...... Data

代码定义:

这里我们还要再添加一个需求就是解析 Data 数据里面的子box,那么我们便要重构一下Box Header 和 Base Box 。

// BaseBox.h  

enum BOX_TYPE{
    FTYP,
    MOOV,
    // 添加3个新的Box类型
        MVHD,
        TRAK,
        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;
        return ERROR;
    }
};

class BaseBox{
private:
    std::vector<BaseBox*> boxs; // 这个用来存放子Box容器
protected:
    Timebyte *data = nullptr;

public:
    BoxHeader h;
    BaseBox(BoxHeader h);
    BaseBox(BoxHeader h, Timebyte * d);
    BaseBox(BaseBox &baseBox);
    ~BaseBox();

    Timebyte * GetData() const {return data;};
    
    
    void PushBox(BaseBox *box);
    BaseBox* GetBox(BOX_TYPE type);
    
    void Analyze(); // 解析data数据的方法,子类有需求就重写这个方法
    virtual size_t GetDataOffset() const {return 0;}; // 这个是获取当前box的偏移量后面会讲解到
    virtual void PrintDataInfo() {};
    virtual void AnalyzeBoxHeader(BoxHeader header, size_t offset) {}; // 具体的解析方法,子类要解析data就重写这个方法

};

实现

// BaseBox.cpp

// ...
// 其他的还是没变  就添加了下面的方法

BaseBox *BaseBox::GetBox(BOX_TYPE type) {
    for (auto &item : boxs) {
        if(item->h.GetType() == type) return item;
    }
    return nullptr;
}

void BaseBox::PushBox(BaseBox *box) {
    boxs.push_back(box);
}

void BaseBox::Analyze() {
    size_t offset = GetDataOffset();
    while (1) {
        BoxHeader header;
        memcpy(header._h_size, data + offset, 4);
        memcpy(header._h_type, data + offset + 4, 4);

        AnalyzeBoxHeader(header, offset);
        offset += header.GetSize(); 
        if (offset >= h.GetDataSize()) break;
    }
}

moov box 的定义

// BaseBox.h  

// ... 其他 box 的定义

class TimeMoovBox : public BaseBox{
private:

public:
    TimeMoovBox(BoxHeader h);
    TimeMoovBox(BoxHeader h, Timebyte * d): BaseBox(h, d){};
    ~TimeMoovBox();

    void AnalyzeBoxHeader(BoxHeader header, size_t offset) override;
};

实现

// TimeMoovBox.cpp

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


void TimeMoovBox::AnalyzeBoxHeader(BoxHeader header, size_t offset) {
    if (header.GetType() == MVHD) {
        printf("===========================\n");
        header.to_string();
    }
    if (header.GetType() == TRAK) {
        printf("===========================\n");
        header.to_string();
    }
}

TimeMoovBox::~TimeMoovBox() {

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