sandor78
10-11-2005, 11:44
E' da un po di tempo che sto studiando le directshow per realizzare un sistema di acqusizioni di immagini da più webcam.
Fino ad ora sono riuscito ad avere un buon risultato, riuscendo a collegare due webcam al pc e visualizzare contemporaneamente i due stream video, però mi è rimasta da fare un'ultima cosa, salvare le immagini come bitmap o come si dice in realizzare un frame grabber.
Purtroppo ho un pò di problemi con il filtro ISampleGrabber, purtroppo non riesco a collegarlo alla filtro sorgente.
Qui di seguito riporto la funzione che sto implementando per realizzare il grabbaggio:
HRESULT hr;
ULONG cFetched;
// Create the Sample Grabber.
IBaseFilter *pGrabberF = NULL;
hr = CoCreateInstance(CLSID_SampleGrabber, NULL,SCTX_INPROC_SERVER,
IID_IBaseFilter, (void**)&pGrabberF);
if (FAILED(hr))
{
return hr;
}
hr = m_pGraph->AddFilter(pGrabberF, L"Sample Grabber");
if (FAILED(hr))
{
return hr;
}
ISampleGrabber *pGrabber;
pGrabberF->QueryInterface(IID_ISampleGrabber, (void**)&pGrabber);
//Create the Source Filter.
ICreateDevEnum *pDevEnum = NULL;
IEnumMoniker *pEnum = NULL;
// Create the System Device Enumerator.
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
reinterpret_cast<void**>(&pDevEnum));
if (SUCCEEDED(hr))
{
// Create an enumerator for the video capture category.
hr = pDevEnum->CreateClassEnumerator(
CLSID_VideoInputDeviceCategory,
&pEnum, 0);
}
IMoniker *pMoniker = NULL;
for (int i=0; i<m_intActualDevice; i++)
{
pEnum->Next (1, &pMoniker, &cFetched);
}
IBaseFilter *pSource = NULL;
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pSource);
if (SUCCEEDED(hr))
{
hr = m_pGraph->AddFilter(pSource, L"Capture Filter");
}
IPin *pSourceOut=NULL, *pGrabIn=NULL;
//Connect pSource to pGrbberF
pSourceOut = GetPin(pSource, PINDIR_OUTPUT);
if (pSourceOut != NULL)
{ // Is the pin good?
pGrabIn = GetPin(pGrabberF, PINDIR_INPUT);
if (pGrabIn != NULL)
{ // Is the pin good?
hr = m_pGraph->Connect(pSourceOut, pGrabIn);
}
}
// Find the required buffer size.
long cbBuffer = 0;
hr = pGrabber->GetCurrentBuffer(&cbBuffer, NULL);
char *pBuffer = new char[cbBuffer];
if (!pBuffer)
{
// Out of memory. Return an error code.
}
hr = pGrabber->GetCurrentBuffer(&cbBuffer, (long*)pBuffer);
AM_MEDIA_TYPE mt;
hr = pGrabber->GetConnectedMediaType(&mt);
pDevEnum->Release();
pEnum->Release();
pMoniker->Release();
N.B.
m_pGraph è una variabile globale in cui gia è stato inserito il filtro sorgente.
Non vorrei che redifinendo la sorgente una seconda volta mi dia dei problemi.........
Grazie per l'aiuto
Fino ad ora sono riuscito ad avere un buon risultato, riuscendo a collegare due webcam al pc e visualizzare contemporaneamente i due stream video, però mi è rimasta da fare un'ultima cosa, salvare le immagini come bitmap o come si dice in realizzare un frame grabber.
Purtroppo ho un pò di problemi con il filtro ISampleGrabber, purtroppo non riesco a collegarlo alla filtro sorgente.
Qui di seguito riporto la funzione che sto implementando per realizzare il grabbaggio:
HRESULT hr;
ULONG cFetched;
// Create the Sample Grabber.
IBaseFilter *pGrabberF = NULL;
hr = CoCreateInstance(CLSID_SampleGrabber, NULL,SCTX_INPROC_SERVER,
IID_IBaseFilter, (void**)&pGrabberF);
if (FAILED(hr))
{
return hr;
}
hr = m_pGraph->AddFilter(pGrabberF, L"Sample Grabber");
if (FAILED(hr))
{
return hr;
}
ISampleGrabber *pGrabber;
pGrabberF->QueryInterface(IID_ISampleGrabber, (void**)&pGrabber);
//Create the Source Filter.
ICreateDevEnum *pDevEnum = NULL;
IEnumMoniker *pEnum = NULL;
// Create the System Device Enumerator.
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
reinterpret_cast<void**>(&pDevEnum));
if (SUCCEEDED(hr))
{
// Create an enumerator for the video capture category.
hr = pDevEnum->CreateClassEnumerator(
CLSID_VideoInputDeviceCategory,
&pEnum, 0);
}
IMoniker *pMoniker = NULL;
for (int i=0; i<m_intActualDevice; i++)
{
pEnum->Next (1, &pMoniker, &cFetched);
}
IBaseFilter *pSource = NULL;
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pSource);
if (SUCCEEDED(hr))
{
hr = m_pGraph->AddFilter(pSource, L"Capture Filter");
}
IPin *pSourceOut=NULL, *pGrabIn=NULL;
//Connect pSource to pGrbberF
pSourceOut = GetPin(pSource, PINDIR_OUTPUT);
if (pSourceOut != NULL)
{ // Is the pin good?
pGrabIn = GetPin(pGrabberF, PINDIR_INPUT);
if (pGrabIn != NULL)
{ // Is the pin good?
hr = m_pGraph->Connect(pSourceOut, pGrabIn);
}
}
// Find the required buffer size.
long cbBuffer = 0;
hr = pGrabber->GetCurrentBuffer(&cbBuffer, NULL);
char *pBuffer = new char[cbBuffer];
if (!pBuffer)
{
// Out of memory. Return an error code.
}
hr = pGrabber->GetCurrentBuffer(&cbBuffer, (long*)pBuffer);
AM_MEDIA_TYPE mt;
hr = pGrabber->GetConnectedMediaType(&mt);
pDevEnum->Release();
pEnum->Release();
pMoniker->Release();
N.B.
m_pGraph è una variabile globale in cui gia è stato inserito il filtro sorgente.
Non vorrei che redifinendo la sorgente una seconda volta mi dia dei problemi.........
Grazie per l'aiuto