首页前端开发HTML视频捕获增加color space converter + Transform Filter

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

时间2024-01-26 16:15:03发布访客分类HTML浏览316
导读:收集整理的这篇文章主要介绍了视频捕获增加color space converter + Transform Filter,觉得挺不错的,现在分享给大家,也给大家做个参考。 其它不解释,贴是代码: IPFilter.h [htML] // ...
收集整理的这篇文章主要介绍了视频捕获增加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_castvoid**> (& 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_castvoid**> (& 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();  


作者:luckyboy101
 

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

APIClassconstHTMLletMappptPropthis

若转载请注明出处: 视频捕获增加color space converter + Transform Filter
本文地址: https://pptw.com/jishu/586987.html
兼容HTML5placeholder属性 html 5画圆

游客 回复需填写必要信息