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 }

Generated on Tue Dec 13 14:46:48 2005 for guliverkli by  doxygen 1.4.5