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

MP4学习(六)ts-mp4源码阅读(4)moov box的解析

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

moov box的解析

常见的MP4结构图

    moov box是个container box,读取box头部之后就开始读取子box了

moov box的定义

/*** moov box的定义,包含:** mvhd、trak(cmov无意义)*/static mp4_atom_handler mp4_moov_atoms[] = {    { "mvhd", &Mp4Meta::mp4_read_mvhd_atom },    { "trak", &Mp4Meta::mp4_read_trak_atom },    { "cmov", &Mp4Meta::mp4_read_cmov_atom },    { NULL, NULL }};

读取moov box

// 读取moov boxintMp4Meta::mp4_read_moov_atom(int64_t atom_header_size, int64_t atom_data_size){    int64_t         atom_size;    int             ret;    if (mdat_atom.buffer != NULL)       // not reasonable for streaming media        return -1;    atom_size = atom_header_size + atom_data_size;    if (atom_data_size >= MP4_MAX_BUFFER_SIZE)        return -1;    if (meta_avail < atom_size) {       // data unsufficient, wait        return 0;    }    moov_atom.buffer = TSIOBufferCreate();    moov_atom.reader = TSIOBufferReaderAlloc(moov_atom.buffer);    TSIOBufferCopy(moov_atom.buffer, meta_reader, atom_header_size, 0);    mp4_meta_consume(atom_header_size);    // 读取box,注意第一个参数是函数指针数组    ret = mp4_read_atom(mp4_moov_atoms, atom_data_size);    return ret;}

读取moov box的子box

    读取子box,根据子box的名字分别调用:

    1、mp4_read_mvhd_atom处理mvhd box

    2、mp4_read_trak_atom处理trak box

    3、mp4_read_cmov_atom处理cmov box

intMp4Meta::mp4_read_atom(mp4_atom_handler *atom, int64_t size){    int         i, ret, rc;    int64_t     atom_size, atom_header_size;    char        buf[32];    char        *atom_header, *atom_name;    if (meta_avail < size)    // data insufficient, not reasonable for internal atom box.        return -1;    while (size > 0) {        if (meta_avail < (int64_t)sizeof(uint32_t))            // data insufficient, not reasonable for internal atom box.            return -1;        IOBufferReaderCopy(meta_reader, buf, sizeof(mp4_atom_header64));        atom_size = mp4_get_32value(buf);        if (atom_size == 0) {            return 1;        }        atom_header = buf;        if (atom_size < (int64_t)sizeof(mp4_atom_header)) {            if (atom_size == 1) {                if (meta_avail < (int64_t)sizeof(mp4_atom_header64)) {                    return -1;                }            } 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))                return -1;            atom_header_size = sizeof(mp4_atom_header);        }        atom_name = atom_header + 4;        if (atom_size + this->passed > this->cl) {            return -1;        }	// 根据mp4_moov_atoms的定义,下面会调用:	// mp4_read_mvhd_atom处理mvhd、mp4_read_trak_atom处理trak、mp4_read_cmov_atom处理cmov        for (i = 0; atom[i].name; i++) {            if (memcmp(atom_name, atom[i].name, 4) == 0) {                if (meta_avail < atom_size)                    return -1;                ret = (this->*atom[i].handler)(atom_header_size, atom_size - atom_header_size);       // -1: error, 0: success.                if (ret < 0) {                    return ret;                }                goto next;            }        }        // insignificant atom box        rc = mp4_atom_next(atom_size, false);        if (rc < 0) {            return rc;        }next:        size -= atom_size;        continue;    }    return 1;}


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