(frameworks/av/media/libstagefright/MPEG4Writer.cpp)
一、MPEG4Writer相关流程
MPEG4Writer是Android stagefright媒体框架下一个的封装类,录制视频调用的MediaRecorder接口类的底层封装实现通过它完成。
以视频为例,MPEG4Writer是视频录制的最后一环。
MPEG4Writer遵守 ISO 14496-12标准进行封装,MP4、3gp、ismv等我们常见的媒体封装格式都是以这种基础文件格式为基础衍生的。
Android系统录像封装流程主要有三个步骤:
1) 录制开始时,写入文件头部。
2) 录制进行时,实时写入音视频轨迹的数据块。
3) 录制结束时,写入索引信息并更新头部参数。
索引负责描述音视频轨迹的特征,会随着音视频轨迹的存储而变化,所以通常做法会将录像文件索引信息放在音视频轨迹流后面,在媒体流数据写完(录像结束)后才能写入。可以看到,存放音视频数据的mdat box是位于第二位的,而负责检索音视频的moov box是位于最后的,这与通常的MP4封装的排列顺序不同,当然这是为了符合录制而产生的结果。因为 moov的大小是随着 mdat 变化的,而我们录制视频的时间预先是不知道的,所以需要先将mdat 数据写入,最后再写入moov,完成封装。
现有Android系统上录像都是录制是MP4或3GP格式,底层就是使用MPEG4Writer组合器类来完成的,它将编码后的音视频轨迹按照MPEG4规范进行封装,填入各个参数,就组合成完整的MP4格式文件。MPEG4Writer的组合功能主要由两种线程完成,一种是负责音视频数据写入封装文件的写线程(WriterThread),一种是音视频数据读取处理的轨迹线程(TrackThread)。轨迹线程一般有两个:视频轨迹数据读取线程和音频轨迹数据读取线程,而写线程只有一个,负责将轨迹线程中打包成Chunk的数据写入封装文件。
如图2所示,轨迹线程是以帧为单位获取数据帧(Sample),并将每帧中的信息及系统环境信息提取汇总存储在内存的trak表中,其中需要维持的信息有Chunk写入文件的偏移地址Stco(Chunk Offset)、Sample与Chunk的映射关系Stsc(Sample-to-Chunk)、关键帧Stss(Sync Sample)、每一帧的持续时间Stts(Time-to-Sample&