線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2753
推到 Plurk!
推到 Facebook!

DirectShow中的Playcap的那個範例

答題得分者是:ikk
GN00291313
一般會員


發表:5
回覆:5
積分:2
註冊:2009-04-14

發送簡訊給我
#1 引用回覆 回覆 發表時間:2010-01-02 05:38:04 IP:114.43.xxx.xxx 訂閱
請問DirectShow中的Playcap的那個範例,它影像的串流在哪邊? 因為我想把影像在buffer中做處理,請各位大大指教一下,謝謝><.....


[code cpp]
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
g_dwGraphRegister=0;
g_pVW = NULL;
g_pMC = NULL;
g_pME = NULL;
g_pGraph = NULL;
g_pCapture = NULL;
g_psCurrent = Stopped;

if(FAILED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED))) //Initialize COM
{
Msg(TEXT("CoInitialize Failed!\r\n"));
Application->Terminate();
return;
}
if(FAILED(CaptureVideo()))
{
Application->Terminate();
return;
}
}
//---------------------------------------------------------------------------
__fastcall TForm1::~TForm1()
{
CloseInterfaces();
CoUninitialize(); // Release COM
}
//---------------------------------------------------------------------------
void __fastcall TForm1::WndProc(Messages::TMessage &Message)
{
switch(Message.Msg)
{
case WM_GRAPHNOTIFY:
HandleGraphEvent();
break;

case WM_SIZE:
ResizeVideoWindow();
break;

case WM_WINDOWPOSCHANGED:
ChangePreviewState(!(IsIconic(Handle)));
break;

case WM_CLOSE:
// Hide the main window while the graph is destroyed
ShowWindow(Handle, SW_HIDE);
CloseInterfaces(); // Stop capturing and release interfaces
break;

case WM_DESTROY:
PostQuitMessage(0);
Message.Result = 0;
return;
}

// Pass this message to the video window for notification of system changes
if (g_pVW)
g_pVW->NotifyOwnerMessage((LONG_PTR)Handle, Message.Msg, Message.WParam, Message.LParam);

TForm::WndProc(Message);
}
//---------------------------------------------------------------------------
void TForm1::Msg(TCHAR *szFormat, ...)
{
TCHAR szBuffer[1024]; // Large buffer for long filenames or URLs
const size_t NUMCHARS = sizeof(szBuffer) / sizeof(szBuffer[0]);
const int LASTCHAR = NUMCHARS - 1;

// Format the input string
va_list pArgs;
va_start(pArgs, szFormat);

// Use a bounded buffer size to prevent buffer overruns. Limit count to
// character size minus one to allow for a NULL terminating character.
_vsntprintf(szBuffer, NUMCHARS - 1, szFormat, pArgs);
va_end(pArgs);

// Ensure that the formatted string is NULL-terminated
szBuffer[LASTCHAR] = TEXT('\0');

MessageBox(NULL, szBuffer, TEXT("PlayCap Message"), MB_OK | MB_ICONERROR);
}
//---------------------------------------------------------------------------
#ifdef REGISTER_FILTERGRAPH // { //
//---------------------------------------------------------------------------
// Removes a filter graph from the Running Object Table
void TForm1::RemoveGraphFromRot(DWORD pdwRegister)
{
IRunningObjectTable *pROT;

if (SUCCEEDED(GetRunningObjectTable(0, &pROT)))
{
pROT->Revoke(pdwRegister);
pROT->Release();
}
}
//---------------------------------------------------------------------------
HRESULT TForm1::AddGraphToRot(IUnknown *pUnkGraph, DWORD *pdwRegister)
{
IMoniker * pMoniker;
IRunningObjectTable *pROT;
WCHAR wsz[128];
HRESULT hr;

if (!pUnkGraph || !pdwRegister)
return E_POINTER;

if (FAILED(GetRunningObjectTable(0, &pROT)))
return E_FAIL;

wsprintfW(wsz, L"FilterGraph x pid x\0", (DWORD_PTR)pUnkGraph,
GetCurrentProcessId());

hr = CreateItemMoniker(L"!", wsz, &pMoniker);
if (SUCCEEDED(hr))
{
// Use the ROTFLAGS_REGISTRATIONKEEPSALIVE to ensure a strong reference
// to the object. Using this flag will cause the object to remain
// registered until it is explicitly revoked with the Revoke() method.
//
// Not using this flag means that if GraphEdit remotely connects
// to this graph and then GraphEdit exits, this object registration
// will be deleted, causing future attempts by GraphEdit to fail until
// this application is restarted or until the graph is registered again.
hr = pROT->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, pUnkGraph,
pMoniker, pdwRegister);
pMoniker->Release();
}

pROT->Release();
return hr;
}
//---------------------------------------------------------------------------
#endif // } //
//---------------------------------------------------------------------------
HRESULT TForm1::GetInterfaces(void)
{
HRESULT hr;

// Create the filter graph
hr = CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC,
IID_IGraphBuilder, (void **) &g_pGraph);
if (FAILED(hr))
return hr;

// Create the capture graph builder
hr = CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,
IID_ICaptureGraphBuilder2, (void **) &g_pCapture);
if (FAILED(hr))
return hr;

// Obtain interfaces for media control and Video Window
hr = g_pGraph->QueryInterface(IID_IMediaControl,(LPVOID *) &g_pMC);
if (FAILED(hr))
return hr;

hr = g_pGraph->QueryInterface(IID_IVideoWindow, (LPVOID *) &g_pVW);
if (FAILED(hr))
return hr;

hr = g_pGraph->QueryInterface(IID_IMediaEvent, (LPVOID *) &g_pME);
if (FAILED(hr))
return hr;

// Set the window handle used to process graph events
hr = g_pME->SetNotifyWindow((OAHWND)Handle, WM_GRAPHNOTIFY, 0);

return hr;
}
//---------------------------------------------------------------------------
void TForm1::CloseInterfaces(void)
{
// Stop previewing data
if (g_pMC)
g_pMC->StopWhenReady();

g_psCurrent = Stopped;
// Stop receiving events
if (g_pME)
g_pME->SetNotifyWindow(NULL, WM_GRAPHNOTIFY, 0);

// Relinquish ownership (IMPORTANT!) of the video window.
// Failing to call put_Owner can lead to assert failures within
// the video renderer, as it still assumes that it has a valid
// parent window.
if(g_pVW)
{
g_pVW->put_Visible(OAFALSE);
g_pVW->put_Owner(NULL);
}

#ifdef REGISTER_FILTERGRAPH
// Remove filter graph from the running object table
if (g_dwGraphRegister)
RemoveGraphFromRot(g_dwGraphRegister);
#endif

// Release DirectShow interfaces
SAFE_RELEASE(g_pMC);
SAFE_RELEASE(g_pME);
SAFE_RELEASE(g_pVW);
SAFE_RELEASE(g_pGraph);
SAFE_RELEASE(g_pCapture);
}
//---------------------------------------------------------------------------
HRESULT TForm1::FindCaptureDevice(IBaseFilter ** ppSrcFilter)
{
HRESULT hr;
IBaseFilter * pSrc = NULL;
CComPtr pMoniker =NULL;
ULONG cFetched;

if (!ppSrcFilter)
return E_POINTER;

// Create the system device enumerator
CComPtr pDevEnum =NULL;

hr = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
IID_ICreateDevEnum, (void **) &pDevEnum);
if (FAILED(hr))
{
Msg(TEXT("Couldn't create system enumerator! hr=0x%x"), hr);
return hr;
}

// Create an enumerator for the video capture devices
CComPtr pClassEnum = NULL;

hr = pDevEnum->CreateClassEnumerator (CLSID_VideoInputDeviceCategory, &pClassEnum, 0);
if (FAILED(hr))
{
Msg(TEXT("Couldn't create class enumerator! hr=0x%x"), hr);
return hr;
}

// If there are no enumerators for the requested type, then
// CreateClassEnumerator will succeed, but pClassEnum will be NULL.
if (pClassEnum == NULL)
{
MessageBox(Handle,TEXT("No video capture device was detected.\r\n\r\n")
TEXT("This sample requires a video capture device, such as a USB WebCam,\r\n")
TEXT("to be installed and working properly. The sample will now close."),
TEXT("No Video Capture Hardware"), MB_OK | MB_ICONINFORMATION);
return E_FAIL;
}

// Use the first video capture device on the device list.
// Note that if the Next() call succeeds but there are no monikers,
// it will return S_FALSE (which is not a failure). Therefore, we
// check that the return code is S_OK instead of using SUCCEEDED() macro.
if (S_OK == (pClassEnum->Next (1, &pMoniker, &cFetched)))
{
// Bind Moniker to a filter object
hr = pMoniker->BindToObject(0,0,IID_IBaseFilter, (void**)&pSrc);
if (FAILED(hr))
{
Msg(TEXT("Couldn't bind moniker to filter object! hr=0x%x"), hr);
return hr;
}
}
else
{
Msg(TEXT("Unable to access video capture device!"));
return E_FAIL;
}

// Copy the found filter pointer to the output parameter.
// Do NOT Release() the reference, since it will still be used
// by the calling function.
*ppSrcFilter = pSrc;

return hr;
}
//---------------------------------------------------------------------------
void TForm1::ResizeVideoWindow(void)
{
// Resize the video preview window to match owner window size
if (g_pVW)
{
RECT rc;

// Make the preview video fill our window
::GetClientRect(Handle, &rc);
g_pVW->SetWindowPosition(0, 0, rc.right, rc.bottom);
}
}
//---------------------------------------------------------------------------
HRESULT TForm1::SetupVideoWindow(void)
{
HRESULT hr;

// Set the video window to be a child of the main window
hr = g_pVW->put_Owner((OAHWND)Handle);
if (FAILED(hr))
return hr;

// Set video window style
hr = g_pVW->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN);
if (FAILED(hr))
return hr;

