DeinterlacerFilter.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小: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::CheckInputType(const CMediaType* mtIn)
  11. {
  12. BITMAPINFOHEADER bih;
  13. if(!ExtractBIH(mtIn, &bih) /*|| bih.biHeight <= 0*/ || bih.biHeight <= 288)
  14. return E_FAIL;
  15. return mtIn->subtype == MEDIASUBTYPE_YUY2 || mtIn->subtype == MEDIASUBTYPE_UYVY
  16. || mtIn->subtype == MEDIASUBTYPE_I420 || mtIn->subtype == MEDIASUBTYPE_YV12 || mtIn->subtype == MEDIASUBTYPE_IYUV 
  17. ? S_OK 
  18. : E_FAIL;
  19. }
  20. HRESULT CDeinterlacerFilter::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut)
  21. {
  22. return mtIn->subtype == mtOut->subtype ? S_OK : E_FAIL;
  23. }
  24. HRESULT CDeinterlacerFilter::Transform(IMediaSample* pIn, IMediaSample* pOut)
  25. {
  26. HRESULT hr;
  27. AM_MEDIA_TYPE* pmt = NULL;
  28. if(SUCCEEDED(pOut->GetMediaType(&pmt)) && pmt)
  29. {
  30. CMediaType mt = *pmt;
  31. m_pOutput->SetMediaType(&mt);
  32. DeleteMediaType(pmt);
  33. }
  34. BYTE* pDataIn = NULL;
  35. if(FAILED(pIn->GetPointer(&pDataIn)) || !pDataIn)
  36. return S_FALSE;
  37. BYTE* pDataOut = NULL;
  38. if(FAILED(hr = pOut->GetPointer(&pDataOut)) || !pDataOut)
  39. return hr;
  40. const CMediaType& mtIn = m_pInput->CurrentMediaType();
  41. const CMediaType& mtOut = m_pOutput->CurrentMediaType();
  42. BITMAPINFOHEADER bihIn, bihOut;
  43. ExtractBIH(&mtIn, &bihIn);
  44. ExtractBIH(&mtOut, &bihOut);
  45. bool fInputFlipped = bihIn.biHeight >= 0 && bihIn.biCompression <= 3;
  46. bool fOutputFlipped = bihOut.biHeight >= 0 && bihOut.biCompression <= 3;
  47. bool fFlip = fInputFlipped != fOutputFlipped;
  48. int bppIn = !(bihIn.biBitCount&7) ? bihIn.biBitCount : 8;
  49. int bppOut = !(bihOut.biBitCount&7) ? bihOut.biBitCount : 8;
  50. int pitchIn = bihIn.biWidth*bppIn>>3;
  51. int pitchOut = bihOut.biWidth*bppOut>>3;
  52. BYTE* pDataOut2 = pDataOut;
  53. if(fFlip) {pDataOut2 += pitchOut*(bihIn.biHeight-1); pitchOut = -pitchOut;}
  54. if(mtIn.subtype == MEDIASUBTYPE_YUY2 || mtIn.subtype == MEDIASUBTYPE_UYVY)
  55. {
  56. DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
  57. }
  58. else if(mtIn.subtype == MEDIASUBTYPE_I420 || mtIn.subtype == MEDIASUBTYPE_YV12 || mtIn.subtype == MEDIASUBTYPE_IYUV)
  59. {
  60. DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
  61. int sizeIn = bihIn.biHeight*pitchIn, sizeOut = abs(bihOut.biHeight)*pitchOut;
  62. pitchIn /= 2; pitchOut /= 2;
  63. bihIn.biHeight /= 2;
  64. pDataIn += sizeIn; pDataOut += sizeOut;
  65. DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
  66. pDataIn += sizeIn/4; pDataOut += sizeOut/4;
  67. DeinterlaceBlend(pDataOut, pDataIn, pitchIn, bihIn.biHeight, pitchOut, pitchIn);
  68. }
  69. return S_OK;
  70. }
  71. HRESULT CDeinterlacerFilter::DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties)
  72. {
  73. if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
  74. BITMAPINFOHEADER bih;
  75. ExtractBIH(&m_pOutput->CurrentMediaType(), &bih);
  76. pProperties->cBuffers = 1;
  77. pProperties->cbBuffer = bih.biSizeImage;
  78. pProperties->cbAlign = 1;
  79. pProperties->cbPrefix = 0;
  80. HRESULT hr;
  81. ALLOCATOR_PROPERTIES Actual;
  82.     if(FAILED(hr = pAllocator->SetProperties(pProperties, &Actual))) 
  83. return hr;
  84.     return pProperties->cBuffers > Actual.cBuffers || pProperties->cbBuffer > Actual.cbBuffer
  85. ? E_FAIL
  86. : NOERROR;
  87. }
  88. HRESULT CDeinterlacerFilter::GetMediaType(int iPosition, CMediaType* pmt)
  89. {
  90.     if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
  91. if(iPosition < 0) return E_INVALIDARG;
  92. if(iPosition > 0) return VFW_S_NO_MORE_ITEMS;
  93. *pmt = m_pInput->CurrentMediaType();
  94. CorrectMediaType(pmt);
  95. return S_OK;
  96. }