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; 
}