开始录象文件路径是否为空初始化音、视频的录象文件格式参数,创建文件的视频stream和音频streamN初始化录象数据参数,比特率、宽高、帧率、数据类型等初始化参数是否成功Y创建录象文件(xx.mp4),往目标文件写文件头NY创建文件是否成功调用音频、视频编解码模块的回调函数,准备获取编码后的音频和视频数据Y打开audio/video callback 函数N返回
录象实现把视频和音频数据写入文件:
这个函数是录象中最主要的函数,实现音频和视频数据的文件写入。因为视频和音频是两个线程,因此将一个时间只能允许一个线程操作。录象文件可能会有录制时间和文件长度的限制,因此写入文件之前,先进行判断。如果有一个条件满足,就关闭audio/video callback 函数。然后通知上层录制完毕,可以结束录像。
如果没有到达限制条件,开始写数据。对于音频数据,设置信息,写记录头,
34
写记录数据;对于视频数据,记录索引标识视频流id,将所有满足条件(指定时间或指定文件长度或未停止录象)的数据在文件中的位置记录下来,方便结束时处理;最后设置信息,写记录头,写记录数据。
流程图如下:
开始audio/video 模块编码后的数据callback 函数收到编码后的数据到达通知锁住函数防止重入lock()是否满足结束录象条件N文件是否已经创建YN关闭audio/video callback 函数关闭audio/video callback 函数Y应用层回调指针是否为空NY通知应用层录象失败,文件未创建成功是音频还是视频数据Y把视频数据写入视频流N应用层回调指针是否为空NY把音频数据写入音频流通知应用录制完毕,已经结束录像解开锁Unlock()返回 35
结束录象流程:
开始是否正在录象Y关闭audio/video callback 函数关闭视频流、音频流N关闭录象文件返回
5.2.1、双缓冲区的存储优化
本文实现过程中发现在使用nannd flash的硬件时,即使wince5.0有了读写缓冲机制,但是在保存到SD卡过程中,还是会产生阻塞,而且这个阻塞时间有时非常长,严重影响了音、视频编码后数据流的保存。
对于编码出来的码流有音频和视频两种,在数据回调过来以后都需要立即放入缓冲区中。双缓冲的原理是,音频和视频数据回来后立刻放入缓冲区A,然后通知取数据的线程,有数据到达;这时线程开始工作,把数据取出来,放到缓冲区B中,然后每当数据满1兆的时候,开始集中写一次文件,平均每写一次文件时间大概500-700ms。
在写文件线程激活的同时,还有音频和视频数据编码完成,这时会把数据立
36
刻放入到缓冲区A中,因为取数据的工作线程消耗的时间,要比数据到达的时间要短,所以缓冲区A不用多长时间会被立即取空。
这样就达到了防止SD卡保存文件,或者flash保存文件的时候引起的阻塞,导致编码帧率降低。
缓冲区A中保存的数据结构: //录象缓冲帧结构
typedef struct tagRecordFrame { }
RECORDFRAME, FAR *LPRECORDFRAME, *PRECORDFRAME; //音频采集数据的结构体 typedef struct {
int iCodecID; // 算法ID
int iSilenceSuppression; // 是否支持静音
int iMaxAI_sduAudioFrames; // 1..256, 每次可以解码的帧数 } AUDIO_CAP;
INT INT INT INT INT
nVideoFormat; nWidth; nHeight;
//视频格式 //宽度
//高度
//数据长度(防止损坏的数据)
//Frame Reference by 30f/s //编码前数据指针 //编码后数据指针
//时间戳
nBufferLength; nTimeRef;
unsigned char unsigned char DWORD BOOL BOOL
*pYUVBuffer; *pCodecBuffer;
dwTimeCaptured;
bIsSnapShot; //快照数据
//1视频数据 0音频数据
bIsVideoData;
37
相关推荐: