视频捕获增加color space converter + Transform Filter

发布时间:2018-12-18 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了视频捕获增加color space converter + Transform Filter脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

其它不解释,贴是代码:

IPFilter.h

[htML]
// 
// Sample DirectShow In-Place Transform Filter that accepts data for use in application 
// 
 
#include <streams.h> 
 
// This is an example transform filter that is created wIThin 
// the application, and not by CoCreateinstance 
class CAppTransform : public CTransformFilter 

public: 
    CAppTransform(LPUNKNOWN pUnkOuter, hrESULT *phr); 
 
    HRESULT CheckInputTyPE(const CMediaType* mtIn); 
     
    HRESULT Transform(IMediaSample *pIn, IMediaSample *pOut); 
    HRESULT CheckTransform(const CMediaType *mtIn,const CMediaType *mtOut); 
    HRESULT DecideBufferSize(IMemAllocator *pAlloc, 
        ALLOCATOR_PROPERTIES *pProperties); 
    HRESULT GetMediaType(int IPOsition, CMediaType *pMediaType); 
private: 
    HRESULT Copy(IMediaSample *pSource, IMediaSample *pDest) const; 
    HRESULT Transform(IMediaSample *pSample); 
}; 
 
 
// DirectShow graph management sample code: 
// This builds a playback graph using RenderFile 
// and then inserts a transform filter on the uncomPressed video. 
class CAppGraphBuilder 

private: 
    CAppTransform*   m_pFilter; 
    DWORD            m_dwObjectTable;  
    ICaptureGraphBuilder2 *m_pBuild; 
    IGraphBuilder *m_pGraph; 
 
public: 
    CAppGraphBuilder(); 
    ~CAppGraphBuilder(); 
 
    void DestroyGraph(void); 
 
    HRESULT BuildFromFile(LPCWSTR pszFile); 
    HRESULT Run(void); 
    HRESULT MakeChild(HWND hwnd); 
    HRESULT ResizeVideoWindow(RECT* prc); 
 
private: 
    void CreateAppFilter(void); 
    HRESULT FinDFilterByInterface(REFIID riid, IBaseFilter** ppFilter); 
    HRESULT ConnectUpstreamOf(IBaseFilter* pFilter,IBaseFilter*pColor, IBaseFilter* pTransform); 
    HRESULT NextUpstream(IBaseFilter* pFilter, IBaseFilter** ppNext);   
    HRESULT CAppGraphBuilder::AddFilterByCLSID(IGraphBuilder *pGraph,const GUID& clsid,LPCWSTR wszName,IBaseFilter **ppF); 
     
    HRESULT InitCaptureGraphBuilder(IGraphBuilder **ppGraph,ICaptureGraphBuilder2 **ppBuild); 
    HRESULT EnumerateDevices(REFGUID category, IEnumMoniker **ppEnum); 
    void DisplayDeviceInformation(IEnumMoniker *pEnum, IMoniker** pMoniker); 
 
    IPin* GetPin(IBaseFilter* pFilter, PIN_DIRECTION dirRequest); 
    // Helper methods 
    IPin* InputPinOf(IBaseFilter* pFilter)  
    { 
        return GetPin(pFilter, PINDIR_INPUT); 
    } 
    IPin* OutputPinOf(IBaseFilter* pFilter)  
    { 
        return GetPin(pFilter, PINDIR_OUTPUT); 
    } 
 
    void AddToObjectTable(void) ; 
    void RemoveFromObjectTable(void); 
}; 

IPFilter.cpp

[html] view plaincopy
// 
// Sample DirectShow Transform Filter that accepts data for use in application 
// 
 
#include "stdafx.h" 
#include "IPFilter.h" 
 
//////////////////////////////////////////////////////////////////////////////// 
CAppTransform::CAppTransform(LPUNKNOWN pUnkOuter, HRESULT *phr) :  
CTransformFilter(NAME("App Transform"), pUnkOuter, GUID_NULL) 


