www.pudn.com > Face3DModel.zip > global.cpp
#include "stdafx.h"
// Free an existing media type (ie free resources it holds)
void WINAPI FreeMediaType(AM_MEDIA_TYPE& mt)
{
if (mt.cbFormat != 0) {
CoTaskMemFree((PVOID)mt.pbFormat);
// Strictly unnecessary but tidier
mt.cbFormat = 0;
mt.pbFormat = NULL;
}
if (mt.pUnk != NULL) {
mt.pUnk->Release();
mt.pUnk = NULL;
}
}
// general purpose function to delete a heap allocated AM_MEDIA_TYPE structure
// which is useful when calling IEnumMediaTypes::Next as the interface
// implementation allocates the structures which you must later delete
// the format block may also be a pointer to an interface to release
void WINAPI DeleteMediaType(AM_MEDIA_TYPE *pmt)
{
// allow NULL pointers for coding simplicity
if (pmt == NULL) {
return;
}
FreeMediaType(*pmt);
CoTaskMemFree((PVOID)pmt);
}
// GetPin: Return the first pin with the specified direction.
HRESULT GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin)
{
if (!pFilter || !ppPin) return E_POINTER;
*ppPin = NULL;
IEnumPins *pEnum;
IPin *pPin;
HRESULT hr = pFilter->EnumPins(&pEnum);
if (FAILED(hr)) return hr;
while(pEnum->Next(1, &pPin, 0) == S_OK)
{
PIN_DIRECTION PinDirThis;
hr = pPin->QueryDirection(&PinDirThis);
if (FAILED(hr)) break;
AM_MEDIA_TYPE mt;
hr = pPin->ConnectionMediaType(&mt);
FreeMediaType(mt);
if (PinDir == PinDirThis)
{
// Found a matching pin.
pEnum->Release();
*ppPin = pPin; // Caller must release the interface.
return S_OK;
}
pPin->Release();
}
pEnum->Release();
return E_FAIL;
}
// ConnectFilters: Connect two filters.
// Note - You could use ICaptureGraphBuilder2::RenderStream also.
HRESULT ConnectFilters(
IGraphBuilder *pGraph,
IBaseFilter *pFirst,
IBaseFilter *pSecond)
{
if (!pGraph || !pFirst || !pSecond) return E_POINTER;
IPin *pOut = NULL, *pIn = NULL;
HRESULT hr = GetPin(pFirst, PINDIR_OUTPUT, &pOut);
if (FAILED(hr)) return hr;
hr = GetPin(pSecond, PINDIR_INPUT, &pIn);
if (FAILED(hr))
{
pOut->Release();
return E_FAIL;
}
hr = pGraph->Connect(pOut, pIn);
pIn->Release();
pOut->Release();
return hr;
}
HRESULT InsertSampleFilter(IGraphBuilder *pGraph, IBaseFilter *pFirst, IBaseFilter *pSample)
{
HRESULT hr = S_OK;
CComPtr pEnumPin;
CComPtr pPin;
PIN_DIRECTION PinDirection;
ULONG ulFetched;
// Enumerate all pins on the filter
hr = pFirst->EnumPins(&pEnumPin);
if(SUCCEEDED(hr))
{
// Step through every pin, looking for the output pins
while (S_OK == (hr = pEnumPin->Next(1L, &pPin, &ulFetched)))
{
CComPtr pConnectedPin;
// Is this pin connected? We're only interested in connected pins.
hr = pPin->ConnectedTo(&pConnectedPin);
if (SUCCEEDED(hr))
{
hr = pPin->QueryDirection(&PinDirection);
if (SUCCEEDED(hr) && (PinDirection == PINDIR_OUTPUT))
{
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
hr = pPin->ConnectionMediaType(&mt);
if (SUCCEEDED(hr) && mt.majortype == MEDIATYPE_Video)
{
CComPtr pPinSampleIn;
CComPtr pPinSampleOut;
hr = pGraph->Disconnect(pPin);
if (SUCCEEDED(hr))
{
hr = pGraph->Disconnect(pConnectedPin);
}
if (SUCCEEDED(hr))
{
hr = GetPin(pSample, PINDIR_INPUT, &pPinSampleIn);
}
if (SUCCEEDED(hr))
{
hr = GetPin(pSample, PINDIR_OUTPUT, &pPinSampleOut);
}
if (SUCCEEDED(hr))
{
hr = pGraph->Connect(pPin, pPinSampleIn);
}
if (SUCCEEDED(hr))
{
hr = pGraph->Connect(pPinSampleOut, pConnectedPin);
if (FAILED(hr))
{
pGraph->Disconnect(pPin);
pGraph->Disconnect(pPinSampleIn);
}
}
if (SUCCEEDED(hr))
{
// CComPtr pEnumFilters;
// CComPtr pBaseFilter;
// pGraph->EnumFilters(&pEnumFilters);
// while (S_OK == pEnumFilters->Next(1, &pBaseFilter, NULL))
// {
// FILTER_INFO filter_Info;
// pBaseFilter->QueryFilterInfo(&filter_Info);
// AfxMessageBox(filter_Info.achName);
// filter_Info.pGraph->Release();
// pBaseFilter.Release();
//
// }
FreeMediaType(mt);
return hr;
}
else
{
// reconnect the break connection
pGraph->ConnectDirect(pPin, pConnectedPin, NULL);
// then find next filter to retry;
PIN_INFO pin_Info;
hr = pConnectedPin->QueryPinInfo(&pin_Info);
if (pin_Info.pFilter != NULL)
{
hr = InsertSampleFilter(pGraph, pin_Info.pFilter, pSample);
pin_Info.pFilter->Release();
if (SUCCEEDED(hr))
{
FreeMediaType(mt);
return hr;
}
}
}
}
else
{
PIN_INFO pin_Info;
hr = pConnectedPin->QueryPinInfo(&pin_Info);
if (pin_Info.pFilter != NULL)
{
hr = InsertSampleFilter(pGraph, pin_Info.pFilter, pSample);
pin_Info.pFilter->Release();
if (SUCCEEDED(hr))
{
FreeMediaType(mt);
return hr;
}
}
}
FreeMediaType(mt);
}
}
pPin.Release();
}
}
return E_FAIL;
}
HRESULT ConnectSampleFilter(IGraphBuilder *pGraph, IBaseFilter *pSample)
{
CComPtr pRenderer;
CComPtr pPinVideoIn;
CComPtr pPinVideoSecondIn;
CComPtr pPinVideoSecondOut;
CComPtr pPinVideoSecondConnect;
CComPtr pPinSampleIn;
CComPtr pPinSampleOut;
CComPtr pEnumPin;
PIN_DIRECTION PinDirection;
ULONG ulFetched;
HRESULT hr = pGraph->FindFilterByName(_T("Video Renderer"), &pRenderer);
if (SUCCEEDED(hr))
{
hr = GetPin(pRenderer, PINDIR_INPUT, &pPinVideoIn);
hr = pPinVideoIn->ConnectedTo(&pPinVideoSecondOut);
PIN_INFO pin_Info;
ZeroMemory(&pin_Info, sizeof(PIN_INFO));
hr = pPinVideoSecondOut->QueryPinInfo(&pin_Info);
if (SUCCEEDED(hr))
{
hr = pin_Info.pFilter->EnumPins(&pEnumPin);
while (S_OK == (hr = pEnumPin->Next(1L, &pPinVideoSecondIn, &ulFetched)))
{
hr = pPinVideoSecondIn->QueryDirection(&PinDirection);
if (SUCCEEDED(hr) && (PinDirection == PINDIR_INPUT))
{
// Is this pin connected? We're only interested in connected pins.
hr = pPinVideoSecondIn->ConnectedTo(&pPinVideoSecondConnect);
if (SUCCEEDED(hr))
{
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
pPinVideoSecondIn->ConnectionMediaType(&mt);
FreeMediaType(mt);
hr = pGraph->Disconnect(pPinVideoSecondIn);
hr = pGraph->Disconnect(pPinVideoSecondConnect);
hr = GetPin(pSample, PINDIR_INPUT, &pPinSampleIn);
hr = GetPin(pSample, PINDIR_OUTPUT, &pPinSampleOut);
hr = pGraph->ConnectDirect(pPinVideoSecondConnect, pPinSampleIn, NULL);
hr = pGraph->ConnectDirect(pPinSampleOut, pPinVideoSecondIn, NULL);
break;
}
}
pPinVideoSecondIn.Release();
}
if (pin_Info.pFilter != NULL)
{
pin_Info.pFilter->Release();
}
}
}
return hr;
}
BOOL IsWindowsMediaFile(LPTSTR lpszFile)
{
TCHAR szFilename[MAX_PATH];
// Copy the file name to a local string and convert to lowercase
_tcsncpy(szFilename, lpszFile, NUMELMS(szFilename));
szFilename[MAX_PATH-1] = 0;
_tcslwr(szFilename);
if (_tcsstr(szFilename, TEXT(".asf")) ||
_tcsstr(szFilename, TEXT(".wma")) ||
_tcsstr(szFilename, TEXT(".wmv")))
return TRUE;
else
return FALSE;
}
HRESULT RenderOutputPins(IGraphBuilder *pGB, IBaseFilter *pFilter)
{
HRESULT hr = S_OK;
IEnumPins * pEnumPin = NULL;
IPin * pConnectedPin = NULL, * pPin = NULL;
PIN_DIRECTION PinDirection;
ULONG ulFetched;
// Enumerate all pins on the filter
hr = pFilter->EnumPins(&pEnumPin);
if(SUCCEEDED(hr))
{
// Step through every pin, looking for the output pins
while (S_OK == (hr = pEnumPin->Next(1L, &pPin, &ulFetched)))
{
// Is this pin connected? We're not interested in connected pins.
hr = pPin->ConnectedTo(&pConnectedPin);
if (pConnectedPin)
{
pConnectedPin->Release();
pConnectedPin = NULL;
}
// If this pin is not connected, render it.
if (VFW_E_NOT_CONNECTED == hr)
{
hr = pPin->QueryDirection(&PinDirection);
if ((S_OK == hr) && (PinDirection == PINDIR_OUTPUT))
{
hr = pGB->Render(pPin);
}
}
pPin->Release();
// If there was an error, stop enumerating
if (FAILED(hr))
break;
}
}
// Release pin enumerator
pEnumPin->Release();
return hr;
}