ZigZag Sin
登 陆
上一篇:esds Box 下一篇:ctts Box

stts Box

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

具体 Box 分析

Stts Box

官方定义

image-20211229220050150

传送门:MP4 文档 P32页

介绍

这个 Box 是记录每一次采样出来的 sample 的时间,也可以理解为解码当前 sample 的解码时间DTS,所以这个 Bos 主要是用来找到任意时间的 sample。Stts Box 这个表格有两项值,其中一项是连续的样点数目即 sample count 和样点相对时间差值,即 sample delta 即表格中每个条目提供了在同一个时间偏移量里面连续的 sample 序号以及 sample 偏移量。

Sample delta简单可以理解为当前这个 sample 的时长,也就是采样了一次过后多久再采样一次,所以把全部 sample 的 sample delta 加起来就是当前这个 track 的总时长。

大家把这个时间理解为该帧数据当前的解码时间即可,计算公式:

DT(n+1) = DT(n) + STTS(n)

工具分析

image-20211229221249785

从上面图可以看出,第一个 sample 默认是从0开始,也就是说第一个 sample 的 Dts 是0,根据公式所以第二个 sample 第一个的 Dts = 0 + 413 = 413。同理第三个 sample 的 Dts 就是 413 + 416 = 829。

我们在 mdhd box 里面可以获取到 Time scale,也就是可以把1s划分为多少个单位,这个MP4文件的 Time scale 是6000,所以一秒钟有6000个单位,第二个 sample Dts = 413,所以经过413个单位就解码第二个sample。

如果sample count 不为1时,相当于有多个 sample 的采样间隔时间是一样的。如果 sample count 数量只有一个的话说明这个 MP4 是固定帧率。

音频 Stts box

image-20211229222118470

音频有1495个采样,每一个采样1024个时间单位,这里音频的 Time scale 是48000。

1495 * 1024 = 1530880

1530880 / 48000 = 31.893333333333334

所以音频时长 31.89秒

image-20211229222458000

image-20211229223700437

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

字段大小实际值(16进制)含义
entry count400 00 04 FD描述了下面采样 sample 的信息个数
sample count4 连续相同时间长度sample delta的sample个数。
sample delta4 每个sample delta即以timescale为单位的时间长度。

代码定义

// BaseBox.h  

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

class TimeSttsBox : public BaseBox {
public:
    Timebyte version = 0;
    Timebyte flags = 0;

    unsigned int entry_count = 0;
    unsigned int sample_count = 0;
    unsigned int sample_delta = 0;

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

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

实现

// TimeSttsBox.cpp

void TimeSttsBox::PrintDataInfo() {
    TimeBufferStream timeBufferStream(data, h.GetDataSize());
    version = timeBufferStream.GetUChar();
    timeBufferStream.GetLenData(&flags, 3);
    entry_count = timeBufferStream.GetUInt();
    sample_count = timeBufferStream.GetUInt();
    sample_delta = timeBufferStream.GetUInt();

    printf("===========================\n");
    h.to_string();
    allSample = sample_count;
    allDelta = sample_count * sample_delta;
    printf("entry_count: %d\n", entry_count);
    if (entry_count == 1) {
        // 如果为1 要么是固定帧率的视频  或者 是音频
        printf("sample_count: %d\n", sample_count);
        printf("sample_delta: %d\n", sample_delta);
        printf("all Delta: %ud\n", allDelta);

    } else {
        for (int i = 0; i < entry_count; ++i) {
            sample_count = timeBufferStream.GetUInt();
            sample_delta = timeBufferStream.GetUInt();
            allSample += sample_count;
            allDelta += sample_delta * sample_count;
        }
        printf("all Sample: %ud\n", allSample);
        printf("all Delta: %ud\n", allDelta);

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