ZigZag Sin
登 陆
上一篇:stts Box 下一篇:stss Box

ctts Box

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

具体 Box 分析

Ctts Box

官方定义

image-20211229224106030

image-20211229224310946

传送门:MP4 文档 P26页

介绍

该 Box 记录的是每个 sample 的 Composition time 和 Decode time 之间的差值,这里通过 Composition Time 就可以计算出 Sample 的 PTS。所以要先解析完 Stts Box 获取到对应 sample 的 DTS 后解析这个 Box 获取到 Sample 的 PTS。

当视频不存在 B 帧的情况下 PTS 是等于 DTS 的,所以不含 B 帧的视频文件也就没有 Ctts Box,同样音频也没有 Ctts Box。

工具分析

image-20211229224513575

根据上文解析的 Stts Box 里面的 DTS,只要在对应的 Sample count 的 DTS 加上当前这个 Sample offset 就是PTS了。

上图箭头标注的 Sample count 为2,说明第3个 sample 和第4个 sample 的 Sample offset 是一样的。

其中该 Box 是 Full Box,后面有四字节的 version 和 flag 字段,其中 flag 默认值用0,这里分析略过,这里就直接解析 Data 的字段。

image-20211229225201302

字段大小实际值(16进制)含义
entry count400 00 04 FB描述了下面采样 sample 的信息个数
sample count4 连续相同 offset 的sample个数。
sample offset4 DTS和PTS之间的偏移量

我们结合 stts box 进行分析即可以得到前面5个 sample 的 DTS 和 PTS:

Sample num12345
sample delta413416418417832
sample offset14891492149314931908
DTS0413416+413=829829+418=12471247+417=1664
PTS14891905232227403572

使用雷神软件分析比对前5个 sample 的 PTS,发现一样。

image-20211229230854986

代码定义

// BaseBox.h  

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

class TimeCttsBox : public BaseBox {
public:
    Timebyte version = 0;
    Timebyte flags = 0;
    unsigned int entry_count = 0;
    unsigned int sample_count = 0;
    unsigned int sample_offset = 0; // CT和DT之间的offset。

    ///// 这里的数据不在data数据区里面
    unsigned int allSample = 0;
    unsigned int allOffset = 0;
    ///// =========================

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

实现

// TimeCttsBox.cpp

void TimeCttsBox::PrintDataInfo() {
    TimeBufferStream timeBufferStream(data, h.GetDataSize());
    version = timeBufferStream.GetUChar();
    timeBufferStream.GetLenData(&flags, 3);
    entry_count = timeBufferStream.GetUInt();
    sample_count = timeBufferStream.GetUInt();
    sample_offset = timeBufferStream.GetUInt();
    allSample = sample_count;
    allOffset = sample_count;
    for (int i = 0; i < entry_count; ++i) {
        sample_count = timeBufferStream.GetUInt();
        sample_offset = timeBufferStream.GetUInt();
        allSample += sample_count;
        allOffset += sample_offset * sample_count;
    }
    printf("===========================\n");
    h.to_string();
    printf("all Sample: %ud\n", allSample);
    printf("all Offset: %ud\n", allOffset);
}
上一篇:stts Box 下一篇:stss Box
给我买个键盘吧。。。求打赏。。。
欢迎加群,一起交流~~~