// 
// CheckTransform 
// 
// To be able to transform the formats must be identical 
// 
HRESULT CAppTransform::CheckTransform(const CMediaType *mtIn,const CMediaType *mtOut) 

    CheckPointer(mtIn,E_POINTER); 
    CheckPointer(mtOut,E_POINTER); 
 
    HRESULT hr; 
    if(FAILED(hr = CheckInputType(mtIn))) 
    { 
        return hr; 
    } 
 
    // format must be a VIDEOINFOHEADER 
    if(*mtOut->FormatType() != FORMAT_VideoInfo) 
    { 
        return E_INVALIDarg
    } 
 
    // formats must be Big enough  
    if(mtIn->FormatLength() < sizeof(VIDEOINFOHEADER) || 
        mtOut->FormatLength() < sizeof(VIDEOINFOHEADER)) 
        return E_INVALIDARG; 
 
    VIDEOINFO *pInput  = (VIDEOINFO *) mtIn->Format(); 
    VIDEOINFO *pOutput = (VIDEOINFO *) mtOut->Format(); 
 
    if(memcmp(&pInput->bmiHeader,&pOutput->bmiHeader,sizeof(BITMAPINFOHEADER)) == 0) 
    { 
        return NOERROR; 
    } 
 
    return E_INVALIDARG; 
 
} // CheckTransform 
// 
// DecideBufferSize 
// 
// Tell the output pin's allocator what size buffers we 
// require. Can only do this when the input is connected 
// 
HRESULT CAppTransform::DecideBufferSize(IMemAllocator *pAlloc,ALLOCATOR_PROPERTIES *pProperties) 

    CheckPointer(pAlloc,E_POINTER); 
    CheckPointer(pProperties,E_POINTER); 
 
    // Is the input pin connected 
 
    if(m_pInput->IsConnected() == FALSE) 
    { 
        return E_UNExpECTED; 
    } 
    HRESULT hr = NOERROR; 
    pProperties->cBuffers = 1; 
    pProperties->cbBuffer = m_pInput->currentMediaType().GetSampleSize(); 
 
    ASSERT(pProperties->cbBuffer); 
 
    // If we don't have fixed sized samples we must guess some size 
 
    if(!m_pInput->CurrentMediaType().bFixedSizeSamples) 
    { 
        if(pProperties->cbBuffer < 100000) 
        { 
            // nothing more than a guess!! 
            pProperties->cbBuffer = 100000; 
        } 
    } 
 
    // Ask the allocator to reserve us some sample memory, NOTE the function 
    // can succeed (that is return NOERROR) but still not have allocated the 
    // memory that we requested, so we must check we got whatever we wanted 
 
    ALLOCATOR_PROPERTIES Actual; 
 
    hr = pAlloc->SetProperties(pProperties,&Actual); 
    if(FAILED(hr)) 
    { 
        return hr; 
    } 
 
    ASSERT(Actual.cBuffers == 1); 
 
    if(pProperties->cBuffers > Actual.cBuffers || 
        pProperties->cbBuffer > Actual.cbBuffer) 
    { 
        return E_FAIL; 
    } 
 
    return NOERROR; 
 
} // DecideBufferSize 
// 
// GetMediaType 
// 
// I support one type, namely the type of the input pin 
// We must be connected to support the single output type 
// 
HRESULT CAppTransform::GetMediaType(int iPosition, CMediaType *pMediaType) 

    // Is the input pin connected 
 
    if(m_pInput->IsConnected() == FALSE) 
    { 
        return E_UNEXPECTED; 
    } 
 
    // This should never happen 
 
    if(iPosition < 0) 
    { 
        return E_INVALIDARG; 
    } 
 
    // Do we have more items to offer 
 
    if(iPosition > 0) 
    { 
        return VFW_S_NO_MORE_ITEMS; 
    } 
 
    CheckPointer(pMediaType,E_POINTER); 
 
    *pMediaType = m_pInput->CurrentMediaType(); 
    return NOERROR; 
 

