MP4学习(四)ts-mp4源码阅读(2)MP4的解析流程

MP4的解析流程



常见的MP4结构图






MP4 box的定义



    MP4也是一个容器

/* 
** MP4容器定义,包含:
** ftyp、moov、mdat
*/
static mp4_atom_handler mp4_atoms[] = {
    { "ftyp", &Mp4Meta::mp4_read_ftyp_atom },
    { "moov", &Mp4Meta::mp4_read_moov_atom },
    { "mdat", &Mp4Meta::mp4_read_mdat_atom },
    { NULL, NULL }
};



MP4的解析步骤


    解析步骤如下:
    1、读取mp4文件
    2、读取box的size字段
    3、如果box的size字段的值是1,表示真实的长度需要用64位来表示,需要继续读取
    4、读取box的名字,根据名字来调用mp4 box中的函数指针:

        (1)mp4_read_ftyp_atom,读取ftyp box

        (2)mp4_read_moov_atom,读取moov box

        (3)mp4_read_mdat_atom,读取mdat box



代码实现

int
Mp4Meta::parse_root_atoms()
{
    int         i, ret, rc;
    int64_t     atom_size, atom_header_size;
    char        buf[64];
    char        *atom_header, *atom_name;

    memset(buf, 0, sizeof(buf));

    for (;;) {

        if (meta_avail < (int64_t)sizeof(uint32_t))
            return 0;

        IOBufferReaderCopy(meta_reader, buf, sizeof(mp4_atom_header64));
		
		// 读取box的size
        atom_size = mp4_get_32value(buf);

        if (atom_size == 0) {
            return 1;
        }

        atom_header = buf;

        if (atom_size < (int64_t)sizeof(mp4_atom_header)) {

			// 如果size等于1,表示真实的size需要64位表示,需要继续读取
            if (atom_size == 1) {
                if (meta_avail < (int64_t)sizeof(mp4_atom_header64)) {
                    return 0;
                }

            } else {
                return -1;
            }

            atom_size = mp4_get_64value(atom_header + 8);
            atom_header_size = sizeof(mp4_atom_header64);

        } else {                                                     // regular atom

            if (meta_avail < (int64_t)sizeof(mp4_atom_header))       // not enough for atom header
                return 0;

            atom_header_size = sizeof(mp4_atom_header);
        }

		// 读取box的名字
        atom_name = atom_header + 4;

        if (atom_size + this->passed > this->cl) {
            return -1;
        }

		// 调用MP4容器的处理函数
        for (i = 0; mp4_atoms[i].name; i++) {
			
			// 根据名字进行调用mp4_read_ftyp_atom、mp4_read_moov_atom、mp4_read_mdat_atom
            if (memcmp(atom_name, mp4_atoms[i].name, 4) == 0) {

                ret = (this->*mp4_atoms[i].handler)(atom_header_size, atom_size - atom_header_size);           // -1: error, 0: unfinished, 1: success

                if (ret <= 0) {
                    return ret;

                } else if (meta_complete) {             // success
                    return 1;
                }

                goto next;
            }
        }

        // nonsignificant atom box
        rc = mp4_atom_next(atom_size, true);            // 0: unfinished, 1: success
        if (rc == 0) {
            return rc;
        }

next:
        continue;
    }

    return 1;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值