gpt4 book ai didi

c++ - Directshow 两次无法启动捕获

转载 作者:行者123 更新时间:2023-11-28 05:24:56 27 4
gpt4 key购买 nike

我正在尝试按照 Windows 开发中心上的 DirectShow 示例来制作我自己的可以将屏幕和音频捕获到视频的应用程序:Capturing Video to an AVI File

第一次开始抓包一切正常,但第二次没有任何反应,没有出现带视频的文件。有没有可能是我忘了取消初始化某些东西?

更新问题似乎不在于缺少发布。第二次流写入文件 1.avi 正在创建,但它是空的,当 pMediaControl->Stop(); 完成时,它会自动删除

更新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。所以我添加了(using this):

                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 值为 NULL。hr = ppGraph->AddFilter(pCap, L"Capture Filter"); 运行正常.接下来我可以在哪里挖掘以查找错误?

(代码已更新)

我的代码:

#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;
}

最佳答案

您可能需要在 DisplayDeviceInformation 函数结束时释放 ppGraph、pBuild、pMediaControl 和 pCap,并在循环结束时释放 pMux。最好改用某种智能指针。

关于c++ - Directshow 两次无法启动捕获,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40740785/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com