HRESULT CAppTransform::Copy(IMediaSample *pSource, IMediaSample *pDest) const 

    CheckPointer(pSource,E_POINTER); 
    CheckPointer(pDest,E_POINTER); 
 
    // Copy the sample data 
    BYTE *pSourceBuffer, *pDestBuffer; 
    long lSourceSize = pSource->GetActualDataLength(); 
 
#ifdef DEBUG 
    long lDestSize = pDest->GetSize(); 
    ASSERT(lDestSize >= lSourceSize); 
#endif 
 
    pSource->GetPointer(&pSourceBuffer); 
    pDest->GetPointer(&pDestBuffer); 
 
    CopyMemory((pvOID) pDestBuffer,(PVOID) pSourceBuffer,lSourceSize); 
 
    // Copy the sample times 
 
    REFERENCE_TIME TimeStart, TimeEnd; 
    if(NOERROR == pSource->GetTime(&TimeStart, &TimeEnd)) 
    { 
        pDest->SetTime(&TimeStart, &TimeEnd); 
    } 
 
    LONGLONG MediaStart, MediaEnd; 
    if(pSource->GetMediaTime(&;mediaStart,&MediaEnd) == NOERROR) 
    { 
        pDest->SetMediaTime(&MediaStart,&MediaEnd); 
    } 
 
    // Copy the Sync point property 
 
    HRESULT hr = pSource->IsSyncPoint(); 
    if(hr == S_OK) 
    { 
        pDest->SetSyncPoint(TRUE); 
    } 
    else if(hr == S_FALSE) 
    { 
        pDest->SetSyncPoint(FALSE); 
    } 
    else 
    {  // an unexpected error has occured..
        return E_UNEXPECTED; 
    } 
 
    // Copy the media type 
 
    AM_MEDIA_TYPE *pMediaType; 
    pSource->GetMediaType(&pMediaType); 
    pDest->SetMediaType(pMediaType); 
    DeleteMediaType(pMediaType); 
 
    // Copy the preroll property 
 
    hr = pSource->IsPreroll(); 
    if(hr == S_OK) 
    { 
        pDest->SetPreroll(TRUE); 
    } 
    else if(hr == S_FALSE) 
    { 
        pDest->SetPreroll(FALSE); 
    } 
    else 
    {  // an unexpected error has occured... 
        return E_UNEXPECTED; 
    } 
 
    // Copy the discontinuity property 
 
    hr = pSource->IsDiscontinuity(); 
 
    if(hr == S_OK) 
    { 
        pDest->SetDiscontinuity(TRUE); 
    } 
    else if(hr == S_FALSE) 
    { 
        pDest->SetDiscontinuity(FALSE); 
    } 
    else 
    {  // an unexpected error has occured... 
        return E_UNEXPECTED; 
    } 
 
    // Copy the actual data length 
 
    long lDataLength = pSource->GetActualDataLength(); 
    pDest->SetActualDataLength(lDataLength); 
 
    return NOERROR; 
 
} // Copy 
// 
// Transform 
// 
// Copy the input sample into the output sample 
// Then transform the output sample 'in place' 
// 
HRESULT CAppTransform::Transform(IMediaSample *pIn, IMediaSample *pOut) 

    HRESULT hr = Copy(pIn, pOut); 
    if (FAILED(hr)) { 
        return hr; 
    } 
 
    return Transform(pOut); 
 
 
} // Transform 
HRESULT CAppTransform::Transform(IMediaSample *pSample) 

    // override to do something inside the application 
    // Such as grabbing a poster frame... 
    // ... 
    BYTE *pData;                // Pointer to the actual image buffer 
    long lDataLen;              // Holds length of any given sample 
    int iPixel;                 // Used to loop through the image pixels 
    tagRGBTRIPLE *prgb;            // Holds a pointer to the current pixel 
 
    AM_MEDIA_TYPE* pType = &m_pInput->CurrentMediaType(); 
    VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *) pType->pbFormat; 
    ASSERT(pvi); 
 
    CheckPointer(pSample,E_POINTER); 
    pSample->GetPointer(&pData); 
    lDataLen = pSample->GetSize(); 
 
    // Get the image properties from the BITMAPINFOHEADER 
 
    int cxImage    = pvi->bmiHeader.biWidth; 
    int cyImage    = pvi->bmiHeader.biHeight; 
    int numPixels  = cxImage * cyImage; 
 
    // int iPixelSize = pvi->bmiHeader.biBitCount / 8; 
    // int cbImage    = cyImage * cxImage * iPixelSize; 
 
 
    prgb = (tagRGBTRIPLE*) pData; 
    for (iPixel=0; iPixel < numPixels; iPixel++, prgb++) { 
    prgb->rgbtRed=prgb->rgbtBlue=prgb->rgbtGreen=(prgb->rgbtRed+prgb->rgbtBlue+prgb->rgbtGreen)/3; 
    } 
    return S_OK; 

 
