- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# DeinterlacerFilter.cpp

    00001 #include "stdafx.h"
    00002 #include ".\deinterlacerfilter.h"
    00003 #include "..\..\DSUtil\MediaTypes.h"
    00004 #include "..\..\..\include\moreuuids.h"
    00005
    00006 CDeinterlacerFilter::CDeinterlacerFilter(LPUNKNOWN punk, HRESULT* phr)
    00007         : CTransformFilter(NAME("CDeinterlacerFilter"), punk, __uuidof(CDeinterlacerFilter))
    00008 {
    00009         if(phr) *phr = S_OK;
    00010 }
    00011
    00012 HRESULT CDeinterlacerFilter::CheckInputType(const CMediaType* mtIn)
    00013 {
    00014         BITMAPINFOHEADER bih;
    00015         if(!ExtractBIH(mtIn, &bih) /*|| bih.biHeight <= 0*/ || bih.biHeight <= 288)
    00016                 return E_FAIL;
    00017
    00018         return mtIn->subtype == MEDIASUBTYPE_YUY2 || mtIn->subtype == MEDIASUBTYPE_UYVY
    00019                 || mtIn->subtype == MEDIASUBTYPE_I420 || mtIn->subtype == MEDIASUBTYPE_YV12 || mtIn->subtype == MEDIASUBTYPE_IYUV
    00020                 ? S_OK
    00021                 : E_FAIL;
    00022 }
    00023
    00024 HRESULT CDeinterlacerFilter::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut)
    00025 {
    00026         return mtIn->subtype == mtOut->subtype ? S_OK : E_FAIL;
    00027 }
    00028
    00029 HRESULT CDeinterlacerFilter::Transform(IMediaSample* pIn, IMediaSample* pOut)
    00030 {
    00031         HRESULT hr;
    00032
    00033         AM_MEDIA_TYPE* pmt = NULL;
    00034         if(SUCCEEDED(pOut->GetMediaType(&pmt)) && pmt)
    00035         {
    00036                 CMediaType mt = *pmt;
    00037                 m_pOutput->SetMediaType(&mt);
    00038                 DeleteMediaType(pmt);
    00039         }
    00040
    00041         BYTE* pDataIn = NULL;
    00042         if(FAILED(pIn->GetPointer(&pDataIn)) || !pDataIn)
    00043                 return S_FALSE;
    00044
    00045         BYTE* pDataOut = NULL;
    00046         if(FAILED(hr = pOut->GetPointer(&pDataOut)) || !pDataOut)
    00047                 return hr;
    00048
    00049         const CMediaType& mtIn = m_pInput->CurrentMediaType();
    00050         const CMediaType& mtOut = m_pOutput->CurrentMediaType();
    00051
    00052         BITMAPINFOHEADER bihIn, bihOut;
    00053         ExtractBIH(&mtIn, &bihIn);
    00054         ExtractBIH(&mtOut, &bihOut);
    00055
    00056         bool fInputFlipped = bihIn.biHeight >= 0 && bihIn.biCompression <= 3;
    00057         bool fOutputFlipped = bihOut.biHeight >= 0 && bihOut.biCompression <= 3;
    00058         bool fFlip = fInputFlipped != fOutputFlipped;
    00059
    00060         int bppIn = !(bihIn.biBitCount&7) ? bihIn.biBitCount : 8;
    00061         int bppOut = !(bihOut.biBitCount&7) ? bihOut.biBitCount : 8;
    00062         int pitchIn = bihIn.biWidth*bppIn>>3;
    00063         int pitchOut = bihOut.biWidth*bppOut>>3;
    00064         BYTE* pDataOut2 = pDataOut;
    00065         if(fFlip) {pDataOut2 += pitchOut*(bihIn.biHeight-1); pitchOut = -pitchOut;}
    00066
    00067         if(mtIn.subtype == MEDIASUBTYPE_YUY2 || mtIn.subtype == MEDIASUBTYPE_UYVY)
    00068         {
    00069                 DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
    00070         }
    00071         else if(mtIn.subtype == MEDIASUBTYPE_I420 || mtIn.subtype == MEDIASUBTYPE_YV12 || mtIn.subtype == MEDIASUBTYPE_IYUV)
    00072         {
    00073                 DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
    00074
    00075                 int sizeIn = bihIn.biHeight*pitchIn, sizeOut = abs(bihOut.biHeight)*pitchOut;
    00076                 pitchIn /= 2; pitchOut /= 2;
    00077                 bihIn.biHeight /= 2;
    00078                 pDataIn += sizeIn; pDataOut += sizeOut;
    00079                 DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
    00080
    00081                 pDataIn += sizeIn/4; pDataOut += sizeOut/4;
    00082                 DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
    00083         }
    00084
    00085         return S_OK;
    00086 }
    00087
    00088 HRESULT CDeinterlacerFilter::DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties)
    00089 {
    00090         if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
    00091
    00092         BITMAPINFOHEADER bih;
    00093         ExtractBIH(&m_pOutput->CurrentMediaType(), &bih);
    00094
    00095         pProperties->cBuffers = 1;
    00096         pProperties->cbBuffer = bih.biSizeImage;
    00097         pProperties->cbAlign = 1;
    00098         pProperties->cbPrefix = 0;
    00099
    00100         HRESULT hr;
    00101         ALLOCATOR_PROPERTIES Actual;
    00102     if(FAILED(hr = pAllocator->SetProperties(pProperties, &Actual)))
    00103                 return hr;
    00104
    00105     return pProperties->cBuffers > Actual.cBuffers || pProperties->cbBuffer > Actual.cbBuffer
    00106                 ? E_FAIL
    00107                 : NOERROR;
    00108 }
    00109
    00110 HRESULT CDeinterlacerFilter::GetMediaType(int iPosition, CMediaType* pmt)
    00111 {
    00112     if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
    00113         if(iPosition < 0) return E_INVALIDARG;
    00114         if(iPosition > 0) return VFW_S_NO_MORE_ITEMS;
    00115         *pmt = m_pInput->CurrentMediaType();
    00116         CorrectMediaType(pmt);
    00117         return S_OK;
    00118 }