多媒体文件中moov容器的写入方法和计算机可读存储介质

文档序号:154840 发布日期:2021-10-26 浏览:25次 >En<

阅读说明:本技术 多媒体文件中moov容器的写入方法和计算机可读存储介质 (Write method of moov container in multimedia file and computer readable storage medium ) 是由 敖滚 刘洋 于 2021-09-18 设计创作,主要内容包括:本发明公开了一种多媒体文件中moov容器的写入方法以及相应的计算机可读存储介质,通过为moov容器中的每个子容器分配预留空间,预先确定各容器在存储载体中的存储位置偏移,并在整个文件写入过程中保持子容器存储位置偏移不变来更新子容器,解决moov容器写入异常所导致的多媒体文件不能读取的风险。(The invention discloses a method for writing in a moov container in a multimedia file and a corresponding computer readable storage medium.)

多媒体文件中moov容器的写入方法和计算机可读存储介质

技术领域

本发明涉及音视频文件编辑技术领域,尤其涉及一种多媒体文件中moov容器的写入方法以及一种计算机可读存储介质。

背景技术

根据ISO/IEC 14496-12标准,mp4文件格式中的媒体描述和媒体数据是分开的,并且媒体数据的组织也比较自由,不一定要按照时间顺序排列。mp4文件中的所有数据都封装在容器(box)中,mp4文件由若干个容器组成,每个容器有类型和长度,若容器中还包含另一个容器,这种容器称为集装容器(container box)。

一个mp4文件中具有ftyp类型的容器,作为mp4格式的标志并包含关于文件的一些信息;还会有且只有一个moov类型的容器,moov类型的容器中存放媒体数据的元数据(metadata)信息,moov类型容器包含文件索引信息,属于集装容器,moov容器结构中包含了stts、stsz、stsc、stco、co64、stss等容器,这些容器的大小可能随着录制时长的增加而变大;以及mdat类型的容器,用于存放mp4文件的媒体数据,mdat类型的容器可以有多个,也可以没有,当媒体数据全部引用其他文件时,媒体数据的结构由元数据进行描述。

当moov类型容器中的数据缺失或异常时,可能导致该mp4文件将无法读取。现有技术中通常的做法是,在存储载体(内置存储模块或外接存储器)中写入mp4文件时,先写入mdat容器,moov容器则先存放在内存中,等录制结束后再将moov容器整体写入文件末尾,这种做法一旦moov容器写入的过程中发生异常没有正常结束,则会导致moov容器中的数据缺失,媒体数据将无法读取。作为上述方案的改进,在写入mdat容器之前,先给moov容器预留一部分空间,周期性对moov容器进行全部重新写入,然而,随着录制时长的增加,与音视频帧信息相关的部分容器大小将会随着增大,在moov整体写入过程中,这些子容器的存储位置偏移会发生变化,所以重写过程一旦异常,将容易导致部分子容器的内容被覆盖后还没写入新的内容导致文件损毁,同时,由于频繁更新大的文件索引,造成性能下降,若增大重写的时间间隔只会降低损毁几率,仍然无法保证安全,并且增大重写时间也容易导致异常发生时部分数据丢失而无法读取。

有些方案是在录制mp4文件的同时创建另一个临时文件,将音视频数据按照顺序写入其中,一旦发生异常,可通过临时文件重新还原索引,这种方案在出现异常时能够通过临时文件进行修复,同时该方案不是标准,容易造成修复时对特定设备的依赖,例如在对应的设备中插入优盘录制,发生异常后在设备修复前拔出并插入其他设备进行播放,则文件将无法播放。

同样的,根据苹果公司的QTFF协议,采用类似文件结构的mov文件也存在上述问题。

发明内容

有鉴于此,基于现有技术中存在的问题,本发明提供一种多媒体文件中moov容器的写入方法,通过为moov容器中的每个子容器分配预留空间,以及根据子容器存储位置偏移来更新子容器,解决moov容器写入异常所导致的多媒体文件不能读取的风险。

为了解决上述问题,本发明提供一种多媒体文件中moov容器的写入方法,用于将moov容器写入存储载体中,该方法包括以下步骤:

根据多媒体文件格式的协议规定,估计moov容器中所有容器的预留空间大小以及moov容器的预留空间大小;

