📄 capturevideo.cpp
字号:
}
}
pinInfo.pFilter->Release();
}
pP->Release();
}
pins->Release();
}
nVSourceCount++;
} // End of While Loop
return S_OK;;
}
HRESULT CCaptureVideo::HandleGraphEventMoniker()
{
LONG evCode, evParam1, evParam2;
HRESULT hr=S_OK;
if (!m_pMEMoniker)
return E_POINTER;
// Process all queued events
while(SUCCEEDED(m_pMEMoniker->GetEvent(&evCode, (LONG_PTR *) &evParam1,
(LONG_PTR *) &evParam2, 0)))
{
// Insert event processing code here, if desired
switch (evCode)
{
// When the user closes the capture window, close the app.
case EC_DEVICE_LOST:
case EC_ERRORABORT:
case EC_USERABORT:
DisplayMesg(TEXT("Received an error event: 0x%x. Closing app.\0"), evCode);
::PostMessage(m_hApp, WM_CLOSE, 0, 0);
break;
}
hr = m_pMEMoniker->FreeEventParams(evCode, evParam1, evParam2);
}
return hr;
}
HRESULT CCaptureVideo::SetupVideoWindowMoniker()
{
HRESULT hr;
// Set the video window to be a child of the main window
hr = m_pVWMoniker->put_Owner((OAHWND)m_hApp);
if (FAILED(hr))
return hr;
// Set video window style
hr = m_pVWMoniker->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN);
if (FAILED(hr))
return hr;
ResizeVideoWindowMoniker();
// Make the video window visible, now that it is properly positioned
hr = m_pVWMoniker->put_Visible(OATRUE);
if (FAILED(hr))
return hr;
hr = m_pVWMoniker->put_MessageDrain((OAHWND)m_hApp);
return hr;
}
HRESULT CCaptureVideo::AddGraphToRotMoniker(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 %08x pid %08x\0", (DWORD_PTR)pUnkGraph,
GetCurrentProcessId());
hr = CreateItemMoniker(L"!", wsz, &pMoniker);
if (SUCCEEDED(hr))
{
hr = pROT->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, pUnkGraph,
pMoniker, pdwRegister);
pMoniker->Release();
}
pROT->Release();
return hr;
}
void CCaptureVideo::RemoveGraphFromRotMoniker(DWORD pdwRegister)
{
IRunningObjectTable *pROT;
if (SUCCEEDED(GetRunningObjectTable(0, &pROT)))
{
pROT->Revoke(pdwRegister);
pROT->Release();
}
}
HRESULT CCaptureVideo::OnGraphNotify(WPARAM wp , LPARAM lp)
{
HandleGraphEvent();
return 0;
}
void CCaptureVideo::DisplayMesg(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("LiveVideo Message"), MB_OK | MB_ICONERROR);
}
void CCaptureVideo::StartSVideo()
{
if( vType == 1) // If WebCam
CloseInterfacesMoniker();
if( m_pCapture == NULL)
{
HRESULT hr= CaptureVideo();
if(FAILED(hr))
{
CloseInterfaces();
return;
}
}
vType = 0; // Initializing current capture device to Video
IAMCrossbar *pX;
//unsigned short a =10;
//MessageBox(NULL,&a,&a, 1);
if ( m_pCapture == NULL)
return;
if(pSrcF == NULL)
return;
HRESULT hr;
hr = m_pCapture->FindInterface(&PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Interleaved, pSrcF,
IID_IAMCrossbar, (void **)&pX);
if(hr != NOERROR)
hr = m_pCapture->FindInterface(&PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video, pSrcF,
IID_IAMCrossbar, (void **)&pX);
LONG lInpin, lOutpin;
hr = pX->get_PinCounts(&lOutpin , &lInpin);
//CString str; str.Format("%ld %ld",l2,l1);
//MessageBox(str);
BOOL IPin=TRUE; LONG pIndex=0 , pRIndex=0 , pType=0;
while( pIndex < lInpin)
{
hr = pX->get_CrossbarPinInfo( IPin , pIndex , &pRIndex , &pType);
/*if( pType == PhysConn_Video_Tuner)
break;
pIndex++;*/
if( pType == PhysConn_Video_SVideo)
break;
pIndex++;
}
BOOL OPin=FALSE; LONG pOIndex=0 , pORIndex=0 , pOType=0;
while( pOIndex < lOutpin)
{
hr = pX->get_CrossbarPinInfo( OPin , pOIndex , &pORIndex , &pOType);
if( pOType == PhysConn_Video_VideoDecoder)
break;
}
pX->Route(pOIndex,pIndex);
pX->Release();
}
void CCaptureVideo::StartCompositeVideo()
{
if(vType == 1) //If Webcam
CloseInterfacesMoniker();
if( m_pCapture == NULL)
{
HRESULT hr= CaptureVideo();
if(FAILED(hr))
{
CloseInterfaces();
return;
}
}
vType = 0; // Initializing current capture device to Video
IAMCrossbar *pX;
if ( m_pCapture == NULL)
return;
if(pSrcF == NULL)
return;
HRESULT hr;
hr = m_pCapture->FindInterface(&PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Interleaved, pSrcF,
IID_IAMCrossbar, (void **)&pX);
if(hr != NOERROR)
hr = m_pCapture->FindInterface(&PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video, pSrcF,
IID_IAMCrossbar, (void **)&pX);
LONG lInpin, lOutpin;
hr = pX->get_PinCounts(&lOutpin , &lInpin);
//CString str; str.Format("%ld %ld",l2,l1);
//MessageBox(str);
BOOL IPin=TRUE; LONG pIndex=0 , pRIndex=0 , pType=0;
while( pIndex < lInpin)
{
hr = pX->get_CrossbarPinInfo( IPin , pIndex , &pRIndex , &pType);
if( pType == PhysConn_Video_Composite)
break;
pIndex++;
}
BOOL OPin=FALSE; LONG pOIndex=0 , pORIndex=0 , pOType=0;
while( pOIndex < lOutpin)
{
hr = pX->get_CrossbarPinInfo( OPin , pOIndex , &pORIndex , &pOType);
if( pOType == PhysConn_Video_VideoDecoder)
break;
}
pX->Route(pOIndex,pIndex);
pX->Release();
}
void CCaptureVideo::StartWebcam()
{
// If Previous mode is Video then Close all interfaces
if( vType == 0 )
CloseInterfaces();
vType = 1; // Initializing current capture device to WebCam
// Initializing Interfaces and Capture using WebCam
HRESULT hr = CaptureVideoByMoniker();
if(FAILED(hr))
{
//AfxMessageBox("No Webcam Found.!") ;
return;
}
}
void CCaptureVideo::StartTVTuner()
{
if(vType == 1) //If Webcam
CloseInterfacesMoniker();
if( m_pCapture == NULL)
{
HRESULT hr= CaptureVideo();
if(FAILED(hr))
{
CloseInterfaces();
return;
}
}
vType = 0; // Initializing current capture device to Video
IAMCrossbar *pX;
if ( m_pCapture == NULL)
return;
if(pSrcF == NULL)
return;
HRESULT hr;
hr = m_pCapture->FindInterface(&PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Interleaved, pSrcF,
IID_IAMCrossbar, (void **)&pX);
if(hr != NOERROR)
hr = m_pCapture->FindInterface(&PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video, pSrcF,
IID_IAMCrossbar, (void **)&pX);
LONG lInpin, lOutpin;
hr = pX->get_PinCounts(&lOutpin , &lInpin);
BOOL IPin=TRUE; LONG pIndex=0 , pRIndex=0 , pType=0;
while( pIndex < lInpin)
{
hr = pX->get_CrossbarPinInfo( IPin , pIndex , &pRIndex , &pType);
if( pType == PhysConn_Video_Tuner)
break;
pIndex++;
}
BOOL OPin=FALSE; LONG pOIndex=0 , pORIndex=0 , pOType=0;
while( pOIndex < lOutpin)
{
hr = pX->get_CrossbarPinInfo( OPin , pOIndex , &pORIndex , &pOType);
if( pOType == PhysConn_Video_VideoDecoder)
break;
}
pX->Route(pOIndex,pIndex);
pX->Release();
}
void CCaptureVideo::StopCapture()
{
if( vType == 1) // If WebCam
CloseInterfacesMoniker();
CloseInterfaces();
bVideo = FALSE;
//CoUninitialize();
}
void CCaptureVideo::ResizeVideoWindowMoniker()
{
// Resize the video preview window to match owner window size
if (m_pVWMoniker)
{
CRect rc;
// Make the preview video fill our window
::GetClientRect(m_hApp,&rc);
m_pVWMoniker->SetWindowPosition(0, 0, rc.right, rc.bottom);
}
}
void CCaptureVideo::ResizeVideoWindow()
{
// Resize the video preview window to match owner window size
if (m_pVW)
{
RECT rc;
// Make the preview video fill our window
::GetClientRect(m_hApp,&rc);
m_pVW->SetWindowPosition(0, 0, rc.right, rc.bottom);
}
}
// Pass it a file name in wszPath, and it will save the filter graph
// to that file.
HRESULT SaveGraphFile(IGraphBuilder *pGraph, WCHAR *wszPath)
{
const WCHAR wszStreamName[] = L"ActiveMovieGraph";
HRESULT hr;
IStorage *pStorage = NULL;
// First, create a document file that will hold the GRF file
hr = StgCreateDocfile(
wszPath,
STGM_CREATE | STGM_TRANSACTED | STGM_READWRITE |
STGM_SHARE_EXCLUSIVE,
0, &pStorage);
if(FAILED(hr))
{
return hr;
}
// Next, create a stream to store.
IStream *pStream;
hr = pStorage->CreateStream(
wszStreamName,
STGM_WRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE,
0, 0, &pStream);
if (FAILED(hr))
{
pStorage->Release();
return hr;
}
// The IpersistStream::Save method converts a stream
// into a persistent object.
IPersistStream *pPersist = NULL;
pGraph->QueryInterface(IID_IPersistStream,
reinterpret_cast<void**>(&pPersist));
hr = pPersist->Save(pStream, TRUE);
pStream->Release();
pPersist->Release();
if (SUCCEEDED(hr))
{
hr = pStorage->Commit(STGC_DEFAULT);
}
pStorage->Release();
return hr;
}
// This code allows us to find a pin (input or output) on a filter.
IPin *GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir)
{
BOOL bFound = FALSE;
IEnumPins *pEnum;
IPin *pPin;
// Begin by enumerating all the pins on a filter
HRESULT hr = pFilter->EnumPins(&pEnum);
if (FAILED(hr))
{
return NULL;
}
// Now look for a pin that matches the direction characteristic.
// When we've found it, we'll return with it.
while(pEnum->Next(1, &pPin, 0) == S_OK)
{
PIN_DIRECTION PinDirThis;
pPin->QueryDirection(&PinDirThis);
if (bFound = (PinDir == PinDirThis))
break;
pPin->Release();
}
pEnum->Release();
return (bFound ? pPin : NULL);
}
HRESULT CCaptureVideo::ConfigureTVAudio(BOOL bActivate)
{
// if (!m_pCap) return S_FALSE;
// Basically we have to grovel the filter graph for a crossbar filter,
// then try to connect the Audio Decoder Out pin to the Audio Tuner In
// pin. Some cards have two crossbar filters.
// Search upstream for a crossbar.
IAMCrossbar *pXBar1 = NULL;
//HRESULT hr = m_pBuild->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, m_pCap,IID_IAMCrossbar, (void**)&pXBar1);
HRESULT hr = m_pCapture->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, m_pCap,IID_IAMCrossbar, (void**)&pXBar1);
if (SUCCEEDED(hr))
{
// Try to connect the audio pins.
hr = ConnectAudio(pXBar1, bActivate);
if (FAILED(hr))
{
// Search upstream for another crossbar.
IBaseFilter *pF = NULL;
hr = pXBar1->QueryInterface(IID_IBaseFilter, (void**)&pF);
if (SUCCEEDED(hr))
{
IAMCrossbar *pXBar2 = NULL;
hr = m_pCapture->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pF,
IID_IAMCrossbar, (void**)&pXBar2);
pF->Release();
if (SUCCEEDED(hr))
{
// Try to connect the audio pins.
hr = ConnectAudio(pXBar2, bActivate);
pXBar2->Release();
}
}
}
pXBar1->Release();
}
return hr;
}
HRESULT ConnectAudio(IAMCrossbar *pXBar, BOOL bActivate)
{
// Look for the Audio Decoder output pin.
long i = 0;
HRESULT hr = FindCrossbarPin(pXBar, PhysConn_Audio_AudioDecoder,
FALSE, &i);
if (SUCCEEDED(hr))
{
if (bActivate) // Activate the audio
{
// Look for the Audio Tuner input pin.
long j = 0;
hr = FindCrossbarPin(pXBar, PhysConn_Audio_Tuner, TRUE, &j);
if (SUCCEEDED(hr))
{
return pXBar->Route(i, j);
}
}
else // Mute the audio
{
return pXBar->Route(i, -1);
}
}
return E_FAIL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -