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
))
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
)
20 if(!ExtractBIH(mtIn
, &bih
) /*|| bih.biHeight <= 0*/ || bih
.biHeight
<= 288)
23 return mtIn
->subtype
== MEDIASUBTYPE_YUY2
|| mtIn
->subtype
== MEDIASUBTYPE_UYVY
24 || mtIn
->subtype
== MEDIASUBTYPE_I420
|| mtIn
->subtype
== MEDIASUBTYPE_YV12
|| mtIn
->subtype
== MEDIASUBTYPE_IYUV
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
)
38 AM_MEDIA_TYPE
* pmt
= NULL
;
39 if(SUCCEEDED(pOut
->GetMediaType(&pmt
)) && pmt
)
42 m_pOutput
->SetMediaType(&mt
);
47 if(FAILED(pIn
->GetPointer(&pDataIn
)) || !pDataIn
)
50 BYTE
* pDataOut
= NULL
;
51 if(FAILED(hr
= pOut
->GetPointer(&pDataOut
)) || !pDataOut
)
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;
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
);
93 HRESULT
CDeinterlacerFilter::DecideBufferSize(IMemAllocator
* pAllocator
, ALLOCATOR_PROPERTIES
* pProperties
)
95 if(m_pInput
->IsConnected() == FALSE
) return E_UNEXPECTED
;
98 ExtractBIH(&m_pOutput
->CurrentMediaType(), &bih
);
100 pProperties
->cBuffers
= 1;
101 pProperties
->cbBuffer
= bih
.biSizeImage
;
102 pProperties
->cbAlign
= 1;
103 pProperties
->cbPrefix
= 0;
106 ALLOCATOR_PROPERTIES Actual
;
107 if(FAILED(hr
= pAllocator
->SetProperties(pProperties
, &Actual
)))
110 return pProperties
->cBuffers
> Actual
.cBuffers
|| pProperties
->cbBuffer
> Actual
.cbBuffer
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
);