⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 samplegrabber.cpp

📁 Window Mobile Capture with DirectDraw
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// SampleGrabber.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "SampleGrabber.h"
#include <windows.h>
#include <commctrl.h>

#pragma warning(disable: 4800)

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
    return TRUE;
}

const AMOVIESETUP_PIN psudSampleGrabberPins[] =
{
	{ L"Input"            // strName
	, FALSE               // bRendered
	, FALSE               // bOutput
	, FALSE               // bZero
	, FALSE               // bMany
	, &CLSID_NULL         // clsConnectsToFilter
	, L""                 // strConnectsToPin
	, 0                   // nTypes
	, NULL                // lpTypes
	}
	,
	{ L"Output"           // strName
	, FALSE               // bRendered
	, TRUE                // bOutput
	, FALSE               // bZero
	, FALSE               // bMany
	, &CLSID_NULL         // clsConnectsToFilter
	, L""                 // strConnectsToPin
	, 0                   // nTypes
	, NULL                // lpTypes
	}
};

const AMOVIESETUP_FILTER sudSampleGrabber =
{ &CLSID_GrabberSample            // clsID
, L"SampleGrabber Example"        // strName
, MERIT_DO_NOT_USE                // dwMerit
, 2                               // nPins
, psudSampleGrabberPins };        // lpPin


// Needed for the CreateInstance mechanism
CFactoryTemplate g_Templates[]=
{
	{ L"Sample Grabber Example"
	, &CLSID_GrabberSample
	, CSampleGrabber::CreateInstance
	, NULL
	, &sudSampleGrabber }

};

int g_cTemplates = sizeof(g_Templates)/sizeof(g_Templates[0]);

//
// CreateInstance
//
// Provide the way for COM to create a CSampleGrabber object
//
CUnknown * WINAPI CSampleGrabber::CreateInstance(LPUNKNOWN punk, HRESULT *phr) 
{
	ASSERT(phr);

	// assuming we don't want to modify the data
	CSampleGrabber *pNewObject = new CSampleGrabber(punk, phr, FALSE);

	if(pNewObject == NULL) {
		if (phr)
			*phr = E_OUTOFMEMORY;
	}

	return pNewObject;   

} // CreateInstance


//----------------------------------------------------------------------------
//
//----------------------------------------------------------------------------

CSampleGrabber::CSampleGrabber( IUnknown * pOuter, HRESULT * phr, BOOL ModifiesData )
: CTransInPlaceFilter( TEXT("SampleGrabber"), (IUnknown*) pOuter, 
					  CLSID_GrabberSample, phr)
					  , m_callback( NULL )
{
	// this is used to override the input pin with our own   
	m_pInput = (CTransInPlaceInputPin*) new CSampleGrabberInPin( this, phr );
	if( !m_pInput )
	{
		if (phr)
			*phr = E_OUTOFMEMORY;
	}

	// Ensure that the output pin gets created.  This is necessary because our
	// SetDeliveryBuffer() method assumes that the input/output pins are created, but
	// the output pin isn't created until GetPin() is called.  The 
	// CTransInPlaceFilter::GetPin() method will create the output pin, since we
	// have not already created one.
	IPin *pOutput = GetPin(1);
	// The pointer is not AddRef'ed by GetPin(), so don't release it
}


STDMETHODIMP CSampleGrabber::NonDelegatingQueryInterface( REFIID riid, void ** ppv) 
{
	CheckPointer(ppv,E_POINTER);

	if(riid == IID_IGrabberSample) {                
		return GetInterface((IGrabberSample *) this, ppv);
	}
	else {
		return CTransInPlaceFilter::NonDelegatingQueryInterface(riid, ppv);
	}
}


//----------------------------------------------------------------------------
// This is where you force the sample grabber to connect with one type
// or the other. What you do here is crucial to what type of data your
// app will be dealing with in the sample grabber's callback. For instance,
// if you don't enforce right-side-up video in this call, you may not get
// right-side-up video in your callback. It all depends on what you do here.
//----------------------------------------------------------------------------

HRESULT CSampleGrabber::CheckInputType( const CMediaType * pmt )
{
	CheckPointer(pmt,E_POINTER);
	CAutoLock lock( &m_Lock );

	// if the major type is not set, then accept anything

	GUID g = *m_mtAccept.Type( );
	if( g == GUID_NULL )
	{
		return NOERROR;
	}

	// if the major type is set, don't accept anything else

	if( g != *pmt->Type( ) )
	{
		return VFW_E_INVALID_MEDIA_TYPE;
	}

	// subtypes must match, if set. if not set, accept anything

	g = *m_mtAccept.Subtype( );
	if( g == GUID_NULL )
	{
		return NOERROR;
	}
	if( g != *pmt->Subtype( ) )
	{
		return VFW_E_INVALID_MEDIA_TYPE;
	}

	// format types must match, if one is set

	g = *m_mtAccept.FormatType( );
	if( g == GUID_NULL )
	{
		return NOERROR;
	}
	if( g != *pmt->FormatType( ) )
	{
		return VFW_E_INVALID_MEDIA_TYPE;
	}

	// at this point, for this sample code, this is good enough,
	// but you may want to make it more strict

	return NOERROR;
}