// Check if we can support this specific proposed type and format 
HRESULT CAppTransform::CheckInputType(const CMediaType *pmt)  

    // We accept a series of raw media types 
    /*if (pmt->majortype == MEDIATYPE_Video && 
    (pmt->subtype == MEDIASUBTYPE_RGB32 || 
    pmt->subtype == MEDIASUBTYPE_RGB24 || 
    pmt->subtype == MEDIASUBTYPE_RGB565 || 
    pmt->subtype == MEDIASUBTYPE_RGB555 || 
    pmt->subtype == MEDIASUBTYPE_UYVY || 
    pmt->subtype == MEDIASUBTYPE_YUY2)|| 
    pmt->subtype==MEDIASUBTYPE_NV12)*/ 
    if (pmt->majortype == MEDIATYPE_Video && 
        (pmt->subtype == MEDIASUBTYPE_RGB24)) 
    { 
        return NOERROR; 
    } 
    return E_FAIL; 

 
 
// --- graph building (examples) ---------  
CAppGraphBuilder::CAppGraphBuilder() :  
m_pBuild(NULL), 
m_pGraph(NULL), 
m_pFilter(NULL), 
m_dwObjectTable(0) 

    CoInitialize(NULL); 

 
CAppGraphBuilder::~CAppGraphBuilder() 

    DestroyGraph(); 
    CoUninitialize(); 

     
void CAppGraphBuilder::DestroyGraph(void) 

    if (m_pGraph)  
    { 
        RemoveFromObjectTable(); 
        // ensure graph window is not child of ours 
        IVideoWindow* pVW = NULL; 
        HRESULT hr = m_pGraph->QueryInterface(IID_IVideoWindow, (void**)&pVW); 
        if (SUCCEEDED(hr))  
        { 
            pVW->put_Visible(OAFALSE); 
            pVW->put_Owner(NULL); 
            pVW->put_MessageDrain(NULL); 
            pVW->Release(); 
        } 
        m_pGraph->Release(); 
        m_pGraph = NULL; 
        m_pBuild->Release(); 
        m_pBuild = NULL; 
    } 
 
    if (m_pFilter)  
    { 
        m_pFilter->Release(); 
        m_pFilter = NULL; 
    } 

HRESULT CAppGraphBuilder::InitCaptureGraphBuilder( 
    IGraphBuilder **ppGraph,  // Receives the pointer. 
    ICaptureGraphBuilder2 **ppBuild  // Receives the pointer. 
    ) 

    if (!ppGraph || !ppBuild) 
    { 
        return E_POINTER; 
    } 
    IGraphBuilder *pGraph = NULL; 
    ICaptureGraphBuilder2 *pBuild = NULL; 
 
    // Create the Capture Graph Builder. 
    HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,  
        CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&pBuild ); 
    if (SUCCEEDED(hr)) 
    { 
        // Create the Filter Graph Manager. 
        hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC_SERVER, 
            IID_IGraphBuilder, (void**)&pGraph); 
        if (SUCCEEDED(hr)) 
        { 
            // Initialize the Capture Graph Builder. 
            pBuild->SetFiltergraph(pGraph); 
 
            // Return both interface pointers to the caller. 
            *ppBuild = pBuild; 
            *ppGraph = pGraph; // The caller must release both interfaces. 
            return S_OK; 
        } 
        else 
        { 
            pBuild->Release(); 
        } 
    } 
    return hr; // Failed 

 
 
 
