diff options
author | Casimir666 <casimir666@users.sourceforge.net> | 2006-06-25 01:37:43 +0400 |
---|---|---|
committer | Casimir666 <casimir666@users.sourceforge.net> | 2006-06-25 01:37:43 +0400 |
commit | 0868305e78da2b0742c2ce349efa041d5622ae21 (patch) | |
tree | 663fd93132c7927910ba7c13188d6332b2e3e5b2 /src/apps/mplayerc/DeinterlacerFilter.cpp | |
parent | 43c8656956a0460fc4551e3ea7a39b9f3094a3e3 (diff) |
git-svn-id: https://mpc-hc.svn.sourceforge.net/svnroot/mpc-hc/trunk@14 10f7b99b-c216-0410-bff0-8a66a9350fd8
Diffstat (limited to 'src/apps/mplayerc/DeinterlacerFilter.cpp')
-rw-r--r-- | src/apps/mplayerc/DeinterlacerFilter.cpp | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/src/apps/mplayerc/DeinterlacerFilter.cpp b/src/apps/mplayerc/DeinterlacerFilter.cpp new file mode 100644 index 000000000..972b071aa --- /dev/null +++ b/src/apps/mplayerc/DeinterlacerFilter.cpp @@ -0,0 +1,123 @@ +#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;
+}
\ No newline at end of file |