VideoDecoderVFW.cpp
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:8k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. #include "VideoDecoderVFW.h"
  2. MediaVideoDecoderVFW::MediaVideoDecoderVFW()
  3. {
  4. this->hic    = NULL;
  5. this->decaps = NULL;
  6. this->invertFlag = 1;
  7. this->inputBuffer = new MediaBuffer();
  8. }
  9. MediaVideoDecoderVFW::~MediaVideoDecoderVFW()
  10. {
  11. delete this->inputBuffer;
  12. }
  13. media_type_t  MediaVideoDecoderVFW::GetType()
  14. {
  15. return MEDIA_TYPE_VIDEO_DECODER;
  16. }
  17. char *MediaVideoDecoderVFW::GetName()
  18. {
  19. if(this->hic) {
  20. ICINFO icInfo;
  21. char *name;
  22. int i;
  23. ICGetInfo(this->hic, &icInfo, sizeof(ICINFO));
  24. name = (char *) new char[128];
  25. for(i=0; i < 128; i++) { 
  26. name[i] = icInfo.szDescription[i] & 255;
  27. }
  28. return name;
  29. }
  30. return "Video For Windows Decoder";
  31. }
  32. MP_RESULT     MediaVideoDecoderVFW::Connect(MediaItem *item)
  33. {
  34. HRESULT h;
  35. if(item != NULL && item->GetType() == MEDIA_TYPE_DECAPS) {
  36. this->decaps = (MediaItemDecaps *) item;
  37. if(this->decaps->GetVideoHeader(0) == NULL)
  38. return MP_RESULT_ERROR;
  39. memcpy(&this->in_bih.bmiHeader, this->decaps->GetVideoHeader(0), sizeof(BITMAPINFOHEADER));
  40. this->hic = ICOpen(mmioFOURCC('V', 'I', 'D', 'C'), 
  41.           this->in_bih.bmiHeader.biCompression,
  42.           ICMODE_FASTDECOMPRESS);
  43. if(this->hic != 0) {
  44. ZeroMemory(&this->out_bih, sizeof(BITMAPINFO));
  45. this->out_bih.bmiHeader.biSize     = sizeof(BITMAPINFOHEADER);
  46. this->out_bih.bmiHeader.biBitCount = 24;
  47. h = ICDecompressGetFormat( this->hic, &this->in_bih, &this->out_bih ); 
  48. if(h == ICERR_OK) {
  49. h = ICDecompressQuery(this->hic, &this->in_bih, &this->out_bih);
  50.     
  51. this->out_bih.bmiHeader.biSizeImage = out_bih.bmiHeader.biWidth*out_bih.bmiHeader.biHeight*out_bih.bmiHeader.biBitCount/8;
  52. h = ICDecompressBegin(this->hic, &this->in_bih, &this->out_bih);  
  53. this->invertFlag = 1;
  54. if(this->in_bih.bmiHeader.biCompression == mmioFOURCC('D', 'I', 'V', '3') ||
  55. this->in_bih.bmiHeader.biCompression == mmioFOURCC('D', 'I', 'V', '4')) {
  56. this->videoMode  = VIDEO_MODE_YUY2;
  57. }
  58. else {
  59. this->videoMode  = VIDEO_MODE_RGB24;
  60. }
  61. if(h != ICERR_OK) {
  62. this->hic    = 0;
  63. this->decaps = NULL;
  64. return MP_RESULT_ERROR;
  65. }
  66. this->inputBuffer->Alloc(VFW_INPUT_SIZE);
  67. return MP_RESULT_OK;
  68. }
  69. }
  70. }
  71. this->decaps = NULL;
  72. return MP_RESULT_ERROR;
  73. }
  74. MP_RESULT     MediaVideoDecoderVFW::ReleaseConnections()
  75. {
  76. if(this->hic) {
  77. ICDecompressEnd(this->hic);
  78. ICClose(this->hic);
  79. this->inputBuffer->Free();
  80. }
  81. return MP_RESULT_OK;
  82. }
  83. DWORD         MediaVideoDecoderVFW::GetCaps()
  84. {
  85. return 0;
  86. }
  87. MP_RESULT     MediaVideoDecoderVFW::Configure(HINSTANCE hInstance, HWND hwnd)
  88. {
  89. return MP_RESULT_OK;
  90. }
  91. unsigned int       MediaVideoDecoderVFW::GetFrameSize()
  92. {
  93. if(this->hic) {
  94. return this->out_bih.bmiHeader.biSizeImage;
  95. }
  96. return 0;
  97. }
  98. media_video_mode_t MediaVideoDecoderVFW::GetVideoMode()
  99. {
  100. return this->videoMode;
  101. }
  102. MP_RESULT          MediaVideoDecoderVFW::SetQuality(DWORD quality)
  103. {
  104. return MP_RESULT_OK;
  105. }
  106. DWORD          MediaVideoDecoderVFW::GetQuality()
  107. {
  108. return 0;
  109. }
  110. BOOL    MediaVideoDecoderVFW::GetInvertFlag()
  111. {
  112. return this->invertFlag;
  113. }
  114. MP_RESULT          MediaVideoDecoderVFW::SetVideoMode(media_video_mode_t mode)
  115. {
  116. if(this->hic) {
  117. switch(mode) {
  118. case VIDEO_MODE_YUY2:
  119. memcpy(&this->out_bih, &this->in_bih, sizeof(BITMAPINFO));
  120. this->out_bih.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  121. this->out_bih.bmiHeader.biCompression = mmioFOURCC('Y', 'U', 'Y', '2');
  122. this->out_bih.bmiHeader.biBitCount    = 16;
  123. ICDecompressEnd(this->hic);
  124. ICDecompressQuery(this->hic, &this->in_bih, &this->out_bih);
  125. this->out_bih.bmiHeader.biSizeImage = out_bih.bmiHeader.biWidth*out_bih.bmiHeader.biHeight*out_bih.bmiHeader.biBitCount/8;
  126. this->videoMode  = VIDEO_MODE_YUY2;
  127. this->invertFlag = 1;
  128. this->out_bih.bmiHeader.biCompression = 0;
  129. ICDecompressBegin(this->hic, &this->in_bih, &this->out_bih);
  130. this->out_bih.bmiHeader.biCompression = mmioFOURCC('Y', 'U', 'Y', '2');
  131. return MP_RESULT_OK;
  132. break;
  133. case VIDEO_MODE_RGB16:
  134. memcpy(&this->out_bih, &this->in_bih, sizeof(BITMAPINFO));
  135. this->out_bih.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) + 12;
  136. this->out_bih.bmiHeader.biCompression = BI_BITFIELDS;
  137. this->out_bih.bmiHeader.biBitCount    = 16;
  138. ((DWORD *) this->out_bih.bmiColors)[0] = (DWORD) 0xF800;
  139. ((DWORD *) this->out_bih.bmiColors)[1] = (DWORD) 0x07E0;
  140. ((DWORD *) this->out_bih.bmiColors)[2] = (DWORD) 0x001F;
  141. ICDecompressEnd(this->hic);
  142. if(ICDecompressQuery(this->hic, &this->in_bih, &this->out_bih) == ICERR_OK) {
  143. this->out_bih.bmiHeader.biSizeImage = out_bih.bmiHeader.biWidth*out_bih.bmiHeader.biHeight*out_bih.bmiHeader.biBitCount/8;
  144. this->invertFlag = 1;
  145. this->videoMode  = VIDEO_MODE_RGB16;
  146. ICDecompressBegin(this->hic, &this->in_bih, &this->out_bih);
  147. return MP_RESULT_OK;
  148. }
  149. break;
  150. case VIDEO_MODE_RGB24:
  151. memcpy(&this->out_bih, &this->in_bih, sizeof(BITMAPINFO));
  152. this->out_bih.bmiHeader.biCompression = BI_RGB;
  153. this->out_bih.bmiHeader.biBitCount    = 24;
  154. ICDecompressEnd(this->hic);
  155. if(ICDecompressQuery(this->hic, &this->in_bih, &this->out_bih) == ICERR_OK) {
  156. this->out_bih.bmiHeader.biSizeImage = out_bih.bmiHeader.biWidth*out_bih.bmiHeader.biHeight*out_bih.bmiHeader.biBitCount/8;
  157. this->videoMode = VIDEO_MODE_RGB24;
  158. this->invertFlag = 1;
  159. ICDecompressBegin(this->hic, &this->in_bih, &this->out_bih);
  160. return MP_RESULT_OK;
  161. }
  162. break;
  163. case VIDEO_MODE_RGB32:
  164. memcpy(&this->out_bih, &this->in_bih, sizeof(BITMAPINFO));
  165. this->out_bih.bmiHeader.biCompression = BI_RGB;
  166. this->out_bih.bmiHeader.biBitCount    = 32;
  167. ICDecompressEnd(this->hic);
  168. if(ICDecompressQuery(this->hic, &this->in_bih, &this->out_bih) == ICERR_OK) {
  169. this->out_bih.bmiHeader.biSizeImage = out_bih.bmiHeader.biWidth*out_bih.bmiHeader.biHeight*out_bih.bmiHeader.biBitCount/8;
  170. this->videoMode = VIDEO_MODE_RGB32;
  171. this->invertFlag = 1;
  172. ICDecompressBegin(this->hic, &this->in_bih, &this->out_bih);
  173. return MP_RESULT_OK;
  174. }
  175. break;
  176. default:
  177. return MP_RESULT_ERROR;
  178. }
  179. }
  180. return MP_RESULT_ERROR;
  181. }
  182. MP_RESULT          MediaVideoDecoderVFW::Decompress(MediaBuffer *mb_out, unsigned int stride)
  183. {
  184. unsigned int size;
  185. HRESULT h;
  186. if(this->decaps && mb_out && this->hic) {
  187. size = this->decaps->GetNextVideoFrameSize(0);
  188. if(size > this->inputBuffer->GetSize())
  189. this->inputBuffer->ReAlloc(size);
  190. if(this->decaps->ReadVideoFrame(0, this->inputBuffer) != MP_RESULT_OK) {
  191. return MP_RESULT_ERROR;
  192. }
  193. this->in_bih.bmiHeader.biSizeImage = size;
  194. if(size == 0) {
  195. return MP_RESULT_OK;
  196. }
  197. else {
  198. h = ICDecompress(this->hic, ICDECOMPRESS_NOTKEYFRAME,
  199.  &this->in_bih.bmiHeader, this->inputBuffer->GetData(),
  200.  &this->out_bih.bmiHeader, mb_out->GetData());
  201. return MP_RESULT_OK;
  202. }
  203. }
  204. return MP_RESULT_ERROR;
  205. }
  206. MP_RESULT          MediaVideoDecoderVFW::Drop(MediaBuffer *mb_out, unsigned int stride)
  207. {
  208. unsigned int size;
  209. HRESULT h;
  210. if(this->decaps && mb_out && this->hic) {
  211. size = this->decaps->GetNextVideoFrameSize(0);
  212. if(size > this->inputBuffer->GetSize())
  213. this->inputBuffer->ReAlloc(size);
  214. this->decaps->ReadVideoFrame(0, this->inputBuffer);
  215. this->in_bih.bmiHeader.biSizeImage = size;
  216. if(size == 0) {
  217. return MP_RESULT_ERROR;
  218. }
  219. else {
  220. h = ICDecompress(this->hic, ICDECOMPRESS_HURRYUP,
  221.  &this->in_bih.bmiHeader, this->inputBuffer->GetData(),
  222.  &this->out_bih.bmiHeader, mb_out->GetData());
  223. return MP_RESULT_OK;
  224. }
  225. }
  226. return MP_RESULT_ERROR;
  227. }