HRESULT CAppGraphBuilder::EnumerateDevices(REFGUID category, IEnumMoniker **ppEnum) 

    ICreateDevEnum *pDevEnum = NULL; 
 
    // Create the System Device Enumerator. 
    HRESULT hr = CoCreateInstance(CLSID_systemdeviceEnum, NULL, 
        CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,  
        reinterpret_cast<void**>(&pDevEnum)); 
    if (SUCCEEDED(hr)) 
    { 
        // Create an enumerator for the video capture category. 
        hr = pDevEnum->CreateClassEnumerator( 
            CLSID_VideoInputDeviceCategory, 
            ppEnum, 0); 
    } 
    return hr; 

void CAppGraphBuilder::DisplayDeviceInformation(IEnumMoniker *pEnum, IMoniker** pMoniker) 

    HWND hList; // Handle to the list box. 
    while (pEnum->Next(1, pMoniker, NULL) == S_OK) 
    { 
        IPropertyBag *pPropBag; 
        HRESULT hr = (*pMoniker)->BindToStorage(0, 0, IID_IPropertyBag,  
            (void**)(&pPropBag)); 
        if (FAILED(hr)) 
        { 
            (*pMoniker)->Release(); 
            continue;  // Skip this one, maybe the next one will work. 
        }  
        // Find the description or friendly name. 
        VARIANT varName; 
        VariantInit(&varName); 
        hr = pPropBag->Read(L"Description", &varName, 0); 
        if (FAILED(hr)) 
        { 
            hr = pPropBag->Read(L"FriendlyName", &varName, 0); 
        } 
        if (SUCCEEDED(hr)) 
        { 
            // Add it to the application's list box. 
            USES_CONVERSION; 
            /*(long)SendMessage(hList, LB_ADDSTRING, 0,  
            (LPARAM)OLE2T(varName.bstrVal));*/ 
            VariantClear(&varName);  
        } 
        pPropBag->Release(); 
        (*pMoniker)->Release(); 
    } 
 
 

HRESULT CAppGraphBuilder::AddFilterByCLSID( 
    IGraphBuilder *pGraph,  // Pointer to the Filter Graph Manager. 
    const GUID& clsid,      // CLSID of the filter to create. 
    LPCWSTR wszName,        // A name for the filter. 
    IBaseFilter **ppF)      // Receives a pointer to the filter. 

    if (!pGraph || ! ppF) return E_POINTER; 
    *ppF = 0; 
    IBaseFilter *pF = 0; 
    HRESULT hr = CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER, 
        IID_IBaseFilter, reinterpret_cast<void**>(&pF)); 
    if (SUCCEEDED(hr)) 
    { 
        hr = pGraph->AddFilter(pF, wszName); 
        if (SUCCEEDED(hr)) 
            *ppF = pF; 
        else 
            pF->Release(); 
    } 
    return hr; 