根据moov容器的存储位置偏移、moov容器中各容器的存储顺序以及各容器的预留空间大小依次获取各容器的存储位置偏移;

根据moov容器的存储位置偏移、各容器的存储位置偏移分别在moov容器及其所包含的各容器内写入相应内容。

其中,moov容器结构中包括集装容器和非集装容器,所述集装容器的预留空间大小等于其所包含的所有容器的预留空间大小和所述集装容器中固定字段所需的存储空间大小,所述固定字段与所述集装容器的类型相关。

其中,将所述moov容器结构中的非集装容器分为定量子容器和变量子容器,所述定量子容器在整个多媒体文件录制过程中有效空间大小不变;所述变量子容器的有效空间随其内所写入的条目数量变化而改变,所述变量子容器中设置有存储其内所写入的总条目数的固定字段;所述有效空间是指容器中所写入的有效数据实际占用的空间。

其中,对于某个变量子容器,估计所述变量子容器的预留空间大小包括步骤:

根据所述变量子容器中所应写入的条目内容和预设的多媒体文件录制时长获取多媒体文件录制结束时在所述变量子容器中所能写入的总条目数的估计值;

根据总条目数的估计值与所述变量子容器中单个条目所需的存储空间大小及其内固定字段所需的存储空间大小获取所述变量子容器的预留空间大小。

进一步,所述变量子容器的预留空间大小还包括预设余量,所述预设余量用于防止条目误差,所述预设余量根据相应变量子容器中单个条目所需的存储空间大小设置。

进一步,根据多媒体文件格式的协议规定,将某些变量子容器所应写入的条目内容进行预先配置,使得相应变量子容器在整个多媒体文件录制过程中所写入的条目数量保持不变。

其中,所述定量子容器的预留空间大小为其内固定字段所需的存储空间大小。

其中,在所述moov容器及其各容器内写入相应内容,包括步骤:

在初始更新时刻,根据moov容器和各容器的存储位置偏移依次在所述存储载体中写入对应固定字段所应存储的内容;对于变量容器,还需写入当前时刻已经存在的条目,并记录最后一个条目的条目编号;

在随后的每一更新时刻,对于moov容器内各容器,更新其内固定字段的值;对于变量子容器,还需根据上一更新时刻所记录的条目编号确定当前更新时刻的起始条目的条目编号后,写入相应数量的条目,并记录最后一个条目的条目编号;若变量子容器在当前更新时刻的条目数量与上一更新时刻的条目数量相同,则不写入。

其中,所述多媒体文件为mp4文件或mov文件。

相应的,本发明还公开了一种计算机可读存储介质,存储有计算机程序,该程序被执行时实现上述多媒体文件中moov容器的写入方法。

与现有技术相比,本发明具有以下优势:

本发明中多媒体文件中moov容器写入方法,根据协议规定,利用mp4、mov标准定义的容器大小可进行设置,以及隶属于同一集装容器的同一层级的容器的存储位置偏移为上一容器的存储位置偏移加该上一容器大小之和的特点,根据估计的各容器预留空间大小依次获取各容器的存储位置偏移并进行记录;在估计各变量子容器的预留空间大小时,根据各变量子容器所应写入的条目内容,确定多媒体文件录制结束时相应变量子容器所需的最大存储空间,保证在整个多媒体文件录制过程中,各容器的存储位置偏移不会发生变化,解决 moov容器写入异常所导致的mp4、mov多媒体文件不能读取的风险;进而为了缩小moov容器预留空间大小与有效空间大小的差距,根据协议规定,对某些变量子容器所应写入的条目内容进行预先配置,使得所述变量子容器在整个多媒体文件录制过程中所写入的条目总数为固定值,则无需根据多媒体文件录制时长来获取多媒体文件录制结束时在该变量子容器中所能写入的总条目数的估计值;在写入过程中,通过更新部分子容器内容进一步优化了moov容器的更新速度,这样可增加更新频率,减少异常发生时丢失的数据量。

附图说明

图1是本发明多媒体文件中moov容器写入方法的流程图;

图2是本发明实施例中mp4文件的moov容器结构示意图;

图3是图2中mdhd容器所包含部分内容的示意图;

