|
|
|
date: Tue, 27 Nov 2007 04:36:48 -0800 (PST),
group: microsoft.public.win32.programmer.directx.sdk
back
directshow: how to get the Previewer (Renderer) Pin
Hi
How to get the Previewer (Renderer) Pin.
We need to insert a filter before the Renderer in the graph.
Is there a way to get the Pin or Filter.
I used the PPC Sample CameraCapture that I improved:
Thank you very much!
Michel
This is the previewe code.
//================================================
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft
end-user
// license agreement (EULA) under which you licensed this SOFTWARE
PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized
to use
// this source code. For a copy of the EULA, please see the
LICENSE.RTF on your
// install media.
//
#include "stdafx.h"
// {3B140E8C-F3AD-465f-BCB7-7660589F790B}
EXTERN_GUID(CLSID_NullRend,
0x8a99caeb, 0xaef5, 0x11da,
0x95, 0x8b, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f );
EXTERN_GUID(CLSID_CSampleGrabber,
0xf3492a9b, 0x6626, 0x4345, 0xab, 0x8d, 0x17, 0xf5, 0x84, 0xdc,
0x1d, 0xe0);
//EXTERN_GUID(CLSID_NullRend,
// 0xbf5023aa, 0xd902, 0x49b2, 0x89, 0x14, 0xcb, 0xdb, 0xf0, 0x75,
0x22, 0xfe);
// Fill in media type information below, this information is used
when
// registering the filter with dshow
const AMOVIESETUP_MEDIATYPE sudPinTypes =
{ &MEDIATYPE_NULL, &MEDIASUBTYPE_NULL };
const AMOVIESETUP_PIN sudPins =
{ L"Null", FALSE, FALSE, FALSE, FALSE, &CLSID_NULL, NULL, 1,
&sudPinTypes };
const AMOVIESETUP_FILTER sudNULL =
{ &CLSID_NullRend, L"NullRend", MERIT_DO_NOT_USE, 1, &sudPins };
extern HWND g_h1;
#define VideoProcAmp_Gain VideoProcAmp_BacklightCompensation + 1
//
// using this flag set the Scene by the IAMVideoProcAmp interface
//
#define VideoProcAmp_Scene VideoProcAmp_Gain + 2
//
// the Scene values
//
typedef
enum{
VideoProcAmp_Scene_Auto = 0x0001,
VideoProcAmp_Scene_Night = 0x0002,
VideoProcAmp_Scene_Sports = 0x0003
} VideoProcAmpScene;
// using this flag set the White Balance by the IAMVideoProcAmp
interface
// the White Balance values
typedef
enum{
VideoProcAmp_WB_Tungsten = 0x0001,
VideoProcAmp_WB_Halogenic = 0x0002,
VideoProcAmp_WB_Fluorescent = 0x0003,
VideoProcAmp_WB_Incandescence = 0x0004,
VideoProcAmp_WB_Sunny = 0x0005,
VideoProcAmp_WB_Cloudy = 0x0006
} VideoProcAmpWhiteBalance;
//
// the Flash values
//
// Auto Flash:
// CameraControlFlags = CameraControl_Flags_Auto
//
typedef
enum{
CameraControl_Flash_Forced = 0x0001,
CameraControl_Flash_NoFlash = 0x0002,
CameraControl_Flash_Close = 0x0003
} CameraControlFlash;
//
// using this flag set the Macro by the IAMCameraControl interface
//
#define CameraControl_Macro 11
//
// the Macro values
//
typedef
enum{
CameraControl_Macro_On = 0x0001,
CameraControl_Macro_Off = 0x0002
} CameraControlMacro;
//
// the Zoom values
//
typedef
enum{
CameraControl_Zoom_100X = 0x0064, // decimal 100
CameraControl_Zoom_125X = 0x007D, // decimal 125
CameraControl_Zoom_150X = 0x0096, // decimal 150
CameraControl_Zoom_200X = 0x00C8, // decimal 200
CameraControl_Zoom_250X = 0x00FA // decimal 250
} CameraControlZoom;
//
// using this flag set the Effect by the IAMCameraControl interface
//
#define CameraControl_Effect 12//CameraControl_Flash + 3
//
// the Effect values
//
typedef
enum{
CameraControl_Effect_Normal = 0x0001,
CameraControl_Effect_BlackWhite = 0x0002,
CameraControl_Effect_Negative = 0x0003,
CameraControl_Effect_Sepia = 0x0004,
} CameraControlEffect;
//
// AC Frequency (?????)
//
// using this flag set the Effect by the IAMCameraControl interface
//
#define CameraControl_ACFrequency 13
//
// the AC Frequency values
//
// Auto Frequency:
// CameraControlFlags = CameraControl_Flags_Auto
//
typedef
enum{
CameraControl_ACFrequency_50Hz = 0x0001,
CameraControl_ACFrequency_60Hz = 0x0002,
} CameraControlACFrequency;
// 2. ISO Sensitivity (ISO ???)
//
// using this flag set the ISO Sensitivity by the IAMCameraControl
interface
//
#define CameraControl_ISOSensitivity 14
//
// the ISO Sensitivity values
// Auto :
// Flags = CameraControl_Flags_Auto
typedef
enum{
CameraControl_ISOSensitivity_100 = 0x0001,
CameraControl_ISOSensitivity_200 = 0x0002,
CameraControl_ISOSensitivity_400 = 0x0003,
} CameraControlISOSensitivity;
// 3. Metering Mode (????)
//
// using this flag set the ISO Exposure Mode by the IAMCameraControl
interface
//
#define CameraControl_MeteringMode 15
//
// the Metering Mode values
//
typedef
enum{
CameraControl_MeteringMode_Normal = 0x0001, //???????(Default)
CameraControl_MeteringMode_Center = 0x0002, //??????
CameraControl_MeteringMode_Background = 0x0003, //??????
} CameraControlMeteringMode;
//
// using this flag set the Preview / Camera / Video Mode
// by the IAMCameraControl interface
//
#define CameraControl_SetMode 16
//
// the Preview / Camera / Video Mode values
//
typedef
enum{
CameraControl_Mode_Preview = 0x0001, // this value only for camera
previewing
CameraControl_Mode_Camera = 0x0002, // this value for previewing and
still capture
CameraControl_Mode_Video = 0x0003, // this value for previewing and
video capture
CameraControl_Mode_VideoRec = 0x0004, // this value for capture
video start
} CameraControlSetMode;
typedef
enum{
CameraControl_Focus_Undo = 0x0001
} CameraControlFocus;
#include "initguid.h"
CGraphManager::CGraphManager()
{
m_fGraphBuilt = FALSE;
ZeroMemory( m_handle, sizeof( m_handle ));
m_hwnd = 0;
m_dwThreadId = 0;
m_hThread = NULL;
m_hCommandCompleted = NULL;
m_currentCommand = COMMAND_NOCOMMAND;
}
CGraphManager::~CGraphManager()
{
if( m_handle[0] )
{
CloseHandle( m_handle[0] );
}
if( m_handle[1] )
{
CloseHandle( m_handle[1] );
}
}
HRESULT
CGraphManager::Init()
{
HRESULT hr = S_OK;
// Create the event that will signal the thread for commands
m_handle[0] = CreateEvent( NULL, FALSE, FALSE, NULL );
if( m_handle[0] == NULL )
{
ERR( HRESULT_FROM_WIN32( GetLastError() ));
}
m_handle[1] = 0;
// Create the event to sync on to wait for the command to be
executed
m_hCommandCompleted = CreateEvent( NULL, FALSE, FALSE, NULL );
if( m_hCommandCompleted == NULL )
{
ERR( HRESULT_FROM_WIN32( GetLastError() ));
}
// CCreate the thread that will run the filtergraph.
// The filtergraph is running on a background thread to prevent
any window message
// reentrancy issue.
m_hThread = CreateThread( NULL, 0, CGraphManager::ThreadProc,
this, 0, &m_dwThreadId );
if( m_hThread == NULL )
{
ERR( HRESULT_FROM_WIN32( GetLastError() ));
}
Cleanup:
return hr;
}
HRESULT
CGraphManager::BuildCaptureGraph()
{
// The Graph is built on a separate thread to
// prevent reentrancy issues.
m_currentCommand = COMMAND_BUILDGRAPH;
SetEvent( m_handle[0] );
WaitForSingleObject( m_hCommandCompleted, INFINITE );
return S_OK;
}
HRESULT
CGraphManager::RunCaptureGraph()
{
// Unlike the other operations, running the graph
// has to happen from the UI thread.
return RunCaptureGraphInternal();
}
HRESULT
CGraphManager::StartRecordVideo()
{
m_currentCommand = COMMAND_STARTCAPTURE;
SetEvent( m_handle[0] );
WaitForSingleObject( m_hCommandCompleted, INFINITE );
return S_OK;
}
HRESULT
CGraphManager::StopRecordVideo()
{
m_currentCommand = COMMAND_STOPCAPTURE;
SetEvent( m_handle[0] );
WaitForSingleObject( m_hCommandCompleted, INFINITE );
return S_OK;
}
HRESULT
CGraphManager::CaptureStillImage()
{
m_currentCommand = COMMAND_STILLIMAGE;
SetEvent( m_handle[0] );
WaitForSingleObject( m_hCommandCompleted, INFINITE );
return S_OK;
}
HRESULT
CGraphManager::ShutDown()
{
m_currentCommand = COMMAND_SHUTDOWN;
SetEvent( m_handle[0] );
WaitForSingleObject( m_hThread, INFINITE );
return S_OK;
}
HRESULT
CGraphManager::RegisterNotificationWindow( HWND hwnd )
{
m_hwnd = hwnd;
return S_OK;
}
DWORD WINAPI
CGraphManager::ThreadProc( LPVOID lpParameter )
{
HRESULT hr = S_OK;
DWORD dwReturnValue;
CGraphManager *pThis = (CGraphManager*) lpParameter;
GRAPHCOMMANDS command = COMMAND_NOCOMMAND;
if( pThis == NULL )
{
return 0;
}
while(( command != COMMAND_SHUTDOWN ) && ( hr != S_FALSE ))
{
dwReturnValue = WaitForMultipleObjects( 2, pThis->m_handle,
FALSE, INFINITE );
switch( dwReturnValue )
{
case WAIT_OBJECT_0:
command = pThis->m_currentCommand;
pThis->ProcessCommand();
break;
case WAIT_OBJECT_0 + 1:
pThis->ProcessDShowEvent();
break;
case MV_BUFFER_ACCESS_BUFFERS_AVAILABLE:
break;
default:
break;
}
};
return 0;
}
HRESULT
CGraphManager::ProcessCommand()
{
HRESULT hr = S_OK;
switch( m_currentCommand )
{
case COMMAND_BUILDGRAPH:
hr = CreateCaptureGraphInternal();
SetEvent( m_hCommandCompleted );
break;
case COMMAND_RUNGRAPH:
hr = RunCaptureGraphInternal();
SetEvent( m_hCommandCompleted );
break;
case COMMAND_STARTCAPTURE:
hr = StartCaptureVideoInternal();
SetEvent( m_hCommandCompleted );
break;
case COMMAND_STOPCAPTURE:
hr = StopCaptureVideoInternal();
SetEvent( m_hCommandCompleted );
break;
case COMMAND_STILLIMAGE:
hr = CaptureStillImageInternal();
SetEvent( m_hCommandCompleted );
break;
case COMMAND_SHUTDOWN:
hr = S_FALSE;
break;
default:
break;
}
return hr;
}
HRESULT
CGraphManager::ProcessDShowEvent()
{
HRESULT hr = S_OK;
long lEventCode, lParam1, lParam2;
CComPtr<IMediaEvent> pMediaEvent;
CComPtr<IGraphBuilder> pFilterGraph;
CComPtr<IMediaControl> pMediaControl;
if( m_pCaptureGraphBuilder == NULL )
{
ERR( E_FAIL );
}
CHK( m_pCaptureGraphBuilder->GetFiltergraph( &pFilterGraph ));
CHK( pFilterGraph->QueryInterface( &pMediaEvent ));
CHK( pMediaEvent->GetEvent( &lEventCode, &lParam1, &lParam2, 0 ));
if( lEventCode == EC_STREAM_CONTROL_STOPPED ) // We have
received a control stream stop event
{
NotifyMessage( MESSAGE_ENDRECORDING, L"Recording done ..." );
// To close the file, get the IMediaControl interface, stop
and
// restart the graph
CHK( pFilterGraph->QueryInterface( &pMediaControl ));
if( pMediaControl == NULL )
{
ERR( E_POINTER );
}
CHK( pMediaControl->Stop());
CHK( pMediaControl->Run());
NotifyMessage( MESSAGE_FILECAPTURED, L"File captured ..." );
}
else if( lEventCode == EC_CAP_FILE_COMPLETED )
{
NotifyMessage( MESSAGE_FILECAPTURED, L"File captured ..." );
}
CHK( pMediaEvent->FreeEventParams( lEventCode, lParam1,
lParam2 ));
Cleanup:
return S_OK;
}
HRESULT
CGraphManager::GetFirstCameraDriver( WCHAR *pwzName )
{
HRESULT hr = S_OK;
HANDLE handle = NULL;
DEVMGR_DEVICE_INFORMATION di;
GUID guidCamera = { 0xCB998A05, 0x122C, 0x4166, 0x84, 0x6A, 0x93,
0x3E, 0x4D, 0x7E, 0x3C, 0x86 };
// Note about the above: The driver material doesn't ship as part of
the SDK. This GUID is hardcoded
// here to be able to enumerate the camera drivers and pass the name
of the driver to the video capture filter
if( pwzName == NULL )
{
return E_POINTER;
}
di.dwSize = sizeof(di);
handle = FindFirstDevice( DeviceSearchByGuid, &guidCamera, &di );
if(( handle == NULL ) || ( di.hDevice == NULL ))
{
ERR( HRESULT_FROM_WIN32( GetLastError() ));
}
StringCchCopy( pwzName, MAX_PATH, di.szLegacyName );
Cleanup:
FindClose( handle );
return hr;
}
HRESULT
CGraphManager::CreateCaptureGraphInternal()
{
HRESULT hr = S_OK;
CComVariant varCamName;
CPropertyBag PropBag;
OAEVENT oaEvent;
WCHAR wzDeviceName[ MAX_PATH + 1 ];
CComPtr<IMediaEvent> pMediaEvent;
CComPtr<IGraphBuilder> pFilterGraph;
CComPtr<IBaseFilter> pVideoEncoder;
CComPtr<IBaseFilter> pASFMultiplexer;
CComPtr<IFileSinkFilter> pFileSinkFilter;
CComPtr<IPersistPropertyBag> pPropertyBag;
CComPtr<IDMOWrapperFilter> pWrapperFilter;
CComPtr<IBaseFilter> pImageSinkFilter;
CComPtr<IBaseFilter> pConnectedFilter;
CComPtr<IAMVideoControl> pVideoControl;
CComPtr<IPin> pStillPin;
CComPtr<IUnknown> pUnkCaptureFilter;
CComPtr<IVideoWindow> pVideoWindow;
IMediaControl *pControl = NULL;
CComPtr<IBaseFilter> nullRenderer;
CComPtr<IFilterGraph> pGrabber;
CComPtr<IBaseFilter> pBuffer;
CComPtr<IUnknown> pUnk1;
CComPtr<IPin> pCaptPin;
CComPtr<IPin> pConnectedPin;
RECT rect;
//
// Create the capture graph builder and register the filtergraph
manager.
//
CHK( m_pCaptureGraphBuilder.CoCreateInstance( CLSID_CaptureGraphBuilder ));
CHK( pFilterGraph.CoCreateInstance( CLSID_FilterGraph ));
CHK( m_pCaptureGraphBuilder->SetFiltergraph( pFilterGraph ));
//
// Create and initialize the video capture filter
//
CHK( m_pVideoCaptureFilter.CoCreateInstance( CLSID_VideoCapture ));
CHK( m_pVideoCaptureFilter.QueryInterface( &pPropertyBag ));
// We are loading the driver CAM1 in the video capture filter.
CHK( GetFirstCameraDriver( wzDeviceName ));
varCamName = wzDeviceName;
if( varCamName.vt != VT_BSTR )
{
ERR( E_OUTOFMEMORY );
}
CHK( PropBag.Write( L"VCapName", &varCamName ));
CHK( pPropertyBag->Load( &PropBag, NULL ));
// Everything succeeded, the video capture filter is added to the
filtergraph
CHK( pFilterGraph->AddFilter( m_pVideoCaptureFilter, L"Video
Capture Filter Source" ));
//
// Third step: Create the video encoder DMO, load the WMV9
encoder, and
// add it to the graph
//
// Create the video encoder
CHK( pVideoEncoder.CoCreateInstance( CLSID_DMOWrapperFilter ));
CHK( pVideoEncoder.QueryInterface( &pWrapperFilter ));
// Load the WMV9 DMO
CHK( pWrapperFilter->Init( CLSID_CWMV9EncMediaObject,
DMOCATEGORY_VIDEO_ENCODER ));
// Everything succeeded, let's add the encoder to the graph
CHK( pFilterGraph->AddFilter( pVideoEncoder, L"WMV9 DMO
Encoder" ));
//
// Create the ASF multiplexer and add it to the graph
//
CHK( m_pCaptureGraphBuilder->SetOutputFileName( &MEDIASUBTYPE_Asf,
L"\\video1.asf", &pASFMultiplexer, &pFileSinkFilter ));
//
// Connect the video capture filter, the encoder and the
multiplexer together
//
CHK( m_pCaptureGraphBuilder->RenderStream( &PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video, m_pVideoCaptureFilter, pVideoEncoder,
pASFMultiplexer ));
CHK(pFilterGraph->QueryInterface(IID_IVideoWindow, (void
**)&pVideoWindow));
CHK(m_pCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,
&MEDIATYPE_Video, m_pVideoCaptureFilter, NULL, NULL ));
// m_pCaptureGraphBuilder->FindP
// CComPtr<IEnumPins> enumPins;
//pVideoWindow->EnumPins(&enumPins);
// FindPin(pVideoWindow,PINDIR_OUTPUT,0,&pConnectedPin);
CHK(pVideoWindow->put_Owner((OAHWND)g_h1));
hr = pVideoWindow->put_WindowStyle(WS_CHILD | WS_VISIBLE |
WS_CLIPSIBLINGS);
GetClientRect(g_h1, &rect);
CHK(pVideoWindow->SetWindowPosition(rect.left,rect.top,rect.right -
rect.left, rect.bottom - rect.top));
CHK(pVideoWindow->put_AutoShow(OATRUE));
CHK(pVideoWindow->put_Visible(OATRUE));
CHK(pVideoWindow->put_WindowState(SW_SHOW));
// CHK(pVideoWindow->put_FullScreenMode(OATRUE));
// CHK(pVideoWindow->SetWindowForeground(OATRUE));
// CHK(m_pCaptureGraphBuilder->QueryInterface(IID_IMediaControl,
(void **) &pControl));
// CHK(pControl->Run());
//
// Create the still image filter, and connect it to the video capture
filter
//
CHK( pImageSinkFilter.CoCreateInstance( CLSID_IMGSinkFilter ));
CHK( pFilterGraph->AddFilter( pImageSinkFilter, L"Still image
filter" ));
CHK( m_pCaptureGraphBuilder->RenderStream( &PIN_CATEGORY_STILL,
&MEDIATYPE_Video, m_pVideoCaptureFilter, NULL, pImageSinkFilter ));
CHK( pImageSinkFilter.QueryInterface( &m_pImageSinkFilter ));
//
// Prevent the data from flowing into the capture stream
//
CHK( m_pCaptureGraphBuilder->ControlStream( &PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video, m_pVideoCaptureFilter, 0, 0 ,0,0 ));
IAMStreamConfig *pStillStreamConfig;
// IBaseFilter *pCap;
// GetDefaultCapDevice( &pCap );
CHK(m_pCaptureGraphBuilder->FindInterface(&PIN_CATEGORY_STILL,
&MEDIATYPE_Video,m_pVideoCaptureFilter, IID_IAMStreamConfig,
(void**)&pStillStreamConfig));
AM_MEDIA_TYPE *pType = NULL , pType1;
int iCount=0, iSize=0;
/* // Does not work for Mio
VIDEO_STREAM_CONFIG_CAPS caps;
pStillStreamConfig->GetNumberOfCapabilities(&iCount, &iSize);
pStillStreamConfig->GetFormat(&pType);
// pType->majortype = MEDIATYPE_Video;
// pType->subtype = MEDIASUBTYPE_RGB555;
int i;
for(i=0;i<iCount;i++)
{
// GetStreamCaps allocates the AM_MEDIA_TYPE, which must be deleted
by using DeleteMediaType
if(pStillStreamConfig->GetStreamCaps(i, &pType, (BYTE*)&caps) ==
S_OK )
{
VIDEOINFOHEADER* m_fVideoHeader = (VIDEOINFOHEADER*)pType-
>pbFormat;
int t=0;
t++; // Just use to debug and test the best mode.
}
}
pStillStreamConfig->GetStreamCaps(2, &pType, (BYTE*)&caps) ; // That
means 320X240
VIDEOINFOHEADER* wert = (VIDEOINFOHEADER*)pType->pbFormat; // Take it
into VIDEOINFOHEADER.
CHK(pStillStreamConfig->SetFormat(pType));
pStillStreamConfig->GetFormat(&pType); // HERE I CHECK the connected
STREAM FORMAT !!
wert = (VIDEOINFOHEADER*)pType->pbFormat; // Take it into
VIDEOINFOHEADER.
//
// Let's get the handle for DShow events. The main loop will
listen to both notifications from
// the UI thread and for DShow notifications
//
*/
CHK( pFilterGraph->QueryInterface( IID_IMediaEvent, (void**)
&pMediaEvent ));
CHK( pMediaEvent->GetEventHandle( &oaEvent ));
m_handle[1] = (HANDLE) oaEvent;
m_fGraphBuilt = TRUE;
// CHK(nullRenderer.CoCreateInstance(CLSID_NullRend));
// CHK(pFilterGraph->AddFilter(nullRenderer,L"NullRenderer"));
// CHK(pGrabber.CoCreateInstance(CLSID_CSampleGrabber));
///////////////////////// No Influence ? ////////////////
CHK( m_pVideoCaptureFilter.QueryInterface( &pVideoControl ));
//TESTING FOR BUFFER//
// CHK( m_pVideoCaptureFilter.QueryInterface( &pUnk1 ));
// CHK( m_pCaptureGraphBuilder->FindPin( pUnk1, PINDIR_INPUT,
&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, FALSE, 0, &pCaptPin ));
// pCaptPin->ConnectedTo(&pConnectedPin);
// PIN_INFO pinInfo;
// pConnectedPin->QueryPinInfo(&pinInfo);
// pConnectedFilter = pinInfo.pFilter;
////////////////////////
// CHK( pVideoControl->SetMode( pStillPin,
VideoControlFlag_FlipHorizontal ));
//////////////////////////////////////////////
// pCaptPin->Release();
CHK( m_pVideoCaptureFilter.QueryInterface( &pUnkCaptureFilter ));
// CHK(pFilterGraph->AddFilter(pGrabber,L"SamGrabber"));
// IPin *pGrabOut = GetOutPin(pGrab, 0);
// IPin *pNullIn = GetInPin(nullRenderer, 0);
// NotifyMessage( MESSAGE_ERROR, L"Building the graph failed" );
IBaseFilter* pSourceFilter=NULL;
hr=S_FALSE;
IOverlay *pOverlay;
if(m_pCaptureGraphBuilder){
if(SUCCEEDED(pFilterGraph->FindFilterByName(L"Video Capture Filter
Source",&pSourceFilter ))){
IAMCameraControl *pControl=NULL;
if(SUCCEEDED(pSourceFilter->QueryInterface(IID_IAMCameraControl,
(void**)&pControl) )){
//CHK(pControl->Set(CameraControl_Zoom,
150,CameraControl_Flags_Manual));
//CHK(pControl-
>Set(CameraControl_Macro,CameraControl_Macro_On,CameraControl_Flags_Manual));
// CHK(pControl-
>Set(CameraControl_SetMode,CameraControl_Mode_Camera ,CameraControl_Flags_Manual));
// CHK(pControl-
>Set(CameraControl_MeteringMode,CameraControl_MeteringMode_Normal,CameraControl_Flags_Manual));
// CHK(pControl-
>Set(CameraControl_Effect,CameraControl_Effect_Normal,CameraControl_Flags_Manual));
}
IAMVideoProcAmp *pVideoControl=NULL;
if(SUCCEEDED(pSourceFilter->QueryInterface(IID_IAMVideoProcAmp,
(void**)&pVideoControl) )){
long nMin,nMax,nDefault,nStep,nCaps;
// hr = pVideoControl-
>GetRange(VideoProcAmp_Gain,&nMin,&nMax,&nStep,&nDefault,&nCaps);
// CHK(pVideoControl->Set(VideoProcAmp_Scene,
1,CameraControl_Flags_Auto));
}
// ConnectPins(nullRenderer, 0, pSourceFilter,0);
// SafeRelease(pControl);
}
// SafeRelease(pSourceFilter);
/*
IBaseFilter *pFilter= NULL;
IPin *pin = NULL;
if(SUCCEEDED(pFilterGraph->FindFilterByName(L"Video
Renderer",&pFilter ))){
if (SUCCEEDED(pFilter->FindPin(L"VMR Input0", &pin))) {
if (SUCCEEDED(pin->QueryInterface(IID_IOverlay,
(void **)&pOverlay))){
pin->Release();
pFilter->Release();
}
// SafeRelease(pControl);
}
// SafeRelease(pSourceFilter);
} */
}
Cleanup:
if( FAILED( hr ))
{
TCHAR s[40];
_stprintf(s,_T("Message=%x\n"),hr);
OutputDebugString(s);
NotifyMessage( MESSAGE_ERROR, L"Building the graph failed" );
}
return hr;
}
HRESULT
CGraphManager::RunCaptureGraphInternal()
{
HRESULT hr = S_OK;
CComPtr<IGraphBuilder> pGraphBuilder;
CComPtr<IMediaControl> pMediaControl;
// Let's make sure that the graph has been initialized
if(( m_pCaptureGraphBuilder == NULL ) || ( m_fGraphBuilt ==
FALSE ))
{
ERR( E_FAIL );
}
// Retrieve the filtergraph off the capture graph builder
CHK( m_pCaptureGraphBuilder->GetFiltergraph( &pGraphBuilder ));
// Get the media control interface, and run the graph
CHK( pGraphBuilder->QueryInterface( &pMediaControl ));
CHK( pMediaControl->Run());
CHK( NotifyMessage( MESSAGE_INFO, L"The Graph is running" ));
Cleanup:
if( FAILED( hr ))
{
NotifyMessage( MESSAGE_ERROR, L"Runing the capture graph failed" );
}
return hr;
}
HRESULT
CGraphManager::StartCaptureVideoInternal()
{
HRESULT hr = S_OK;
LONGLONG dwStart = 0, dwEnd = 0;
WORD wStartCookie = 1, wEndCookie = 2;
CComPtr<IGraphBuilder> pGraphBuilder;
// Make sure that the capture graph builder is present
if(( m_pCaptureGraphBuilder == NULL ) || ( m_fGraphBuilt ==
FALSE ))
{
ERR( E_FAIL );
}
// Let's retrieve the event signaled by the filtergraph
CHK( m_pCaptureGraphBuilder->GetFiltergraph( &pGraphBuilder ));
// To start the video capture, call
ICaptureGraphBuilder2::ControlStream.
dwStart=0;
dwEnd=MAXLONGLONG;
CHK( m_pCaptureGraphBuilder->ControlStream( &PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video, NULL, &dwStart, &dwEnd, wStartCookie, wEndCookie ));
CHK( NotifyMessage( MESSAGE_INFO, L"Capturing...." ));
Cleanup:
if( FAILED( hr ))
{
NotifyMessage( MESSAGE_ERROR, L"Starting the video recording
failed" );
}
return hr;
}
HRESULT
CGraphManager::StopCaptureVideoInternal()
{
HRESULT hr = S_OK;
LONGLONG dwStart = 0, dwEnd = 0;
WORD wStartCookie = 1, wEndCookie = 2;
CComPtr<IGraphBuilder> pFilterGraph;
CComPtr<IMediaSeeking> pMediaSeeking;
CHK( m_pCaptureGraphBuilder->GetFiltergraph( &pFilterGraph ));
CHK( pFilterGraph->QueryInterface( &pMediaSeeking ));
// Stop the capture of the graph
dwStart = 0;
CHK( pMediaSeeking->GetCurrentPosition( &dwEnd ));
CHK( m_pCaptureGraphBuilder->ControlStream( &PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video, NULL, &dwStart, &dwEnd, wStartCookie, wEndCookie ));
// The filtergraph will fire a EC_CONTROLSTREAM_STOPPED event once
the capture of the video is completed
// The event will be caught in the main loop and processed in the
ProcessDshowEvents function
CHK( NotifyMessage( MESSAGE_INFO, L"Encoding file ..." ));
Cleanup:
if( FAILED( hr ))
{
NotifyMessage( MESSAGE_ERROR, L"Stopping the video recording
failed" );
}
return hr;
}
HRESULT
CGraphManager::CaptureStillImageInternal()
{
HRESULT hr = S_OK;
CComPtr<IFileSinkFilter> pFileSink;
CComPtr<IUnknown> pUnkCaptureFilter;
CComPtr<IPin> pStillPin;
CComPtr<IAMVideoControl> pVideoControl;
if(( m_pCaptureGraphBuilder == NULL ) || ( m_fGraphBuilt ==
FALSE ))
{
ERR( E_FAIL );
}
CHK( m_pImageSinkFilter.QueryInterface( &pFileSink ));
CHK( pFileSink->SetFileName( L"\\test.jpg", NULL ));
CHK( m_pVideoCaptureFilter.QueryInterface( &pUnkCaptureFilter ));
CHK( m_pCaptureGraphBuilder->FindPin( pUnkCaptureFilter,
PINDIR_OUTPUT, &PIN_CATEGORY_STILL, &MEDIATYPE_Video, FALSE, 0,
&pStillPin ));
CHK( m_pVideoCaptureFilter.QueryInterface( &pVideoControl ));
CHK( pVideoControl->SetMode( pStillPin, VideoControlFlag_Trigger ));
Sleep(200);
// CHK( m_pImageSinkFilter.QueryInterface( &pFileSink ));
CHK( pFileSink->SetFileName( L"\\test1.jpg", NULL ));
// CHK( m_pVideoCaptureFilter.QueryInterface( &pUnkCaptureFilter ));
// CHK( m_pCaptureGraphBuilder->FindPin( pUnkCaptureFilter,
PINDIR_OUTPUT, &PIN_CATEGORY_STILL, &MEDIATYPE_Video, FALSE, 0,
&pStillPin ));
// CHK( m_pVideoCaptureFilter.QueryInterface( &pVideoControl ));
CHK( pVideoControl->SetMode( pStillPin, VideoControlFlag_Trigger ));
Sleep(200);
// CHK( m_pImageSinkFilter.QueryInterface( &pFileSink ));
CHK( pFileSink->SetFileName( L"\\test2.jpg", NULL ));
// CHK( m_pVideoCaptureFilter.QueryInterface( &pUnkCaptureFilter ));
// CHK( m_pCaptureGraphBuilder->FindPin( pUnkCaptureFilter,
PINDIR_OUTPUT, &PIN_CATEGORY_STILL, &MEDIATYPE_Video, FALSE, 0,
&pStillPin ));
// CHK( m_pVideoCaptureFilter.QueryInterface( &pVideoControl ));
CHK( pVideoControl->SetMode( pStillPin, VideoControlFlag_Trigger ));
Sleep(200);
// CHK( m_pImageSinkFilter.QueryInterface( &pFileSink ));
CHK( pFileSink->SetFileName( L"\\test3.jpg", NULL ));
// CHK( m_pVideoCaptureFilter.QueryInterface( &pUnkCaptureFilter ));
// CHK( m_pCaptureGraphBuilder->FindPin( pUnkCaptureFilter,
PINDIR_OUTPUT, &PIN_CATEGORY_STILL, &MEDIATYPE_Video, FALSE, 0,
&pStillPin ));
// CHK( m_pVideoCaptureFilter.QueryInterface( &pVideoControl ));
CHK( pVideoControl->SetMode( pStillPin, VideoControlFlag_Trigger ));
Cleanup:
if( FAILED( hr ))
{
NotifyMessage( MESSAGE_ERROR, L"Capturing a still image failed" );
}
return hr;
}
HRESULT
CGraphManager::NotifyMessage( DSHOW_MESSAGE message, WCHAR *wzText )
{
HRESULT hr = S_OK;
Message *pMessage;
WCHAR *wzString;
if(( wzText == NULL ) || ( *wzText == NULL ))
{
ERR( E_POINTER );
}
if( m_hwnd == NULL )
{
return S_FALSE;
}
pMessage = (Message*) LocalAlloc( LMEM_ZEROINIT,
sizeof( Message ));
if( pMessage == NULL )
{
ERR( E_OUTOFMEMORY );
}
wzString = (WCHAR*) LocalAlloc( LMEM_ZEROINIT, ( wcslen( wzText )
+ 1 ) * sizeof( WCHAR ));
if( wzString == NULL )
{
ERR( E_OUTOFMEMORY );
}
StringCchCopy( wzString, wcslen( wzText ) + 1, wzText );
pMessage->wzMessage = wzString;
pMessage->dwMessage = message;
PostMessage( m_hwnd, WM_USER, 0, (LPARAM) pMessage );
Cleanup:
return hr;
}
void CGraphManager::FindPin(IBaseFilter* baseFilter,
PIN_DIRECTION direction,
int pinNumber,
IPin** destPin)
{
CComPtr<IEnumPins> enumPins;
*destPin = NULL;
if (SUCCEEDED(baseFilter->EnumPins(&enumPins))) {
ULONG numFound;
IPin* tmpPin;
while (SUCCEEDED(enumPins->Next(1, &tmpPin, &numFound))) {
PIN_DIRECTION pinDirection;
tmpPin->QueryDirection(&pinDirection);
if (pinDirection == direction) {
if (pinNumber == 0) {
// Return the pin's interface
*destPin = tmpPin;
break;
}
pinNumber--;
}
tmpPin->Release();
}
}
}
BOOL CGraphManager::ConnectPins(IBaseFilter* outputFilter,
unsigned int outputNum,
IBaseFilter* inputFilter,
unsigned int inputNum)
{
CComPtr<IPin> inputPin;
CComPtr<IPin> outputPin;
CComPtr<IGraphBuilder> pFilterGraph;
m_pCaptureGraphBuilder->GetFiltergraph( &pFilterGraph );
if (!outputFilter || !inputFilter) {
return false;
}
FindPin(outputFilter, PINDIR_OUTPUT, outputNum, &outputPin);
FindPin(inputFilter, PINDIR_INPUT, inputNum, &inputPin);
if (inputPin && outputPin) {
return SUCCEEDED(pFilterGraph->Connect(outputPin, inputPin));
} else {
return false;
}
}
BOOL CGraphManager::InsertFilter(IBaseFilter* outputFilter,
unsigned int outputNum,
IBaseFilter* inputFilter,
unsigned int inputNum,
IBaseFilter* intermediateFilter,
unsigned int inputIntermNum,
unsigned int outputIntermNum
)
{
CComPtr<IPin> inputPin;
CComPtr<IPin> outputPin;
CComPtr<IPin> inputIntermPin;
CComPtr<IPin> outputIntermPin;
CComPtr<IGraphBuilder> pFilterGraph;
BOOL bRes;
m_pCaptureGraphBuilder->GetFiltergraph( &pFilterGraph );
if (!outputFilter || !inputFilter || !intermediateFilter) {
return FALSE;
}
FindPin(outputFilter, PINDIR_OUTPUT, outputNum, &outputPin);
FindPin(inputFilter, PINDIR_INPUT, inputNum, &inputPin);
FindPin(intermediateFilter, PINDIR_OUTPUT, outputIntermNum,
&outputIntermPin);
FindPin(intermediateFilter, PINDIR_INPUT, inputIntermNum,
&inputIntermPin);
if (inputPin && outputPin && outputIntermPin , inputIntermPin) {
bRes = SUCCEEDED(pFilterGraph->Disconnect(outputPin));
if (!bRes) return FALSE;
bRes = SUCCEEDED(pFilterGraph->Disconnect(inputPin));
if (!bRes) return FALSE;
bRes = SUCCEEDED(pFilterGraph->Connect(outputPin, inputIntermPin));
if (!bRes) return FALSE;
bRes = SUCCEEDED(pFilterGraph->Connect(outputIntermPin, inputPin));
if (!bRes) return FALSE;
}
else return FALSE;
return TRUE;
}
date: Tue, 27 Nov 2007 04:36:48 -0800 (PST)
author: Michton
Re: directshow: how to get the Previewer (Renderer) Pin
You will probably find that using the capture graph to add filters using
RenderStream is easier:
// (audio)
hr = pCaptureGraph->RenderStream(NULL, &MEDIATYPE_Audio, pSource,
pAudioEncoder,pMP4Writer);
// (video)
// connect source (cam) to red eye filter
hr = pCaptureGraph->RenderStream(NULL, &MEDIATYPE_Video, pSource,
NULL,pRedEyeFilter);
// connect red eye, to video encoder, to mp4 writer
hr = pCaptureGraph->RenderStream(NULL, &MEDIATYPE_Video, pRedEyeFilter,
pVideoEncoder,pMP4Writer);
You can call this multiple times to insert a number of filters, i.e if you
wanted to add a red eye reduction filter etc, its very flexible and you're
code will be much smaller and easier to read.
--
--
GraemeW
Blog - http://ce4all.blogspot.com
"Michton" wrote in message
news:70dfdca8-bdef-4bea-be21-5b1fc24e62c4@e25g2000prg.googlegroups.com...
> Hi
>
> How to get the Previewer (Renderer) Pin.
>
> We need to insert a filter before the Renderer in the graph.
>
> Is there a way to get the Pin or Filter.
> I used the PPC Sample CameraCapture that I improved:
>
>
> Thank you very much!
>
>
> Michel
> This is the previewe code.
> //================================================
> //
> // Copyright (c) Microsoft Corporation. All rights reserved.
> //
> //
> // Use of this source code is subject to the terms of the Microsoft
> end-user
> // license agreement (EULA) under which you licensed this SOFTWARE
> PRODUCT.
> // If you did not accept the terms of the EULA, you are not authorized
> to use
> // this source code. For a copy of the EULA, please see the
> LICENSE.RTF on your
> // install media.
> //
> #include "stdafx.h"
> // {3B140E8C-F3AD-465f-BCB7-7660589F790B}
>
> EXTERN_GUID(CLSID_NullRend,
> 0x8a99caeb, 0xaef5, 0x11da,
> 0x95, 0x8b, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f );
> EXTERN_GUID(CLSID_CSampleGrabber,
> 0xf3492a9b, 0x6626, 0x4345, 0xab, 0x8d, 0x17, 0xf5, 0x84, 0xdc,
> 0x1d, 0xe0);
>
> //EXTERN_GUID(CLSID_NullRend,
> // 0xbf5023aa, 0xd902, 0x49b2, 0x89, 0x14, 0xcb, 0xdb, 0xf0, 0x75,
> 0x22, 0xfe);
>
> // Fill in media type information below, this information is used
> when
> // registering the filter with dshow
> const AMOVIESETUP_MEDIATYPE sudPinTypes =
> { &MEDIATYPE_NULL, &MEDIASUBTYPE_NULL };
> const AMOVIESETUP_PIN sudPins =
> { L"Null", FALSE, FALSE, FALSE, FALSE, &CLSID_NULL, NULL, 1,
> &sudPinTypes };
> const AMOVIESETUP_FILTER sudNULL =
> { &CLSID_NullRend, L"NullRend", MERIT_DO_NOT_USE, 1, &sudPins };
>
> extern HWND g_h1;
> #define VideoProcAmp_Gain VideoProcAmp_BacklightCompensation + 1
> //
> // using this flag set the Scene by the IAMVideoProcAmp interface
> //
> #define VideoProcAmp_Scene VideoProcAmp_Gain + 2
> //
> // the Scene values
> //
> typedef
> enum{
> VideoProcAmp_Scene_Auto = 0x0001,
> VideoProcAmp_Scene_Night = 0x0002,
> VideoProcAmp_Scene_Sports = 0x0003
> } VideoProcAmpScene;
>
> // using this flag set the White Balance by the IAMVideoProcAmp
> interface
> // the White Balance values
> typedef
> enum{
> VideoProcAmp_WB_Tungsten = 0x0001,
> VideoProcAmp_WB_Halogenic = 0x0002,
> VideoProcAmp_WB_Fluorescent = 0x0003,
> VideoProcAmp_WB_Incandescence = 0x0004,
> VideoProcAmp_WB_Sunny = 0x0005,
> VideoProcAmp_WB_Cloudy = 0x0006
> } VideoProcAmpWhiteBalance;
>
> //
> // the Flash values
> //
> // Auto Flash:
> // CameraControlFlags = CameraControl_Flags_Auto
> //
> typedef
> enum{
> CameraControl_Flash_Forced = 0x0001,
> CameraControl_Flash_NoFlash = 0x0002,
> CameraControl_Flash_Close = 0x0003
> } CameraControlFlash;
>
> //
> // using this flag set the Macro by the IAMCameraControl interface
> //
> #define CameraControl_Macro 11
> //
> // the Macro values
> //
> typedef
> enum{
> CameraControl_Macro_On = 0x0001,
> CameraControl_Macro_Off = 0x0002
> } CameraControlMacro;
> //
> // the Zoom values
> //
> typedef
> enum{
> CameraControl_Zoom_100X = 0x0064, // decimal 100
> CameraControl_Zoom_125X = 0x007D, // decimal 125
> CameraControl_Zoom_150X = 0x0096, // decimal 150
> CameraControl_Zoom_200X = 0x00C8, // decimal 200
> CameraControl_Zoom_250X = 0x00FA // decimal 250
> } CameraControlZoom;
> //
> // using this flag set the Effect by the IAMCameraControl interface
> //
> #define CameraControl_Effect 12//CameraControl_Flash + 3
> //
> // the Effect values
> //
> typedef
> enum{
> CameraControl_Effect_Normal = 0x0001,
> CameraControl_Effect_BlackWhite = 0x0002,
> CameraControl_Effect_Negative = 0x0003,
> CameraControl_Effect_Sepia = 0x0004,
> } CameraControlEffect;
> //
> // AC Frequency (?????)
> //
> // using this flag set the Effect by the IAMCameraControl interface
> //
> #define CameraControl_ACFrequency 13
> //
> // the AC Frequency values
> //
> // Auto Frequency:
> // CameraControlFlags = CameraControl_Flags_Auto
> //
> typedef
> enum{
> CameraControl_ACFrequency_50Hz = 0x0001,
> CameraControl_ACFrequency_60Hz = 0x0002,
> } CameraControlACFrequency;
>
> // 2. ISO Sensitivity (ISO ???)
> //
> // using this flag set the ISO Sensitivity by the IAMCameraControl
> interface
> //
> #define CameraControl_ISOSensitivity 14
> //
> // the ISO Sensitivity values
> // Auto :
> // Flags = CameraControl_Flags_Auto
>
> typedef
> enum{
> CameraControl_ISOSensitivity_100 = 0x0001,
> CameraControl_ISOSensitivity_200 = 0x0002,
> CameraControl_ISOSensitivity_400 = 0x0003,
> } CameraControlISOSensitivity;
>
> // 3. Metering Mode (????)
> //
> // using this flag set the ISO Exposure Mode by the IAMCameraControl
> interface
> //
> #define CameraControl_MeteringMode 15
> //
> // the Metering Mode values
> //
>
> typedef
> enum{
> CameraControl_MeteringMode_Normal = 0x0001, //???????(Default)
> CameraControl_MeteringMode_Center = 0x0002, //??????
> CameraControl_MeteringMode_Background = 0x0003, //??????
> } CameraControlMeteringMode;
>
> //
> // using this flag set the Preview / Camera / Video Mode
> // by the IAMCameraControl interface
> //
> #define CameraControl_SetMode 16
>
> //
> // the Preview / Camera / Video Mode values
> //
> typedef
> enum{
> CameraControl_Mode_Preview = 0x0001, // this value only for camera
> previewing
> CameraControl_Mode_Camera = 0x0002, // this value for previewing and
> still capture
> CameraControl_Mode_Video = 0x0003, // this value for previewing and
> video capture
> CameraControl_Mode_VideoRec = 0x0004, // this value for capture
> video start
> } CameraControlSetMode;
>
> typedef
> enum{
> CameraControl_Focus_Undo = 0x0001
> } CameraControlFocus;
>
> #include "initguid.h"
>
> CGraphManager::CGraphManager()
> {
> m_fGraphBuilt = FALSE;
> ZeroMemory( m_handle, sizeof( m_handle ));
> m_hwnd = 0;
> m_dwThreadId = 0;
> m_hThread = NULL;
> m_hCommandCompleted = NULL;
> m_currentCommand = COMMAND_NOCOMMAND;
> }
>
>
> CGraphManager::~CGraphManager()
> {
> if( m_handle[0] )
> {
> CloseHandle( m_handle[0] );
> }
>
> if( m_handle[1] )
> {
> CloseHandle( m_handle[1] );
> }
> }
>
>
> HRESULT
> CGraphManager::Init()
> {
> HRESULT hr = S_OK;
>
> // Create the event that will signal the thread for commands
> m_handle[0] = CreateEvent( NULL, FALSE, FALSE, NULL );
> if( m_handle[0] == NULL )
> {
> ERR( HRESULT_FROM_WIN32( GetLastError() ));
> }
> m_handle[1] = 0;
>
> // Create the event to sync on to wait for the command to be
> executed
> m_hCommandCompleted = CreateEvent( NULL, FALSE, FALSE, NULL );
> if( m_hCommandCompleted == NULL )
> {
> ERR( HRESULT_FROM_WIN32( GetLastError() ));
> }
>
> // CCreate the thread that will run the filtergraph.
> // The filtergraph is running on a background thread to prevent
> any window message
> // reentrancy issue.
> m_hThread = CreateThread( NULL, 0, CGraphManager::ThreadProc,
> this, 0, &m_dwThreadId );
> if( m_hThread == NULL )
> {
> ERR( HRESULT_FROM_WIN32( GetLastError() ));
> }
>
>
> Cleanup:
> return hr;
> }
>
>
> HRESULT
> CGraphManager::BuildCaptureGraph()
> {
> // The Graph is built on a separate thread to
> // prevent reentrancy issues.
> m_currentCommand = COMMAND_BUILDGRAPH;
> SetEvent( m_handle[0] );
> WaitForSingleObject( m_hCommandCompleted, INFINITE );
>
> return S_OK;
> }
>
>
> HRESULT
> CGraphManager::RunCaptureGraph()
> {
> // Unlike the other operations, running the graph
> // has to happen from the UI thread.
> return RunCaptureGraphInternal();
> }
>
>
> HRESULT
> CGraphManager::StartRecordVideo()
> {
> m_currentCommand = COMMAND_STARTCAPTURE;
> SetEvent( m_handle[0] );
> WaitForSingleObject( m_hCommandCompleted, INFINITE );
>
> return S_OK;
> }
>
>
> HRESULT
> CGraphManager::StopRecordVideo()
> {
> m_currentCommand = COMMAND_STOPCAPTURE;
> SetEvent( m_handle[0] );
> WaitForSingleObject( m_hCommandCompleted, INFINITE );
>
> return S_OK;
> }
>
>
> HRESULT
> CGraphManager::CaptureStillImage()
> {
> m_currentCommand = COMMAND_STILLIMAGE;
> SetEvent( m_handle[0] );
> WaitForSingleObject( m_hCommandCompleted, INFINITE );
>
> return S_OK;
> }
>
>
> HRESULT
> CGraphManager::ShutDown()
> {
> m_currentCommand = COMMAND_SHUTDOWN;
> SetEvent( m_handle[0] );
> WaitForSingleObject( m_hThread, INFINITE );
>
> return S_OK;
> }
>
>
> HRESULT
> CGraphManager::RegisterNotificationWindow( HWND hwnd )
> {
> m_hwnd = hwnd;
> return S_OK;
> }
>
>
> DWORD WINAPI
> CGraphManager::ThreadProc( LPVOID lpParameter )
> {
> HRESULT hr = S_OK;
> DWORD dwReturnValue;
> CGraphManager *pThis = (CGraphManager*) lpParameter;
> GRAPHCOMMANDS command = COMMAND_NOCOMMAND;
>
> if( pThis == NULL )
> {
> return 0;
> }
>
> while(( command != COMMAND_SHUTDOWN ) && ( hr != S_FALSE ))
> {
> dwReturnValue = WaitForMultipleObjects( 2, pThis->m_handle,
> FALSE, INFINITE );
> switch( dwReturnValue )
> {
> case WAIT_OBJECT_0:
> command = pThis->m_currentCommand;
> pThis->ProcessCommand();
> break;
>
> case WAIT_OBJECT_0 + 1:
> pThis->ProcessDShowEvent();
> break;
> case MV_BUFFER_ACCESS_BUFFERS_AVAILABLE:
> break;
> default:
> break;
> }
> };
>
> return 0;
> }
>
>
> HRESULT
> CGraphManager::ProcessCommand()
> {
> HRESULT hr = S_OK;
>
> switch( m_currentCommand )
> {
> case COMMAND_BUILDGRAPH:
> hr = CreateCaptureGraphInternal();
> SetEvent( m_hCommandCompleted );
> break;
>
> case COMMAND_RUNGRAPH:
> hr = RunCaptureGraphInternal();
> SetEvent( m_hCommandCompleted );
> break;
>
> case COMMAND_STARTCAPTURE:
> hr = StartCaptureVideoInternal();
> SetEvent( m_hCommandCompleted );
> break;
>
> case COMMAND_STOPCAPTURE:
> hr = StopCaptureVideoInternal();
> SetEvent( m_hCommandCompleted );
> break;
>
> case COMMAND_STILLIMAGE:
> hr = CaptureStillImageInternal();
> SetEvent( m_hCommandCompleted );
> break;
>
> case COMMAND_SHUTDOWN:
> hr = S_FALSE;
> break;
>
> default:
> break;
> }
>
> return hr;
> }
>
>
> HRESULT
> CGraphManager::ProcessDShowEvent()
> {
> HRESULT hr = S_OK;
> long lEventCode, lParam1, lParam2;
>
> CComPtr<IMediaEvent> pMediaEvent;
> CComPtr<IGraphBuilder> pFilterGraph;
> CComPtr<IMediaControl> pMediaControl;
>
> if( m_pCaptureGraphBuilder == NULL )
> {
> ERR( E_FAIL );
> }
>
> CHK( m_pCaptureGraphBuilder->GetFiltergraph( &pFilterGraph ));
> CHK( pFilterGraph->QueryInterface( &pMediaEvent ));
> CHK( pMediaEvent->GetEvent( &lEventCode, &lParam1, &lParam2, 0 ));
>
> if( lEventCode == EC_STREAM_CONTROL_STOPPED ) // We have
> received a control stream stop event
> {
> NotifyMessage( MESSAGE_ENDRECORDING, L"Recording done ..." );
>
> // To close the file, get the IMediaControl interface, stop
> and
> // restart the graph
> CHK( pFilterGraph->QueryInterface( &pMediaControl ));
> if( pMediaControl == NULL )
> {
> ERR( E_POINTER );
> }
>
> CHK( pMediaControl->Stop());
> CHK( pMediaControl->Run());
>
> NotifyMessage( MESSAGE_FILECAPTURED, L"File captured ..." );
> }
> else if( lEventCode == EC_CAP_FILE_COMPLETED )
> {
> NotifyMessage( MESSAGE_FILECAPTURED, L"File captured ..." );
> }
>
>
> CHK( pMediaEvent->FreeEventParams( lEventCode, lParam1,
> lParam2 ));
>
> Cleanup:
> return S_OK;
> }
>
>
> HRESULT
> CGraphManager::GetFirstCameraDriver( WCHAR *pwzName )
> {
> HRESULT hr = S_OK;
> HANDLE handle = NULL;
> DEVMGR_DEVICE_INFORMATION di;
> GUID guidCamera = { 0xCB998A05, 0x122C, 0x4166, 0x84, 0x6A, 0x93,
> 0x3E, 0x4D, 0x7E, 0x3C, 0x86 };
> // Note about the above: The driver material doesn't ship as part of
> the SDK. This GUID is hardcoded
> // here to be able to enumerate the camera drivers and pass the name
> of the driver to the video capture filter
>
> if( pwzName == NULL )
> {
> return E_POINTER;
> }
>
> di.dwSize = sizeof(di);
>
> handle = FindFirstDevice( DeviceSearchByGuid, &guidCamera, &di );
> if(( handle == NULL ) || ( di.hDevice == NULL ))
> {
> ERR( HRESULT_FROM_WIN32( GetLastError() ));
> }
>
> StringCchCopy( pwzName, MAX_PATH, di.szLegacyName );
>
> Cleanup:
> FindClose( handle );
> return hr;
> }
>
>
>
> HRESULT
> CGraphManager::CreateCaptureGraphInternal()
> {
> HRESULT hr = S_OK;
> CComVariant varCamName;
> CPropertyBag PropBag;
> OAEVENT oaEvent;
> WCHAR wzDeviceName[ MAX_PATH + 1 ];
>
> CComPtr<IMediaEvent> pMediaEvent;
> CComPtr<IGraphBuilder> pFilterGraph;
> CComPtr<IBaseFilter> pVideoEncoder;
> CComPtr<IBaseFilter> pASFMultiplexer;
> CComPtr<IFileSinkFilter> pFileSinkFilter;
> CComPtr<IPersistPropertyBag> pPropertyBag;
> CComPtr<IDMOWrapperFilter> pWrapperFilter;
> CComPtr<IBaseFilter> pImageSinkFilter;
> CComPtr<IBaseFilter> pConnectedFilter;
>
> CComPtr<IAMVideoControl> pVideoControl;
> CComPtr<IPin> pStillPin;
> CComPtr<IUnknown> pUnkCaptureFilter;
>
> CComPtr<IVideoWindow> pVideoWindow;
> IMediaControl *pControl = NULL;
> CComPtr<IBaseFilter> nullRenderer;
> CComPtr<IFilterGraph> pGrabber;
>
> CComPtr<IBaseFilter> pBuffer;
> CComPtr<IUnknown> pUnk1;
> CComPtr<IPin> pCaptPin;
> CComPtr<IPin> pConnectedPin;
>
> RECT rect;
>
> //
> // Create the capture graph builder and register the filtergraph
> manager.
> //
>
> CHK( m_pCaptureGraphBuilder.CoCreateInstance(
> CLSID_CaptureGraphBuilder ));
> CHK( pFilterGraph.CoCreateInstance( CLSID_FilterGraph ));
> CHK( m_pCaptureGraphBuilder->SetFiltergraph( pFilterGraph ));
>
>
> //
> // Create and initialize the video capture filter
> //
>
> CHK( m_pVideoCaptureFilter.CoCreateInstance( CLSID_VideoCapture ));
> CHK( m_pVideoCaptureFilter.QueryInterface( &pPropertyBag ));
>
> // We are loading the driver CAM1 in the video capture filter.
> CHK( GetFirstCameraDriver( wzDeviceName ));
> varCamName = wzDeviceName;
> if( varCamName.vt != VT_BSTR )
> {
> ERR( E_OUTOFMEMORY );
> }
>
> CHK( PropBag.Write( L"VCapName", &varCamName ));
> CHK( pPropertyBag->Load( &PropBag, NULL ));
>
> // Everything succeeded, the video capture filter is added to the
> filtergraph
> CHK( pFilterGraph->AddFilter( m_pVideoCaptureFilter, L"Video
> Capture Filter Source" ));
>
>
>
> //
> // Third step: Create the video encoder DMO, load the WMV9
> encoder, and
> // add it to the graph
> //
>
> // Create the video encoder
> CHK( pVideoEncoder.CoCreateInstance( CLSID_DMOWrapperFilter ));
> CHK( pVideoEncoder.QueryInterface( &pWrapperFilter ));
>
> // Load the WMV9 DMO
> CHK( pWrapperFilter->Init( CLSID_CWMV9EncMediaObject,
> DMOCATEGORY_VIDEO_ENCODER ));
>
> // Everything succeeded, let's add the encoder to the graph
> CHK( pFilterGraph->AddFilter( pVideoEncoder, L"WMV9 DMO
> Encoder" ));
>
> //
> // Create the ASF multiplexer and add it to the graph
> //
> CHK( m_pCaptureGraphBuilder->SetOutputFileName( &MEDIASUBTYPE_Asf,
> L"\\video1.asf", &pASFMultiplexer, &pFileSinkFilter ));
>
> //
> // Connect the video capture filter, the encoder and the
> multiplexer together
> //
> CHK( m_pCaptureGraphBuilder->RenderStream( &PIN_CATEGORY_CAPTURE,
> &MEDIATYPE_Video, m_pVideoCaptureFilter, pVideoEncoder,
> pASFMultiplexer ));
> CHK(pFilterGraph->QueryInterface(IID_IVideoWindow, (void
> **)&pVideoWindow));
> CHK(m_pCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,
> &MEDIATYPE_Video, m_pVideoCaptureFilter, NULL, NULL ));
>
> // m_pCaptureGraphBuilder->FindP
> // CComPtr<IEnumPins> enumPins;
> //pVideoWindow->EnumPins(&enumPins);
> // FindPin(pVideoWindow,PINDIR_OUTPUT,0,&pConnectedPin);
>
> CHK(pVideoWindow->put_Owner((OAHWND)g_h1));
> hr = pVideoWindow->put_WindowStyle(WS_CHILD | WS_VISIBLE |
> WS_CLIPSIBLINGS);
>
> GetClientRect(g_h1, &rect);
> CHK(pVideoWindow->SetWindowPosition(rect.left,rect.top,rect.right -
> rect.left, rect.bottom - rect.top));
> CHK(pVideoWindow->put_AutoShow(OATRUE));
> CHK(pVideoWindow->put_Visible(OATRUE));
> CHK(pVideoWindow->put_WindowState(SW_SHOW));
> // CHK(pVideoWindow->put_FullScreenMode(OATRUE));
> // CHK(pVideoWindow->SetWindowForeground(OATRUE));
>
> // CHK(m_pCaptureGraphBuilder->QueryInterface(IID_IMediaControl,
> (void **) &pControl));
>
> // CHK(pControl->Run());
> //
> // Create the still image filter, and connect it to the video capture
> filter
> //
>
>
> CHK( pImageSinkFilter.CoCreateInstance( CLSID_IMGSinkFilter ));
> CHK( pFilterGraph->AddFilter( pImageSinkFilter, L"Still image
> filter" ));
> CHK( m_pCaptureGraphBuilder->RenderStream( &PIN_CATEGORY_STILL,
> &MEDIATYPE_Video, m_pVideoCaptureFilter, NULL, pImageSinkFilter ));
> CHK( pImageSinkFilter.QueryInterface( &m_pImageSinkFilter ));
>
> //
> // Prevent the data from flowing into the capture stream
> //
> CHK( m_pCaptureGraphBuilder->ControlStream( &PIN_CATEGORY_CAPTURE,
> &MEDIATYPE_Video, m_pVideoCaptureFilter, 0, 0 ,0,0 ));
>
>
> IAMStreamConfig *pStillStreamConfig;
> // IBaseFilter *pCap;
> // GetDefaultCapDevice( &pCap );
> CHK(m_pCaptureGraphBuilder->FindInterface(&PIN_CATEGORY_STILL,
> &MEDIATYPE_Video,m_pVideoCaptureFilter, IID_IAMStreamConfig,
> (void**)&pStillStreamConfig));
>
> AM_MEDIA_TYPE *pType = NULL , pType1;
>
> int iCount=0, iSize=0;
> /* // Does not work for Mio
> VIDEO_STREAM_CONFIG_CAPS caps;
> pStillStreamConfig->GetNumberOfCapabilities(&iCount, &iSize);
>
> pStillStreamConfig->GetFormat(&pType);
> // pType->majortype = MEDIATYPE_Video;
> // pType->subtype = MEDIASUBTYPE_RGB555;
> int i;
> for(i=0;i<iCount;i++)
> {
> // GetStreamCaps allocates the AM_MEDIA_TYPE, which must be deleted
> by using DeleteMediaType
>
> if(pStillStreamConfig->GetStreamCaps(i, &pType, (BYTE*)&caps) ==
> S_OK )
> {
> VIDEOINFOHEADER* m_fVideoHeader = (VIDEOINFOHEADER*)pType-
>>pbFormat;
> int t=0;
> t++; // Just use to debug and test the best mode.
> }
> }
> pStillStreamConfig->GetStreamCaps(2, &pType, (BYTE*)&caps) ; // That
> means 320X240
> VIDEOINFOHEADER* wert = (VIDEOINFOHEADER*)pType->pbFormat; // Take it
> into VIDEOINFOHEADER.
> CHK(pStillStreamConfig->SetFormat(pType));
> pStillStreamConfig->GetFormat(&pType); // HERE I CHECK the connected
> STREAM FORMAT !!
> wert = (VIDEOINFOHEADER*)pType->pbFormat; // Take it into
> VIDEOINFOHEADER.
> //
> // Let's get the handle for DShow events. The main loop will
> listen to both notifications from
> // the UI thread and for DShow notifications
> //
> */
> CHK( pFilterGraph->QueryInterface( IID_IMediaEvent, (void**)
> &pMediaEvent ));
> CHK( pMediaEvent->GetEventHandle( &oaEvent ));
> m_handle[1] = (HANDLE) oaEvent;
>
> m_fGraphBuilt = TRUE;
>
> // CHK(nullRenderer.CoCreateInstance(CLSID_NullRend));
> // CHK(pFilterGraph->AddFilter(nullRenderer,L"NullRenderer"));
> // CHK(pGrabber.CoCreateInstance(CLSID_CSampleGrabber));
> ///////////////////////// No Influence ? ////////////////
> CHK( m_pVideoCaptureFilter.QueryInterface( &pVideoControl ));
> //TESTING FOR BUFFER//
> // CHK( m_pVideoCaptureFilter.QueryInterface( &pUnk1 ));
> // CHK( m_pCaptureGraphBuilder->FindPin( pUnk1, PINDIR_INPUT,
> &PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, FALSE, 0, &pCaptPin ));
> // pCaptPin->ConnectedTo(&pConnectedPin);
> // PIN_INFO pinInfo;
> // pConnectedPin->QueryPinInfo(&pinInfo);
> // pConnectedFilter = pinInfo.pFilter;
> ////////////////////////
> // CHK( pVideoControl->SetMode( pStillPin,
> VideoControlFlag_FlipHorizontal ));
> //////////////////////////////////////////////
> // pCaptPin->Release();
> CHK( m_pVideoCaptureFilter.QueryInterface( &pUnkCaptureFilter ));
>
> // CHK(pFilterGraph->AddFilter(pGrabber,L"SamGrabber"));
> // IPin *pGrabOut = GetOutPin(pGrab, 0);
> // IPin *pNullIn = GetInPin(nullRenderer, 0);
> // NotifyMessage( MESSAGE_ERROR, L"Building the graph failed" );
> IBaseFilter* pSourceFilter=NULL;
>
>
> hr=S_FALSE;
> IOverlay *pOverlay;
>
>
> if(m_pCaptureGraphBuilder){
> if(SUCCEEDED(pFilterGraph->FindFilterByName(L"Video Capture Filter
> Source",&pSourceFilter ))){
> IAMCameraControl *pControl=NULL;
> if(SUCCEEDED(pSourceFilter->QueryInterface(IID_IAMCameraControl,
> (void**)&pControl) )){
> //CHK(pControl->Set(CameraControl_Zoom,
> 150,CameraControl_Flags_Manual));
> //CHK(pControl-
>>Set(CameraControl_Macro,CameraControl_Macro_On,CameraControl_Flags_Manual));
> // CHK(pControl-
>>Set(CameraControl_SetMode,CameraControl_Mode_Camera
>>,CameraControl_Flags_Manual));
> // CHK(pControl-
>>Set(CameraControl_MeteringMode,CameraControl_MeteringMode_Normal,CameraControl_Flags_Manual));
> // CHK(pControl-
>>Set(CameraControl_Effect,CameraControl_Effect_Normal,CameraControl_Flags_Manual));
> }
> IAMVideoProcAmp *pVideoControl=NULL;
> if(SUCCEEDED(pSourceFilter->QueryInterface(IID_IAMVideoProcAmp,
> (void**)&pVideoControl) )){
> long nMin,nMax,nDefault,nStep,nCaps;
> // hr = pVideoControl-
>>GetRange(VideoProcAmp_Gain,&nMin,&nMax,&nStep,&nDefault,&nCaps);
> // CHK(pVideoControl->Set(VideoProcAmp_Scene,
> 1,CameraControl_Flags_Auto));
> }
> // ConnectPins(nullRenderer, 0, pSourceFilter,0);
>
> // SafeRelease(pControl);
> }
> // SafeRelease(pSourceFilter);
>
> /*
> IBaseFilter *pFilter= NULL;
> IPin *pin = NULL;
> if(SUCCEEDED(pFilterGraph->FindFilterByName(L"Video
> Renderer",&pFilter ))){
> if (SUCCEEDED(pFilter->FindPin(L"VMR Input0", &pin))) {
> if (SUCCEEDED(pin->QueryInterface(IID_IOverlay,
> (void **)&pOverlay))){
> pin->Release();
> pFilter->Release();
> }
> // SafeRelease(pControl);
> }
> // SafeRelease(pSourceFilter);
>
> } */
>
> }
>
>
> Cleanup:
> if( FAILED( hr ))
> {
> TCHAR s[40];
> _stprintf(s,_T("Message=%x\n"),hr);
> OutputDebugString(s);
> NotifyMessage( MESSAGE_ERROR, L"Building the graph failed" );
> }
> return hr;
> }
>
>
> HRESULT
> CGraphManager::RunCaptureGraphInternal()
> {
> HRESULT hr = S_OK;
>
> CComPtr<IGraphBuilder> pGraphBuilder;
> CComPtr<IMediaControl> pMediaControl;
>
> // Let's make sure that the graph has been initialized
> if(( m_pCaptureGraphBuilder == NULL ) || ( m_fGraphBuilt ==
> FALSE ))
> {
> ERR( E_FAIL );
> }
>
> // Retrieve the filtergraph off the capture graph builder
> CHK( m_pCaptureGraphBuilder->GetFiltergraph( &pGraphBuilder ));
>
> // Get the media control interface, and run the graph
> CHK( pGraphBuilder->QueryInterface( &pMediaControl ));
> CHK( pMediaControl->Run());
>
> CHK( NotifyMessage( MESSAGE_INFO, L"The Graph is running" ));
>
> Cleanup:
> if( FAILED( hr ))
> {
> NotifyMessage( MESSAGE_ERROR, L"Runing the capture graph failed" );
> }
> return hr;
> }
>
>
> HRESULT
> CGraphManager::StartCaptureVideoInternal()
> {
> HRESULT hr = S_OK;
> LONGLONG dwStart = 0, dwEnd = 0;
> WORD wStartCookie = 1, wEndCookie = 2;
>
> CComPtr<IGraphBuilder> pGraphBuilder;
>
> // Make sure that the capture graph builder is present
> if(( m_pCaptureGraphBuilder == NULL ) || ( m_fGraphBuilt ==
> FALSE ))
> {
> ERR( E_FAIL );
> }
>
> // Let's retrieve the event signaled by the filtergraph
> CHK( m_pCaptureGraphBuilder->GetFiltergraph( &pGraphBuilder ));
>
>
> // To start the video capture, call
> ICaptureGraphBuilder2::ControlStream.
> dwStart=0;
> dwEnd=MAXLONGLONG;
> CHK( m_pCaptureGraphBuilder->ControlStream( &PIN_CATEGORY_CAPTURE,
> &MEDIATYPE_Video, NULL, &dwStart, &dwEnd, wStartCookie, wEndCookie ));
>
> CHK( NotifyMessage( MESSAGE_INFO, L"Capturing...." ));
>
> Cleanup:
> if( FAILED( hr ))
> {
> NotifyMessage( MESSAGE_ERROR, L"Starting the video recording
> failed" );
> }
> return hr;
> }
>
>
> HRESULT
> CGraphManager::StopCaptureVideoInternal()
> {
> HRESULT hr = S_OK;
> LONGLONG dwStart = 0, dwEnd = 0;
> WORD wStartCookie = 1, wEndCookie = 2;
>
>
> CComPtr<IGraphBuilder> pFilterGraph;
> CComPtr<IMediaSeeking> pMediaSeeking;
>
> CHK( m_pCaptureGraphBuilder->GetFiltergraph( &pFilterGraph ));
> CHK( pFilterGraph->QueryInterface( &pMediaSeeking ));
>
> // Stop the capture of the graph
> dwStart = 0;
> CHK( pMediaSeeking->GetCurrentPosition( &dwEnd ));
> CHK( m_pCaptureGraphBuilder->ControlStream( &PIN_CATEGORY_CAPTURE,
> &MEDIATYPE_Video, NULL, &dwStart, &dwEnd, wStartCookie, wEndCookie ));
>
> // The filtergraph will fire a EC_CONTROLSTREAM_STOPPED event once
> the capture of the video is completed
> // The event will be caught in the main loop and processed in the
> ProcessDshowEvents function
> CHK( NotifyMessage( MESSAGE_INFO, L"Encoding file ..." ));
>
> Cleanup:
> if( FAILED( hr ))
> {
> NotifyMessage( MESSAGE_ERROR, L"Stopping the video recording
> failed" );
> }
> return hr;
> }
>
>
> HRESULT
> CGraphManager::CaptureStillImageInternal()
> {
> HRESULT hr = S_OK;
> CComPtr<IFileSinkFilter> pFileSink;
> CComPtr<IUnknown> pUnkCaptureFilter;
> CComPtr<IPin> pStillPin;
> CComPtr<IAMVideoControl> pVideoControl;
>
> if(( m_pCaptureGraphBuilder == NULL ) || ( m_fGraphBuilt ==
> FALSE ))
> {
> ERR( E_FAIL );
> }
>
> CHK( m_pImageSinkFilter.QueryInterface( &pFileSink ));
> CHK( pFileSink->SetFileName( L"\\test.jpg", NULL ));
>
> CHK( m_pVideoCaptureFilter.QueryInterface( &pUnkCaptureFilter ));
> CHK( m_pCaptureGraphBuilder->FindPin( pUnkCaptureFilter,
> PINDIR_OUTPUT, &PIN_CATEGORY_STILL, &MEDIATYPE_Video, FALSE, 0,
> &pStillPin ));
> CHK( m_pVideoCaptureFilter.QueryInterface( &pVideoControl ));
> CHK( pVideoControl->SetMode( pStillPin, VideoControlFlag_Trigger ));
>
> Sleep(200);
> // CHK( m_pImageSinkFilter.QueryInterface( &pFileSink ));
> CHK( pFileSink->SetFileName( L"\\test1.jpg", NULL ));
>
> // CHK( m_pVideoCaptureFilter.QueryInterface( &pUnkCaptureFilter ));
> // CHK( m_pCaptureGraphBuilder->FindPin( pUnkCaptureFilter,
> PINDIR_OUTPUT, &PIN_CATEGORY_STILL, &MEDIATYPE_Video, FALSE, 0,
> &pStillPin ));
> // CHK( m_pVideoCaptureFilter.QueryInterface( &pVideoControl ));
> CHK( pVideoControl->SetMode( pStillPin, VideoControlFlag_Trigger ));
>
> Sleep(200);
> // CHK( m_pImageSinkFilter.QueryInterface( &pFileSink ));
> CHK( pFileSink->SetFileName( L"\\test2.jpg", NULL ));
>
> // CHK( m_pVideoCaptureFilter.QueryInterface( &pUnkCaptureFilter ));
> // CHK( m_pCaptureGraphBuilder->FindPin( pUnkCaptureFilter,
> PINDIR_OUTPUT, &PIN_CATEGORY_STILL, &MEDIATYPE_Video, FALSE, 0,
> &pStillPin ));
> // CHK( m_pVideoCaptureFilter.QueryInterface( &pVideoControl ));
> CHK( pVideoControl->SetMode( pStillPin, VideoControlFlag_Trigger ));
>
> Sleep(200);
> // CHK( m_pImageSinkFilter.QueryInterface( &pFileSink ));
> CHK( pFileSink->SetFileName( L"\\test3.jpg", NULL ));
>
> // CHK( m_pVideoCaptureFilter.QueryInterface( &pUnkCaptureFilter ));
> // CHK( m_pCaptureGraphBuilder->FindPin( pUnkCaptureFilter,
> PINDIR_OUTPUT, &PIN_CATEGORY_STILL, &MEDIATYPE_Video, FALSE, 0,
> &pStillPin ));
> // CHK( m_pVideoCaptureFilter.QueryInterface( &pVideoControl ));
> CHK( pVideoControl->SetMode( pStillPin, VideoControlFlag_Trigger ));
>
>
> Cleanup:
> if( FAILED( hr ))
> {
> NotifyMessage( MESSAGE_ERROR, L"Capturing a still image failed" );
> }
> return hr;
> }
>
>
> HRESULT
> CGraphManager::NotifyMessage( DSHOW_MESSAGE message, WCHAR *wzText )
> {
> HRESULT hr = S_OK;
> Message *pMessage;
> WCHAR *wzString;
>
> if(( wzText == NULL ) || ( *wzText == NULL ))
> {
> ERR( E_POINTER );
> }
>
> if( m_hwnd == NULL )
> {
> return S_FALSE;
> }
>
> pMessage = (Message*) LocalAlloc( LMEM_ZEROINIT,
> sizeof( Message ));
> if( pMessage == NULL )
> {
> ERR( E_OUTOFMEMORY );
> }
>
> wzString = (WCHAR*) LocalAlloc( LMEM_ZEROINIT, ( wcslen( wzText )
> + 1 ) * sizeof( WCHAR ));
> if( wzString == NULL )
> {
> ERR( E_OUTOFMEMORY );
> }
>
> StringCchCopy( wzString, wcslen( wzText ) + 1, wzText );
>
> pMessage->wzMessage = wzString;
> pMessage->dwMessage = message;
>
> PostMessage( m_hwnd, WM_USER, 0, (LPARAM) pMessage );
>
>
> Cleanup:
> return hr;
> }
> void CGraphManager::FindPin(IBaseFilter* baseFilter,
> PIN_DIRECTION direction,
> int pinNumber,
> IPin** destPin)
> {
>
> CComPtr<IEnumPins> enumPins;
>
> *destPin = NULL;
>
> if (SUCCEEDED(baseFilter->EnumPins(&enumPins))) {
> ULONG numFound;
> IPin* tmpPin;
>
> while (SUCCEEDED(enumPins->Next(1, &tmpPin, &numFound))) {
> PIN_DIRECTION pinDirection;
>
> tmpPin->QueryDirection(&pinDirection);
> if (pinDirection == direction) {
> if (pinNumber == 0) {
> // Return the pin's interface
> *destPin = tmpPin;
> break;
> }
> pinNumber--;
> }
> tmpPin->Release();
> }
> }
> }
> BOOL CGraphManager::ConnectPins(IBaseFilter* outputFilter,
> unsigned int outputNum,
> IBaseFilter* inputFilter,
> unsigned int inputNum)
> {
>
> CComPtr<IPin> inputPin;
> CComPtr<IPin> outputPin;
> CComPtr<IGraphBuilder> pFilterGraph;
> m_pCaptureGraphBuilder->GetFiltergraph( &pFilterGraph );
>
> if (!outputFilter || !inputFilter) {
> return false;
> }
>
> FindPin(outputFilter, PINDIR_OUTPUT, outputNum, &outputPin);
> FindPin(inputFilter, PINDIR_INPUT, inputNum, &inputPin);
>
> if (inputPin && outputPin) {
> return SUCCEEDED(pFilterGraph->Connect(outputPin, inputPin));
> } else {
> return false;
> }
> }
>
>
> BOOL CGraphManager::InsertFilter(IBaseFilter* outputFilter,
> unsigned int outputNum,
> IBaseFilter* inputFilter,
> unsigned int inputNum,
> IBaseFilter* intermediateFilter,
> unsigned int inputIntermNum,
> unsigned int outputIntermNum
> )
>
> {
> CComPtr<IPin> inputPin;
> CComPtr<IPin> outputPin;
> CComPtr<IPin> inputIntermPin;
> CComPtr<IPin> outputIntermPin;
> CComPtr<IGraphBuilder> pFilterGraph;
> BOOL bRes;
>
> m_pCaptureGraphBuilder->GetFiltergraph( &pFilterGraph );
>
> if (!outputFilter || !inputFilter || !intermediateFilter) {
> return FALSE;
> }
> FindPin(outputFilter, PINDIR_OUTPUT, outputNum, &outputPin);
> FindPin(inputFilter, PINDIR_INPUT, inputNum, &inputPin);
> FindPin(intermediateFilter, PINDIR_OUTPUT, outputIntermNum,
> &outputIntermPin);
> FindPin(intermediateFilter, PINDIR_INPUT, inputIntermNum,
> &inputIntermPin);
> if (inputPin && outputPin && outputIntermPin , inputIntermPin) {
> bRes = SUCCEEDED(pFilterGraph->Disconnect(outputPin));
> if (!bRes) return FALSE;
> bRes = SUCCEEDED(pFilterGraph->Disconnect(inputPin));
> if (!bRes) return FALSE;
> bRes = SUCCEEDED(pFilterGraph->Connect(outputPin, inputIntermPin));
> if (!bRes) return FALSE;
> bRes = SUCCEEDED(pFilterGraph->Connect(outputIntermPin, inputPin));
> if (!bRes) return FALSE;
> }
> else return FALSE;
> return TRUE;
> }
date: Wed, 19 Dec 2007 09:52:02 -0000
author: Graeme Wintle
|
|