进展:保存为无压缩的avi格式文件,回放框架初步搭建起来
方案的选择:
- 简单的方法是使用openCV
- 创建文件存储原始数据(无压缩)
- 解析avi格式,用微软的库去操作
如果不压缩保存avi,数据量还是很大 ,大约每秒100兆左右。考虑到时间的问题和内存的问题(边播放边压缩和存储),在可以容忍的条件下,先搁置一下压缩的问题,把路子走通。
1) AVIFileInit();//初始化;
2) AVIFileOpen(); //打开一个AVI文件并获文件的句柄;
3) AVIFileInfo(); //获取文件的相关信息,如图像的Width和Height等;
4) AVIFileGetStream(); //建立一个指向需要访问的数据流的指针;
5) AVIStreamInfo(); //获取存储数据流信息的AVISTREAMINFO结构;
6) AVIStreamRead(); //读取数据流中的原始数据, 对AVI文件进行所需的编辑处理;
7) AVIStreamRelease(); //释放指向视频流的指针;
8) AVIFileRelease();//释放流
9) AVIFileExit(); //释放AVI文件,断开流与文件的关联
把按帧把内存数据依次写入文件的过程中,遇到不少错误,也收获了些许经验;比如是否应该把avi对象放入已有的类中进行类内操作,还是设置成全局变量。经过一番折腾,终于看到avi文件出现了;文件太大是意料之中的,但是存储播放视频发现图像上下倒置。是内存数据存放的问题?还是写入的时候,读取方式从后到前啊?最后查明原因是后者,存储顺序是这样的:先从图像最下面一行开始,从左向右,依次存储,最后存储正数第一行。明白问题所在了,方法也就有了。下面是数据倒置和帧写入文件的部分代码。
BYTE *pBuffer = new BYTE[LockedRect.size];
for(int i = 0; i < 480; i++) {
//优化效率 knife-1
memcpy(pBuffer + i * 640 * 4,(BYTE*)LockedRect.pBits + (480 - i - 1) * 640 * 4,640 * 4);
}
hr = AVIStreamWrite(ps,frame,1,(LPBYTE)pBuffer,LockedRect.size,AVIIF_KEYFRAME, NULL, NULL);
delete []pBuffer;
在回放的时候还要把数据再倒置一遍,使其正确绘出,这是意料之中的事。这样一来,我所做的事情是这样的:保存和读取各倒置了一次数据,达到的目的就是保存的avi视频文件在其他播放器(QQ影音,media player)中图像不至于上下颠倒。
由于通过内存映射文件可以在多个进程间共享数据,因此在进行这种应用时应当考虑dwShareMode参数设置对运行结果的影响。
说明:
SYSTEM_INFO结构体包含了当前计算机的信息。这个信息包括计算机的体系结构、中央处理器的类型、系统中中央处理器的数量、页面的大小以及其他信息。