图4是图2中视频轨道stts容器所包含部分内容的示意图;

图5是图2中音频轨道stts容器所包含部分内容的示意图;

图6是图2中视频轨道stsz容器所包含部分内容的示意图;

图7是图2中视频轨道stsc容器所包含部分内容的示意图;

图8是图2中视频轨道co64容器所包含部分内容的示意图;

图9是图2中视频轨道stss容器所包含部分内容的示意图;

图10是图6中stsz容器内所包含部分内容的初始更新时刻示意图;

图11是图10中stsz容器内所包含部分内容的某一更新时刻示意图。

具体实施方式

下面结合实施例对本发明作更进一步的说明。

为了便于描述,本发明中定义预留空间为容器被预先分配的存储空间,有效空间为容器中所写入的有效数据实际占用的空间。根据非集装容器的有效空间在整个多媒体文件录制过程中是否变化,即非集装容器的有效空间大小是否随多媒体文件录制时长发生变化定义定量子容器和变量子容器,定量子容器在整个多媒体文件录制过程中有效空间大小保持不变,变量子容器在整个moov容器写入的过程中,有效空间随其内所写入的条目数量变化而改变,而且变量子容器中设置有存储其内所写入的总条目数的固定字段。

如图1所示,本发明多媒体文件中moov容器写入方法,用于将moov容器写入存储载体中,包括以下步骤:

(1)根据多媒体文件格式的协议规定,估计moov容器中所有容器的预留空间大小以及moov容器的预留空间大小;

(2)根据moov容器的存储位置偏移、moov容器中各容器的存储顺序以及各容器的预留空间大小依次获取各容器的存储位置偏移;

(3)根据 moov容器的存储位置偏移、各容器的存储位置偏移分别在moov容器及其所包含的各容器内写入相应内容。

本发明中的moov容器写入方法,适用于mp4文件或mov文件,两者的moov容器结构框架类似,本发明中仅以mp4文件为例进行详细介绍。

本实施例以某一mp4文件的容器结构为例介绍moov容器的写入方法,如图2所示,该mp4文件中有且只有一个ftyp容器,该容器只能被包含在文件层中,放置在文件的最开始,用于指示mp4文件应用的相关信息,图2中ftyp容器大小为28个字节,存储位置偏移为0x0;free容器的内容可以被忽略,该box被删除后,不会对播放产生任何影响。

根据mp4、mov标准定义,隶属于同一集装容器的同一层级的容器的存储位置偏移为上一容器的存储位置偏移加该上一容器存储空间之和。因而,对于本实施例中的moov容器来说,其存储位置偏移可通过fyyp容器大小和free容器大小之和得出,如图1所示其存储位置偏移为0x24。

本发明方案主要涉及moov容器(Movie Box),根据mp4文件格式的标准协议规定(ISO/IEC 14496系列标准),图2中所示的moov容器并未包含协议中规定的所有子容器,本实施例仅为了便于说明本发明moov容器的写入方法而做代表性示例。如图2所示,本发明实施例中moov容器包括了mvhd容器(Movie Header Box)和两个trak容器(Track Box),以及meta容器(Meta Box)和udta容器(User Data Box)。其中,mvhd容器一般作为moov容器的第一个子容器,为必要子容器,其中包括了容器大小、容器类型、容器版本、时间刻度、时间长度等内容不变或内容更新但不影响该容器总体大小的固定字段,为定量子容器;meta容器包括了一些描述性内容,该集装容器为非必要容器;udta容器包括了关于其内含容器的用户信息和数据,该集装容器为非必要容器。trak容器包含一个轨道(track)的相关信息,也属于集装容器,为必要容器,其内包含有定量子容器和变量子容器。

下文将介绍如何根据多媒体文件格式的协议规定,估计moov容器中所有容器的预留空间大小以及moov容器的预留空间大小。

集装容器的预留空间大小等于其所直接包含的所有容器的预留空间大小和该集装容器内固定字段(对应类中定义的变量)所需的存储空间大小,固定字段存放在相应容器的头部位置,固定字段及其所需的存储空间大小与集装容器所属的容器类型相关,在ISO/IEC 14496-12协议均进行了定义。

如下ISO/IEC 14496-12协议中所规定的Box类,Box类中定义了size、boxtype两个变量,两个变量对应的存储空间是固定的,该容器为mp4中所有box的基类,则该基类的固定字段用于存储容器大小和容器类型。moov容器以及其结构内的trak、edts、mdia、minf、dinf、stbl为Box类的拓展类,对此类集装容器来说,其内固定字段所需的存储空间大小为容器大小的存储空间(对应变量size ,32位,4个字节)和容器类型的存储空间(对应变量type ,32位,4个字节)。

aligned(8) class Box (unsigned int(32) boxtype,

optional unsigned int(8)[16] extended_type) {

unsigned int(32) size;

unsigned int(32) type = boxtype;

if (size==1) {

unsigned int(64) largesize;

} else if (size==0) {

// box extends to end of file

}

if (boxtype==‘uuid’) {

unsigned int(8)[16] usertype = extended_type;

}

}

以图2中第一个trak容器为例,该容器的预留空间大小为其所包含的所有容器tkhd、edts、mdia容器的预留空间大小之和(92+36+1741112)加上8个字节,为1741248个字节。

在moov容器结构中还存在诸如dref、stsd等集装容器,此类容器为FullBox的扩展类,如下ISO/IEC 14496-12协议中所规定的FullBox类的定义,该类中继承了Box类的所有定义,并在Box类基础上增加了存储版本信息version和标志信息flags两个变量,这些变量对应的大小都是固定的。故此类集装容器的固定字段用于存储容器大小(32位,4个字节)和容器类型(32位,4个字节)、版本信息(对应变量version,8位,1个字节)和标志信息(对应变量flags,24位,3个字节),固定字段所需的存储空间大小也是固定的,为12个字节。

aligned(8) class FullBox(unsigned int(32) boxtype, unsigned int(8) v,bit(24) f)

extends Box(boxtype) {

unsigned int(8) version = v;

bit(24) flags = f;

}

以图2中dref容器为例,如下ISO/IEC 14496-12协议中dref容器的定义,该容器在FullBox的基础上进行了扩展,进一步增加了entry_count这个变量,存储该变量的大小也是规定的(32位,4个字节),故此类集装容器中固定字段的空间大小为16个字节。故而dref容器预留空间大小为其内容器url容器(DataEntryBox类)的预留空间大小(12个字节)加上16个字节,其预留空间大小为28个字节。

aligned(8) class DataReferenceBox

extends FullBox(‘dref’, version = 0, 0) {

unsigned int(32) entry_count;

for (i=1; i <= entry_count; i++) {

DataEntryBox(entry_version, entry_flags) data_entry;

}

}

对于非集装容器,在本发明中将其分为定量子容器与变量子容器,对于定量子容器来说,其预留空间大小的估计与集装容器的区别仅在于,集装容器中包含了其他容器,而非集装容器中不包含其他容器,因而,定量子容器的预留空间大小为其内固定字段所需的存储空间大小。

图2中moov容器中所直接包含的容器mvhd,trak容器所直接包含的容器tkhd容器,edts容器所直接包含的elst、hdlr容器以及minf容器所直接包含的vmhd、hdlr容器,dref容器所直接包含的url容器、stbl容器所直接包含的stsd均为定量子容器。

以图2和图3中mdhd容器为例,如下ISO/IEC 14496-12协议中mdhd容器的定义,该容器的固定字段在FullBox的基础(12个字节)上进行了扩展,增加了creation_time、modification_time、timescale、duration、language、pre_defined变量,当version==0时,这些变量所需的存储空间大小为20个字节,则可得到mdhd的预留空间大小为32个字节。

aligned(8) class MediaHeaderBox extends FullBox(‘mdhd’, version, 0) {

if (version==1) {

unsigned int(64) creation_time;

unsigned int(64) modification_time;

unsigned int(32) timescale;

unsigned int(64) duration;

} else { // version==0

unsigned int(32) creation_time;

unsigned int(32) modification_time;

unsigned int(32) timescale;

unsigned int(32) duration;

}

bit(1) pad = 0;

unsigned int(5)[3] language; // ISO-639-2/T language code

unsigned int(16) pre_defined = 0;

}

