转自:http://www.cnblogs.com/haibindev/archive/2011/10/17/2214518.html
mp4应该算是一种比较复杂的媒体格式了,起源于QuickTime。以前研究的时候就花了一番的功夫,尤其是如何把它完美的融入到视频点播应用中,更是费尽了心思,主要问题是处理mp4文件庞大的“媒体头”。当然,流媒体点播也可以采用flv格式来做,flv也可以封装H.264视频数据的,不过Adobe却不推荐这么做,人家说毕竟mp4才是H.264最佳的存储格式嘛。
这几天整理并重构了一下mp4文件的解析程序,融合了分解与合并的程序,以前是c语言写的,应用在linux上运行的服务器程序上,现在改成c++,方便我在其他项目中使用它,至于用不用移植一份c#的,暂时用不到,等有必要了再说吧。这篇文章先简单介绍一下mp4文件的大体结构,以及它的分割算法,之后再写文章介绍如何把mp4完美应用在点播项目中。
一、MP4格式分析
MP4(MPEG-4 Part 14)是一种常见的多媒体容器格式,它是在“ISO/IEC 14496-14”标准文件中定义的,属于MPEG-4的一部分,是“ISO/IEC 14496-12(MPEG-4 Part 12 ISO base media file format)”标准中所定义的媒体格式的一种实现,后者定义了一种通用的媒体文件结构标准。MP4是一种描述较为全面的容器格式,被认为可以在其中嵌入任何形式的数据,各种编码的视频、音频等都不在话下,不过我们常见的大部分的MP4文件存放的AVC(H.264)或MPEG-4(Part 2)编码的视频和AAC编码的音频。MP4格式的官方文件后缀名是“.mp4”,还有其他的以mp4为基础进行的扩展或者是缩水版本的格式,包括:M4V, 3GP, F4V等。
mp4是由一个个“box”组成的,大box中存放小box,一级嵌套一级来存放媒体信息。box的基本结构是:
其中,size指明了整个box所占用的大小,包括header部分。如果box很大(例如存放具体视频数据的mdat box),超过了uint32的最大数值,size就被设置为1,并用接下来的8位uint64来存放大小。
一个mp4文件有可能包含非常多的box,在很大程度上增加了解析的复杂性,这个网页上http://mp4ra.org/atoms.html记录了一些当前注册过的box类型。看到这么多box,如果要全部支持,一个个解析,怕是头都要爆了。还好,大部分mp4文件没有那么多的box类型,下图就是一个简化了的,常见的mp4文件结构:
一般来说,解析媒体文件,最关心的部分是视频文件的宽高、时长、码率、编码格式、帧列表、关键帧列表,以及所对应的时戳和在文件中的位置,这些信息,在mp4中,是以特定的算法分开存放在stbl box下属的几个box中的,需要解析stbl下面所有的box,来还原媒体信息。下表是对于以上几个重要的box存放信息的说明:
看吧,要获取到mp4文件的帧列表,还挺不容易的,需要一层层解析,然后综合stts stsc stsz stss stco等这几个box的信息,才能还原出帧列表,每一帧的时戳和偏移量。而且,你要照顾可能出现或者可能不出现的那些box。。。可以看的出来,mp4把帧sample进行了分组,也就是chunk,需要间接的通过chunk来描述帧,这样做的理由是可以压缩存储空间,缩小媒体信息所占用的文件大小。这里面,stsc box的解析相对来说比较复杂,它用了一种巧妙的方式来说明sample和chunk的映射关系,特别介绍一下。
这是stsc box的结构,前几项的意义就不解释了,可以看到stsc box里每个entry结构体都存有三项数据,它们的意思是:“从first_chunk这个chunk序号开始,每个chunk都有samples_per_chunk个数的sample,而且每个sample都可以通过sample_description_index这个索引,在stsd box中找到描述信息”。也就是说,每个entry结构体描述的是一组chunk,它们有相同的特点,那就是每个chunk包含samples_per_chunk个sample,好,那你要问,这组相同特点的chunk有多少个?请通过下一个entry结构体来推算,用下一个entry的first_chunk减去本次的first_chunk,就得到了这组chunk的个数。最后一个entry结构体则表明从该first_chunk到最后一个chunk,每个chunk都有sampls_per_chunk个sample。很拗口吧,不过,就是这个意思:)。由于这种算法无法得知文件所有chunk的个数,所以你必须借助于stco或co64。直接上代码可能会清楚些:
1. 首先直接分析entry
2. 然后,通过stco或co64获知chunk总个数之后,开始还原映射表
读出stsc之后,就可以综合stbl下的所有box,推算出视频和音频帧列表,时戳和偏移量等数据。下面截图展示获取到的关键帧列表:
有了关键帧列表之后,就可以继续我们一下个题目,就是mp4文件的分割。实现mp4的分割,是把mp4应用到点播系统中最关键的技术环节,做不到这个,就无法实现点播播放mp4影片的“拖动”。
二、MP4文件的分割算法
所谓“分割”,就是把大文件切成小文件,要实现mp4的分割,
- 首先,需要获取到关键帧列表
- 然后,选择要分割的时间段(比如从关键帧开始)
- 接着,重新生成moov box(注意所有相关的box 以及 box size都需要改变)
- 最后,拷贝对应的数据,生成新文件
第一点,上面已经介绍了,第二点,只需要遍历关键帧列表,就能找到离你想要分割的时间段最接近的关键帧,第四点就是“copy-paste”的工作,关键在于第三点。因为这一步涉及到stbl下的所有box,必须重新生成entrys,同样的,其他的box都还好,只需要保留关键帧所对应的sample和chunk,其余的删掉即可,只是stsc box的比较麻烦,说起来比较啰嗦,还是直接看代码吧:
修改完box之后,需要重新生成moov box,由于moov box的大小以及时长等信息都发生了改变,所以需要box的大小做相应的修改,这点千万不能忘记,否则播放器会解析错误。重新生成box之后,还要计算一下分割后的数据的长度,由于数据长度也发生了改变,所以修改mdat box的大小的同时,要同时修改stbl下所有box的chunk offset,切记!
以下是整个的逻辑过程:
所有这些都实现之后,就具备了做mp4点播系统的条件了。
相关推荐
这篇文章先简单介绍一下mp4文件的大体结构,以及它的分割算法。
在IT领域,分割算法是一种广泛应用于图像处理、计算机视觉以及机器学习的重要技术。标题提到的“一个比较好用的分割算法”很可能是指一个特定的图像分割工具或库,它使用C#编程语言实现,并且提供了方便的接口供用户...
本文将深入探讨使用C语言编写的XML文件解析源码,并讲解如何实现XML文件的基本操作,如查找、增加和删除节点。 在C语言中处理XML文件通常涉及到以下几个关键步骤: 1. **内存管理**:由于C语言没有内置的高级数据...
本文将深入探讨"bin"格式的点云样例文件,以及如何理解和处理这种数据。 "bin"格式是一种常见的用于存储点云数据的二进制文件格式。与ASCII格式(如.pcd或.txt)相比,bin格式具有更高的数据存储效率,因为二进制...
《文件分割合并工具UltraFileSplitter的深度解析与应用指南》 在数字化时代,大文件的处理成为我们日常工作中常见的挑战。文件分割合并工具UltraFileSplitter,以其高效、便捷的特点,成为了处理大文件的理想选择。...
2. **分割算法**:文件分割的算法是源代码的重点。这可能包括计算每个分片的大小,确保分割的连续性,以及处理边界情况,比如最后一个分片可能小于其他分片。 3. **用户界面(UI)**:如果该文件分割器具有图形用户...
总的来说,"VC音频文件分割源码"是一个深入研究音频处理技术的宝贵资源,涵盖了音频文件解析、时间戳处理、数据分割和文件保存等多个方面。通过阅读和理解这个源码,开发者不仅可以学习到音频处理的基础知识,还可以...
MP3(MPEG-1 Audio Layer 3)是一种广泛使用的音频压缩格式,它允许我们将大容量的音乐文件压缩成更小的尺寸,便于存储和传输。MP3算法的核心在于其高效的有损压缩技术,它通过牺牲一部分音质来实现文件大小的显著...
文件分割器的核心算法是计算分割点。这通常包括计算出每个分段文件的最大大小,然后在原始文件中找到合适的位置进行切割。在VB中,可以使用循环结构配合文件流读取器来实现这一过程,确保在分割时不会丢失任何数据。...
NC文件解析是将这些指令转换为机器可理解的形式的关键步骤。 本压缩包包含的资源是用于解析NC文件的动态库源代码。动态库(Dynamic Link Library,DLL)是一种共享软件组件,它包含可由多个程序同时使用的函数和...
首先,`Parser.java`文件很可能是实现解析算法的主要类。在Java中,一个解析器通常会包含方法来分解输入的字符串,识别运算符、操作数、括号以及函数调用等元素。它可能使用了递归下降解析或词法分析等技术,将字符...
3. **解析数据**:根据CLI文件的格式,解析出每层的像素数据。这可能需要对字符串进行处理,例如分割、转换等操作。 4. **处理数据**:将读取到的像素数据转换为MATLAB的矩阵形式,便于进一步的图像处理,如轮廓提取...
"mpeg文件格式分析.doc"文档可能详细涵盖了MPEG文件的结构、编码算法、帧类型(I帧、P帧、B帧)、量化表、宏块结构、熵编码等技术细节。I帧是图像的完整快照,而P帧和B帧利用前后的参考帧进行预测编码,从而大幅减少...
4. **保留原始格式**:在分割过程中,工具会尽可能保持原文件的格式不变,包括换行符、编码等,确保分割后的每个小文件都能正确阅读和解析。 5. **支持多种文件类型**:虽然名称中提到的是“文本文件”,但一些强大...
点云技术是计算机视觉和三维重建领域中的重要组成部分,它通过采集环境中物体表面的大量离散点来构建三维空间模型...通过解析和操作这个文件,我们可以深入了解PLY格式的结构,并进一步掌握点云数据的分析与应用技巧。
C++ ini文件解析器是一种用于处理配置文件的工具,这些配置文件通常采用ini格式,用于存储应用程序的设置和参数。Ini文件以其简单易读的结构而闻名,由多个节(Section)组成,每个节内包含若干键值对(Key-Value ...
根据所提供的文件信息,上述内容大致概述了STL文件分割与拼接处理软件开发的关键知识点。实际的软件开发过程可能还会包含更多的细节和技术难点,但以上几点是开发此类软件必须要考虑的核心要素。论文作者李锦在王...
总的来说,图像纹理聚类分割算法是一种基于统计和机器学习的图像处理技术,它在医学影像分析、遥感图像解析、工业检测等领域有着广泛的应用。通过深入理解并优化这种算法,我们可以更准确地识别和理解图像中的复杂...
在提供的代码文件`SplitBigXml.java`中,很可能实现了这样一个分段解析的过程,它可能将大XML文件分割成多个小块,然后逐块进行解析和处理,这样可以避免一次性加载整个文件。另外,`XMLOutputBuffer.java`可能是...