我正在尝试使用基于来自C++的概念的本NeHe教程接口编写一个OpenGL视频类,但使用更现代的代码(用于OpenGL 3/4)。在最初加载视频(而不是检索帧)的函数中,我引用了AVIStreamGetFrameOpen() (根据MSDN )
返回可以与GetFrame函数一起使用的AVIStreamGetFrame对象。
同一页还说:
如果系统找不到可以将流解压缩为给定格式或任何RGB格式的解压缩器,则函数返回NULL。
我的问题是 AVIStreamGetFrameOpen()返回NULL,如前所述,这意味着没有找到与文件匹配的解压缩程序。但是,我的文件可以在Windows中播放,没有问题,我认为这意味着应该可以使用解压缩器。
当涉及到VFW时,似乎缺乏文档,而且MSDN页面并不总是非常有用。有人知道是什么导致了这个问题吗?
下面是该函数的代码:
bool Video::Load(std::string FileName) {
try {
if (this->bLoaded)
this->UnLoad();
AVIFileInit();
if (AVIStreamOpenFromFile(&pavi, FileName.c_str(), streamtypeVIDEO, 0, OF_READ, NULL) != 0)
throw "Failed to open the AVI video stream.";
AVIStreamInfo(pavi, &psi, sizeof(psi)); // Reads Information About The Stream Into psi
this->szWidth = psi.rcFrame.right - psi.rcFrame.left; // Width Is Right Side Of Frame Minus Left
this->szHeight = psi.rcFrame.bottom - psi.rcFrame.top; // Height Is Bottom Of Frame Minus Top
ulnLastFrame = AVIStreamLength(pavi); // The Last Frame Of The Stream
this->dDuration = AVIStreamSampleToTime(pavi, ulnLastFrame) / 1000.0f;
this->dSecondsPerFrame = this->dDuration / ulnLastFrame;
pgf = AVIStreamGetFrameOpen(pavi, NULL); // Create The PGETFRAME Using Our Request Mode
if (pgf == NULL)
// ===== ERROR THROWN HERE =====
throw "Failed to open the AVI GetFrame object.";
glGenTextures(1, &this->unTexID);
glBindTexture(GL_TEXTURE_2D, this->unTexID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, this->szWidth, this->szHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
}
catch (const char* e) {
Message((std::string("Error: ") + e + "\nFile: \"" + FileName + "\"").c_str(), "Error");
return false;
}
this->bLoaded = true;
return true;
}忽略我奇怪的变量前缀。
发布于 2016-08-30 18:53:22
我的问题是,AVIStreamGetFrameOpen()返回NULL,如前所述,这意味着没有找到与文件匹配的解压缩程序。但是,我的文件可以在Windows中播放,没有问题,我认为这意味着应该可以使用解压缩器。
您认为应该提供解压缩器的假设是错误的。
Windows提供了几个与视频和音频相关的基线API:用于Windows的视频、DirectShow、媒体基金会、以及Windows。上面也有层(AudioVideoPlayback,MediaElement等)。
API之间存在一定的互操作性:有时API之间共享编解码器和其他对象,或者一个API为其他对象提供兼容性包装器。
然而,在您的场景中,情况并非如此。是一个遗留的API,它无法为更新的API使用编解码器。反过来使用Media作为主API,而DirectShow作为复杂场景的备用API,在这种情况下,它提供了第二次尝试播放文件的机会。基本上,Windows当前版本中仍然存在的唯一原因是对遗留应用程序的支持:新提供的视频/音频相关功能不适用于VFW,不仅是微软的,还有第三方。
另外,32位编解码器和64位编解码器是独立的,某些代码只能使用各自比特的编解码器。
也就是说,Windows和您的代码在消耗相同的API方面没有交集。播放该文件并不意味着您的VFW代码也应该能够播放。您遇到的问题是,没有安装合适的解码器从文件中读取和解码视频(您没有提到格式,盲目猜测这里是AVI与H.264视频)。
发布于 2019-02-13 14:28:24
VFW是非常古老的/遗留的/废弃的。
根据视窗,VFW只支持以下格式:
我也在阅读NeHe教程。第35课中使用的Face2.avi是用cinepak格式编码的。
E:\>ffmpeg -i Face2.avi -hide_banner
Input #0, avi, from 'Face2.avi':
Duration: 00:00:03.04, start: 0.000000, bitrate: 1116 kb/s
Stream #0:0: Video: cinepak (cvid / 0x64697663), rgb24, 160x120, 29.97 tbr, 29.97 tbn, 29.97 tbc
~~~~~~~如果必须使用VFW,可以使用用于Windows的ffmpeg将视频转换为cinepak或msvideo1格式:
ffmpeg -i your_video.xxx -vcodec cinepak output.avi(转换到cinepak比msvideo1花费的时间要长得多,但它的质量要好得多。)
https://stackoverflow.com/questions/39059959
复制相似问题