//----------------------------------------------------------------------------
// This bit is almost straight out of the base classes.
// We override this so we can handle Transform( )'s error
// result differently.
//----------------------------------------------------------------------------

HRESULT CSampleGrabber::Receive( IMediaSample * pms ) // xiaqz:>
{
	return CTransInPlaceFilter::Receive(pms);
}

//{
//	CheckPointer(pms,E_POINTER);
//
//	HRESULT hr;
//	AM_SAMPLE2_PROPERTIES * const pProps = m_pInput->SampleProps();
//
//	if (pProps->dwStreamId != AM_STREAM_MEDIA) 
//	{
//		if( m_pOutput->IsConnected() )
//			return m_pOutput->Deliver(pms);
//		else
//			return NOERROR;
//	}
//
//	if (UsingDifferentAllocators()) 
//	{
//		// We have to copy the data.
//
//		pms = Copy(pms);
//
//		if (pms == NULL) 
//		{
//			return E_UNEXPECTED;
//		}
//	}
//
//	// have the derived class transform the data
//	hr = Transform(pms);
//
//	if (FAILED(hr)) 
//	{
//		DbgLog((LOG_TRACE, 1, TEXT("Error from TransInPlace")));
//		if (UsingDifferentAllocators()) 
//		{
//			pms->Release();
//		}
//		return hr;
//	}
//
//	if (hr == NOERROR) 
//	{
//		hr = m_pOutput->Deliver(pms);
//	}
//
//	// release the output buffer. If the connected pin still needs it,
//	// it will have addrefed it itself.
//	if (UsingDifferentAllocators()) 
//	{
//		pms->Release();
//	}
//
//	return hr;
//}


//----------------------------------------------------------------------------
// Transform
//----------------------------------------------------------------------------

HRESULT CSampleGrabber::Transform ( IMediaSample * pms )
{
	CheckPointer(pms,E_POINTER);
	CAutoLock lock( &m_Lock );

	ATLASSERT(FALSE);

	if( m_callback )
	{
		REFERENCE_TIME StartTime, StopTime;
		pms->GetTime( &StartTime, &StopTime);

		StartTime += m_pInput->CurrentStartTime( );
		StopTime  += m_pInput->CurrentStartTime( );

		BOOL * pTypeChanged = &((CSampleGrabberInPin*) m_pInput)->m_bMediaTypeChanged;

		HRESULT hr = m_callback( pms, &StartTime, &StopTime, *pTypeChanged );

		*pTypeChanged = FALSE; // now that we notified user, we can clear it

		return hr;
	}

	return NOERROR;
}


//----------------------------------------------------------------------------
// SetAcceptedMediaType
//----------------------------------------------------------------------------

STDMETHODIMP CSampleGrabber::SetAcceptedMediaType( const CMediaType * pmt )
{
	CAutoLock lock( &m_Lock );

	if( !pmt )
	{
		m_mtAccept = CMediaType( );
		return NOERROR;        
	}

	CopyMediaType( &m_mtAccept, pmt );
	return S_OK;
}

//----------------------------------------------------------------------------
// GetAcceptedMediaType
//----------------------------------------------------------------------------

STDMETHODIMP CSampleGrabber::GetConnectedMediaType( CMediaType * pmt )
{
	if( !m_pInput || !m_pInput->IsConnected( ) )
	{
		return VFW_E_NOT_CONNECTED;
	}

	return m_pInput->ConnectionMediaType( pmt );
}


//----------------------------------------------------------------------------
// SetCallback
//----------------------------------------------------------------------------

STDMETHODIMP CSampleGrabber::SetCallback( SAMPLECALLBACK Callback )
{
	CAutoLock lock( &m_Lock );

	m_callback = Callback;

	return NOERROR;
}


//----------------------------------------------------------------------------
// inform the input pin of the allocator buffer we wish to use. See the
// input pin's SetDeliverBuffer method for comments. 
//----------------------------------------------------------------------------

STDMETHODIMP CSampleGrabber::SetDeliveryBuffer( ALLOCATOR_PROPERTIES props, BYTE * m_pBuffer )
{
	// have the input/output pins been created?
	if( !InputPin( ) || !OutputPin( ) )
	{
		return E_POINTER;
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -