【问题标题】:DirectShow - Selecting video deviceDirectShow - 选择视频设备
【发布时间】:2013-06-06 15:02:24
【问题描述】:

这是我在 MSND 参考之后能够编写的代码: http://msdn.microsoft.com/en-us/library/dd407269(v=vs.85).aspx

#include <iostream>
#include <conio.h>
#include <dshow.h>

// Helper function for initializing ICaptureGraphBuilder2 and IGraphBuilder
// MSDN function: http://msdn.microsoft.com/en-us/library/dd373396(v=vs.85).aspx
// Arguments are passed  by pointers
HRESULT InitCaptureGraphBuilder(ICaptureGraphBuilder2 **, IGraphBuilder **);

// Helper function for retriving an enumerator for a specified device category
// MSDN function:          http://msdn.microsoft.com/en-us/library/dd377566(v=vs.85).aspx
// MSDN about moniker:     http://msdn.microsoft.com/en-us/library/ms679705(v=vs.85).aspx
// MSDN about enumerator:  http://msdn.microsoft.com/en-us/library/dd407292(v=vs.85).aspx
// You need to pass by reference the type of device a nd by pointer the IEnumMoniker
HRESULT EnumerateDevices(REFGUID, IEnumMoniker **);

// Helper function for preparing the output video file
// You need to pass by ponter ICaptureGraphBuilder2 and IBaseFilter
HRESULT PrepareOutputFile(ICaptureGraphBuilder2 **, IBaseFilter **);

int main()
{
   ICaptureGraphBuilder2   *capture_graph       = NULL;
   IGraphBuilder           *graph               = NULL;
   IEnumMoniker            *device_enumerator;
   IBaseFilter             *capture_filter;
   HRESULT                 hr;

   hr = CoInitialize(NULL);
   hr = InitCaptureGraphBuilder(&capture_graph, &graph);
   hr = EnumerateDevices(CLSID_VideoInputDeviceCategory, &device_enumerator);

   // hr = PrepareOutputFile(&capture_graph, &capture_filter);

   // At the end:
   // capture_graph->Release();
   // graph->Release();

}

HRESULT InitCaptureGraphBuilder(ICaptureGraphBuilder2 **ppCapture_graph, IGraphBuilder **ppGraph)
{
   if (!ppCapture_graph || !ppGraph) {
      return E_POINTER;
   }

   ICaptureGraphBuilder2   *capture_graph  = NULL;
   IGraphBuilder           *graph  = NULL;

   // Create the Capture Graph Builder
   HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&capture_graph);

   if (SUCCEEDED(hr)) {
      // Create the Filter Graph Manager
      hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&graph);

      if (SUCCEEDED(hr)) {
         // Initialize the Capture Graph Builder
         capture_graph->SetFiltergraph(graph);

         // Return both interface pointers to the caller
         // !! The caller must release both interfaces !!
         *ppCapture_graph  = capture_graph;
         *ppGraph          = graph;

         return S_OK;
      } else {
         capture_graph->Release();
      }
   }

   // Failed
   return hr;
}

HRESULT EnumerateDevices(REFGUID category, IEnumMoniker **ppDevice_enumerator)
{
   ICreateDevEnum *create_dev_enum;

   // Create the System Device Enumerator
   HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&create_dev_enum));

   if (SUCCEEDED(hr)) {
      // Create an enumerator for the selected category
      hr = create_dev_enum->CreateClassEnumerator(category, ppDevice_enumerator, 0);

      if (hr == S_FALSE) {
         // The category is empty. Treat as an error
         hr = VFW_E_NOT_FOUND;
      }
      create_dev_enum->Release();
   }

   return hr;
}

现在我仍然不明白如何选择我想要的视频设备。 使用EnumerateDevices() 函数,我返回枚举器(我认为是一种包含所有设备的向量),但我如何在PrepareOutputFile()(我必须写)之前使用它?!

【问题讨论】:

  • 还可以看看 AForge.NET,这是一个非常易于使用、文档完善的框架,它封装了 DirectShow 的难点:aforgenet.com

标签: c++ windows device directshow enumerate


【解决方案1】:

请参阅 MSDN 上的 Selecting a Capture Device。你基本上是在做那里的拳头代码 sn-p 建议。进一步看一下 - 它会指导您下一步做什么,特别是 IMoniker::BindToObject 是为您的捕获图过滤实例的调用。

【讨论】:

  • 我继续阅读这篇文章,是的,我找到了我正在搜索的内容。我每天都在做这个项目,所以我有点累了......非常感谢!
  • @Romar R. 我不明白最后一段代码:'IBaseFilter pCap = NULL; hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void*)&pCap); if (SUCCEEDED(hr)) { hr = m_pGraph->AddFilter(pCap, L"捕获过滤器"); }' 我应该把它放在 Main 函数还是 DisplayInformation() 里面? m_Graph 和我的 IGraphBuilder *graph 一样吗?
  • 当你枚举对象时你会得到IMoniker,一旦你得到pMoniker,你就可以使用它的BindToObject——来创建实际的过滤器。或者,您可以在以后随时操作,只要您握住界面即可。
  • +1 @RomanR。 - 我从来不明白绰号是什么。如果可以发表评论将不胜感激。谢谢。
  • Moniker 在这里是一种短路。您将获得一个命名对象,通过BindObject 方法,您可以在需要时获得真正的设备。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-12
  • 2011-12-23
  • 1970-01-01
相关资源
最近更新 更多