Hi!
I tested the webcams with GraphEdit. The filter graph is like this:
Webcam 1 -> AVI Decompressor -> Video Renderer
Webcam 2 -> AVI Decompressor -> Video Renderer
Webcam 3 -> AVI Decompressor -> Video Renderer
In some case(with the old webcams) it works; somtimes(when the new microsoft webcam not as the first being captured device) it says:
"This graph can't play. A device attached to the system is not functioning. (Return code: 0x8007001f)"
So does that mean the problem is of the device? Or did made a wrong filter graph under GraphEdit?
Hello experts,
I currentlly get an error called like topic says.
My project is a webcam controller for multiple webcams. I wrote it under winXP, Visual Studio 2010 C++ Express, WinForm Application.
But I think it's similar to c# and I thought more of you code such program under c#,
so I'd also like the c# experts to see it and do me a favour.
It works well with the old 3 logitech webcams. But when I added a fourth Microsoft lifcam HD5000. It shows me en error to connect this new one.
The error is after this code line:
hr = test2.pMC->Run();
*pMC points to the IMediaControl. The test2 is object 2 of my CamShow Class, for capturing the videostream.
The return value of hr is -2147024865. I'd like say that to be an unkown error.
But after several tries on different PCs, the return values is always this.
The same error has also happened when I run the release in win7 PC.
I post the way how I capture the video steams in the buttom. It's a little long, I hope you have patient and time to see it. Otherwise if you have question on me, I'm very glad to answer.
It will be such a benefitIf if you have also seen the same error before and know the solution. Or if you are glad to help to see the reason, I'll be thankful! I really need your help!
CamShow.h
#include <DShow.h>
#include <Windows.h>
#define SAFE_RELEASE(x) {if (x) x->Release(); x=NULL;}
#define WM_GRAPHNOTIFY WM_APP+1
class CamShow
{
public: CamShow();
~CamShow();
public:
HRESULT InitComLib();
HRESULT CaptureVideo(int);
HRESULT FindCaptureDevice(IBaseFilter **ppSrcFilter, int);
HRESULT GetInterfaces();
HRESULT Stop();
void CloseInterfaces(void);
void ControlRelease();
void EventRelease();
void GraphBuilderRelease();
void CoUnini();
public:
HRESULT hr;
IGraphBuilder *pGraphBuilder;
ICaptureGraphBuilder *pCGB;
ICaptureGraphBuilder2 *pCGB2;
IVideoWindow *pVW;
IMediaControl *pMC;
IMediaEventEx *pME;
HWND ghApp;
DWORD g_dwGraphRegister;
};
CamShow.cpp
#include "stdafx.h"
#include "CamShow.h"
CamShow::CamShow()
{ hr = NULL;
pGraphBuilder = NULL;
pCGB = NULL;
pCGB2 = NULL;
pVW = NULL;
pMC = NULL;
pME = NULL;
ghApp = 0;
g_dwGraphRegister = 0;
}
CamShow::~CamShow() {}
HRESULT CamShow::InitComLib()
{
hr = CoInitialize(NULL);
return hr;
}
HRESULT CamShow::CaptureVideo(int NO)
{
IBaseFilter *pSrcFilter = NULL;
IBaseFilter *pSampleGrabberFilter = NULL;
hr = pCGB2->SetFiltergraph(pGraphBuilder);
if (FAILED(hr))
{
MessageBox(NULL,TEXT("Set FilterGraph error!"), NULL, MB_OK | MB_ICONINFORMATION);
return hr;
}
hr = FindCaptureDevice(&pSrcFilter, NO);
if (FAILED(hr))
{
return hr;
}
hr = pGraphBuilder->AddFilter(pSrcFilter, L"Capture Filter");
if (FAILED(hr))
{
MessageBox(NULL, TEXT("AddFilter error! \r\n"), NULL, MB_OK | MB_ICONINFORMATION);
pSrcFilter->Release();
return hr;
}
hr = pCGB2->RenderStream (&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
pSrcFilter, NULL, NULL);
if (FAILED(hr))
{
MessageBox(NULL, TEXT("Rendering stream error!"), NULL, MB_OK | MB_ICONINFORMATION);
pSrcFilter->Release();
return hr;
}
pSrcFilter->Release();
return S_OK;
}
HRESULT CamShow::FindCaptureDevice(IBaseFilter ** ppSrcFilter, int NO)
{
HRESULT hr = S_OK;
IBaseFilter *pSrc = NULL;
IMoniker *pMoniker = NULL;
ULONG cFetched;
int DevNO = 0;
IEnumMoniker *pClassEnum = NULL;
ICreateDevEnum *pDevEnum = NULL;
if (!ppSrcFilter)
return E_POINTER;
hr = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
IID_ICreateDevEnum, (void **) &pDevEnum);
if (FAILED(hr))
{
MessageBox(NULL,TEXT("system enumerator not able to be created!"), NULL, MB_OK | MB_ICONINFORMATION);
}
if (SUCCEEDED(hr))
{
hr = pDevEnum->CreateClassEnumerator (CLSID_VideoInputDeviceCategory,
&pClassEnum, 0);
if (FAILED(hr))
{
MessageBox(NULL, TEXT("class enum can't be created! hr=0x%x"), NULL, MB_OK | MB_ICONINFORMATION);
}
pDevEnum->Release();
}
if (SUCCEEDED(hr))
{
if (pClassEnum == NULL)
{
MessageBox(ghApp,TEXT("No usable webcams!\r\n\r\n"),
TEXT(""), MB_OK | MB_ICONINFORMATION);
hr = E_FAIL;
}
}
while (pClassEnum->Next(1, &pMoniker, &cFetched) == S_OK)
{
DevNO++;
if (DevNO==NO)
{
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void **)&pSrc);
if (FAILED(hr))
return hr;
pMoniker->Release();
break;
}
}
if (SUCCEEDED(hr))
{
*ppSrcFilter = pSrc;
(*ppSrcFilter)->AddRef();
}
return hr;
}
HRESULT CamShow::GetInterfaces()
{
hr = CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC,
IID_IGraphBuilder, (void **) &pGraphBuilder);
if (FAILED(hr))
return hr;
hr = CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,
IID_ICaptureGraphBuilder2, (void **) &pCGB2);
if (FAILED(hr))
return hr;
hr = pGraphBuilder->QueryInterface(IID_IMediaControl,(LPVOID *) &pMC);
if (FAILED(hr))
return hr;
hr = pGraphBuilder->QueryInterface(IID_IVideoWindow, (LPVOID *) &pVW);
if (FAILED(hr))
return hr;
hr = pGraphBuilder->QueryInterface(IID_IMediaEvent, (LPVOID *) &pME);
if (FAILED(hr))
return hr;
return hr;
}
HRESULT CamShow::Stop()
{
if (pMC!=NULL)
{
hr = pMC->Stop();
SAFE_RELEASE(pMC);
}
return hr;
}
void CamShow::CloseInterfaces()
{
if (pMC)
pMC->StopWhenReady();
if (pME)
pME->SetNotifyWindow(NULL, WM_GRAPHNOTIFY, 0);
if (pVW)
{
pVW->put_Visible(OAFALSE);
pVW->put_Owner(NULL);
}
SAFE_RELEASE(pMC);
SAFE_RELEASE(pME);
SAFE_RELEASE(pVW);
SAFE_RELEASE(pCGB2);
SAFE_RELEASE(pGraphBuilder);
}
void CamShow::ControlRelease()
{
pMC->Release();
}
void CamShow::EventRelease()
{ pME->Release();
}
void CamShow::GraphBuilderRelease()
{ pGraphBuilder->Release();
}
void CamShow::CoUnini()
{
CoUninitialize();
}
Form1.h
#pragma once
#include "CamShow.h"
#include "GlobalVar.h"
CamShow test1;
CamShow test2;
CamShow test3;
namespace My3Cam {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
}
protected:
~Form1()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::PictureBox^ pictureBox1;
protected:
private: System::Windows::Forms::PictureBox^ pictureBox2;
private: System::Windows::Forms::PictureBox^ pictureBox3;
private: System::Windows::Forms::Button^ button1;
private: System::Windows::Forms::Button^ button2;
private:
System::ComponentModel::Container ^components;
private: static HRESULT hr = NULL;
......(Windows Form Designer generated code)
Click "Connect"
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
button1->Enabled=false;
button2->Enabled=true;
hr = test1.InitComLib();
hr = test1.GetInterfaces();
hr = test1.CaptureVideo(2);
System::Drawing::Rectangle rc = pictureBox1->ClientRectangle;
hr = test1.pVW->put_Owner(OAHWND(this->pictureBox1->Handle.ToInt64()));
hr = test1.pVW->put_WindowStyle( WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN );
hr = test1.pVW->SetWindowPosition( 0, 0, rc.Right, rc.Bottom );
hr = test1.pMC->Run();
test1.CoUnini();
hr = test2.InitComLib();
hr = test2.GetInterfaces();
hr= test2.CaptureVideo(1);
System::Drawing::Rectangle rc2 = pictureBox2->ClientRectangle;
hr = test2.pVW->put_Owner(OAHWND(this->pictureBox2->Handle.ToInt64()));
hr = test2.pVW->put_WindowStyle( WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN );
hr = test2.pVW->SetWindowPosition( 0, 0, rc2.Right, rc2.Bottom );
hr = test2.pMC->Run();
test2.CoUnini();
hr = test3.InitComLib();
hr = test3.GetInterfaces();
hr= test3.CaptureVideo(3);
System::Drawing::Rectangle rc3 = pictureBox3->ClientRectangle;
hr = test3.pVW->put_Owner(OAHWND(this->pictureBox3->Handle.ToInt64()));
hr = test3.pVW->put_WindowStyle( WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN );
hr = test3.pVW->SetWindowPosition( 0, 0, rc3.Right, rc3.Bottom );
hr = test3.pMC->Run();
test3.CoUnini();
}
Acturally I used three comboBoxes in my original program to read all video devices on PC, and to choose one for each pictureBox. Here I've simplified that, but it is enough to show the error. And as I tested, it runs without code error.
Just the pictureBox, which has hr = -214724865 after pMC->Run(), shows black image.
If you want to change the turns of webcams in each pictureBoxes, just change the value in the three clips:
hr = test1.CaptureVideo(2);
hr = test2.CaptureVideo(1);
hr = test3.CaptureVideo(3);
it can be 1 to n, n is the number of all devices. For example, there are 6 webcams,
then you can choose the 1, 5, 4 to capture.
Click "Disconnect"
private: System::Void button2_Click_1(System::Object^ sender, System::EventArgs^ e) {
btnConnect->Enabled = true;
btnDisconnect->Enabled = false;
test1.Stop();
test2.Stop();
test3.Stop();
}