DeinterlacerFilter.cpp
上传用户:tangyu_668
上传日期:2014-02-27
资源大小:678k
文件大小:4k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include ".deinterlacerfilter.h"
  3. #include "....DSUtilMediaTypes.h"
  4. #include "......includemoreuuids.h"
  5. CDeinterlacerFilter::CDeinterlacerFilter(LPUNKNOWN punk, HRESULT* phr)
  6. : CTransformFilter(NAME("CDeinterlacerFilter"), punk, __uuidof(CDeinterlacerFilter))
  7. {
  8. if(phr) *phr = S_OK;
  9. }
  10. HRESULT CDeinterlacerFilter::CheckConnect(PIN_DIRECTION dir, IPin* pPin)
  11. {
  12. return GetCLSID(pPin) == __uuidof(*this) ? E_FAIL : S_OK;
  13. }
  14. HRESULT CDeinterlacerFilter::CheckInputType(const CMediaType* mtIn)
  15. {
  16. BITMAPINFOHEADER bih;
  17. if(!ExtractBIH(mtIn, &bih) /*|| bih.biHeight <= 0*/ || bih.biHeight <= 288)
  18. return E_FAIL;
  19. return mtIn->subtype == MEDIASUBTYPE_YUY2 || mtIn->subtype == MEDIASUBTYPE_UYVY
  20. || mtIn->subtype == MEDIASUBTYPE_I420 || mtIn->subtype == MEDIASUBTYPE_YV12 || mtIn->subtype == MEDIASUBTYPE_IYUV 
  21. ? S_OK 
  22. : E_FAIL;
  23. }
  24. HRESULT CDeinterlacerFilter::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut)
  25. {
  26. return mtIn->subtype == mtOut->subtype ? S_OK : E_FAIL;
  27. }
  28. HRESULT CDeinterlacerFilter::Transform(IMediaSample* pIn, IMediaSample* pOut)
  29. {
  30. HRESULT hr;
  31. AM_MEDIA_TYPE* pmt = NULL;
  32. if(SUCCEEDED(pOut->GetMediaType(&pmt)) && pmt)
  33. {
  34. CMediaType mt = *pmt;
  35. m_pOutput->SetMediaType(&mt);
  36. DeleteMediaType(pmt);
  37. }
  38. BYTE* pDataIn = NULL;
  39. if(FAILED(pIn->GetPointer(&pDataIn)) || !pDataIn)
  40. return S_FALSE;
  41. BYTE* pDataOut = NULL;
  42. if(FAILED(hr = pOut->GetPointer(&pDataOut)) || !pDataOut)
  43. return hr;
  44. const CMediaType& mtIn = m_pInput->CurrentMediaType();
  45. const CMediaType& mtOut = m_pOutput->CurrentMediaType();
  46. BITMAPINFOHEADER bihIn, bihOut;
  47. ExtractBIH(&mtIn, &bihIn);
  48. ExtractBIH(&mtOut, &bihOut);
  49. bool fInputFlipped = bihIn.biHeight >= 0 && bihIn.biCompression <= 3;
  50. bool fOutputFlipped = bihOut.biHeight >= 0 && bihOut.biCompression <= 3;
  51. bool fFlip = fInputFlipped != fOutputFlipped;
  52. int bppIn = !(bihIn.biBitCount&7) ? bihIn.biBitCount : 8;
  53. int bppOut = !(bihOut.biBitCount&7) ? bihOut.biBitCount : 8;
  54. int pitchIn = bihIn.biWidth*bppIn>>3;
  55. int pitchOut = bihOut.biWidth*bppOut>>3;
  56. BYTE* pDataOut2 = pDataOut;
  57. if(fFlip) {pDataOut2 += pitchOut*(bihIn.biHeight-1); pitchOut = -pitchOut;}
  58. if(mtIn.subtype == MEDIASUBTYPE_YUY2 || mtIn.subtype == MEDIASUBTYPE_UYVY)
  59. {
  60. DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
  61. }
  62. else if(mtIn.subtype == MEDIASUBTYPE_I420 || mtIn.subtype == MEDIASUBTYPE_YV12 || mtIn.subtype == MEDIASUBTYPE_IYUV)
  63. {
  64. DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
  65. int sizeIn = bihIn.biHeight*pitchIn, sizeOut = abs(bihOut.biHeight)*pitchOut;
  66. pitchIn /= 2; pitchOut /= 2;
  67. bihIn.biHeight /= 2;
  68. pDataIn += sizeIn; pDataOut += sizeOut;
  69. DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
  70. pDataIn += sizeIn/4; pDataOut += sizeOut/4;
  71. DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
  72. }
  73. return S_OK;
  74. }
  75. HRESULT CDeinterlacerFilter::DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties)
  76. {
  77. if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
  78. BITMAPINFOHEADER bih;
  79. ExtractBIH(&m_pOutput->CurrentMediaType(), &bih);
  80. pProperties->cBuffers = 1;
  81. pProperties->cbBuffer = bih.biSizeImage;
  82. pProperties->cbAlign = 1;
  83. pProperties->cbPrefix = 0;
  84. HRESULT hr;
  85. ALLOCATOR_PROPERTIES Actual;
  86.     if(FAILED(hr = pAllocator->SetProperties(pProperties, &Actual))) 
  87. return hr;
  88.     return pProperties->cBuffers > Actual.cBuffers || pProperties->cbBuffer > Actual.cbBuffer
  89. ? E_FAIL
  90. : NOERROR;
  91. }
  92. HRESULT CDeinterlacerFilter::GetMediaType(int iPosition, CMediaType* pmt)
  93. {
  94.     if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
  95. if(iPosition < 0) return E_INVALIDARG;
  96. if(iPosition > 0) return VFW_S_NO_MORE_ITEMS;
  97. *pmt = m_pInput->CurrentMediaType();
  98. CorrectMediaType(pmt);
  99. return S_OK;
  100. }