HRESULT CAppGraphBuilder::BuildFromFile(LPCWSTR pszFile) 

    DestroyGraph(); 
    IMoniker* pMoniker; 
     
    IMediaEvent   *pEvent; 
 
    InitCaptureGraphBuilder(&m_pGraph,&m_pBuild); 
     
    HRESULT hr = m_pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent); 
 
    AddToObjectTable(); 
    IBaseFilter *pCap; // Video capture filter. 
    IEnumMoniker *pEnum; 
 
    hr = EnumerateDevices(CLSID_VideoInputDeviceCategory, &pEnum); 
 
    DisplayDeviceInformation(pEnum, &pMoniker); 
    hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pCap); 
    if (SUCCEEDED(hr)) 
    { 
        hr = m_pGraph->AddFilter(pCap, L"Capture Filter"); 
    } 
    hr = m_pBuild->RenderStream(&PIN_CATEGORY_PrevIEW, &MEDIATYPE_Video, pCap, NULL, NULL); 
 
 
    IBaseFilter *pMux; 
    hr = m_pBuild->SetOutputFileName(&MEDIASUBTYPE_Avi,L"D://Example.avi",&pMux,NULL); 
    hr = m_pBuild->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,pCap,NULL,pMux); 
 
     
     
    // Try to find the video renderer, by looking for IVideoWindow 
    IBaseFilter* pVR; 
    hr = FindFilterByInterface(IID_IVideoWindow, &pVR); 
    if (FAILED(hr))  
    { 
        return hr; 
    } 
 
    // Find the media type on the input pin of the Video Renderer 
    // to check for overlay connection where no actual data is passed 
    IPin* pPin = InputPinOf(pVR); 
    AM_MEDIA_TYPE mt; 
    pPin->ConnectionMediaType(&mt); 
    pPin->Release(); 
    CMediaType mtIn = mt; 
    FreeMediaType(mt); 
 
    if (mtIn.subtype == MEDIASUBTYPE_Overlay)  
    { 
        // This connection may be a overlay mixer  
        // need to move upstream one place 
        IBaseFilter* pOvMix = NULL; 
        hr = NextUpstream(pVR, &pOvMix); 
        pVR->Release(); 
        if (FAILED(hr))  
        { 
            return hr; 
        } 
        pVR = pOvMix; 
    } 
 
    // Create the transform and insert in graph 
    CreateAppFilter(); 
 
    // Add Color Space Convert 
    IBaseFilter *pColor; 
    hr=AddFilterByCLSID(m_pGraph, CLSID_Colour, L"Color Space Converter", &pColor); 
 
    // Try to insert our transform filter 
    hr = ConnectUpstreamOf(pVR, pColor,m_pFilter); 
    //pVR->Release(); 
 
     
    //pColor->Release(); 
 
    return hr; 

 
// Start the graph 
HRESULT CAppGraphBuilder::Run(void) 

    IMediaControl* pControl = NULL; 
    HRESULT hr = m_pGraph->QueryInterface(IID_IMediaControl, (void**)&pControl); 
    if (SUCCEEDED(hr))  
    { 
        hr = pControl->Run(); 
        pControl->Release(); 
    } 
    return hr; 

 
// Make the video window a child of this app 
HRESULT CAppGraphBuilder::MakeChild(HWND hwnd) 

    if (!m_pGraph)  
    { 
        return E_FAIL; 
    } 
 
    IVideoWindow* pVW = NULL; 
    HRESULT hr = m_pGraph->QueryInterface(IID_IVideoWindow, (void**)&pVW); 
    if (SUCCEEDED(hr))  
    { 
        HWND hwndOld; 
        pVW->get_Owner((LONG*)&hwndOld); 
        if (hwndOld != hwnd) 
        { 
            pVW->put_AutoShow(OAFALSE); 
            pVW->put_Visible(OAFALSE); 
             
            long    WindowStyle = 0; 
            // Tweak the video's window style to get rid of the caption and frame: 
            hr = pVW->get_WindowStyle(&WindowStyle); 
            if (SUCCEEDED(hr))  
            { 
                WindowStyle &= ~WS_OVERLAPPEDWINDOW; // No frame junk 
                WindowStyle |= WS_CHILD;             // Needs to be child 
                hr = pVW->put_WindowStyle(WindowStyle); 
            } 
 
            pVW->put_Owner((LONG)hwnd); 
            pVW->put_MessageDrain((LONG)hwnd); 
 
            if (hwnd != NULL)  
            { 
                RECT rc; 
                GetClientRect(hwnd, &rc); 
                pVW->SetWindowPosition( 
                        rc.left, 
                        rc.top, 
                        rc.right - rc.left, 
                        rc.bottom - rc.top); 
                pVW->put_Visible(OATRUE); 
            } 
        } 
        pVW->Release(); 
    } 
 
    return hr; 

 
