ZigZag Sin
登 陆
上一篇:trak Box 下一篇:mdia Box

tkhd Box

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

具体 Box 分析

tkhd Box

官方介绍定义

image-20211218191306712

传送门:MP4 文档 P18页

介绍

tkhd Box 里面包含了当前的 Track 的媒体整体信息,包括时长、图像的宽度和高度等,同时该 Box 是 Full Box。

字段分析:

名称大小(byte)意义说明
Box length4Box 整体的大小包含 Header 和 Data部分
Box type4”trak”的ASCII码,表明是 trak Boxbox 属性值,通常是固定值
version1box版本,0或1一般为0
flags3
creation time4当前Track创建时间1904-01-01零点开始
modification time4当前Track修改时间1904-01-01零点开始
track ID4该Track的id
reserve4保留位4字节
duration4该 Track 的时长,需要和时间戳进行一起计算
reserver8保留位8字节
layer2视频层,值小的在上层
alternate group2track分组信息,表示该track和其它track没有建立群组关系一般默认为0
volume2播放此track的音量1.0为正常音量
reserver2保留位2字节
matrix36视频变换矩阵
width4则表示图像的宽度video track
height4则表示图像的高度video track

工具分析:

用16进制工具查看,后面标记的 tkhd box 的内容,发现是紧接在 trak box 后面,如图:

image-20211218192608048

具体值(Video Track):

名称实际值(16进制)具体值(10进制 / ASCII)字段位置
Box length00 00 00 5C92Header
Box type74 6B 68 64"tkhd"Header
version000Header
flags00 00 011Header
creation timeDA 25 22 453659866693Data
modification timeDA 25 22 453659866693Data
track ID00 00 00 011Data
reserve00 00 00 00 Data
duration00 1D 33 A11913761Data
reserver00 ... Data
layer00 00 Data
alternate group00 00 Data
volume00 00video track 0Data
reserver00 00 Data
matrix... Data
width00 07 80 001920Data
height00 04 38 001080Data

打开 MP4 Explorer 验证:

image-20211218193852983

符合上面我们得出的数据,下面还有一个 trak box 其中还包含了一个 tkhd box,这个是音频的 trak,这里就不过多分析了,具体分析方法和上面如出一辙,大家可以尝试自己去分析查看对应的字段值。

代码定义:

// BaseBox.h  

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

class TimeTkhdBox : public BaseBox {
public:
    Timebyte version = 0;
    Timebyte flags = 0;
    unsigned int creation_time = 0; // 4 创建时间(相对于UTC时间1904-01-01零点的秒数)

    unsigned int modification_time = 0;// 4 修改时间(相对于UTC时间1904-01-01零点的秒数)

    unsigned int track_ID=0; //4 唯一标识该Track的一个非零值
    unsigned int reserve = 0; // 4 保留位8字节

    unsigned int duration = 0; // 4 该Track的播放时长,需要和时间戳进行一起计算,然后得到播放的时间坐标。

    unsigned long long reserve1 = 0; // 8 保留位8字节

    unsigned short layer=0;// 2 视频层,值小的在上层
    unsigned short alternate_group = 0; // 2 track分组信息,一般默认为0,表示该track和其它track没有建立群组关系
    unsigned short volume = 0; // 2 播放此track的音量,1.0为正常音量

    unsigned char matrix[36] = {0}; // 36 视频变换矩阵

    unsigned int width = 0; // 4 如果该Track为Video Track,则表示图像的宽度(16.16浮点表示)

    unsigned int height = 0; // 4 如果该Track为Video Track,则表示图像的高度(16.16浮点表示)


    TimeTkhdBox(BoxHeader h);
    TimeTkhdBox(BoxHeader h, Timebyte * d): BaseBox(h, d){};
    void PrintDataInfo() override;
};

实现

// TimeTkhdBox.cpp

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

void TimeTkhdBox::PrintDataInfo() {
    printf("===========================\n");
    h.to_string();
    TimeBufferStream bufferStream(data, h.GetDataSize());
    version = bufferStream.GetUChar();
    bufferStream.GetLenData(&flags, 3);
    creation_time = bufferStream.GetUInt();
    modification_time = bufferStream.GetUInt();
    track_ID = bufferStream.GetUInt();
    reserve = bufferStream.GetUInt();
    duration = bufferStream.GetUInt();
    bufferStream.GetLenData(&reserve1, 8);
    layer = bufferStream.GetUShort();
    alternate_group = bufferStream.GetUShort();
    volume = bufferStream.GetUShort();
    bufferStream.GetLenData(matrix, 36);
    width = bufferStream.GetUInt();
    height = bufferStream.GetUInt();

    printf("version:%ud \n", version);
    printf("flags:%ud \n", flags);
    printf("creation_time:%ud \n", creation_time);
    printf("creation_time: ");
    printf("modification_time:%ud \n", modification_time);
    printf("track_ID:%ud \n", track_ID);
    printf("duration:%ud \n", duration);
    printf("layer:%ud \n", layer);
    printf("alternate_group:%ud \n", alternate_group);
    printf("volume:%ud \n", volume);
    printf("width:%ud \n", width);
    printf("height:%ud \n", height);
}

最后修改一下 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();
    }

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