视频捕获增加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核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: 视频捕获增加color space converter + Transform Filter
本文地址: https://pptw.com/jishu/586987.html