对于变量子容器来说,在整个moov容器写入的过程中,有效空间随其内所写入的条目数量变化而改变,而且变量子容器中设置有存储其内所写入的总条目数的固定字段。根据协议规定,多媒体文件在写入时并不会在存储载体中存储每个容器的存储位置偏移,在多媒体文件读取时,根据初始位置偏移0x0和各容器的存储空间大小而依次获取各容器的存储位置偏移,而在读取变量子容器内容时,则先根据其存储位置偏移读取固定字段的内容,再根据固定字段中的条目数来读取条目内容,也正是基于这一点,虽然本发明方案中moov容器写入方法导致变量子容器预留空间大小大于其有效空间大小,通过本发明方法所录制的多媒体文件仍能够正常读取。

本发明中为了便于说明发明方案,实施例中的mp4文件包括音、视频信息,第一个trak记录视频轨道信息,第二个trak记录音频轨道信息,stbl容器包含了关于track中sample所有的时间和位置信息,以及sample的编解码等信息;stbl容器包括stsd容器(Sample Description Box)、stts容器(Time To Sample Box)、stsz容器(Sample SizeBox)、stsc容器(Sample To Chunk Box)、co64容器(Chunk Offset Box)、stss容器(SyncSample Box)等。stbl容器中包括了定量子容器和变量子容器,stsd容器中包含了编码类型和编码的初始化信息,在整个多媒体文件录制过程中,该容器的有效空间大小保持不变,stsd容器为集装容器,其内所直接包含的容器全部为定量子容器。

下文将重点介绍stts容器、stsz容器、co64容器预留空间大小的计算,这些容器均属于FullBox类的扩展。根据标准,这些容器中所记录的内容与帧数量相关,有效空间大小随着录制时长的增加可能会增加。对于stts容器、stsz容器、co64容器这类子容器,其预留空间大小Si的计算公式为:

Si=Si_const+Ni_frame*Si_frame(1)

其中,下标i用来标识容器种类,Si_const为i所标识容器中固定字段所需的存储空间大小, Si_frame表示i所标识容器中用于记录帧信息的单个条目所需的存储空间,Ni_frame表示mp4文件完成录制时i所标识容器中的总条目数的估计值,即帧数估计值。固定字段所需的存储空间大小以及单个条目所需的存储空间大小可根据标准确定。

帧数估计值Ni_frame的计算公式为:

Ni_frame=[Trec*Fframe](2)

其中,Trec表示录制时长,该值根据用户选择来确定,Fframe为帧率,[.]表示取整。

本实施例中,对于视频轨道,平均帧率预先设定为Fframe=24000/1001fps,对于音频轨道,帧率为Fframe=44100/1024(每秒钟音频采样率为44100,每帧1024个采样),录制时长Trec=1h,则本实施例中对于视频轨道,Ni_frame=86313,对于音频轨道,Ni_frame=155039。

以图4所示为例,stts容器中存储的是每个采样(sample)的时长,stts 容器在FullBox的基础(12个字节)上增加了变量(entry_count字段,32位,4个字节)即条目数以及各条目记录,每个条目均用来记录帧信息,如图4所示,若不同帧的采样时长不一致,则每个条目需更新,内容包括该条目所对应的视频帧所包括的采样数和采样时长,例如条目0的采样数sample_count为1,采样时长sample_duration为1025个单位;条目1的采样数sample_count为1,采样时长sample_duration为977个单位,而条目2的采样数sample_count为3,采样时长sample_duration为1001个单位。对于这种情况,stts容器的预留空间为固定字段所需的存储空间大小Si_const与所有条目所需存储空间之和,如下ISO/IEC 14496-12协议中stts容器的定义,当下标i标识stts容器时,固定字段所需的存储空间大小Si_const为16个字节,每帧对应大小Si_frame为8个字节(sample_count和sample_delta各32位,4个字节),帧率是预先设定的,本实施例中视频轨道根据公式(1)计算所得stts容器的预留空间大小Si如图3所示,为690520个字节。

aligned(8) class TimeToSampleBox

extends FullBox(’stts’, version = 0, 0) {

unsigned int(32) entry_count;

int i;

for (i=0; i < entry_count; i++) {

unsigned int(32) sample_count;

unsigned int(32) sample_delta;

}

}

