📄 t_root.cpp
字号:
#include <windows.h>
#include <streams.h>
#include <initguid.h>
#if (1100 > _MSC_VER)
#include <olectlid.h>
#else
#include <olectl.h>
#endif
#include "i[!output PROJECT_NAME].h"
#include "[!output PROJECT_NAME]Prop.h"
#include "[!output PROJECT_NAME].h"
#include "resource.h"
#include <assert.h>
#include <stdio.h>
#define TRANSFORM_NAME L"[!output PROJECT_NAME] Filter"
// returns width of row rounded up to modulo 4
int RowWidth(int w) {
if (w % 4)
w += 4 - w % 4;
return w;
}
// Setup information
const AMOVIESETUP_MEDIATYPE sudPinTypes =
{
&MEDIATYPE_Video, // Major type
&MEDIASUBTYPE_NULL // Minor type
};
const AMOVIESETUP_PIN sudpPins[] =
{
{ L"Input", // Pins string name
FALSE, // Is it rendered
FALSE, // Is it an output
FALSE, // Are we allowed none
FALSE, // And allowed many
&CLSID_NULL, // Connects to filter
NULL, // Connects to pin
1, // Number of types
&sudPinTypes // Pin information
},
{ L"Output", // Pins string name
FALSE, // Is it rendered
TRUE, // Is it an output
FALSE, // Are we allowed none
FALSE, // And allowed many
&CLSID_NULL, // Connects to filter
NULL, // Connects to pin
1, // Number of types
&sudPinTypes // Pin information
}
};
const AMOVIESETUP_FILTER sud[!output PROJECT_NAME] =
{
&CLSID_[!output PROJECT_NAME], // Filter CLSID
TRANSFORM_NAME, // String name
MERIT_DO_NOT_USE, // Filter merit
2, // Number of pins
sudpPins // Pin information
};
// List of class IDs and creator functions for the class factory. This
// provides the link between the OLE entry point in the DLL and an object
// being created. The class factory will call the static CreateInstance
CFactoryTemplate g_Templates[] = {
{ TRANSFORM_NAME
, &CLSID_[!output PROJECT_NAME]
, C[!output PROJECT_NAME]::CreateInstance
, NULL
, &sud[!output PROJECT_NAME] }
,
{ TRANSFORM_NAME L" Properties"
, &CLSID_[!output PROJECT_NAME]PropertyPage
, C[!output PROJECT_NAME]Properties::CreateInstance }
};
int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
//
// DllRegisterServer
//
// Handles sample registry and unregistry
//
STDAPI DllRegisterServer()
{
return AMovieDllRegisterServer2( TRUE );
}
//
// DllUnregisterServer
//
STDAPI DllUnregisterServer()
{
return AMovieDllRegisterServer2( FALSE );
}
//
// Constructor
//
C[!output PROJECT_NAME]::C[!output PROJECT_NAME](TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr) :
CTransformFilter(tszName, punk, CLSID_[!output PROJECT_NAME]),
CPersistStream(punk, phr)
{
// TODO: read parameters from profile
m_[!output PROJECT_NAME]Parameters.param1 = GetProfileInt("[!output PROJECT_NAME]", "param1", 0);
m_[!output PROJECT_NAME]Parameters.param2 = GetProfileInt("[!output PROJECT_NAME]", "param2", 0);
}
//
// WriteProfileInt
//
// Writes an integer to the profile.
//
void WriteProfileInt(char *section, char *key, int i)
{
char str[80];
sprintf(str, "%d", i);
WriteProfileString(section, key, str);
}
//
// ~C[!output PROJECT_NAME]
//
C[!output PROJECT_NAME]::~C[!output PROJECT_NAME]()
{
// TODO: write parameters from profile
WriteProfileInt("[!output PROJECT_NAME]", "param1", m_[!output PROJECT_NAME]Parameters.param1);
WriteProfileInt("[!output PROJECT_NAME]", "param2", m_[!output PROJECT_NAME]Parameters.param2);
}
//
// CreateInstance
//
// Provide the way for COM to create a [!output PROJECT_NAME] object
//
CUnknown *C[!output PROJECT_NAME]::CreateInstance(LPUNKNOWN punk, HRESULT *phr)
{
C[!output PROJECT_NAME] *pNewObject = new C[!output PROJECT_NAME](NAME("[!output PROJECT_NAME]"), punk, phr);
if (pNewObject == NULL) {
*phr = E_OUTOFMEMORY;
}
return pNewObject;
}
//
// NonDelegatingQueryInterface
//
// Reveals I[!output PROJECT_NAME] and ISpecifyPropertyPages
//
STDMETHODIMP C[!output PROJECT_NAME]::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
CheckPointer(ppv,E_POINTER);
if (riid == IID_I[!output PROJECT_NAME]) {
return GetInterface((I[!output PROJECT_NAME] *) this, ppv);
} else if (riid == IID_ISpecifyPropertyPages) {
return GetInterface((ISpecifyPropertyPages *) this, ppv);
} else {
return CTransformFilter::NonDelegatingQueryInterface(riid, ppv);
}
}
//
// Transform
//
// Transforms the input and saves results in the the output
//
HRESULT C[!output PROJECT_NAME]::Transform(IMediaSample *pIn, IMediaSample *pOut)
{
// input
AM_MEDIA_TYPE* pTypeIn = &m_pInput->CurrentMediaType();
VIDEOINFOHEADER *pVihIn = (VIDEOINFOHEADER *)pTypeIn->pbFormat;
int inWidth = pVihIn->bmiHeader.biWidth;
int inHeight = pVihIn->bmiHeader.biHeight;
int inBytesPerPixel = pVihIn->bmiHeader.biBitCount / 8;
unsigned char *pSrc = 0;
pIn->GetPointer((unsigned char **)&pSrc);
assert(pSrc);
// output
AM_MEDIA_TYPE *pTypeOut = &m_pOutput->CurrentMediaType();
VIDEOINFOHEADER *pVihOut = (VIDEOINFOHEADER *)pTypeOut->pbFormat;
int outBytesPerPixel = pVihOut->bmiHeader.biBitCount / 8;
unsigned char *pDst = 0;
pOut->GetPointer((unsigned char **)&pDst);
assert(pDst);
// TODO: insert procesing code here
// for now, just make a copy of the input
HRESULT hr = Copy(pIn, pOut);
if (hr != S_OK)
return hr;
return NOERROR;
}
//
// CheckInputType
//
// Check the input type is OK - return an error otherwise
//
HRESULT C[!output PROJECT_NAME]::CheckInputType(const CMediaType *mtIn)
{
// check this is a VIDEOINFOHEADER type
if (*mtIn->FormatType() != FORMAT_VideoInfo) {
return E_INVALIDARG;
}
// Can we transform this type
if (CanPerformTransform(mtIn)) {
return NOERROR;
}
return E_FAIL;
}
//
// Checktransform
//
// Check a transform can be done between these formats
//
HRESULT C[!output PROJECT_NAME]::CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut)
{
if (CanPerformTransform(mtIn)) {
if (*mtOut->Subtype() == *mtIn->Subtype())
return S_OK;
else
return VFW_E_TYPE_NOT_ACCEPTED;
}
return VFW_E_TYPE_NOT_ACCEPTED;
}
//
// DecideBufferSize
//
// Tell the output pin's allocator what size buffers we
// require. Can only do this when the input is connected
//
HRESULT C[!output PROJECT_NAME]::DecideBufferSize(IMemAllocator *pAlloc,ALLOCATOR_PROPERTIES *pProperties)
{
// Is the input pin connected
if (m_pInput->IsConnected() == FALSE) {
return E_UNEXPECTED;
}
ASSERT(pAlloc);
ASSERT(pProperties);
HRESULT hr = NOERROR;
// get input dimensions
CMediaType inMediaType = m_pInput->CurrentMediaType();
VIDEOINFOHEADER *vihIn = (VIDEOINFOHEADER *)inMediaType.Format();
pProperties->cBuffers = 1;
pProperties->cbBuffer = GetBitmapSize(&vihIn->bmiHeader);
ASSERT(pProperties->cbBuffer);
// 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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -