stagefright之MPEG4Extractor(三)(stsz,stss)


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 的大小
更详细的理结构(示例):

//Mpeg4Extractor
case 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

发布了14 篇原创文章 · 获赞 22 · 访问量 11万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览