如果track中每个sample的采样时长是一致的,只需记录一个条目便能正常读取mp4文件,为了便于比较,以如图5所示的第二个trak为例,该trak记录音频轨道,stts容器中条目数不会随着录制时长而变化,故此时的stts容器大小固定不变,预留空间等于条目数字段等固定字段所需的存储空间大小(Si_const)16个字节和固定数量条目(一条条目)的大小8个字节之和,预留空间等于有效空间。

采样时长可根据实际场景的需要来设置是否为固定值,简而言之,若预知采样时长不固定,则stts容器为变量子容器,若预设采样时长固定,则stts容器在整个多媒体录制过程中有效空间大小不发生变化,该情况为变量子容器的特例。本发明实施例通过预先配置与stts容器条目内容相关的信息,便可降低预留空间的大小,缩小预留空间和有效空间之间的差距。

如图6所示,stsz容器中定义了每个sample的大小sample_size和媒体中全部sample的数目sample_count,图例中sample_size为0,表明本发明实施例中mp4文件sample的大小不是固定的,需写入每个sample的大小,而sample_count的数据只需更新具体的数值,不会影响stsz容器的大小。显然,stsz容器的有效空间会随着sample条目的增加而递增,但由于预留了足够的空间,新增条目不会覆盖下一个容器。如下ISO/IEC 14496-12协议中stsz容器的定义,当下标i标识stsz容器时,Si_const为FullBox中固定字段(12个字节)、sample_size字段(4个字节)和sample_count字段(4个字节)的总大小,共20个字节,每帧对应大小Si_frame为4个字节,Ni_frame根据上文介绍方式获得,则对于视频轨道,根据公式(1)计算所得stsz容器的预留空间大小如图1中第一个trak中所示,为345272个字节;对于音频轨道,根据公式(1)计算如图1中第二个trak中所示,为620176个字节。

aligned(8) class SampleSizeBox extends FullBox(‘stsz’, version = 0,0) {

unsigned int(32) sample_size;

unsigned int(32) sample_count;

if (sample_size==0) {

for (i=1; i <= sample_count; i++) {

unsigned int(32) entry_size;

}

}

}

stsc容器中描述了sample与chunk的映射关系,chunk可以包含连续存储的一个或多个sample,当chunk中包含多个sample时,chunk与sample的对应关系是不固定的,由于chunk的条目数无法直接估计,若按照最大帧数来估计stsc容器中所需写入的最大条目数,如下ISO/IEC 14496-12协议中stsc容器的定义,stsc容器中固定字段所需的存储空间大小为FullBox对应的12个字节,和其增加的4个字节(对应entry_count变量),共计16个字节,而stsc中每条条目需要12个字节来进行存储,势必导致stsc的预留空间大小远大于stsc在文件录制结束时的有效空间大小,导致空间浪费以及moov容器过大。本实施例为了简化处理,预先设置一个chunk仅包含一个sample,则stsc中只需存储一个条目信息便可实现多媒体文件的正确读取,如图7所示,其预留空间大小为28个字节。

aligned(8) class SampleToChunkBox

extends FullBox(‘stsc’, version = 0, 0) {

unsigned int(32) entry_count;

for (i=1; i <= entry_count; i++) {

unsigned int(32) first_chunk;

unsigned int(32) samples_per_chunk;

unsigned int(32) sample_description_index;

}

}

同样根据ISO/IEC 14496-12协议中定义(下未示),co64容器、stco容器中描述chunk在媒体流中的位置,区别仅在于co64容器对应64位长度,stco容器对应32位长度。由于本实施例中优化了stsc中条目所存储的内容,每个sample便是一个独立的chunk,因此co64容器中所存储的条目与sample为一一对应关系,当下标i标识co64容器时,Si_const为16个字节(FullBox对应的12个字节,和对应类中增加的固定字段entry_count所需的4个字节),每帧对应大小Si_frame为8个字节。对于视频轨道,根据公式(1)计算所得co64容器的预留空间大小如图8所示,为690520个字节。对于音频轨道,根据公式(1)计算如图1中第二个trak容器中所示,为1240328个字节。

