mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-05-07 05:53:06 +00:00
Update filter to latest architecture (without V4L_STOP/V4L_START)
git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@147 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
This commit is contained in:
parent
8f2170723e
commit
5aad08e70f
1 changed files with 353 additions and 51 deletions
|
|
@ -37,8 +37,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include <initguid.h>
|
||||
#include "dxfilter.h"
|
||||
#include <qedit.h>
|
||||
//#include <atlbase.h>
|
||||
//#include <atlcom.h>
|
||||
|
||||
HRESULT AddGraphToRot(IUnknown *pUnkGraph, DWORD *pdwRegister);
|
||||
void RemoveGraphFromRot(DWORD pdwRegister);
|
||||
|
|
@ -48,16 +46,10 @@ typedef struct V4wState{
|
|||
char dev[512];
|
||||
int devidx;
|
||||
|
||||
//CComPtr<IGraphBuilder> m_pGraph;
|
||||
//CComPtr<ICaptureGraphBuilder2> m_pBuilder;
|
||||
//CComPtr<IMediaControl> m_pControl;
|
||||
IGraphBuilder *m_pGraph;
|
||||
ICaptureGraphBuilder2 *m_pBuilder;
|
||||
IMediaControl *m_pControl;
|
||||
CDXFilter *m_pDXFilter;
|
||||
//CComPtr<IBaseFilter> m_pIDXFilter;
|
||||
//CComPtr<IBaseFilter> m_pNullRenderer;
|
||||
//CComPtr<IBaseFilter> m_pDeviceFilter;
|
||||
IBaseFilter *m_pIDXFilter;
|
||||
IBaseFilter *m_pNullRenderer;
|
||||
IBaseFilter *m_pDeviceFilter;
|
||||
|
|
@ -74,7 +66,6 @@ typedef struct V4wState{
|
|||
float fps;
|
||||
float start_time;
|
||||
int frame_count;
|
||||
bool_t running;
|
||||
}V4wState;
|
||||
|
||||
static V4wState *s_callback=NULL;
|
||||
|
|
@ -385,13 +376,12 @@ int try_format_size(V4wState *s, int format, int width, int height, GUID *pPinCa
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int v4w_open_videodevice(V4wState *s)
|
||||
static int v4w_configure_videodevice(V4wState *s)
|
||||
{
|
||||
// Initialize COM
|
||||
CoInitialize(NULL);
|
||||
|
||||
// get a Graph
|
||||
//HRESULT hr=s->m_pGraph.CoCreateInstance(CLSID_FilterGraph);
|
||||
HRESULT hr= CoCreateInstance (CLSID_FilterGraph,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
|
|
@ -403,7 +393,6 @@ static int v4w_open_videodevice(V4wState *s)
|
|||
}
|
||||
|
||||
// get a CaptureGraphBuilder2
|
||||
//hr=s->m_pBuilder.CoCreateInstance(CLSID_CaptureGraphBuilder2);
|
||||
hr= CoCreateInstance (CLSID_CaptureGraphBuilder2,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
|
|
@ -418,7 +407,6 @@ static int v4w_open_videodevice(V4wState *s)
|
|||
s->m_pBuilder->SetFiltergraph(s->m_pGraph);
|
||||
|
||||
// get mediacontrol so we can start and stop the filter graph
|
||||
//hr=s->m_pGraph.QueryInterface(&(s->m_pControl));
|
||||
hr=s->m_pGraph->QueryInterface (IID_IMediaControl, (void **)&s->m_pControl);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
|
|
@ -460,14 +448,228 @@ static int v4w_open_videodevice(V4wState *s)
|
|||
pEnumMoniker->Reset();
|
||||
|
||||
int pos=0;
|
||||
while(S_OK == pEnumMoniker->Next(1, &pMoniker, &nFetched) )
|
||||
{
|
||||
IPropertyBag *pBag;
|
||||
hr = pMoniker->BindToStorage( 0, 0, IID_IPropertyBag, (void**) &pBag );
|
||||
if( hr != S_OK )
|
||||
continue;
|
||||
|
||||
if (s->dev[0]=='\0')
|
||||
break;
|
||||
|
||||
VARIANT var;
|
||||
VariantInit(&var);
|
||||
hr = pBag->Read( L"FriendlyName", &var, NULL );
|
||||
if( hr != S_OK )
|
||||
{
|
||||
pMoniker->Release();
|
||||
continue;
|
||||
}
|
||||
//USES_CONVERSION;
|
||||
char szName[256];
|
||||
|
||||
WideCharToMultiByte(CP_ACP,0,var.bstrVal,-1,szName,256,0,0);
|
||||
VariantClear(&var);
|
||||
|
||||
if (strcmp(szName, s->dev)==0)
|
||||
break;
|
||||
|
||||
pMoniker->Release();
|
||||
pBag->Release();
|
||||
pMoniker=NULL;
|
||||
pBag=NULL;
|
||||
}
|
||||
|
||||
if(pMoniker==NULL)
|
||||
{
|
||||
int pos=0;
|
||||
while(S_OK == pEnumMoniker->Next(1, &pMoniker, &nFetched) )
|
||||
{
|
||||
if (pos>=s->devidx)
|
||||
break;
|
||||
pos++;
|
||||
pMoniker->Release();
|
||||
pMoniker=NULL;
|
||||
IPropertyBag *pBag;
|
||||
hr = pMoniker->BindToStorage( 0, 0, IID_IPropertyBag, (void**) &pBag );
|
||||
if( hr != S_OK )
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(pMoniker==NULL)
|
||||
{
|
||||
return -6;
|
||||
}
|
||||
|
||||
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&s->m_pDeviceFilter );
|
||||
if(FAILED(hr))
|
||||
{
|
||||
return -7;
|
||||
}
|
||||
|
||||
s->m_pGraph->AddFilter(s->m_pDeviceFilter, L"Device Filter");
|
||||
|
||||
pMoniker->Release();
|
||||
pEnumMoniker->Release();
|
||||
pCreateDevEnum->Release();
|
||||
|
||||
|
||||
GUID pPinCategory;
|
||||
|
||||
if (try_format(s, s->pix_fmt, &pPinCategory)==0)
|
||||
s->pix_fmt = s->pix_fmt;
|
||||
else if (try_format(s,MS_YUV420P, &pPinCategory)==0)
|
||||
s->pix_fmt = MS_YUV420P;
|
||||
else if (try_format(s,MS_YUY2, &pPinCategory)==0)
|
||||
s->pix_fmt = MS_YUY2;
|
||||
else if (try_format(s,MS_YUYV, &pPinCategory)==0)
|
||||
s->pix_fmt = MS_YUYV;
|
||||
else if (try_format(s,MS_UYVY, &pPinCategory)==0)
|
||||
s->pix_fmt = MS_UYVY;
|
||||
else if (try_format(s,MS_RGB24, &pPinCategory)==0)
|
||||
s->pix_fmt = MS_RGB24;
|
||||
else
|
||||
{
|
||||
ms_error("Unsupported video pixel format.");
|
||||
return -8;
|
||||
}
|
||||
|
||||
if (s->pix_fmt == MS_YUV420P)
|
||||
ms_message("Driver supports YUV420P, using that format.");
|
||||
else if (s->pix_fmt == MS_YUY2)
|
||||
ms_message("Driver supports YUY2 (UYVY), using that format.");
|
||||
else if (s->pix_fmt == MS_YUYV)
|
||||
ms_message("Driver supports YUV422, using that format.");
|
||||
else if (s->pix_fmt == MS_UYVY)
|
||||
ms_message("Driver supports UYVY, using that format.");
|
||||
else if (s->pix_fmt == MS_RGB24)
|
||||
ms_message("Driver supports RGB24, using that format.");
|
||||
|
||||
if (try_format_size(s, s->pix_fmt, s->vsize.width, s->vsize.height, &pPinCategory)==0)
|
||||
ms_message("Selected Size: %ix%i.", s->vsize.width, s->vsize.height);
|
||||
else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_QCIF_W, MS_VIDEO_SIZE_QCIF_H, &pPinCategory)==0)
|
||||
ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_QCIF_W, MS_VIDEO_SIZE_QCIF_H);
|
||||
else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_CIF_W, MS_VIDEO_SIZE_CIF_H, &pPinCategory)==0)
|
||||
ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_CIF_W, MS_VIDEO_SIZE_CIF_H);
|
||||
else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_4CIF_W, MS_VIDEO_SIZE_4CIF_H, &pPinCategory)==0)
|
||||
ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_4CIF_W, MS_VIDEO_SIZE_4CIF_H);
|
||||
else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_VGA_W, MS_VIDEO_SIZE_VGA_H, &pPinCategory)==0)
|
||||
ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_VGA_W, MS_VIDEO_SIZE_VGA_H);
|
||||
else if (try_format_size(s, s->pix_fmt, MS_VIDEO_SIZE_QVGA_W, MS_VIDEO_SIZE_QVGA_H, &pPinCategory)==0)
|
||||
ms_message("Selected Size: %ix%i.", MS_VIDEO_SIZE_QVGA_W, MS_VIDEO_SIZE_QVGA_H);
|
||||
else
|
||||
{
|
||||
ms_error("No supported size found for format.");
|
||||
/* size not supported? */
|
||||
return -9;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int v4w_open_videodevice(V4wState *s)
|
||||
{
|
||||
// Initialize COM
|
||||
CoInitialize(NULL);
|
||||
|
||||
// get a Graph
|
||||
HRESULT hr= CoCreateInstance (CLSID_FilterGraph,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
IID_IGraphBuilder, //IID_IBaseFilter,
|
||||
(void **)&s->m_pGraph);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// get a CaptureGraphBuilder2
|
||||
hr= CoCreateInstance (CLSID_CaptureGraphBuilder2,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
IID_ICaptureGraphBuilder2, //IID_IBaseFilter,
|
||||
(void **)&s->m_pBuilder);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
// connect capture graph builder with the graph
|
||||
s->m_pBuilder->SetFiltergraph(s->m_pGraph);
|
||||
|
||||
// get mediacontrol so we can start and stop the filter graph
|
||||
hr=s->m_pGraph->QueryInterface (IID_IMediaControl, (void **)&s->m_pControl);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
return -3;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
HANDLE m_hLogFile=CreateFile(L"DShowGraphLog.txt",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
|
||||
if(m_hLogFile!=INVALID_HANDLE_VALUE)
|
||||
{
|
||||
hr=s->m_pGraph->SetLogFile((DWORD_PTR)m_hLogFile);
|
||||
/* ASSERT(SUCCEEDED(hr)); */
|
||||
}
|
||||
|
||||
//AddGraphToRot(s->m_pGraph, &s->rotregvalue);
|
||||
#endif
|
||||
|
||||
ICreateDevEnum *pCreateDevEnum = NULL;
|
||||
IEnumMoniker *pEnumMoniker = NULL;
|
||||
IMoniker *pMoniker = NULL;
|
||||
|
||||
ULONG nFetched = 0;
|
||||
|
||||
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
|
||||
IID_ICreateDevEnum, (PVOID *)&pCreateDevEnum);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
return -4;
|
||||
}
|
||||
|
||||
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
|
||||
&pEnumMoniker, 0);
|
||||
if (FAILED(hr) || pEnumMoniker == NULL) {
|
||||
//printf("no device\n");
|
||||
return -5;
|
||||
}
|
||||
|
||||
pEnumMoniker->Reset();
|
||||
|
||||
int pos=0;
|
||||
while(S_OK == pEnumMoniker->Next(1, &pMoniker, &nFetched) )
|
||||
{
|
||||
IPropertyBag *pBag;
|
||||
hr = pMoniker->BindToStorage( 0, 0, IID_IPropertyBag, (void**) &pBag );
|
||||
if( hr != S_OK )
|
||||
continue;
|
||||
|
||||
if (s->dev[0]=='\0')
|
||||
break;
|
||||
|
||||
VARIANT var;
|
||||
VariantInit(&var);
|
||||
hr = pBag->Read( L"FriendlyName", &var, NULL );
|
||||
if( hr != S_OK )
|
||||
{
|
||||
pMoniker->Release();
|
||||
continue;
|
||||
}
|
||||
//USES_CONVERSION;
|
||||
char szName[256];
|
||||
|
||||
WideCharToMultiByte(CP_ACP,0,var.bstrVal,-1,szName,256,0,0);
|
||||
VariantClear(&var);
|
||||
|
||||
if (strcmp(szName, s->dev)==0)
|
||||
break;
|
||||
|
||||
pMoniker->Release();
|
||||
pBag->Release();
|
||||
pMoniker=NULL;
|
||||
pBag=NULL;
|
||||
}
|
||||
|
||||
if(pMoniker==NULL)
|
||||
{
|
||||
return -6;
|
||||
|
|
@ -627,7 +829,6 @@ static int v4w_open_videodevice(V4wState *s)
|
|||
|
||||
|
||||
// get null renderer
|
||||
//hr=s->m_pNullRenderer.CoCreateInstance(CLSID_NullRenderer);
|
||||
hr=CoCreateInstance (CLSID_NullRenderer,
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
|
|
@ -646,12 +847,7 @@ static int v4w_open_videodevice(V4wState *s)
|
|||
&MEDIATYPE_Video, s->m_pDeviceFilter, s->m_pIDXFilter, s->m_pNullRenderer);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
//hr = s->m_pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,
|
||||
// &MEDIATYPE_Video, s->m_pDeviceFilter, s->m_pIDXFilter, s->m_pNullRenderer);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return -17;
|
||||
}
|
||||
return -17;
|
||||
}
|
||||
|
||||
//m_pDXFilter->SetBufferSamples(TRUE);
|
||||
|
|
@ -735,7 +931,6 @@ static void v4w_init(MSFilter *f){
|
|||
s->devidx=0;
|
||||
s->vsize.width=MS_VIDEO_SIZE_CIF_W;
|
||||
s->vsize.height=MS_VIDEO_SIZE_CIF_H;
|
||||
//s->pix_fmt=MS_RGB24;
|
||||
s->pix_fmt=MS_YUV420P;
|
||||
|
||||
s->rotregvalue = 0;
|
||||
|
|
@ -756,10 +951,66 @@ static void v4w_init(MSFilter *f){
|
|||
s->start_time=0;
|
||||
s->frame_count=-1;
|
||||
s->fps=15;
|
||||
memset(s->dev, 0, sizeof(s->dev));
|
||||
|
||||
f->data=s;
|
||||
}
|
||||
|
||||
static int _v4w_test(V4wState *s, void *arg)
|
||||
{
|
||||
int i;
|
||||
i = v4w_configure_videodevice(s);
|
||||
|
||||
if (i!=0)
|
||||
{
|
||||
s->pix_fmt = MS_YUV420P;
|
||||
s->vsize.width = MS_VIDEO_SIZE_CIF_W;
|
||||
s->vsize.height = MS_VIDEO_SIZE_CIF_H;
|
||||
}
|
||||
|
||||
//RemoveGraphFromRot(s->rotregvalue);
|
||||
if (s->m_pGraph!=NULL)
|
||||
{
|
||||
if (s->m_pNullRenderer!=NULL)
|
||||
s->m_pGraph->RemoveFilter(s->m_pNullRenderer);
|
||||
if (s->m_pIDXFilter!=NULL)
|
||||
s->m_pGraph->RemoveFilter(s->m_pIDXFilter);
|
||||
if (s->m_pDeviceFilter!=NULL)
|
||||
s->m_pGraph->RemoveFilter(s->m_pDeviceFilter);
|
||||
}
|
||||
|
||||
if (s->m_pNullRenderer)
|
||||
s->m_pNullRenderer->Release();
|
||||
if (s->m_pIDXFilter)
|
||||
s->m_pIDXFilter->Release();
|
||||
if (s->m_pDeviceFilter)
|
||||
s->m_pDeviceFilter->Release();
|
||||
|
||||
if (s->m_pBuilder)
|
||||
s->m_pBuilder->Release();
|
||||
if (s->m_pControl)
|
||||
s->m_pControl->Release();
|
||||
if (s->m_pGraph)
|
||||
s->m_pGraph->Release();
|
||||
|
||||
if (s->m_pDXFilter!=NULL)
|
||||
s->m_pDXFilter->Release();
|
||||
|
||||
s->m_pNullRenderer=NULL;
|
||||
s->m_pIDXFilter=NULL;
|
||||
s->m_pDeviceFilter=NULL;
|
||||
s->m_pBuilder=NULL;
|
||||
s->m_pControl=NULL;
|
||||
s->m_pGraph=NULL;
|
||||
s->m_pDXFilter=NULL;
|
||||
|
||||
CoUninitialize();
|
||||
s_callback = NULL;
|
||||
flushq(&s->rq,0);
|
||||
ms_message("v4w: checked device size=%ix%i format=%i (err=%i)", s->vsize.width, s->vsize.height, s->pix_fmt, i);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static int _v4w_start(V4wState *s, void *arg)
|
||||
{
|
||||
|
|
@ -868,20 +1119,6 @@ static int _v4w_stop(V4wState *s, void *arg){
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int v4w_start(MSFilter *f, void *arg){
|
||||
V4wState *s=(V4wState*)f->data;
|
||||
_v4w_start(s, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int v4w_stop(MSFilter *f, void *arg){
|
||||
V4wState *s=(V4wState*)f->data;
|
||||
_v4w_stop(s, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void v4w_uninit(MSFilter *f){
|
||||
V4wState *s=(V4wState*)f->data;
|
||||
int idx;
|
||||
|
|
@ -984,14 +1221,14 @@ static mblk_t * v4w_make_nowebcam(V4wState *s){
|
|||
|
||||
static void v4w_preprocess(MSFilter * obj){
|
||||
V4wState *s=(V4wState*)obj->data;
|
||||
s->running=TRUE;
|
||||
if (s->rotregvalue==0)
|
||||
_v4w_start(s, NULL);
|
||||
if (s->rotregvalue==0)
|
||||
s->fps=1;
|
||||
}
|
||||
|
||||
static void v4w_postprocess(MSFilter * obj){
|
||||
V4wState *s=(V4wState*)obj->data;
|
||||
s->running=FALSE;
|
||||
s->start_time=0;
|
||||
s->frame_count=-1;
|
||||
flushq(&s->rq,0);
|
||||
|
|
@ -1054,6 +1291,11 @@ static int v4w_set_pix_fmt(MSFilter *f,void *arg){
|
|||
|
||||
static int v4w_get_pix_fmt(MSFilter *f,void *arg){
|
||||
V4wState *s=(V4wState*)f->data;
|
||||
if (s->rotregvalue==0){
|
||||
_v4w_test(s, NULL); /* check supported format */
|
||||
*((MSPixFmt*)arg) = (MSPixFmt)s->pix_fmt;
|
||||
return 0;
|
||||
}
|
||||
*((MSPixFmt*)arg) = (MSPixFmt)s->pix_fmt;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1098,6 +1340,12 @@ static int v4w_set_image(MSFilter *f, void *arg){
|
|||
ms_mutex_unlock(&s->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int v4w_set_name(MSFilter *f, void *arg){
|
||||
V4wState *s=(V4wState*)f->data;
|
||||
snprintf(s->dev, sizeof(s->dev), (char*)arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static MSFilterMethod methods[]={
|
||||
{ MS_FILTER_SET_FPS , v4w_set_fps },
|
||||
|
|
@ -1105,10 +1353,8 @@ static MSFilterMethod methods[]={
|
|||
{ MS_FILTER_GET_PIX_FMT , v4w_get_pix_fmt },
|
||||
{ MS_FILTER_SET_VIDEO_SIZE, v4w_set_vsize },
|
||||
{ MS_FILTER_GET_VIDEO_SIZE, v4w_get_vsize },
|
||||
{ MS_V4L_START , v4w_start },
|
||||
{ MS_V4L_STOP , v4w_stop },
|
||||
{ MS_V4L_SET_DEVICE , v4w_set_device },
|
||||
{ MS_V4L_SET_IMAGE , v4w_set_image },
|
||||
{ MS_V4L_SET_DEVICE, v4w_set_device },
|
||||
{ MS_FILTER_SET_IMAGE, v4w_set_image },
|
||||
{ 0 , NULL }
|
||||
};
|
||||
|
||||
|
|
@ -1152,16 +1398,17 @@ MSFilterDesc ms_v4w_desc={
|
|||
MS_FILTER_DESC_EXPORT(ms_v4w_desc)
|
||||
|
||||
static MSFilter *vfw_create_reader(MSWebCam *obj){
|
||||
return ms_filter_new_from_desc(&ms_v4w_desc);
|
||||
MSFilter *f=ms_filter_new_from_desc(&ms_v4w_desc);
|
||||
v4w_set_name(f,obj->name);
|
||||
return f;
|
||||
}
|
||||
|
||||
static void vfw_detect(MSWebCamManager *obj);
|
||||
|
||||
static void vfw_cam_init(MSWebCam *cam){
|
||||
cam->name=ms_strdup("dx0");
|
||||
}
|
||||
|
||||
MSWebCamDesc ms_v4w_cam_desc={
|
||||
MSWebCamDesc ms_directx_cam_desc={
|
||||
"DirectX Video Grabber",
|
||||
&vfw_detect,
|
||||
&vfw_cam_init,
|
||||
|
|
@ -1170,6 +1417,61 @@ MSWebCamDesc ms_v4w_cam_desc={
|
|||
};
|
||||
|
||||
static void vfw_detect(MSWebCamManager *obj){
|
||||
MSWebCam *cam=ms_web_cam_new(&ms_v4w_cam_desc);
|
||||
ms_web_cam_manager_add_cam(obj,cam);
|
||||
ICreateDevEnum *pCreateDevEnum = NULL;
|
||||
IEnumMoniker *pEnumMoniker = NULL;
|
||||
IMoniker *pMoniker = NULL;
|
||||
HRESULT hr;
|
||||
|
||||
ULONG nFetched = 0;
|
||||
|
||||
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
|
||||
IID_ICreateDevEnum, (PVOID *)&pCreateDevEnum);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
|
||||
&pEnumMoniker, 0);
|
||||
if (FAILED(hr) || pEnumMoniker == NULL) {
|
||||
//printf("no device\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
pEnumMoniker->Reset();
|
||||
|
||||
int pos=0;
|
||||
while(S_OK == pEnumMoniker->Next(1, &pMoniker, &nFetched) )
|
||||
{
|
||||
IPropertyBag *pBag;
|
||||
hr = pMoniker->BindToStorage( 0, 0, IID_IPropertyBag, (void**) &pBag );
|
||||
if( hr != S_OK )
|
||||
continue;
|
||||
|
||||
VARIANT var;
|
||||
VariantInit(&var);
|
||||
hr = pBag->Read( L"FriendlyName", &var, NULL );
|
||||
if( hr != S_OK )
|
||||
{
|
||||
pMoniker->Release();
|
||||
continue;
|
||||
}
|
||||
//USES_CONVERSION;
|
||||
char szName[256];
|
||||
|
||||
WideCharToMultiByte(CP_ACP,0,var.bstrVal,-1,szName,256,0,0);
|
||||
VariantClear(&var);
|
||||
|
||||
MSWebCam *cam=ms_web_cam_new(&ms_directx_cam_desc);
|
||||
cam->name=ms_strdup(szName);
|
||||
ms_web_cam_manager_add_cam(obj,cam);
|
||||
|
||||
pMoniker->Release();
|
||||
pBag->Release();
|
||||
pMoniker=NULL;
|
||||
pBag=NULL;
|
||||
}
|
||||
|
||||
pEnumMoniker->Release();
|
||||
pCreateDevEnum->Release();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue