stsc 和 stsz 是 mp4 stbl 中依赖上下文的结构化表,不能直接 fread:需先逐层解析 moov→trak→stbl 定位,考虑版本/标志、大小字段逻辑(如 stsz 的 sample_size=0 才有尺寸数组)、字节序及 box 重排,否则必错。

stsc 和 stsz 是什么,为什么不能直接用 fread 读取
MP4 文件中的 stsc(Sample To Chunk)和 stsz(Sample Size)是 stbl(Sample Table)子盒子内的结构化二进制表,不是纯线性数组。它们的字段长度、字节序、数量字段位置都依赖于前面的 stsd、stco/co64 等盒子解析结果,且可能被压缩(如 stsz 的 sample_size == 0 表示所有样本等长,此时实际尺寸需从 stsd 中的编码器信息反推)。直接按固定偏移 fread 会跳过版本/标志位、误判条目数,或在 64 位 chunk offset 场景下错位。
如何定位 stsc/stsz 的起始位置:必须先解析 moov → trak → mdia → minf → stbl
MP4 是树状 box 结构,stsc 和 stsz 必须从 moov 入口逐层向下找,不能靠 magic 字符串暴力搜索(可能出现在 free、mdat 或加密 payload 中)。关键路径是:moov → trak(通常取第一个视频 trak,检查 hdlr 的 handler_type == "vide")→ mdia → minf → stbl。每个 box 头部是 4 字节 size + 4 字节 type,size=1 表示 64 位扩展长度,需额外读 8 字节。
实操建议:
- 写一个通用
parse_box_header(FILE* fp),返回{type, size, is_large},并用fseek跳过 padding - 进入
stbl后,顺序扫描子 box:遇到"stsc"或"stsz"就解析,不要假设固定顺序(标准允许重排) - 注意
stsz可能是stz2(compact size table),它用 4/8/16 位变长编码,需检查field_size字段
stsc 解析难点:chunk 到 sample 的映射不是一一对应
stsc 定义的是“第 N 个 chunk 从第 M 个 sample 开始,连续 K 个 sample 属于该 chunk”。但 chunk 内 sample 数量可变,且同一 chunk 可能跨多个 stsc 条目(因采样率变化或编码分组)。最易错的是:把 first_chunk 当作数组下标直接访问 —— 它是 1-based,且不连续。
正确做法:
- 读出全部
stsc条目后,构建一个按first_chunk排序的 vector,然后对任意目标 chunk ID,用 upper_bound 找到“最后一个first_chunk ≤ target”的条目 -
samples_per_chunk是该 chunk 实际包含的 sample 数,不是全局常量;sample_description_index仅用于关联stsd,多数场景可忽略 - 若需查第 S 个 sample 属于哪个 chunk,得反向遍历
stsc+ 累加samples_per_chunk × (next_first_chunk − current_first_chunk),别硬算公式
stsz 解析时必须区分 sample_size == 0 和 entry_count == 0
stsz 头部有 sample_size(默认大小)和 sample_count。当 sample_size != 0,说明所有 sample 等长,entry_count 为 0,无需后续数据;当 sample_size == 0,才真正有 sample_count 个 32 位 size 条目。常见错误是忽略这个分支,导致把后续的 stco 数据当成 size 数组读烂。
验证技巧:
- 用
ffprobe -v trace input.mp4 2>&1 | grep -A5 stsz看 ffmpeg 实际解析值,比文档更可靠 - 读完
stsz后,用fseek(fp, current_pos, SEEK_SET)回退并检查下一个 box type 是否合理(比如紧接stco或stss) - 对 HEVC 编码,
stsz的 size 值常包含 NALU 起始码(0x00000001),但这属于mdat数据组织逻辑,stsz本身只管字节数,不解释内容
真正麻烦的是 stsc 和 stsz 联合使用时的边界:比如最后一个 chunk 的 sample 数量可能小于 samples_per_chunk(因总 sample 数不是整除),这个余数必须从 stsz 的实际条目数倒推,而不是信任 stsc 的理论值。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