// Resize the video window 
HRESULT CAppGraphBuilder::ResizeVideoWindow(RECT* prc) 

    if (!m_pGraph)  
    { 
        return E_FAIL; 
    } 
 
    IVideoWindow* pVW = NULL; 
    HRESULT hr = m_pGraph->QueryInterface(IID_IVideoWindow, (void**)&pVW); 
    if (SUCCEEDED(hr))  
    { 
        hr = pVW->SetWindowPosition( 
            prc->left, 
            prc->top, 
            prc->right - prc->left, 
            prc->bottom - prc->top); 
        pVW->Release(); 
    } 
    return hr; 

 
// Create the app-based filter and insert into graph (unconnected) 
void CAppGraphBuilder::CreateAppFilter(void) 

    if (m_pFilter)  
    { 
        m_pFilter->Release(); 
        m_pFilter = NULL; 
    } 
 
    HRESULT hr = S_OK; 
    m_pFilter = new CAppTransform(NULL, &hr); 
    // Make the initial refcount 1 to match COM creation!!! 
    m_pFilter->AddRef(); 
 
    // Add to graph -- nb need to Query properly for the 
    // right interface before giving that to the graph object 
    IBaseFilter* pFilter = NULL; 
    hr = m_pFilter->QueryInterface(IID_IBaseFilter, (void**)&pFilter); 
    if (SUCCEEDED(hr))  
    { 
        hr = m_pGraph->AddFilter(pFilter, L"App Transform"); 
        pFilter->Release(); 
    } 

 
// Locate a filter within the graph by seArching (from renderers upstream) 
// looking for a specific interface on the filter 
HRESULT CAppGraphBuilder::FindFilterByInterface(REFIID riid, IBaseFilter** ppFilter) 

    *ppFilter = NULL; 
 
    IEnumfilters* pEnum; 
    HRESULT hr = m_pGraph->EnumFilters(&pEnum); 
    if (FAILED(hr))  
    { 
        return hr; 
    } 
 
    IBaseFilter* pFilter = NULL; 
    while (pEnum->Next(1, &pFilter, NULL) == S_OK)  
    { 
        // Check for required interface 
        IUnknown* pUnk; 
        HRESULT hrQuery = pFilter->QueryInterface(riid, (void**)&pUnk); 
        if (SUCCEEDED(hrQuery))  
        { 
            pUnk->Release(); 
            pEnum->Release(); 
            *ppFilter = pFilter; 
            return S_OK; 
        } 
        pFilter->Release(); 
    } 
    pEnum->Release(); 
 
    return E_FAIL; 

 
 
// Connect the filter pTransform upstream of pFilter by reconnecting pins. 
// Assumes that pTransform has only one input and one output, and 
// that pFilter has only one input. 
HRESULT CAppGraphBuilder::ConnectUpstreamOf(IBaseFilter* pFilter, IBaseFilter*pColor,IBaseFilter* pTransform) 

    IPin* pPinIn = InputPinOf(pFilter); 
    if (!pPinIn)  
    { 
        return E_FAIL; 
    } 
 
    // Get the peer output pin 
    IPin* pPinOut = NULL; 
    HRESULT hr = pPinIn->ConnectedTo(&pPinOut); 
    if (FAILED(hr))  
    { 
        pPinIn->Release(); 
        return hr; 
    } 
 
    // Disconnect the current connection 
    hr = m_pGraph->Disconnect(pPinOut); 
    if (SUCCEEDED(hr))  
    { 
        hr = m_pGraph->Disconnect(pPinIn); 
    } 
 
    // Insert pTransform filter by connecting its input pin and output pin 
    if (SUCCEEDED(hr))  
    { 
        IPin* pPinInCor = InputPinOf(pColor); 
        hr = m_pGraph->Connect(pPinOut, pPinInCor); 
        pPinInCor->Release(); 
    } 
    if (SUCCEEDED(hr))  
    { 
        IPin* pPinInXfm = InputPinOf(pTransform); 
        IPin* pPinOutCor = OutputPinOf(pColor); 
        hr = m_pGraph->Connect(pPinOutCor, pPinInXfm); 
        pPinInXfm->Release(); 
        pPinOutCor->Release(); 
    } 
    if (SUCCEEDED(hr))  
    { 
        IPin* pPinOutXfm = OutputPinOf(pTransform); 
        hr = m_pGraph->Connect(pPinOutXfm, pPinIn); 
        pPinOutXfm->Release(); 
    } 
     
    pPinIn->Release(); 
    pPinOut->Release(); 
    return hr; 

 
