- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
在查看了一个非常相似的问题并看到几乎相同的代码之后,我决定单独提出这个问题。我想在 DirectShow 使用的默认窗口中显示网络摄像头视频流的视频预览,并且我还希望能够在任何给定时刻对视频流“拍照”。
我从 MSDN 上的 DirectShow 示例以及 AMCap 示例代码开始,我认为预览部分应该有一些东西,但没有。除了使用已弃用的 SampleGrabber 之外,我没有发现从视频流中抓取图像的示例,因此我尽量不使用它。
下面是我的代码,一行一行。请注意,EnumerateCameras 中的大部分代码都被注释掉了。该代码将用于附加到另一个窗口,我不想这样做。在 MSDN 文档中,它明确指出 VMR_7 创建自己的窗口来显示视频流。我的应用程序没有出现任何错误,但此窗口从未出现。
我的问题是:我做错了什么?或者,如果您知道我正在尝试做的一个简单示例,请将我链接到它。 AMCap不是一个简单的例子,供引用。
注意:InitalizeVMR 用于在无窗口状态下运行,这是我的最终目标(集成到 DirectX 游戏中)。不过现在,我只想让它以最简单的模式运行。
编辑:这个问题的第一部分,即预览相机流,已经解决。我现在只是在寻找已弃用的 SampleGrabber 类的替代品,这样我就可以随时拍摄照片并将其保存到文件中。
编辑:在谷歌上查找将近一个小时后,普遍认为您必须使用 ISampleGrabber。如果您发现任何不同之处,请告诉我。
测试代码(main.cpp):
CWebcam* camera = new CWebcam();
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
MessageBox(NULL, L"text", L"caption", NULL);
if (SUCCEEDED(hr))
{
camera->Create();
camera->EnumerateCameras();
camera->StartCamera();
}
int d;
cin >> d;
网络摄像头.cpp:
#include "Webcam.h"
CWebcam::CWebcam() {
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
//m_pTexInst = nullptr;
//m_pTexRes = nullptr;
}
CWebcam::~CWebcam() {
CoUninitialize();
m_pDeviceMonikers->Release();
m_pMediaController->Release();
}
BOOL CWebcam::Create() {
InitCaptureGraphBuilder(&m_pFilterGraph, &m_pCaptureGraph);
hr = m_pFilterGraph->QueryInterface(IID_IMediaControl, (void **)&m_pMediaController);
return TRUE;
}
void CWebcam::Destroy() {
}
void CWebcam::EnumerateCameras() {
HRESULT hr = EnumerateDevices(CLSID_VideoInputDeviceCategory, &m_pDeviceMonikers);
if (SUCCEEDED(hr))
{
//DisplayDeviceInformation(m_pDeviceMonikers);
//m_pDeviceMonikers->Release();
IMoniker *pMoniker = NULL;
if(m_pDeviceMonikers->Next(1, &pMoniker, NULL) == S_OK)
{
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&m_pCameraFilter);
if (SUCCEEDED(hr))
{
hr = m_pFilterGraph->AddFilter(m_pCameraFilter, L"Capture Filter");
}
}
// connect the output pin to the video renderer
if(SUCCEEDED(hr))
{
hr = m_pCaptureGraph->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
m_pCameraFilter, NULL, NULL);
}
//InitializeVMR(hwnd, m_pFilterGraph, &m_pVMRControl, 1, FALSE);
//get the video window that will be displayed from the filter graph
IVideoWindow *pVideoWindow = NULL;
hr = m_pFilterGraph->QueryInterface(IID_IVideoWindow, (void **)&pVideoWindow);
/*if(hr != NOERROR)
{
printf("This graph cannot preview properly");
}
else
{
//get the video stream configurations
hr = m_pCaptureGraph->FindInterface(&PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video, m_pCameraFilter,
IID_IAMStreamConfig, (void **)&m_pVideoStreamConfig);
//Find out if this is a DV stream
AM_MEDIA_TYPE *pMediaTypeDV;
//fake window handle
HWND window = NULL;
if(m_pVideoStreamConfig && SUCCEEDED(m_pVideoStreamConfig->GetFormat(&pMediaTypeDV)))
{
if(pMediaTypeDV->formattype == FORMAT_DvInfo)
{
// in this case we want to set the size of the parent window to that of
// current DV resolution.
// We get that resolution from the IVideoWindow.
IBasicVideo* pBasivVideo;
// If we got here, gcap.pVW is not NULL
//ASSERT(pVideoWindow != NULL);
hr = pVideoWindow->QueryInterface(IID_IBasicVideo, (void**)&pBasivVideo);
/*if(SUCCEEDED(hr))
{
HRESULT hr1, hr2;
long lWidth, lHeight;
hr1 = pBasivVideo->get_VideoHeight(&lHeight);
hr2 = pBasivVideo->get_VideoWidth(&lWidth);
if(SUCCEEDED(hr1) && SUCCEEDED(hr2))
{
ResizeWindow(lWidth, abs(lHeight));
}
}
}
}
RECT rc;
pVideoWindow->put_Owner((OAHWND)window); // We own the window now
pVideoWindow->put_WindowStyle(WS_CHILD); // you are now a child
GetClientRect(window, &rc);
pVideoWindow->SetWindowPosition(0, 0, rc.right, rc.bottom); // be this big
pVideoWindow->put_Visible(OATRUE);
}*/
}
}
BOOL CWebcam::StartCamera() {
if(m_bIsStreaming == FALSE)
{
m_bIsStreaming = TRUE;
hr = m_pMediaController->Run();
if(FAILED(hr))
{
// stop parts that ran
m_pMediaController->Stop();
return FALSE;
}
return TRUE;
}
return FALSE;
}
void CWebcam::EndCamera() {
if(m_bIsStreaming)
{
hr = m_pMediaController->Stop();
m_bIsStreaming = FALSE;
//invalidate client rect as well so that it must redraw
}
}
BOOL CWebcam::CaptureToTexture() {
return TRUE;
}
HRESULT CWebcam::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
}
HRESULT CWebcam::EnumerateDevices(REFGUID category, IEnumMoniker **ppEnum)
{
// Create the System Device Enumerator.
ICreateDevEnum *pSystemDeviceEnumerator;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pSystemDeviceEnumerator));
if (SUCCEEDED(hr))
{
// Create an enumerator for the category.
hr = pSystemDeviceEnumerator->CreateClassEnumerator(category, ppEnum, 0);
if (hr == S_FALSE)
{
hr = VFW_E_NOT_FOUND; // The category is empty. Treat as an error.
}
pSystemDeviceEnumerator->Release();
}
return hr;
}
void CWebcam::DisplayDeviceInformation(IEnumMoniker *pEnum)
{
IMoniker *pMoniker = NULL;
int counter = 0;
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);
// Get description or friendly name.
hr = pPropBag->Read(L"Description", &var, 0);
if (FAILED(hr))
{
hr = pPropBag->Read(L"FriendlyName", &var, 0);
}
if (SUCCEEDED(hr))
{
printf("%d: %S\n", counter, var.bstrVal);
VariantClear(&var);
}
hr = pPropBag->Write(L"FriendlyName", &var);
// WaveInID applies only to audio capture devices.
hr = pPropBag->Read(L"WaveInID", &var, 0);
if (SUCCEEDED(hr))
{
printf("%d: WaveIn ID: %d\n", counter, var.lVal);
VariantClear(&var);
}
hr = pPropBag->Read(L"DevicePath", &var, 0);
if (SUCCEEDED(hr))
{
// The device path is not intended for display.
printf("%d: Device path: %S\n", counter, var.bstrVal);
VariantClear(&var);
}
pPropBag->Release();
pMoniker->Release();
counter++;
}
}
HRESULT CWebcam::InitializeVMR(
HWND hwndApp, // Application window.
IGraphBuilder* pFG, // Pointer to the Filter Graph Manager.
IVMRWindowlessControl** ppWc, // Receives the interface.
DWORD dwNumStreams, // Number of streams to use.
BOOL fBlendAppImage // Are we alpha-blending a bitmap?
)
{
IBaseFilter* pVmr = NULL;
IVMRWindowlessControl* pWc = NULL;
*ppWc = NULL;
// Create the VMR and add it to the filter graph.
HRESULT hr = CoCreateInstance(CLSID_VideoMixingRenderer, NULL,
CLSCTX_INPROC, IID_IBaseFilter, (void**)&pVmr);
if (FAILED(hr))
{
return hr;
}
hr = pFG->AddFilter(pVmr, L"Video Mixing Renderer");
if (FAILED(hr))
{
pVmr->Release();
return hr;
}
// Set the rendering mode and number of streams.
IVMRFilterConfig* pConfig;
hr = pVmr->QueryInterface(IID_IVMRFilterConfig, (void**)&pConfig);
if (SUCCEEDED(hr))
{
pConfig->SetRenderingMode(VMRMode_Windowless);
// Set the VMR-7 to mixing mode if you want more than one video
// stream, or you want to mix a static bitmap over the video.
// (The VMR-9 defaults to mixing mode with four inputs.)
if (dwNumStreams > 1 || fBlendAppImage)
{
pConfig->SetNumberOfStreams(dwNumStreams);
}
pConfig->Release();
hr = pVmr->QueryInterface(IID_IVMRWindowlessControl, (void**)&pWc);
if (SUCCEEDED(hr))
{
pWc->SetVideoClippingWindow(hwndApp);
*ppWc = pWc; // The caller must release this interface.
}
}
pVmr->Release();
// Now the VMR can be connected to other filters.
return hr;
}
最佳答案
在无窗口模式下,VMR 不会创建单独的窗口。由于您开始为 widnowless 模式进行初始化,因此您必须跟随 SetVideoClippingWindow 和 IVMRWindowlessControl::SetVideoPosition 调用以提供窗口内的位置,请参阅 VMR Windowless Mode on MSDN .
关于c++ - DirectShow:网络摄像头预览和图像捕获,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7550643/
我目前正在处理 Windows Media Foundation。但是,由于 Microsoft H.264 解码器的一些问题和一些缺少自定义格式的解码器,我想知道是否可以直接使用 CLSID 实例化
IMediaEvent 和 IMediaEventEx 没有说明图中哪个过滤器发送了检索到的 DirectShow 事件。有什么办法可以找到这些信息。特别是对于图中的过滤器之一发送 EC_ERRORA
我已经阅读了 DirectShow 上的 MSDN 文档,但它仍然令人困惑。我觉得我需要更多关于对象的上下文:图形、图钉、过滤器...等。谷歌搜索并没有给我太多的工作。我需要什么才能理解 Direct
正如我刚刚发现的那样,友好的名称不能保证是唯一的。如果我可以从该标识符实例化过滤器而无需枚举它们,则可加分。 最佳答案 可以通过 WaveOutId 识别包装 WaveOut 设备的渲染器过滤器。那些
我想捕获当前帧及其前一帧以进行分析并生成一个新帧来显示。是说我必须写一个变换DirectShow过滤器吗?但我是 DirectShow 的新手。我被MSDN的大量文档弄糊涂了。所以我想知道是否有任何简
enter code here我必须动态停止和启动 Video Renderer Filter。在不创建新图表的情况下,使用“普通”直接展示架构是不可能的。但是使用 GMFBridge 似乎是可能的。
在网上搜索了几个小时后,我非常想找到解决方案。我已经在 DirectShow 中启动并运行 OGG Theora 解码器,它输出 YV12 和 YUY2 颜色模型。 现在,我想为这个输出制作一个 RG
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
长篇故事: 有一个 H264/MPEG-4 源 我可以用 RTSP 协议(protocol)连接这个源。 我可以使用 RTP 协议(protocol)获取原始 UDP 数据包。 然后将这些原始 UDP
这可能是一个愚蠢的问题,但我很难概念化我需要在这里做什么......过去我使用 DirectShow 连接到相机并使用源过滤器捕获 AVI,AVI多路复用器、压缩过滤器、运行图表等……小菜一碟。在这种
我有一些自定义 DirectShow 过滤器(用于编码/解码/多路复用/多路分离)。 我想在 Media Foundation 上将它们用作 MFT。 我听过一些人说: “微软声称所有 DirectS
我做了一个简单的图表来编写 MKV 文件。但我不想使用文件编写器。我想使用 SampleGabber 并使用简单的程序获取流。问题是我从 Matroska muxer 以外的任何地方获取数据!(我该怎
我正在使用使用 DirectShow 库的 WPF 应用程序,它可以很好地抓取图像或记录实时提要,但我希望最终用户不应该看到任何网络摄像头正在拍照,即我想要用户不应看到正在呈现来自网络摄像头的提要的图
我应该写一个直接显示过滤器 从实时源获取输入(视频、音频)。 它应该将数据(视频,音频:已编码)提供给解码器过滤器 MyCustomDirectShowSourceFilter ---> Decode
我在从 DirectShow 筛选器图表编辑器连接到远程图表时遇到问题。当我运行创建直接显示图形的应用程序时,在我的 Windows XP 计算机上,图形显示在远程图形列表中,但在 Windows 7
什么是微软的 DirectShow ,以及它与以下内容有何关系: 编解码器? 容器? 编解码器和容器之间的确切区别是什么? 最佳答案 用简单的英语: 编解码器是一种算法和/或代码,可将音频或视频从 R
我开发了一个使用 DirectShow 从外部设备捕获视频的 Windows 应用程序。图像分辨率为 640x480,未经压缩保存的视频尺寸非常大(大约每秒 27MB)。 我的目标是尽可能地减小这个大
我正在尝试用 C# 制作一个允许用户录制视频的网络摄像头应用程序。我一直在使用 DirectShow.Net 来预览网络摄像头并拍摄快照。但需要能够在预览网络摄像头的同时捕捉视频和音频。我尝试过的一件
我已经找了很长时间,但是找不到解决方案。 如何从USB(符合Directshow规范)输入设备捕获音频并直接传递到PC扬声器(“音频渲染器”)? 我相信这不是一项艰巨的任务,但是我确实在网络上找不到任
我正在从我的应用程序执行 VLC 以从 DirectShow 音频捕获设备捕获和编码。 VLC 通过 STDOUT 将编码数据发送到我的应用程序。我需要一种枚举 DirectShow 音频捕获设备的方
我是一名优秀的程序员,十分优秀!