Sample Size Atoms - STSZ个人觉得该box的作用仅仅就是获得sample的总数以及每个sample的大小。猜测这里的sample总数应该和上面stts中sample count总数相加相等,实际验证确实是这样的。
字段 长度 ( 字节) 描述 尺寸 4 这个 atom 的字节数 类型 4 stsz 版本 1 这个 atom 的版本 标志 3 这里为 0 Sample size 4 全部 sample的数目。如果所有的 sample有相同的长度,这个字段就是这个值。否则,这个字段的值就是 0。那些长度存在 sample size 表中 条目数目 4 sample size 的数目 sample size sample size 表的结构。这个表根据 sample number索引,第一项就是第一个 sample,第二项就是第二个 sample 大小 4 每个 sample 的大小更详细的理结构(示例):
//Mpeg4Extractorcase FOURCC('s', 't', 's', 'z'): case FOURCC('s', 't', 'z', '2'): { status_t err = mLastTrack->sampleTable->setSampleSizeParams( chunk_type, data_offset, chunk_data_size); if (err != OK) { return err; } ................................ //不要看着setSampleSizeParams很复杂,其实没做什么太伟大的事情,就干了两件事 // 一是获取这个video track or audio track里sample的数量n(sample数量除以时间,就是帧速率); //二是获取mSampleSizeOffset ,以后可以根据这个位置找打每个sample的大小。 status_t SampleTable::setSampleSizeParams( uint32_t type, off64_t data_offset, size_t data_size) { if (mSampleSizeOffset >= 0) { return ERROR_MALFORMED; } CHECK(type == kSampleSizeType32 || type == kSampleSizeTypeCompact); mSampleSizeOffset = data_offset; if (data_size < 12) { return ERROR_MALFORMED; } uint8_t header[12]; if (mDataSource->readAt( data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { return ERROR_IO; } if (U32_AT(header) != 0) { // Expected version = 0, flags = 0. return ERROR_MALFORMED; } mDefaultSampleSize = U32_AT(&header[4]); mNumSampleSizes = U32_AT(&header[8]);//获取sample的数量 if (type == kSampleSizeType32) { mSampleSizeFieldSize = 32; if (mDefaultSampleSize != 0) { return OK; } if (data_size < 12 + mNumSampleSizes * 4) { return ERROR_MALFORMED; } } else { if ((mDefaultSampleSize & 0xffffff00) != 0) { // The high 24 bits are reserved and must be 0. return ERROR_MALFORMED; } mSampleSizeFieldSize = mDefaultSampleSize & 0xff; mDefaultSampleSize = 0; if (mSampleSizeFieldSize != 4 && mSampleSizeFieldSize != 8 && mSampleSizeFieldSize != 16) { return ERROR_MALFORMED; } if (data_size < 12 + (mNumSampleSizes * mSampleSizeFieldSize + 4) / 8) { return ERROR_MALFORMED; } } return OK; }
//Sync Sample Atoms - STSS
该box用于获取关键帧的sampleIndex,关键帧主要是在seek的时候用到(选时播放)
case FOURCC('s', 't', 's', 's'):
{
status_t err =
mLastTrack->sampleTable->setSyncSampleParams(
data_offset, chunk_data_size);
if (err != OK) {
return err;
}
*offset += chunk_size;
break;
}
status_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) {
if (mSyncSampleOffset >= 0 || data_size < 8) {
return ERROR_MALFORMED;
}
mSyncSampleOffset = data_offset;
uint8_t header[8];
if (mDataSource->readAt(
data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
return ERROR_IO;
}
if (U32_AT(header) != 0) {
// Expected version = 0, flags = 0.
return ERROR_MALFORMED;
}
mNumSyncSamples = U32_AT(&header[4]);
if (mNumSyncSamples < 2) {
ALOGV("Table of sync samples is empty or has only a single entry!");
}
mSyncSamples = new uint32_t[mNumSyncSamples];
size_t size = mNumSyncSamples * sizeof(uint32_t);
if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, size)
!= (ssize_t)size) {
return ERROR_IO;
}
for (size_t i = 0; i < mNumSyncSamples; ++i) {
mSyncSamples[i] = ntohl(mSyncSamples[i]) - 1;
}
return OK;
}
字段
|
长度 ( 字节)
|
描述
|
尺寸
|
4
|
这个 atom 的字节数
|
类型
|
4
|
stss
|
版本
|
1
|
这个 atom 的版本
|
标志
|
3
|
这里为 0
|
条目数目
|
4
|
sync sample 的数目
|
sync sample
|
|
sync sample 表的结构
|
Sample 序号
|
4
|
是关键帧的 sample 序号
|
如下图,第二行开始,每四个字节都表示sampleIndex