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

多媒体编程

开发平台:

Visual C++

  1. /**************************************************************************************
  2.  *                                                                                    *
  3.  *                                                                                    *
  4.  **************************************************************************************/
  5. #include "VideoBuffer.h"
  6. /* 
  7.  *
  8.  * 只执行一次
  9.  *
  10.  */
  11. MediaVideoBuffer::MediaVideoBuffer()
  12. {
  13. DWORD i;
  14. for(i=0; i < 1; i++) {
  15. this->buffer[i] = new MediaBuffer();
  16. }
  17. this->bufferedFrames = 0;
  18. this->enabled = FALSE;
  19. this->decoder        = NULL;
  20. this->bufferingMutex = CreateMutex(NULL, FALSE, NULL);
  21. }
  22. MediaVideoBuffer::~MediaVideoBuffer()
  23. {
  24. DWORD i;
  25. for(i=0; i < 1; i++) {
  26. delete this->buffer[i];
  27. }
  28. CloseHandle(this->bufferingMutex);
  29. }
  30. /*
  31.  * 媒体项方法
  32.  */
  33. media_type_t MediaVideoBuffer::GetType()
  34. {
  35. return MEDIA_TYPE_VIDEO_BUFFER;
  36. }
  37. char *MediaVideoBuffer::GetName()
  38. {
  39. return "Default Video Buffer";
  40. }
  41. MP_RESULT MediaVideoBuffer::Connect(MediaItem *item)
  42. {
  43. DWORD i;
  44. /*
  45.  * 接受任何视频解码器
  46.  *
  47.  */
  48. if(item != NULL && item->GetType() == MEDIA_TYPE_VIDEO_DECODER) {
  49. this->decoder = (MediaItemVideoDecoder *) item;
  50. if(this->decoder->GetFrameSize() != 0) {
  51. for(i=0; i < 1; i++) {
  52. if(this->buffer[i] == NULL) {
  53. this->buffer[i] = new MediaBuffer();
  54. }
  55. this->buffer[i]->Alloc(this->decoder->GetFrameSize());
  56. }
  57. this->bufferedFrames = 0;
  58. this->endReachedAt   = VIDEO_BUFFER_END_NOT_REACHED;
  59. this->bufferingThread = NULL;
  60. return MP_RESULT_OK;
  61. }
  62. }
  63. this->decoder = NULL;
  64. return MP_RESULT_ERROR;
  65. }
  66. MP_RESULT MediaVideoBuffer::ReleaseConnections()
  67. {
  68. DWORD i;
  69. if(this->decoder) {
  70. for(i=0; i < 1; i++) {
  71. this->buffer[i]->Free();
  72. }
  73. this->decoder = NULL;
  74. }
  75. return MP_RESULT_OK;
  76. }
  77. DWORD         MediaVideoBuffer::GetCaps()
  78. {
  79. return 0;
  80. }
  81. MP_RESULT     MediaVideoBuffer::Configure(HINSTANCE hInstance, HWND hwnd)
  82. {
  83. return MP_RESULT_ERROR;
  84. }
  85. /**************************************************************
  86.  *                                                            *
  87.  *                       视频缓冲线程                         *
  88.  *                  ----------------------                    *
  89.  *                                                            *
  90.  **************************************************************/
  91. DWORD WINAPI BufferingThreadFunc( LPVOID lpData)
  92. {
  93. MediaVideoBuffer *buffer = (MediaVideoBuffer *) lpData;
  94. while(TRUE) {
  95. if(buffer->bufferedFrames >= VIDEO_BUFFER_SIZE) {
  96. buffer->suspended = TRUE;
  97. SuspendThread(buffer->bufferingThread);
  98. }
  99. else {
  100. WaitForSingleObject(buffer->bufferingMutex, INFINITE);
  101. if(buffer->decoder->Decompress(buffer->buffer[buffer->bufferedFrames], 0) != MP_RESULT_OK) {
  102. buffer->endReachedAt = buffer->bufferedFrames;
  103. ReleaseMutex(buffer->bufferingMutex);
  104. return 0;
  105. }
  106. buffer->bufferedFrames++;
  107. ReleaseMutex(buffer->bufferingMutex);
  108. }
  109. }
  110. return 0;
  111. }
  112. /**************************************************************/
  113. /*
  114.  * 视频缓冲方法
  115.  */
  116. MP_RESULT MediaVideoBuffer::StartBuffering(unsigned int stride)
  117. {
  118. DWORD i;
  119. this->stride = stride;
  120. if(this->enabled) {
  121. if(this->bufferingThread != NULL)
  122. return MP_RESULT_ERROR;
  123. this->bufferedFrames = 0;
  124. this->suspended      = 0;
  125. CloseHandle(this->bufferingMutex);
  126. this->bufferingMutex = CreateMutex(NULL, FALSE, NULL);
  127. /*
  128.  * 等待缓冲器直到填充一半
  129.  */
  130. for(i=0; i<VIDEO_BUFFER_SIZE; i++) {
  131. if(this->decoder->Decompress(this->buffer[this->bufferedFrames], 0) != MP_RESULT_OK) {
  132. this->endReachedAt = this->bufferedFrames;
  133. return MP_RESULT_ERROR;
  134. }
  135. this->bufferedFrames++;
  136. }
  137. /*
  138.  * 启动一个线程
  139.  */
  140. this->bufferingThread = CreateThread(NULL, 0, BufferingThreadFunc, (LPVOID) this, 0, &this->bufferingThreadId);
  141. SetThreadPriority(this->bufferingThread, THREAD_PRIORITY_ABOVE_NORMAL);
  142. }
  143. return MP_RESULT_ERROR;
  144. }
  145. MP_RESULT MediaVideoBuffer::StopBuffering()
  146. {
  147. if(this->enabled) {
  148. WaitForSingleObject(this->bufferingMutex, INFINITE);
  149. TerminateThread(this->bufferingThread, 0);
  150. this->bufferingThread = NULL;
  151. ReleaseMutex(this->bufferingMutex);
  152. this->bufferedFrames = 0;
  153. this->endReachedAt   = VIDEO_BUFFER_END_NOT_REACHED;
  154. }
  155. return MP_RESULT_OK;
  156. }
  157. MediaBuffer *MediaVideoBuffer::GetOneFrame()
  158. {
  159. DWORD i;
  160. MediaBuffer *temp;
  161. if(this->enabled) {
  162. if(this->endReachedAt == 0)
  163. return NULL;
  164. WaitForSingleObject(this->bufferingMutex, INFINITE);
  165. if(this->bufferedFrames > 1) {
  166. if(this->endReachedAt < VIDEO_BUFFER_END_NOT_REACHED) {
  167. this->endReachedAt--;
  168. }
  169. /*
  170.  * 检查是否结束
  171.  */
  172. if(this->endReachedAt == 0) {
  173. ReleaseMutex(this->bufferingMutex);
  174. return NULL;
  175. }
  176. temp = this->buffer[0];
  177. for(i=0; i < VIDEO_BUFFER_SIZE - 1; i++) {
  178. this->buffer[i] = this->buffer[i+1];
  179. }
  180. this->buffer[VIDEO_BUFFER_SIZE - 1] = temp;
  181. this->bufferedFrames--;
  182. ReleaseMutex(this->bufferingMutex);
  183. if(this->suspended && this->endReachedAt == VIDEO_BUFFER_END_NOT_REACHED) {
  184. this->suspended = FALSE;
  185. ResumeThread(this->bufferingThread);
  186. }
  187. return this->buffer[0];
  188. }
  189. else {
  190. /*
  191.  * 解压缩
  192.  */
  193. if(this->decoder->Decompress(this->buffer[this->bufferedFrames], 0) != MP_RESULT_OK) {
  194. this->endReachedAt = 0;
  195. this->suspended = TRUE;
  196. SuspendThread(this->bufferingThread);
  197. ReleaseMutex(this->bufferingMutex);
  198. return NULL;
  199. }
  200. if(this->bufferedFrames == 1)
  201. this->bufferedFrames--;
  202. temp = this->buffer[0];
  203. for(i=0; i < VIDEO_BUFFER_SIZE - 1; i++) {
  204. this->buffer[i] = this->buffer[i+1];
  205. }
  206. this->buffer[VIDEO_BUFFER_SIZE - 1] = temp;
  207. ReleaseMutex(this->bufferingMutex);
  208. if(this->suspended && this->endReachedAt == VIDEO_BUFFER_END_NOT_REACHED) {
  209. this->suspended = FALSE;
  210. ResumeThread(this->bufferingThread);
  211. }
  212. return temp;
  213. }
  214. }
  215. else {
  216. if(this->decoder->Decompress(this->buffer[0], this->stride) != MP_RESULT_OK) {
  217. return NULL;
  218. }
  219. return this->buffer[0];
  220. }
  221. }
  222. MediaBuffer  *MediaVideoBuffer::GetLastFrame()
  223. {
  224. if(this->decoder) {
  225. return this->buffer[0];
  226. }
  227. return NULL;
  228. }
  229. MP_RESULT MediaVideoBuffer::DropOneFrame()
  230. {
  231. if(this->decoder) {
  232. WaitForSingleObject(this->bufferingMutex, INFINITE);
  233. this->decoder->Drop(this->buffer[0], this->stride);
  234. ReleaseMutex(this->bufferingMutex);
  235. }
  236. return MP_RESULT_OK;
  237. }