首页 > 学院 > 开发设计 > 正文

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

2019-11-06 09:16:25
字体:
来源:转载
供稿:网友

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

代码实现

intMp4Meta::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;}


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表