Directshow захватить в файл, ничего не происходит

Я пытаюсь выполнить примеры DirectShow в центре разработки Windows, чтобы создать собственное приложение, которое может захватывать экран и аудио в видео: Захват видео в файл AVI

Весь код идет нормально, но ничего не происходит, файл avi не появляется. Веб-камера подключена, я вижу поток с AMCap. В коде cam появляется с правильным именем файла. Windows SDK установлен, моя платформа — win7 x64.

Мой код:

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

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

#pragma comment(lib, "strmiids")

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
}

void DisplayDeviceInformation(IEnumMoniker *pEnum)
{
IMoniker *pMoniker = NULL;

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))
{
hr = ppGraph->AddFilter(pCap, L"Capture Filter");
if (SUCCEEDED(hr)) {
IBaseFilter *pMux;
hr = pBuild->SetOutputFileName(
&MEDIASUBTYPE_Avi,  // Specifies AVI for the target file.
L"C:\\a\\Example.avi", // File name.
&pMux,              // Receives a pointer to the mux.
NULL);              // (Optional) Receives a pointer to the file sink.

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

}
}

pPropBag->Release();
pMoniker->Release();
}
}

int _tmain(int argc, _TCHAR* argv[])
{

HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (SUCCEEDED(hr))
{
IEnumMoniker *pEnum;

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

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

2

Решение

Ваш код перечисляет устройства (источники), создает конвейер записи файлов, затем отбрасывает все и переходит на следующее устройство.

Код не должен делать фактическую запись.

Минимальный недостающий кусок это (нижняя часть вашего DisplayDeviceInformation):

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

///////////////////////////////////////////////////
// Added
IMediaControl* pMediaControl;
ppGraph->QueryInterface(&pMediaControl);
pMediaControl->Run();
Sleep(5000);
pMediaControl->Stop();
///////////////////////////////////////////////////

pPropBag->Release();
pMoniker->Release();
2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector