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的sizeatom_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 atomif (meta_avail < (int64_t)sizeof(mp4_atom_header)) // not enough for atom headerreturn 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_atomif (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: successif (ret <= 0) {return ret;} else if (meta_complete) { // successreturn 1;}goto next;}}// nonsignificant atom boxrc = mp4_atom_next(atom_size, true); // 0: unfinished, 1: successif (rc == 0) {return rc;}next:continue;}return 1;
}
MP4学习(四)ts-mp4源码阅读(2)MP4的解析流程相关推荐
- c++读取图片_四、faster-rcnn源码阅读:数据流读取
数据读取在faster-rcnn源码里是比较简单的部分,但也是非常重要的部分,不了解数据,就不可能了解算法. 另一方面,由于python环境碎片话化,源码调用的库在你的电脑上如果碰巧(其实概率还蛮大, ...
- springmvc源码阅读3--dispatcherServlet reqeust的执行流程
一.前言 太多的时候总是会遇到群里面问,报404怎么肥事呀,前台的参数怎么后台收不到呀--,上次就在群里面遇到过,围绕这一个点:input的name值是不是错了呀,人家妹子都截了好几次图说没有问题,然 ...
- JVM源码阅读-本地库加载流程和原理
前言 本文主要研究OpenJDK中JVM源码中涉及到native本地库的加载流程和原理的部分.主要目的是为了了解本地库是如何被加载到虚拟机,以及是如何找到并执行本地库里的本地方法,以及JNI的 JNI ...
- Halide学习笔记----Halide tutorial源码阅读3
Halide入门教程03 // Halide tutorial lesson 3: Inspecting the generated code // Halide入门第三课:检测生成代码// This ...
- C-libev学习笔记-事件库源码阅读6-API-ev_default_loop(),ev_init()
ev_default_loop() 声明: EV_API_DECL struct ev_loop *ev_default_loop (unsigned int flags EV_CPP (= 0)) ...
- Halide学习笔记----Halide tutorial源码阅读2
Halide入门教程02 // Halide tutorial lesson 2: Processing images // Halide入门第二课: 处理图像// This lesson demon ...
- Halide学习笔记----Halide tutorial源码阅读5
Halide入门教程05 // Halide教程第五课:向量化,并行化,平铺,数据分块 // 本课展示了如何才操作函数像素索引的计算顺序,包括向量化/并行化/平铺/分块等技术// 在linux系统中, ...
- python学习笔记之三——MakeHuman源码阅读
1.@装饰器的用法 简单的说,@装饰器就是用来提供调用的, def funA(arg):print 'A'a=arg()@funA def funB():print 'B' 此处的@相当于funA(f ...
- 源码阅读:AFNetworking(十六)——UIWebView+AFNetworking
该文章阅读的AFNetworking的版本为3.2.0. 这个分类提供了对请求周期进行控制的方法,包括进度监控.成功和失败的回调. 1.接口文件 1.1.属性 /**网络会话管理者对象*/ @prop ...
最新文章
- ubuntu18.04.4 安装百度硬盘
- JDK5.0 特性-线程任务执行架构 ScheduledExecutorService
- html多重边框,中间空白,CSS实现多重边框
- boost::process::environment相关的测试程序
- JSON.parse使用 之 Unexpected token o in JSON at position 1 报错原因
- 《On the Momentum Term in Gradient Descent Learning Algorithm》原文解读
- 后台无刷新修改字段js
- Linq to Sql : 三种事务处理方式
- 如何为Kubernetes实现原地升级
- 电商优秀设计作品展示
- 二叉树:听说递归能做的,栈也能做!
- 学习笔记之TCP/IP协议分层与OSI參考模型
- 通达OA 指纹考勤机接口 源代码
- 软件工程导论复习提纲
- 计算机设计大赛答辩ppt
- 2021年机修钳工(中级)报名考试及机修钳工(中级)考试资料
- 小爱同学课程表自动导入教程(2)——新版青果教务系统
- java程序判断是否是闰年_用Java程序判断是否是闰年
- JavaSE银行账户管理系统
- 按头安利 好看又实用的冰淇淋VRay材质球素材看这里