MP4文件格式简要解析

准备

安装mediaInfo、QTAtomViewer.exe、MP4info.exe等软件

视频一些参数

封装格式:我也不太清楚

编码格式:我也不太清楚

分辨率:图像的长和宽。

帧率:一秒播放的图片数,如15fps、30fps,体现在画面的流畅度。

码率:压缩后每秒显示的图片数据量,通俗地说,就是流量。如298kbps,体现在视频文件的大小和画质。

压缩比:分辨率*帧率/码率,简单来说就是压缩前每秒的数据量比上压缩后每秒的数据量。

音频一些参数

声道:录音时录音的位置不同产生不同的声道,有单声道、立体声(左右声道)、四声道环绕、5.1声道等。放歌时切换到左声道,两个音箱都播放左声道,切换到右声道时,两个音箱都播放右声道,切换到立体音时,左音箱播放左声道,右音箱播放右声道。可用暴风影音体验一下。

音轨: ①电视上看到录音时歌手都是在录音棚里戴着耳机唱歌,其实这就使用了多音轨技术,先把伴奏录好(音轨1),歌手再根据伴奏唱歌(音轨2)。②在K房使用的也是多音轨(原唱和伴唱)③有些老歌经常是粤语版和国语版一起唱,这也是多音轨技术

采样率:录制声音时对声音的采样频率,一般为44.1KHz

MP4文件组成

MP4由一个个的box(以前叫atom)组成,如下图,每个box包含不同的信息(再如下图),在程序中用结构体表示各个box,形象地说MP4文件就是由各个结构体组织起来的。所以,首先要了解这些box的组成和意义。

主要概念:sample、chunk、track

sample,在这里实际上就是一帧或连续几帧

chunk,一个或几个sample组成的单元

track,视频或音频序列,sample的集合


MP4主要由三个box组成,ftyp、mdat和moov。ftyp指示一些头部信息,通过ftyp box可以判断文件类型。mdat box存放的是媒体数据,就是播放的音频实实在在的元数据,比如我们需要取到第一帧的图片数据就存放在这个box里面。这么多数据,怎么知道这些数据的准确位置呢?这就要靠moov box来解析了。一般情况下,一个moov box包含一个mvhd和若干个track box。①mvhd box中存放一些create/modify time(基准时间是1904-1-1 0:00 AM)等信息,duration/time scale就是视频的长度(单位为s)。②track box一般包含tkhd和mdia两个box,tkhd中存放有视频长度和宽度等信息,,,,,,,最重要的是mdia -> minf -> stbl box下面的6个box,分别是stsd、stts、stss、stsc、stsz、stco,比如要查找第N秒的图片数据,步骤如下:

1、确定第N秒在媒体时间坐标系统中的位置,即N*time_scale

2、根据stts(time to sample)确定sample序号

3、根据stsc(sample to chunk)确定对应该sample的chunk

4、根据stco(chunk offset)中提取该chunk的偏移量

5、根据stsz(sample size)找到该sample在chunk内的偏移量和sample的大小。


例如:以test.mp4为例说明,用QTAtomViewer.exe查看此文件可知time_scale为90000,即一秒分为90000个刻度,现在假设要查看第一秒的数据,步骤如下:

1、一秒在媒体时间坐标系统中的位置,即1*90000 = 90000;

2、由stts,sample duration = 6000, 90000/6000 = 15, 即sample序号为15

3、由stsc,因为samples Per chunk = 1, 所以chunk序号也为15

4、由stco,序号为15的chunk的offset = 62719

5、由stsz,sample 在 chunk内的偏移为0,且大小为3554。

也就是说,程序到62719的地址开始,读取3554byte的数据,就是第一秒的图片数据。如果要查看第一帧(第0秒)的数据,同样按照上面的步骤可定位到地址28,读取5280byte的数据

现在知道了MP4文件的组成,也知道了怎么去获取第N帧的数据,那么无论程序多么复杂,它都是围绕这个主题来做文章了


最后附上一小段简单的视频解析的代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define BOX_FTYP 0x66747970
#define MDAT_BOX 0x6D646174
#define MOOV_BOX 0x6D6F6F76
#define	MVHD_BOX 0x6D766864
#define TRAK_BOX 0x7472616B
#define IODS_BOX 0x696F6473
#define UDTA_BOX 0x75647461
#define FREE_BOX 0x66726565
#define TKHD_BOX 0x746B6864
#define MDIA_BOX 0x6D646961
#define MDHD_BOX 0x6D646864
#define	HDLR_BOX 0x68646C72
#define MINF_BOX 0x6D696E66
#define DINF_BOX 0x64696E66
#define TREF_BOX 0x74726566
#define STBL_BOX 0x7374626C
#define STSD_BOX 0x73747364
#define MP4S_BOX 0x6D703473
#define ESDS_BOX 0x65736473
#define STTS_BOX 0x73747473
#define STSC_BOX 0x73747363
#define STSZ_BOX 0x7374737A
#define STCO_BOX 0x7374636F
#define STSS_BOX 0x73747373
#define CTTS_BOX 0x63747473
#define EDTS_BOX 0x65647473
#define VMHD_BOX 0x766D6864
#defin
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值