无代码单色 AVI 读取器






2.86/5 (4投票s)
2006年5月15日
1分钟阅读

46763

1660
无需安装编解码器驱动即可读取 AVI 文件的方法。
引言
当我使用 C++ 项目处理单色 AVI 文件时,我注意到在某些机器上,我需要管理员权限才能安装编解码器驱动程序。由于我在学校计算机实验室工作,获取这些权限非常困难,我选择通过直接使用 DLL 驱动程序来解决问题,而不是通过操作系统使用它。
背景
本文使用了 Ben Rudiak-Gould 在 GPL 许可下开发的无损 Win32 视频编解码器 Huffyuv 的代码。
它还使用了开源计算机视觉库 OPENCV 来查看帧。
使用代码
AVI 读取器被封装在一个名为 CMonochromeAviReader
的类中。
读取器使用从原始 Huffyuv 代码编译的编解码器库。对 Ben 代码所做的修改是向编解码器主结构 CodeInst
添加了关键字 __declspec(dllexport)
。
struct __declspec(dllexport) CodecInst {
...
};
创建了两个实例:第一个 CodecInst m_codec
用于编解码器,另一个 ICDECOMPRESS m_icinfo
必须跟踪一个帧的压缩和未压缩数据。
typedef struct { DWORD dwFlags; LPBITMAPINFOHEADER lpbiInput; LPVOID lpInput; LPBITMAPINFOHEADER lpbiOutput; LPVOID lpOutput; DWORD ckid; } ICDECOMPRESS;
字段 lpInput
用于从未压缩的数据中提取数据,而 lpOutput
用于压缩数据。
IplImage* CMonochromeAviReader::ReadFrame(unsigned int index) { AVIStreamRead(m_pAviStream, index, 1, m_icinfo.lpInput, m_frameStreamLength, NULL, NULL); if(... compressed data ...) { m_codec.Decompress(&m_icinfo, 0); m_codec.DecompressEnd(); cvSetImageData(m_pFrameRGB,m_icinfo.lpOutput,m_width*3); ... return m_pFrame; } else if(... uncompressed data ...) { cvSetImageData(m_pFrame,m_icinfo.lpInput,m_width*1); return m_pFrame; } else { return NULL; } }
请注意,OPENCV 函数 cvSetImageData( IplImage* image, void* data, width)
也可以替换为 memcpy(IplImage* image->imageData,void *data, width*height)
,但 cvSetImageData
更好,因为它针对 Intel 处理器进行了优化,并且它不会复制所有数据;它只是一个指向,而 memcpy
必须将内存复制到新分配的空间中。
修订历史
16-05-2006
- 修复了
Close
方法中的错误。
15-05-2006
- 原始文章。
就这样,各位!