2016-11-22 3 views
0

キャプチャを開始カント私はビデオに画面と音声をキャプチャすることができ、自分のアプリケーションを作成するには、Windowsのdevの中央上のDirectShow例フォロースルーしようとしています:Capturing Video to an AVI FileDirectShowは二回

初めてのキャプチャは、すべてがOKです開始しますしかし、2番目の何も起こらない、ビデオとファイルが表示されません。私は初期化を忘れてしまった可能性はありますか?

更新日 問題がリリースされていないようです。第二の時間の流れは、ファイル1.aviが作成された書き込みが、それは、空とpMediaControl->Stop();が行われたときに自動的に私がことがわかった2回目のアップデート2

を削除します。

   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. 

戻りE_INVALIDARG

   if (a == 1) { 
        CComPtr<IPin> sourcePin; 
        CComPtr<IPin> dumpPin; 
        sourcePin = GetPin(pMux, PINDIR_OUTPUT); 
        dumpPin = GetPin(pCap, PINDIR_INPUT); 
        hr = ppGraph->Connect(sourcePin, dumpPin); 
       } 

そして私はdumpPin値がOK NULL【選択hr = ppGraph->AddFilter(pCap, L"Capture Filter");実行である第二の時間にthahtを見つけました:だから私は(using this)を追加しました。どこでエラーを見つけるために次に掘ることができますか?

(コードが更新される)

マイコード:

#include "stdafx.h" 
#include <iostream> 

#include <windows.h> 
#include <dshow.h> 

#include <atlbase.h> 
#include <dshow.h> 


#include <vector> 
#include <string> 

#pragma comment(lib, "strmiids") 


IPin *GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir) 
{ 
    BOOL  bFound = FALSE; 
    IEnumPins *pEnum; 
    IPin  *pPin; 

    pFilter->EnumPins(&pEnum); 
    while (pEnum->Next(1, &pPin, 0) == S_OK) 
    { 
     PIN_DIRECTION PinDirThis; 
     pPin->QueryDirection(&PinDirThis); 
     if (bFound = (PinDir == PinDirThis)) 
      break; 
     pPin->Release(); 
    } 
    pEnum->Release(); 
    return (bFound ? pPin : 0); 
} 

HRESULT EnumerateDevices(REFGUID category, IEnumMoniker **ppEnum) 
{ 
    // Create the System Device Enumerator. 
    ICreateDevEnum *pDevEnum; 
    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, 
     CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDevEnum)); 

    if (SUCCEEDED(hr)) 
    { 
     // Create an enumerator for the category. 
     hr = pDevEnum->CreateClassEnumerator(category, ppEnum, 0); 
     if (hr == S_FALSE) 
     { 
      hr = VFW_E_NOT_FOUND; // The category is empty. Treat as an error. 
     } 
     pDevEnum->Release(); 
    } 
    return hr; 
} 

HRESULT InitCaptureGraphBuilder(
    IGraphBuilder **ppGraph, // Receives the pointer. 
    ICaptureGraphBuilder2 **ppBuild // Receives the pointer. 
) 
{ 
    if (!ppGraph || !ppBuild) 
    { 
     return E_POINTER; 
    } 
    IGraphBuilder *pGraph = NULL; 
    ICaptureGraphBuilder2 *pBuild = NULL; 

    // Create the Capture Graph Builder. 
    HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, 
     CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&pBuild); 
    if (SUCCEEDED(hr)) 
    { 
     // Create the Filter Graph Manager. 
     hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC_SERVER, 
      IID_IGraphBuilder, (void**)&pGraph); 
     if (SUCCEEDED(hr)) 
     { 
      // Initialize the Capture Graph Builder. 
      pBuild->SetFiltergraph(pGraph); 

      // Return both interface pointers to the caller. 
      *ppBuild = pBuild; 
      *ppGraph = pGraph; // The caller must release both interfaces. 
      return S_OK; 
     } 
     else 
     { 
      pBuild->Release(); 
     } 
    } 
    return hr; // Failed 
} 

struct Capture { 
    IPropertyBag *pPropBag; 
    IGraphBuilder *ppGraph; 
    IBaseFilter *pCap; 
    ICaptureGraphBuilder2 *pBuild; 
}; 