// Find the First pin of a specific direction on a given filter 
IPin* CAppGraphBuilder::GetPin(IBaseFilter* pFilter, PIN_DIRECTION dirRequest) 

    IPin * foundPin = NULL; 
 
    IEnumPins* pEnum = NULL; 
    HRESULT hr = pFilter->EnumPins(&pEnum); 
    if (SUCCEEDED(hr))  
    { 
        IPin* pPin = NULL; 
        while (!foundPin && pEnum->Next(1, &pPin, 0) == S_OK)  
        { 
            PIN_DIRECTION dir; 
            pPin->QueryDirection(&dir); 
            if (dir == dirRequest)  
            { 
                foundPin = pPin; 
            } 
            else 
            { 
                pPin->Release(); 
            } 
        } 
        pEnum->Release(); 
    } 
    return foundPin; 

 
// Follow the pin connections to return the filter that is  
// connected to the first input pin of pFilter 
HRESULT CAppGraphBuilder::NextUpstream(IBaseFilter* pFilter, IBaseFilter** ppNext) 

    IPin* pPin = InputPinOf(pFilter); 
    if (!pPin)  
    { 
        return E_FAIL; 
    } 
 
    // Get the peer output pin 
    IPin* pPinOut = NULL; 
    HRESULT hr = pPin->ConnectedTo(&pPinOut); 
    pPin->Release(); 
    if (FAILED(hr))  
    { 
        return hr; 
    } 
 
    PIN_INFO info; 
    pPinOut->QueryPinInfo(&info); 
    pPinOut->Release(); 
    *ppNext = info.pFilter; 
     
    return S_OK; 

 
 
 
//////////////////////// For GraphEdit Dubug purpose ///////////////////////////// 
void CAppGraphBuilder::AddToObjectTable(void) 

    IMoniker * pMoniker = 0; 
    IRunningObjectTable * objectTable = 0; 
    if (SUCCEEDED(GetRunningObjectTable(0, &objectTable)))  
    { 
        WCHAR wsz[256]; 
        wsprintfW(wsz, L"FilterGraph %08p pid %08x", (DWORD_PTR)m_pGraph, GetCurrentProcessId()); 
        HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker); 
        if (SUCCEEDED(hr))  
        { 
            hr = objectTable->Register(0, m_pGraph, pMoniker, &m_dwObjectTable); 
            pMoniker->Release(); 
        } 
        objectTable->Release(); 
    } 

 
void CAppGraphBuilder::RemoveFromObjectTable(void) 

    IRunningObjectTable * objectTable = 0; 
    if (SUCCEEDED(GetRunningObjectTable(0, &objectTable)))  
    { 
        objectTable->Revoke(m_dwObjectTable); 
        objectTable->Release(); 
        m_dwObjectTable = 0; 
    } 

调用:

[html] 
LPCWSTR wchFile=L"D://example.avi"; 
        m_Graph.BuildFromFile(wchFile); 
        m_Graph.MakeChild(GetSafeHwnd()); 
        m_Graph.Run(); 

视频捕获增加color space converter + Transform Filter


作者:luckyboy101
 

脚本宝典总结

以上是脚本宝典为你收集整理的视频捕获增加color space converter + Transform Filter全部内容,希望文章能够帮你解决视频捕获增加color space converter + Transform Filter所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。