X64 transport [Part 5] (Update plugins.cpp)
[xy_vsfilter.git] / src / apps / mplayerc / DeinterlacerFilter.cpp
blob972b071aa32c4a73a7eba83b1999455af0a88a31
1 #include "stdafx.h"
2 #include ".\deinterlacerfilter.h"
3 #include "..\..\DSUtil\MediaTypes.h"
4 #include "..\..\..\include\moreuuids.h"
6 CDeinterlacerFilter::CDeinterlacerFilter(LPUNKNOWN punk, HRESULT* phr)
7 : CTransformFilter(NAME("CDeinterlacerFilter"), punk, __uuidof(CDeinterlacerFilter))
9 if(phr) *phr = S_OK;
12 HRESULT CDeinterlacerFilter::CheckConnect(PIN_DIRECTION dir, IPin* pPin)
14 return GetCLSID(pPin) == __uuidof(*this) ? E_FAIL : S_OK;
17 HRESULT CDeinterlacerFilter::CheckInputType(const CMediaType* mtIn)
19 BITMAPINFOHEADER bih;
20 if(!ExtractBIH(mtIn, &bih) /*|| bih.biHeight <= 0*/ || bih.biHeight <= 288)
21 return E_FAIL;
23 return mtIn->subtype == MEDIASUBTYPE_YUY2 || mtIn->subtype == MEDIASUBTYPE_UYVY
24 || mtIn->subtype == MEDIASUBTYPE_I420 || mtIn->subtype == MEDIASUBTYPE_YV12 || mtIn->subtype == MEDIASUBTYPE_IYUV
25 ? S_OK
26 : E_FAIL;
29 HRESULT CDeinterlacerFilter::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut)
31 return mtIn->subtype == mtOut->subtype ? S_OK : E_FAIL;
34 HRESULT CDeinterlacerFilter::Transform(IMediaSample* pIn, IMediaSample* pOut)
36 HRESULT hr;
38 AM_MEDIA_TYPE* pmt = NULL;
39 if(SUCCEEDED(pOut->GetMediaType(&pmt)) && pmt)
41 CMediaType mt = *pmt;
42 m_pOutput->SetMediaType(&mt);
43 DeleteMediaType(pmt);
46 BYTE* pDataIn = NULL;
47 if(FAILED(pIn->GetPointer(&pDataIn)) || !pDataIn)
48 return S_FALSE;
50 BYTE* pDataOut = NULL;
51 if(FAILED(hr = pOut->GetPointer(&pDataOut)) || !pDataOut)
52 return hr;
54 const CMediaType& mtIn = m_pInput->CurrentMediaType();
55 const CMediaType& mtOut = m_pOutput->CurrentMediaType();
57 BITMAPINFOHEADER bihIn, bihOut;
58 ExtractBIH(&mtIn, &bihIn);
59 ExtractBIH(&mtOut, &bihOut);
61 bool fInputFlipped = bihIn.biHeight >= 0 && bihIn.biCompression <= 3;
62 bool fOutputFlipped = bihOut.biHeight >= 0 && bihOut.biCompression <= 3;
63 bool fFlip = fInputFlipped != fOutputFlipped;
65 int bppIn = !(bihIn.biBitCount&7) ? bihIn.biBitCount : 8;
66 int bppOut = !(bihOut.biBitCount&7) ? bihOut.biBitCount : 8;
67 int pitchIn = bihIn.biWidth*bppIn>>3;
68 int pitchOut = bihOut.biWidth*bppOut>>3;
69 BYTE* pDataOut2 = pDataOut;
70 if(fFlip) {pDataOut2 += pitchOut*(bihIn.biHeight-1); pitchOut = -pitchOut;}
72 if(mtIn.subtype == MEDIASUBTYPE_YUY2 || mtIn.subtype == MEDIASUBTYPE_UYVY)
74 DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
76 else if(mtIn.subtype == MEDIASUBTYPE_I420 || mtIn.subtype == MEDIASUBTYPE_YV12 || mtIn.subtype == MEDIASUBTYPE_IYUV)
78 DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
80 int sizeIn = bihIn.biHeight*pitchIn, sizeOut = abs(bihOut.biHeight)*pitchOut;
81 pitchIn /= 2; pitchOut /= 2;
82 bihIn.biHeight /= 2;
83 pDataIn += sizeIn; pDataOut += sizeOut;
84 DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
86 pDataIn += sizeIn/4; pDataOut += sizeOut/4;
87 DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
90 return S_OK;
93 HRESULT CDeinterlacerFilter::DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties)
95 if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
97 BITMAPINFOHEADER bih;
98 ExtractBIH(&m_pOutput->CurrentMediaType(), &bih);
100 pProperties->cBuffers = 1;
101 pProperties->cbBuffer = bih.biSizeImage;
102 pProperties->cbAlign = 1;
103 pProperties->cbPrefix = 0;
105 HRESULT hr;
106 ALLOCATOR_PROPERTIES Actual;
107 if(FAILED(hr = pAllocator->SetProperties(pProperties, &Actual)))
108 return hr;
110 return pProperties->cBuffers > Actual.cBuffers || pProperties->cbBuffer > Actual.cbBuffer
111 ? E_FAIL
112 : NOERROR;
115 HRESULT CDeinterlacerFilter::GetMediaType(int iPosition, CMediaType* pmt)
117 if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
118 if(iPosition < 0) return E_INVALIDARG;
119 if(iPosition > 0) return VFW_S_NO_MORE_ITEMS;
120 *pmt = m_pInput->CurrentMediaType();
121 CorrectMediaType(pmt);
122 return S_OK;