stss容器中描述media 容器中的关键帧,关键帧是可独立编解码的帧,对于视频编码来说,需要在box中存储关键帧的序号,而对于音频来说,每一采样都可类比于关键帧。stts容器的预留空间计算公式为:

S=Sconst+Kframe*Sframe(3)

其中,Sconst容器中固定字段所需的存储空间大小之和,用于记录关键帧信息的单个条目所需的存储空间,Kframe表示关键帧的估计数量。

对于stss容器,同样根据ISO/IEC 14496-12协议中stss容器的定义(下未示),由于其也为FullBox类的拓展,Sconst为固定字段entry_count所需的存储空间大小(32位,4个字节)加上FullBox固定字段存储空间所需的12个字节即16个字节,每个关键帧的记录条目所需存储空间大小Sframe为4个字节,关键帧的估计数量Kframe,可根据关键帧的帧率(或帧间隔)来计算,关键帧的帧率通过预设配置,一般设置为单位时长内所具有的关键帧数,或者是间隔固定帧数取一关键帧,本实施例为一秒一次关键帧,则录制时长Trec=3600s时,得到14416个字节,本实施例中为了防止编码器出现误差导致实际关键帧的数量大于计算所得,故而根据单个条目所需的存储空间大小设置了余量(本例中增加了一条作为余量),如图9所示的14420个字节。

本实施例中仅基于stss容器设置了余量,对于其他变量子容器,在实现时也可根据需要设置余量。简而言之,作为一种实施方式,变量子容器的预留空间大小还可包括预设余量,预设余量用于防止条目误差,预设余量根据相应变量子容器所对应的单个条目所需的存储空间大小设置。

总而言之,上述公式(1)与公式(3)中的变量子容器的预留空间大小计算逻辑是一致的,即:

根据变量子容器中所应写入的条目内容和预设的多媒体文件录制时长获取多媒体文件录制结束时在相应变量子容器中所能写入的总条目数的估计值;

根据总条目数的估计值与相应变量子容器中单个条目所需的存储空间大小、固定字段所需的存储空间大小获取相应变量子容器的预留空间大小。

而对于某些能够通过预先配置其条目存储内容而减少预留空间大小的变量子容器,如stts容器和stsc容器,作为变量子容器的特例,与上述一般变量子容器的区别仅在于,相应变量子容器在整个多媒体文件录制过程中所写入的总条目数是固定,无需根据多媒体文件录制时长来获取。

通过上文方式便可估计moov容器中所有子容器的预留空间大小以及moov容器的预留空间大小,下文将结合上文关于固定字段的介绍进一步介绍如何根据moov容器的存储位置偏移、moov容器中各容器的存储顺序以及各容器的预留空间大小依次获取各容器的存储位置偏移。本发明在整个写入过程中,各容器的存储位置偏移均记录在内存中。

如图2所示,moov容器的存储位置偏移为0x24,因moov容器为Box类的扩展类,故其直接包含的第一个容器mvhd容器的存储位置偏移为moov容器的存储位置偏移(0x24)加上moov容器位于头部的固定字段大小(8个字节)即0x2c。

对于moov容器中所直接包含的容器,以trak容器为例,其存储位置偏移则由位于同一层级的mvhd容器的存储位置偏移(0x2c)加上mvhd容器的存储空间(108个字节)来获得,即0x98。

以trak容器中所直接包含的tkhd容器为例,其存储位置偏移为trak容器的存储位置偏移(0x98)加上trak容器固定字段所需的存储空间(8个字节)即(0xa0)。以trak容器中所直接包含的edts容器为例,其存储位置偏移则由位于同一层级的tkhd容器的存储位置偏移(0xa0)加上tkhd容器的存储空间(92个字节)来获得,即0xfc。

简而言之,隶属于同一集装容器的同一层级的容器的存储位置偏移为上一容器的存储位置偏移加该上一容器存储空间之和,集装容器内第一个容器的存储位置偏移为该集装容器的存储位置偏移加上该集装容器所对应的固定字段所需的存储空间。

相较于现有技术,以图2中第一个track中的stts容器为例,该容器为变量子容器,如果按现有技术对moov容器整体更新,则随着录制时长的增加,stts容器所需的存储空间变大,势必会导致stsz容器、stsc容器、co64容器、stss容器的存储位置偏移,如果在moov容器未全部写入时发生异常,则容易导致无法正确查找到在后的几个容器,进而无法播放mp4文件。

