Show DeinterlacerFilter.cpp syntax highlighted
#include "stdafx.h"
#include ".\deinterlacerfilter.h"
#include "..\..\DSUtil\MediaTypes.h"
#include "..\..\..\include\moreuuids.h"
CDeinterlacerFilter::CDeinterlacerFilter(LPUNKNOWN punk, HRESULT* phr)
: CTransformFilter(NAME("CDeinterlacerFilter"), punk, __uuidof(CDeinterlacerFilter))
{
if(phr) *phr = S_OK;
}
HRESULT CDeinterlacerFilter::CheckConnect(PIN_DIRECTION dir, IPin* pPin)
{
return GetCLSID(pPin) == __uuidof(*this) ? E_FAIL : S_OK;
}
HRESULT CDeinterlacerFilter::CheckInputType(const CMediaType* mtIn)
{
BITMAPINFOHEADER bih;
if(!ExtractBIH(mtIn, &bih) /*|| bih.biHeight <= 0*/ || bih.biHeight <= 288)
return E_FAIL;
return mtIn->subtype == MEDIASUBTYPE_YUY2 || mtIn->subtype == MEDIASUBTYPE_UYVY
|| mtIn->subtype == MEDIASUBTYPE_I420 || mtIn->subtype == MEDIASUBTYPE_YV12 || mtIn->subtype == MEDIASUBTYPE_IYUV
? S_OK
: E_FAIL;
}
HRESULT CDeinterlacerFilter::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut)
{
return mtIn->subtype == mtOut->subtype ? S_OK : E_FAIL;
}
HRESULT CDeinterlacerFilter::Transform(IMediaSample* pIn, IMediaSample* pOut)
{
HRESULT hr;
AM_MEDIA_TYPE* pmt = NULL;
if(SUCCEEDED(pOut->GetMediaType(&pmt)) && pmt)
{
CMediaType mt = *pmt;
m_pOutput->SetMediaType(&mt);
DeleteMediaType(pmt);
}
BYTE* pDataIn = NULL;
if(FAILED(pIn->GetPointer(&pDataIn)) || !pDataIn)
return S_FALSE;
BYTE* pDataOut = NULL;
if(FAILED(hr = pOut->GetPointer(&pDataOut)) || !pDataOut)
return hr;
const CMediaType& mtIn = m_pInput->CurrentMediaType();
const CMediaType& mtOut = m_pOutput->CurrentMediaType();
BITMAPINFOHEADER bihIn, bihOut;
ExtractBIH(&mtIn, &bihIn);
ExtractBIH(&mtOut, &bihOut);
bool fInputFlipped = bihIn.biHeight >= 0 && bihIn.biCompression <= 3;
bool fOutputFlipped = bihOut.biHeight >= 0 && bihOut.biCompression <= 3;
bool fFlip = fInputFlipped != fOutputFlipped;
int bppIn = !(bihIn.biBitCount&7) ? bihIn.biBitCount : 8;
int bppOut = !(bihOut.biBitCount&7) ? bihOut.biBitCount : 8;
int pitchIn = bihIn.biWidth*bppIn>>3;
int pitchOut = bihOut.biWidth*bppOut>>3;
BYTE* pDataOut2 = pDataOut;
if(fFlip) {pDataOut2 += pitchOut*(bihIn.biHeight-1); pitchOut = -pitchOut;}
if(mtIn.subtype == MEDIASUBTYPE_YUY2 || mtIn.subtype == MEDIASUBTYPE_UYVY)
{
DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
}
else if(mtIn.subtype == MEDIASUBTYPE_I420 || mtIn.subtype == MEDIASUBTYPE_YV12 || mtIn.subtype == MEDIASUBTYPE_IYUV)
{
DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
int sizeIn = bihIn.biHeight*pitchIn, sizeOut = abs(bihOut.biHeight)*pitchOut;
pitchIn /= 2; pitchOut /= 2;
bihIn.biHeight /= 2;
pDataIn += sizeIn; pDataOut += sizeOut;
DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
pDataIn += sizeIn/4; pDataOut += sizeOut/4;
DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
}
return S_OK;
}
HRESULT CDeinterlacerFilter::DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties)
{
if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
BITMAPINFOHEADER bih;
ExtractBIH(&m_pOutput->CurrentMediaType(), &bih);
pProperties->cBuffers = 1;
pProperties->cbBuffer = bih.biSizeImage;
pProperties->cbAlign = 1;
pProperties->cbPrefix = 0;
HRESULT hr;
ALLOCATOR_PROPERTIES Actual;
if(FAILED(hr = pAllocator->SetProperties(pProperties, &Actual)))
return hr;
return pProperties->cBuffers > Actual.cBuffers || pProperties->cbBuffer > Actual.cbBuffer
? E_FAIL
: NOERROR;
}
HRESULT CDeinterlacerFilter::GetMediaType(int iPosition, CMediaType* pmt)
{
if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
if(iPosition < 0) return E_INVALIDARG;
if(iPosition > 0) return VFW_S_NO_MORE_ITEMS;
*pmt = m_pInput->CurrentMediaType();
CorrectMediaType(pmt);
return S_OK;
}
See more files for this project here