微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用DirectShow将video捕获到AVI文件

我正在尝试用directshow编写一个C ++应用程序,将video捕获保存到文件中。 代码中的步骤是:1.创buildCapture Graph Builder 2.创build系统设备枚举器3.创build系统设备枚举器 – 为了获取捕获filter4.为video捕获类别创build一个枚举器5.创build查询捕捉video

附加代码

// gets the device filter HRESULT getDeviceFilter(REFCLSID clsid,int order,IBaseFilter **pCap) { ICreateDevEnum *pDevEnum = NULL; IEnumMoniker *pEnum = NULL; // Create the System Device Enumerator. HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER,IID_ICreateDevEnum,reinterpret_cast<void**>(&pDevEnum)); if (SUCCEEDED(hr)) { // Create an enumerator for the video capture category. hr = pDevEnum->CreateClassEnumerator( clsid,&pEnum,0); } IMoniker *pMoniker = NULL; if (pEnum->Next(1,&pMoniker,NULL) == S_OK) hr = pMoniker->BindToObject(0,IID_IBaseFilter,(void**)pCap); return hr; } int main() { IGraphBuilder *pGraph = 0; ICaptureGraphBuilder2 *pBuild = 0; IBaseFilter *pCap = 0; HRESULT hr = CoInitialize(NULL); // Create the Capture Graph Builder. hr = CoCreateInstance(CLSID_CaptureGraphBuilder2,IID_ICaptureGraphBuilder2,(void**)&pBuild ); ICreateDevEnum *pDevEnum = NULL; IEnumMoniker *pEnum = NULL; // Create the System Device Enumerator. hr = CoCreateInstance(CLSID_SystemDeviceEnum,reinterpret_cast<void**>(&pDevEnum)); IBaseFilter *pMux = 0; hr = pBuild->SetoutputFileName(&MEDIASUBTYPE_Avi,// Specifies AVI for the target file. L"C:\Example.avi",// File name. &pMux,// Receives a pointer to the mux. NULL); // (Optional) Receives a pointer to the file sink. // gets the first device,VDM tv card hr = getDeviceFilter(CLSID_VideoInputDeviceCategory,&pCap); hr = pBuild->RenderStream(&PIN_CATEGORY_CAPTURE,// Pin category. &MEDIATYPE_Video,// Media type. pCap,// Capture filter. NULL,// Intermediate filter (optional). pMux); // Mux or file sink filter. // Release the mux filter. pMux->Release(); IConfigAviMux *pConfigMux = NULL; hr = pMux->QueryInterface(IID_IConfigAviMux,(void**)&pConfigMux); if (SUCCEEDED(hr)) { pConfigMux->SetMasterStream(1); pConfigMux->Release(); } return 0; }

但是,在调用RenderStream时,我得到一个E_INVALIDARG错误

有什么build议么?

通过C#加载时的空白Windowsfunction列表

使用C ++从Windows资源pipe理器获取图像属性

子请求不发送或请求挂起

我们如何轮询堆栈状态 – 未使用(可用)的内存

不匹配的c + +头版本

谢谢

为什么单线程比使用pthread的Ubuntu中的multithreading更快?

如何在C ++中使用Visual Studio使用二维数组?

以编程方式刻录CD

Winapishell扩展覆盖Windows命令

如何编辑在Windowsregistry值(registry)通过代码在C#?

看看这个话题 。 看来你已经错过了一些步骤。

首先,你没有在任何地方使用pGraph 。 您应该创建一个图形管理器,然后通过使用SetFiltergraph提供一个指向图形管理器的指针来初始化图形构建器。

// Create the Filter Graph Manager. hr = CoCreateInstance(CLSID_Filtergraph,IID_IGraphBuilder,(void**)&pGraph); if (SUCCEEDED(hr)) { // Initialize the Capture Graph Builder. pBuild->SetFiltergraph(pGraph); // ... }

其次,您使用的是不是由图形管理器管理的过滤器。 从这里引用:

调用方法之前,必须将pSource,pIntermediate和pSink指定的所有过滤器添加到图中。

您必须使用AddFilter将过滤器pCap和pMux添加到您之前创建的图形管理器。 你应该在调用RenderStream之前做这个。 这是因为RenderStream最终调用管理器上的连接方法

如果上述步骤不能解决您的问题,还有其他几件事情可以尝试。

设备过滤器 。 您正在使用CLSID_VideoInputDeviceCategory的第一个设备,但是您确定这是正确的设备吗? 网络摄像头等也包含在这个类别中。 确保没有连接相同类别的其他设备,然后重试。

连接 。 每个设备是不同的。 这可能是您的设备不能直接连接到多路复用器。 在这种情况下,我们必须弄清楚为什么,并确定是否需要连接额外的滤波器(如解码器)。 GraphEdit是一个非常快速方法来找到这些过滤器。

Pin类别/媒体类型 。 根据我的经验,E_INVALIDARG是由RenderStream的前两个参数引起的90%的时间。 尝试将引脚类别或媒体类型设置为NULL 。

系统设备枚举器 :正如你自己所描述的,你正在创建一个系统设备枚举器两次。 这对我来说似乎很奇怪,为什么不使用一个呢?

如果你的代码仍然不起作用,你应该提供给我更多的信息。 使用GraphEdit时你有没有达到目标? 您的VDM电视卡过滤器如何看起来像(引脚,媒体类型)?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