DSSampleGrabber.cxx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #if defined(_WIN32_WCE)
  2. #include <ddraw.h>
  3. #include <internals/wince/DSSampleGrabber.h>
  4. #include <initguid.h>
  5. // {38589364-71FD-4641-B426-E443DB023568}
  6. TDSHOW_DEFINE_GUID(CLSID_SampleGrabber,
  7. 0x38589364, 0x71fd, 0x4641, 0xb4, 0x26, 0xe4, 0x43, 0xdb, 0x2, 0x35, 0x68);
  8. #define RGB565_MASK_RED 0xF800
  9. #define RGB565_MASK_GREEN 0x07E0
  10. #define RGB565_MASK_BLUE 0x001F
  11. DSSampleGrabber::DSSampleGrabber(TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr)
  12. :CTransInPlaceFilter (tszName, punk, CLSID_SampleGrabber, phr)
  13. {
  14. #define FPS_INPUT 30
  15. #define FPS_OUTPUT 5
  16. this->m_rtFrameLength = (10000000)/FPS_OUTPUT;
  17. this->m_inputFps = FPS_INPUT;
  18. this->m_outputFps = FPS_OUTPUT;
  19. this->m_iFrameNumber = 0;
  20. this->m_progress = 0;
  21. this->m_bProcessFrame = true;
  22. this->callback = NULL;
  23. this->m_rgb24 = NULL;
  24. m_cRef = 0;
  25. }
  26. DSSampleGrabber::~DSSampleGrabber()
  27. {
  28. this->callback = NULL;
  29. if(this->m_rgb24) {
  30. delete[]this->m_rgb24;
  31. this->m_rgb24 = NULL;
  32. }
  33. }
  34. HRESULT DSSampleGrabber::SetFps(int inputFps, int outputFps)
  35. {
  36. if (inputFps <= 0 || outputFps <= 0) {
  37. return E_FAIL;
  38. }
  39. // Stop prcessing
  40. this->m_bProcessFrame = false;
  41. if (inputFps < outputFps) {
  42. this->m_inputFps = this->m_outputFps = inputFps;
  43. }
  44. else {
  45. this->m_outputFps = outputFps;
  46. this->m_inputFps = inputFps;
  47. }
  48. // Restart processing
  49. this->m_iFrameNumber = 0;
  50. this->m_progress = 0;
  51. this->m_bProcessFrame = true;
  52. return S_OK;
  53. }
  54. HRESULT DSSampleGrabber::Transform(IMediaSample *pSample)
  55. {
  56. BYTE *pData = NULL;
  57. HRESULT hr = S_OK;
  58. HRESULT ret = S_FALSE;
  59. if (!this->m_bProcessFrame) {
  60. return S_FALSE;
  61. }
  62. // Get pointer to the video buffer data
  63. if ( FAILED(pSample->GetPointer(&pData)) ) {
  64. ret = E_FAIL;
  65. goto bail;
  66. }
  67. pSample->SetTime(NULL, NULL);
  68. // Drop frame?
  69. if (this->m_iFrameNumber == 0) {
  70. ret = S_OK;
  71. }
  72. else if (this->m_progress >= this->m_inputFps) {
  73. this->m_progress -= this->m_inputFps;
  74. ret = S_OK;
  75. }
  76. // Mark frame as accepted
  77. if (ret == S_OK) {
  78. // Set TRUE on every sample for uncompressed frames
  79. pSample->SetSyncPoint(TRUE);
  80. long Size = pSample->GetSize();
  81. if ( this->callback ) {
  82. LONGLONG start, end;
  83. WORD *rgb565 = (WORD*)pData;
  84. for(int i = 0, i24 = 0, i565 = 0; i< (Size/2); i++, i24+=3, i565+=1) {
  85. BYTE *p24 = (this->m_rgb24+i24);
  86. WORD val565 = *(rgb565 + i565);
  87. // extract RGB
  88. p24[2] = (val565 & RGB565_MASK_RED) >> 11;
  89. p24[1] = (val565 & RGB565_MASK_GREEN) >> 5;
  90. p24[0] = (val565 & RGB565_MASK_BLUE);
  91. // amplify the image
  92. p24[2] <<= 3;
  93. p24[1] <<= 2;
  94. p24[0] <<= 3;
  95. }
  96. pSample->GetMediaTime(&start, &end);
  97. this->callback->BufferCB( (double)start, this->m_rgb24, ((Size >> 1) * 3));
  98. }
  99. }
  100. this->m_progress += this->m_outputFps;
  101. this->m_iFrameNumber++;
  102. bail:
  103. SAFE_DELETE_ARRAY( pData );
  104. SAFE_RELEASE(pSample);
  105. return ret;
  106. }
  107. HRESULT DSSampleGrabber::CheckInputType(const CMediaType* mtIn)
  108. {
  109. VIDEOINFO *video;
  110. if ( !IsEqualGUID( *mtIn->Subtype(), MEDIASUBTYPE_RGB565 ) || !(video=(VIDEOINFO *)mtIn->Format()) ) {
  111. return E_FAIL;
  112. }
  113. return S_OK;
  114. }
  115. STDMETHODIMP DSSampleGrabber::SetCallback( DSISampleGrabberCB* callback_ )
  116. {
  117. if (!callback_) {
  118. return E_FAIL;
  119. }
  120. this->callback = callback_;
  121. return S_OK;
  122. }
  123. HRESULT DSSampleGrabber::SetSize(int width, int height)
  124. {
  125. ZeroMemory(&this->mt, sizeof(CMediaType));
  126. VIDEOINFO *pvi = (VIDEOINFO *)this->mt.AllocFormatBuffer(sizeof(VIDEOINFO));
  127. if (NULL == pvi) {
  128. return E_OUTOFMEMORY;
  129. }
  130. ZeroMemory(pvi, sizeof(VIDEOINFO));
  131. pvi->bmiHeader.biCompression = BI_RGB;
  132. pvi->bmiHeader.biBitCount = 24;
  133. pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  134. pvi->bmiHeader.biWidth = width;
  135. pvi->bmiHeader.biHeight = height;
  136. pvi->bmiHeader.biPlanes = 1;
  137. pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader);
  138. pvi->bmiHeader.biClrImportant = 0;
  139. // Frame rate
  140. pvi->AvgTimePerFrame = 10000000/this->m_outputFps;
  141. SetRectEmpty(&(pvi->rcSource)); // we want the whole image area rendered.
  142. SetRectEmpty(&(pvi->rcTarget)); // no particular destination rectangle
  143. this->mt.SetType(&MEDIATYPE_Video);
  144. this->mt.SetFormatType(&FORMAT_VideoInfo);
  145. this->mt.SetTemporalCompression(FALSE);
  146. this->mt.SetSubtype(&MEDIASUBTYPE_RGB24);
  147. this->mt.SetSampleSize(pvi->bmiHeader.biSizeImage);
  148. this->m_rgb24 = new BYTE[pvi->bmiHeader.biSizeImage];
  149. return S_OK;
  150. }
  151. #endif /* _WIN32_WCE */