⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 t_root.cpp

📁 Multimedia Programming
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#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 + -