做网络视频监控的时候用到了AVIFile,将一帧一帧图像压缩编码成avi文件。一开始程序在执行到AVISaveOptions时总是会自动弹出一个选择框,里面列出了系统所带的各种编码格式。但是因为我们的项目确定了要用mpeg-4编码,所以每次在保存视频之前都选择的话是比较多余的而且会使用户感受比较差。因此,我就研究了下如何在程序中设置编码类型,然后阻止对话框的弹出。
里面有两个变量,opts和aopts;
AVICOMPRESSOPTIONS opts;
AVICOMPRESSOPTIONS FAR * aopts[1] = {&opts};
弹出选择对话框的是以下的if语句,当用户选择了编码类型之后,aopts就有值了,后面也就可以进一步进行编码工作了。
if (!AVISaveOptions(NULL, 0, 1, &m_pStream, (LPAVICOMPRESSOPTIONS FAR *) &aopts))
{
AVISaveOptionsFree(1,(LPAVICOMPRESSOPTIONS FAR *) &aopts);
return S_FALSE;
}
看起来突破点就只有自己给opts正确赋值,然后才可以进行正确的压缩编码了。上网搜了很多帖子,以下两个帖子给了我很大的帮助。
http://topic.csdn.net/t/20020817/19/949116.html
http://topic.csdn.net/u/20071227/16/c0166735-bf83-4e6a-a10c-77bafcfd8fb1.html
但是,因为每个人的具体情况是不同的,有的代码也不是完全正确的,需要自己去调试,去改正。比如,第一个帖子里提到的给lpParms和cbParms赋值的方法我也试过了,但是好像有问题。这个过程也是学到了很多的。于是,又上msdn查opts的数据结构,单步调试程序看opts的赋值情况,换不同电脑看赋值有何不同,折腾来折腾去,终于搞定了一套方法。代码如下:
// Step 4: Get codec and infos about codec
//首先利用ICOpen打开一个编码器或者解码器,我要用的是xvid
HIC hic=ICOpen(mmioFOURCC('v','i','d','s'), mmioFOURCC('X','V','I','D'), ICMODE_COMPRESS);
DWORD dwSize=ICGetStateSize(hic);
LPVOID lpvod=(LPVOID)GlobalAlloc(NULL,dwSize);
ICClose(hic);
memset(&opts, 0, sizeof(opts));
//给opts结构体赋值
opts.fccType=0;
opts.fccHandler=0x64697678;//xvid 1684633208 这个是fccHandler的值,可以从ICGetInfo中得到
//opts.fccHandler=0x6376736d;//microsoft video 1 compression
//opts.fccHandler=0x64697663;// for cinepak codec
opts.dwKeyFrameEvery=0;
opts.dwQuality=0;
opts.dwBytesPerSecond=0;
opts.dwFlags=8;//AVICOMPRESSF_KEYFRAMES;
opts.lpFormat=0x00000000;
opts.cbFormat=0;
opts.lpParms=lpvod;
opts.cbParms=dwSize;
opts.dwInterleaveEvery=0;
// Step 5: Create a compressed stream using codec options.
hr = AVIMakeCompressedStream(&m_pStreamCompressed,
m_pStream,
&opts,
NULL);
这样就可以了。
这件事给我的感受是不要怕麻烦,不要眼高手低,觉得这个问题有多难多难然后就不愿意付出行动。一开始我是有抵触心理的,但是事实证明,无论表面看起来多难的问题都有解决办法。在我查资料的过程中,还有一点体会,就是不放过任何一个机会。我记得很清楚的是,在我查看了好多网页都无果的时候,我真的是快放弃了。但是后来点开一个网页,这个网页已经无法查看了。不过我另辟蹊径,点开了网页快照,功夫不负有心人,终于让我找到点思路,心里还是很开心的,呵呵。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/mengzhuanghua/archive/2010/10/22/5959688.aspx