传送门:MP4 文档 P32页
I 帧是一个视频解码的关键,当视频进行 seek 操作和清晰度切换,首先就要找到当前时间点附近的 I 帧,只有拿到 I 帧才能开始解码。所以这个 Box 可以说挺简单的,里面存的数据是对应 Sample 的 I 帧。当然音频是不存在这个 Box 的。
这里存放的就是对应是 I 帧的 Sample。
其中该 Box 是 Full Box,后面有四字节的 version 和 flag 字段,其中 flag 默认值用0,这里分析略过,这里就直接解析 Data 的字段。
字段 | 大小 | 实际值(16进制) | 含义 |
---|---|---|---|
entry count | 4 | 00 00 00 2E | 关键帧的sample个数 |
sample count | 4 | 关键帧sample序号 |
// BaseBox.h
// ...
// 其他 Box 的定义
class TimeStssBox : public BaseBox{
public:
Timebyte version = 0;
Timebyte flags = 0;
unsigned int *IFrames = nullptr;
unsigned int entry_count = 0; // 关键帧的sample个数
TimeStssBox(BoxHeader h, Timebyte * d): BaseBox(h, d){};
~TimeStssBox();
void CheckIFrame();
};
实现
// TimeStssBox.cpp
TimeStssBox::~TimeStssBox() {
if (IFrames) {
delete[] IFrames;
IFrames = nullptr;
}
}
void TimeStssBox::CheckIFrame() {
printf("===========================\n");
h.to_string();
TimeBufferStream bufferStream(data, h.GetDataSize());
bufferStream.GetUInt(); // flag version
entry_count = bufferStream.GetUInt();
IFrames = new unsigned int[entry_count];
for (int i = 0; i < entry_count; ++i) {
IFrames[i] = bufferStream.GetUInt();
}
}