// Use helper function to position video window in client rect
// of main application window
ResizeVideoWindow();

// Make the video window visible, now that it is properly positioned
hr = g_pVW->put_Visible(OATRUE);
if (FAILED(hr))
return hr;

return hr;
}
//---------------------------------------------------------------------------
HRESULT TForm1::CaptureVideo()
{
HRESULT hr;
IBaseFilter *pSrcFilter=NULL;

// Get DirectShow interfaces
hr = GetInterfaces();
if (FAILED(hr))
{
Msg(TEXT("Failed to get video interfaces! hr=0x%x"), hr);
return hr;
}

// Attach the filter graph to the capture graph
hr = g_pCapture->SetFiltergraph(g_pGraph);
if (FAILED(hr))
{
Msg(TEXT("Failed to set capture filter graph! hr=0x%x"), hr);
return hr;
}

// Use the system device enumerator and class enumerator to find
// a video capture/preview device, such as a desktop USB video camera.
hr = FindCaptureDevice(&pSrcFilter);
if (FAILED(hr))
{
// Don't display a message because FindCaptureDevice will handle it
return hr;
}

// Add Capture filter to our graph.
hr = g_pGraph->AddFilter(pSrcFilter, L"Video Capture");
if (FAILED(hr))
{
Msg(TEXT("Couldn't add the capture filter to the graph! hr=0x%x\r\n\r\n")
TEXT("If you have a working video capture device, please make sure\r\n")
TEXT("that it is connected and is not being used by another application.\r\n\r\n")
TEXT("The sample will now close."), hr);
pSrcFilter->Release();
return hr;
}

// Render the preview pin on the video capture filter
// Use this instead of g_pGraph->RenderFile
hr = g_pCapture->RenderStream (&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
pSrcFilter, NULL, NULL);
if (FAILED(hr))
{
Msg(TEXT("Couldn't render the video capture stream. hr=0x%x\r\n")
TEXT("The capture device may already be in use by another application.\r\n\r\n")
TEXT("The sample will now close."), hr);
pSrcFilter->Release();
return hr;
}

// Now that the filter has been added to the graph and we have
// rendered its stream, we can release this reference to the filter.
pSrcFilter->Release();

// Set video window style and position
hr = SetupVideoWindow();
if (FAILED(hr))
{
Msg(TEXT("Couldn't initialize video window! hr=0x%x"), hr);
return hr;
}

#ifdef REGISTER_FILTERGRAPH
// Add our graph to the running object table, which will allow
// the GraphEdit application to "spy" on our graph
hr = AddGraphToRot(g_pGraph, &g_dwGraphRegister);
if (FAILED(hr))
{
Msg(TEXT("Failed to register filter graph with ROT! hr=0x%x"), hr);
g_dwGraphRegister = 0;
}
#endif

// Start previewing video data
hr = g_pMC->Run();
if (FAILED(hr))
{
Msg(TEXT("Couldn't run the graph! hr=0x%x"), hr);
return hr;
}

// Remember current state
g_psCurrent = Running;

return S_OK;
}
//---------------------------------------------------------------------------
HRESULT TForm1::ChangePreviewState(int nShow)
{
HRESULT hr=S_OK;

// If the media control interface isn't ready, don't call it
if (!g_pMC)
return S_OK;

if (nShow)
{
if (g_psCurrent != Running)
{
// Start previewing video data
hr = g_pMC->Run();
g_psCurrent = Running;
}
}
else
{
// Stop previewing video data
hr = g_pMC->StopWhenReady();
g_psCurrent = Stopped;
}

return hr;
}
//---------------------------------------------------------------------------
HRESULT TForm1::HandleGraphEvent(void)
{
LONG evCode, evParam1, evParam2;
HRESULT hr=S_OK;

if (!g_pME)
return E_POINTER;

while(SUCCEEDED(g_pME->GetEvent(&evCode, (LONG_PTR *) &evParam1,
(LONG_PTR *) &evParam2, 0)))
{
//
// Free event parameters to prevent memory leaks associated with
// event parameter data. While this application is not interested
// in the received events, applications should always process them.
//
hr = g_pME->FreeEventParams(evCode, evParam1, evParam2);

// Insert event processing code here, if desired
}

return hr;
}
//---------------------------------------------------------------------------
[/code]

ikk
尊榮會員


發表:4
回覆:413
積分:768
註冊:2003-06-30

發送簡訊給我
#2 引用回覆 回覆 發表時間:2010-01-04 13:35:05 IP:163.28.xxx.xxx 訂閱
它是直接秀在VideoWindow的...
要取得資料是透過 SamlpeGrabber..
DXSDK\Samples\C \DirectShow\Editing\GrabBitmaps\GrabBitmaps.cpp
------
FPGA驗證, FPGA開發平台, http://smims.com
系統時間:2024-04-25 12:49:33
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!