void DisplayDeviceInformation(IEnumMoniker *pEnum,int a) 
{ 
    IMoniker *pMoniker = NULL; 
    std::vector<Capture> captures; 

    while (pEnum->Next(1, &pMoniker, NULL) == S_OK) 
    { 
     IPropertyBag *pPropBag; 
     HRESULT hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag)); 
     if (FAILED(hr)) 
     { 
      pMoniker->Release(); 
      continue; 
     } 

     VARIANT var; 
     VariantInit(&var); 

     hr = pPropBag->Read(L"DevicePath", &var, 0); 
     if (SUCCEEDED(hr)) 
     { 
      // The device path is not intended for display. 
      printf("Device path: %S\n", var.bstrVal); 
      VariantClear(&var); 
     } 

     IGraphBuilder *ppGraph; 
     ICaptureGraphBuilder2 *pBuild; // Capture Graph Builder 
     hr = InitCaptureGraphBuilder(&ppGraph, &pBuild); 


     IBaseFilter *pCap; // Video capture filter. 
     hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pCap); 
     if (SUCCEEDED(hr)) 
     { 
      std::wstring name = std::wstring(L"C:\\a\\") + std::to_wstring(a) + std::wstring(L".avi"); 
      const wchar_t *cname = name.c_str(); 
      hr = ppGraph->AddFilter(pCap, L"Capture Filter"); 
      if (SUCCEEDED(hr)) { 
       IBaseFilter *pMux; 
       hr = pBuild->SetOutputFileName(
        &MEDIASUBTYPE_Avi, // Specifies AVI for the target file. 
        cname, // File name. 
        &pMux,    // Receives a pointer to the mux. 
        NULL);    // (Optional) Receives a pointer to the file sink. 

       if (a == 1) { 
        CComPtr<IPin> sourcePin; 
        CComPtr<IPin> dumpPin; 

        sourcePin = GetPin(pMux, PINDIR_OUTPUT); 
        dumpPin = GetPin(pCap, PINDIR_INPUT); 

        hr = ppGraph->Connect(sourcePin, dumpPin); 

       } 

       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(0); 
        pConfigMux->Release(); 
       } 

       IConfigInterleaving *pInterleave = NULL; 
       hr = pMux->QueryInterface(IID_IConfigInterleaving, (void**)&pInterleave); 
       if (SUCCEEDED(hr)) 
       { 
        pInterleave->put_Mode(INTERLEAVE_CAPTURE); 
        pInterleave->Release(); 
       } 
       pMux->Release(); 
      } 
     } 

     Capture capt; 
     capt.ppGraph = ppGraph; 
     capt.pPropBag = pPropBag; 
     capt.pCap = pCap; 
     capt.pBuild = pBuild; 
     captures.push_back(capt); 

    } 

    for (auto cap : captures) 
    { 
     IMediaControl* pMediaControl; 
     cap.ppGraph->QueryInterface(&pMediaControl); 
     pMediaControl->Run(); 
    } 

    Sleep(5000); 

    for (auto cap : captures) 
    { 
     IMediaControl* pMediaControl; 
     cap.ppGraph->QueryInterface(&pMediaControl); 
     pMediaControl->Stop(); 
     pMediaControl->Release(); 

     cap.pCap->Release(); 

     cap.ppGraph->Release(); 
     cap.pBuild->Release(); 

     cap.pPropBag->Release(); 
    } 

    pMoniker->Release(); 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); 
    for (int a = 0; a <= 1; a++) { 

     if (SUCCEEDED(hr)) 
     { 
      IEnumMoniker *pEnum; 

      hr = EnumerateDevices(CLSID_VideoInputDeviceCategory, &pEnum); 
      if (SUCCEEDED(hr)) 
      { 
       DisplayDeviceInformation(pEnum,a); 
       pEnum->Release(); 
      } 

     } 
    } 
    if (SUCCEEDED(hr)) 
    { 
     CoUninitialize(); 
    } 


    int i; 
    std::cin >> i; 
    return 0; 
} 

答えて

0

これを解決する方法もわからなかったので、私はちょうど外部プロセスのスポーンを使用しました。

1

あなたはサイクルの終わりにDisplayDeviceInformation機能とPMUXの終わりにppGraph、pBuild、pMediaControlとPCAPをリリースする必要がある場合があります。代わりに何らかのスマートポインタを使用する方が良いでしょう。

+0

それはそうではないようですが、それらのすべてを解放することは助けになりませんでした。 : – novox

+0

まだリリースされていないリリースがあります。最初のimediacontrolはリリースされていません。 – VuVirt

+0

それはあまりにもそうではないように見えますが、私はそれをリリースしようとしたときにプログラムがクラッシュします。 – novox