本发明方法根据moov容器的存储位置偏移、moov容器中各容器的存储顺序以及各容器的预留空间大小依次获取各容器的存储位置偏移,并将各容器的存储位置偏移记录在内存中。由于预先为各子容器预留了合适的存储空间,在本发明实施例中各容器在存储空间的偏移在整个moov容器的写入过程中可以保持固定不变,即使在moov容器写入过程中发生异常,也不会导致无法查找到子容器,也不会存在某个子容器中所写入的内容被其他子容器覆盖的情况。

下文将介绍如何根据 moov容器的存储位置偏移、各容器的存储位置偏移分别在moov容器及其所包含的各容器内写入相应内容。

作为一种容器内容更新方式,写入过程包括以下步骤:

在初始更新时刻,根据moov容器和各容器的存储位置偏移依次在各容器中写入固定字段所应存储的内容,固定字段的内容与容器类型相关,详见上文描述;对于变量容器,还需写入当前时刻已经存在的条目;

在随后的每一更新时刻,对于moov容器内各容器,更新其内固定字段的值;对于变量子容器,还需更新当前时刻已经存在的条目。

作为另一种容器内容更新方式,为了减少更新内容,对于变量子容器,仅进行部分条目的更新,包括以下步骤:

在初始更新时刻,根据moov容器和各容器的存储位置偏移依次在各容器中写入固定字段所应存储的内容,固定字段的内容与容器类型相关,详见上文描述;对于变量容器,还需写入当前时刻已经存在的条目,并记录最后一个条目的条目编号;

在随后的每一更新时刻,对于moov容器内各容器,更新其内固定字段的值;对于变量子容器,还需根据上一更新时刻所记录的条目编号确定当前更新时刻的起始条目的条目编号后,写入相应数量的条目,并记录最后一个条目的条目编号;若变量子容器在当前更新时刻的条目数量与上一更新时刻的条目数量相同,即上文中所介绍的变量子容器的特例,则无需写入。

上述更新各容器内固定字段的值,根据固定字段值得变化情况,可以是全部更新也可以是仅对发生变化的内容做部分更新。

具体的,以变量子容器stsz容器为例,结合图6、图10、图11所示,在初始更新时刻,根据stsz变量子容器的存储位置偏移(0xa8bd8)写入固定字段的内容,当前时刻已经存在的条目如92条,并记录最后一个条目的条目编号如91;

在紧随其后的一个更新时刻,更新其内固定字段的值,对比图10和图11所示,sample_count字段内容发生变化(对应存储位置偏移0xa8be8),由之前的92(十六进制5C)变为154(十六进制9A);根据上一更新时刻所记录的条目编号91确定当前更新时刻的起始条目的条目编号92后,写入一定数量的条目如62,并记录最后一个条目的条目编号153(对比图10和图11所示,stsz的有效空间大小发生了变化);如此完成随后的每一更新时刻的内容写入。

当然,作为另一种变量子容器的条目更新方式,也可周期写入固定数量的条目,例如每次只写入90个条目,一旦内存中累计90个新条目时则将相应条目写入存储载体中。

作为一种实施方式,本发明还提供一种计算机存储介质,在该存储介质中存储有程序,这样的计算机存储介质可以内置于mp4录制设备中,可通过mp4录制设备提供的物理按键配合显示器抑或是触屏显示器、web界面等供用户在录制mp4文件之前预先设置录制时长以及与帧相关的一些信息,如帧率、关键帧的帧率、编码格式、采样时长等,处理器执行该计算机存储介质中所存储的程序时便可实现mp4文件的录制。

以上详细描述了本发明的优选实施方式,但是,本发明并不限于上述实施方式中的具体细节,在本发明的技术构思范围内,可以对本发明的技术方案进行多种等同变换,这些等同变换均属于本发明的保护范围。

22页详细技术资料下载
上一篇:一种医用注射器针头装配设备
下一篇:用于执行参考电压训练操作的系统

网友询问留言

已有0条留言

还没有人留言评论。精彩留言会获得点赞!

精彩留言,会给你点赞!