我想写使用AVIStreamWrite AVI文件,但生成的AVI文件是有点乱了。 avi中的图像包含适当的图像和颜色,但视频的持续时间和速度已关闭。我录制了一段应该在7秒钟左右的视频,并在Windows资源管理器中查看文件属性,结果显示它有大约2秒的持续时间。当我在媒体播放器中播放它时,它太短了,似乎很快播放(视频中的动作就像快进)。我似乎也无法使用Media Player在视频中寻找。 下面是我在做什么...AVI有不正确的长度和播放速度
//初始化
HRESULT AVIWriter::Init()
{
HRESULT hr = S_OK;
_hAVIFile = NULL;
_videoStream = NULL;
_frameCount = 0;
AVIFileInit();
::DeleteFileW(_filename);
hr = AVIFileOpen(&_hAVIFile,_filename,OF_WRITE|OF_CREATE, NULL);
if (hr != AVIERR_OK)
{
::cout << "AVI ERROR";
return 0;
}
/**************************************/
// Create a raw video stream in the file
::ZeroMemory(&_streamInfo, sizeof(_streamInfo));
_streamInfo.fccType = streamtypeVIDEO; // stream type
_streamInfo.fccHandler = 0; // No compressor
_streamInfo.dwScale = 1;
_streamInfo.dwRate = _aviFps; //this is 30
_streamInfo.dwSuggestedBufferSize = 0;
_streamInfo.dwSampleSize = 0;
SetRect(&_streamInfo.rcFrame, 0, 0,_bmi.biWidth , _bmi.biHeight);
hr = AVIFileCreateStream( _hAVIFile, // file pointer
&_videoStream,// returned stream pointer
&_streamInfo); // stream header
hr = AVIStreamSetFormat(_videoStream, 0,
&_bmi,
sizeof(_bmi));
return hr;
}
//调用这个,当我从我的相机接收帧
HRESULT AVIWriter::AddFrameToAVI(BYTE* buffer)
{
HRESULT hr;
long size = _bmi.biHeight * _bmi.biWidth * 3;
hr = AVIStreamWrite(_videoStream, // stream pointer
_frameCount++, // time of this frame
1, // number to write
buffer, // pointer to data
size,// size of this frame
AVIIF_KEYFRAME, // flags....
NULL,
NULL);
return hr;
}
//调用此当我做
void AVIWriter::CloseAVI()
{
AVIStreamClose(_videoStream);
AVIFileClose(_hAVIFile);
AVIFileExit();
}
现在,作为一个测试我用DirectShow中的GraphEdit中创建包含此相同的相机VideoCapture过滤器和AVI MUX的图形和创建的AVI文件。由此产生的AVI文件很好。帧速率为30 fps,与我使用的相同。我通过调用AVIStreamInfo来查询两个avi文件(我的'坏'和'用'GraphEdit创建的'好'),两个文件的流信息几乎相同。我本来预计每秒样本数量或者帧数是为了我的'坏'avi,但事实并非如此。我做错了什么,会导致我的AVI有不正确的长度,似乎以提高的速度播放?我是新来的使用VFW,所以任何帮助表示赞赏。谢谢
那么,多少帧你居然写的呢?什么是关闭文件时的_frameCount?它不是'150',是吗? – 2012-02-03 15:49:34
嗯...所以我再次跑了一遍,我录了大约14秒,最后拍了大约4秒的视频。 _frameCount实际上是141帧,其在30fps约4.7秒。似乎我必须在某个地方丢帧。基本上我做的是我创建了一个DirectShow图形连接到我的笔记本电脑摄像头,使用ISampleGrabberCB我抓住每一帧,然后发布给我的订阅者,其中之一是我的avi作家。我猜我在我的sampleGrabberCB中或者在我的发布框架中大约每四帧中就有一帧丢失。 – mash 2012-02-03 16:10:55