传送门:MP4 文档 P19页
mdia Box 可以看到官方的定义也是一个比较简单的 Box 相当于一个分隔符,重要的信息都在 Data 区,里面包含了一些重要的 Box,所以该 Box 是 Full Box,关于这个 Box 比较简单就不会花太多篇幅进行解析。
名称 | 大小(byte) | 意义 | 说明 |
---|---|---|---|
Box length | 4 | Box 整体的大小 | 包含 Header 和 Data部分 |
Box type | 4 | ”mdia”的ASCII码,表明是 mdiaBox | box 属性值,通常是固定值 |
名称 | 实际值(16进制) | 具体值(10进制 / ASCII) | 字段位置 |
---|---|---|---|
Box length | 00 00 6B EA | 27626 | Header |
Box type | 6D 64 69 61 | "mdia" | Header |
Data | ... |
// BaseBox.h
// ...
// 其他 Box 的定义
class TimeMdiaBox : public BaseBox {
public:
TimeMdiaBox(BoxHeader h);
TimeMdiaBox(BoxHeader h, Timebyte * d): BaseBox(h, d){};
void AnalyzeData() override;
void AnalyzeBoxHeader(BoxHeader header, size_t offset) override;
};
实现
// TimeMdiaBox.cpp
TimeMdiaBox::TimeMdiaBox(BoxHeader h) : BaseBox(h) {
if (h.GetDataSize()) {
data = new Timebyte[h.GetDataSize()];
}
}
void TimeMdiaBox::AnalyzeData() {
printf("===========================\n");
h.to_string();
size_t offset = 0;
for (;;) {
BoxHeader header;
memcpy(header._h_size, data + offset, 4);
memcpy(header._h_type, data + offset + 4, 4);
if (header.GetType() == MDHD) {
// printInfo
} else if (header.GetType() == HDLR) {
// printInfo
} else if (header.GetType() == MINF) {
// Analyze
TimeMinfBox timeMinfBox(header, data + offset + 8);
timeMinfBox.AnalyzeData();
}
offset += header.GetSize();
if (offset >= h.GetSize() - 8) break;
}
}
void TimeMdiaBox::AnalyzeBoxHeader(BoxHeader header, size_t offset) {
if (header.GetType() == MINF) {
printf("===========================\n");
header.to_string();
}
if(header.GetType() == MDHD) {
// pass
}
if(header.GetType() == HDLR) {
// pass
}
}
这里我们看到它的子 Box,就添加一下 Header 和 Box_Type
enum BOX_TYPE{
FTYP,
MOOV,
MVHD,
TRAK,
LODS,
TKHD,
MDIA,
// 添加3个新的Box类型
MDHD,
HDLR,
MINF,
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]=='d'&&_h_type[2]=='a'&&_h_type[3]=='t') return MDAT;
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;
else if (_h_type[0]=='m'&&_h_type[1]=='d'&&_h_type[2]=='h'&&_h_type[3]=='d') return MDHD;
else if (_h_type[0]=='h'&&_h_type[1]=='d'&&_h_type[2]=='l'&&_h_type[3]=='r') return HDLR;
else if (_h_type[0]=='m'&&_h_type[1]=='i'&&_h_type[2]=='n'&&_h_type[3]=='f') return MINF;
return ERROR;
}
};
最后再修改一下 父Box TimeTrakBox.cpp
// TimeTrakBox.cpp
void TimeTrakBox::AnalyzeBoxHeader(BoxHeader header, size_t offset) {
if (header.GetType() == TKHD) {
TimeTkhdBox* timeTkhdBox = new TimeTkhdBox(header, data + offset + 8);
timeTkhdBox->PrintDataInfo();
PushBox(timeTkhdBox);
}
if (header.GetType() == MDIA) {
printf("===========================\n");
header.to_string();
TimeMdiaBox *timeMdiaBox = new TimeMdiaBox(header, data + offset + 8);
timeMdiaBox->Analyze(); // 这个Box类似分隔符 所以就直接解析他的Data数据就行
PushBox(timeMdiaBox);
}
}