VideoBuffer.cpp
上传用户:lusi_8715
上传日期:2007-01-08
资源大小:199k
文件大小:5k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /**************************************************************************************
  2.  *                                                                                    *
  3.  * This application contains code from OpenDivX and is released as a "Larger Work"    *
  4.  * under that license. Consistant with that license, this application is released     *
  5.  * under the GNU General Public License.                                              *
  6.  *                                                                                    *
  7.  * The OpenDivX license can be found at: http://www.projectmayo.com/opendivx/docs.php *
  8.  * The GPL can be found at: http://www.gnu.org/copyleft/gpl.html                      *
  9.  *                                                                                    *
  10.  * Copyright (c) 2001 - Project Mayo                                                  *
  11.  *                                                                                    *
  12.  * Authors: Damien Chavarria <adrc at projectmayo.com>                                *
  13.  *                                                                                    *
  14.  **************************************************************************************/
  15. #include "VideoBuffer.h"
  16. /*
  17.  * Class functions
  18.  */
  19. /*
  20.  * Constructor
  21.  */
  22. VideoBuffer::VideoBuffer(AviDecaps *decaps, Codec *codec)
  23. {
  24. unsigned int i;
  25. this->input_buffer = NULL;
  26. if(decaps != NULL || codec != NULL) {
  27. this->decaps = decaps;
  28. this->codec  = codec;
  29. this->input_buffer = (char *) malloc(VIDEO_BUFFER_SIZE);
  30. for(i=0; i < 1/*BUFFER_SIZE*/; i++) {
  31. this->frames[i] = (char *) malloc(decaps->Width()*decaps->Height()*4);
  32. memset(this->frames[i], 0, decaps->Width()*decaps->Height()*4);
  33. }
  34. this->frame_size = decaps->Width()*decaps->Height()*3;
  35. this->free_slots = BUFFER_SIZE;
  36. //this->mutex = CreateMutex (NULL, FALSE, NULL);
  37. this->running = 0;
  38. this->mode    = VIDEO_BUFFER_INACTIVE;
  39. }
  40. }
  41. VideoBuffer::~VideoBuffer()
  42. {
  43. }
  44. DWORD WINAPI FillThread(LPVOID lpData)
  45. {
  46. VideoBuffer *videoBuffer;
  47. videoBuffer = (VideoBuffer *) lpData;
  48. if(videoBuffer == NULL)
  49. return 0;
  50. while(videoBuffer->running) {
  51. Sleep(2);
  52. if(videoBuffer->free_slots > 0) {
  53. long frame_size = 0;
  54. WaitForSingleObject(videoBuffer->mutex, INFINITE);
  55. if( (BUFFER_SIZE - videoBuffer->free_slots - 1) > 0) {
  56. memcpy(videoBuffer->frames[BUFFER_SIZE - videoBuffer->free_slots],
  57.    videoBuffer->frames[BUFFER_SIZE - videoBuffer->free_slots - 1],
  58.    videoBuffer->frame_size);
  59. }
  60. /*
  61.  * Do Decomp here
  62.  */
  63. frame_size = videoBuffer->decaps->NextVideoFrame(videoBuffer->input_buffer);
  64. if(frame_size == -2) {
  65. /*
  66.  * We're at the end of the file
  67.  */
  68.     ReleaseMutex(videoBuffer->mutex);
  69. return 0;
  70. }
  71. videoBuffer->codec->Decompress(videoBuffer->input_buffer, 
  72.    frame_size, 
  73.    videoBuffer->frames[BUFFER_SIZE - videoBuffer->free_slots]);
  74. videoBuffer->free_slots--;
  75. ReleaseMutex(videoBuffer->mutex);
  76. }
  77. }
  78. return 0;
  79. }
  80. void VideoBuffer::Start()
  81. {
  82. /*
  83.  * First fill our buffer
  84.  *
  85.  */
  86. this->free_slots = BUFFER_SIZE;
  87. this->running    = 1;
  88. if(mode == VIDEO_BUFFER_ACTIVE) {
  89. //this->fillThread = CreateThread( NULL, 0, FillThread, (LPVOID) this, 0, &this->id );
  90. //SetThreadPriority(this->fillThread, THREAD_PRIORITY_ABOVE_NORMAL);
  91. }
  92. }
  93. void VideoBuffer::Stop()
  94. {
  95. this->running = 0;
  96. //TerminateThread(this->fillThread, 0);
  97. unsigned int i;
  98. if(this->input_buffer != NULL)
  99. free(this->input_buffer);
  100. for(i=0; i < 1/*BUFFER_SIZE*/; i++) {
  101. if(this->frames[i] != NULL)
  102. free(this->frames[i]);
  103. }
  104. }
  105. char *VideoBuffer::GiveMeAFrame()
  106. {
  107. unsigned int i;
  108. switch(this->mode) {
  109. case VIDEO_BUFFER_ACTIVE:
  110. if(this->input_buffer && this->free_slots < BUFFER_SIZE) {
  111. long frame_size = 0;
  112. char *temp;
  113. temp = this->frames[0];
  114. //WaitForSingleObject(this->mutex, INFINITE);
  115. for(i=0; i < BUFFER_SIZE - 1; i++) {
  116. this->frames[i] = this->frames[i+1];
  117. }
  118. this->frames[BUFFER_SIZE - 1] = temp;
  119. this->free_slots++;
  120. //ReleaseMutex(this->mutex);
  121. return this->frames[0];
  122. }
  123. else {
  124. /*
  125.  * Shouldn't happen
  126.  */
  127. return NULL; //this->frames[0];
  128. }
  129. break;
  130. case VIDEO_BUFFER_INACTIVE:
  131. long frame_size = 0;
  132. /*
  133.  * Do Decomp here
  134.  */
  135. frame_size = this->decaps->NextVideoFrame(this->input_buffer);
  136. if(frame_size == -2) {
  137. /*
  138.  * We're at the end of the file
  139.  */
  140. return NULL;
  141. }
  142. this->codec->Decompress(this->input_buffer, 
  143.       frame_size, 
  144.     this->frames[0]);
  145. break;
  146. }
  147. return this->frames[0];
  148. }
  149. void VideoBuffer::Drop()
  150. {
  151. unsigned int i;
  152. long frame_size = 0;
  153. switch(this->mode) {
  154. case VIDEO_BUFFER_INACTIVE:
  155. /*
  156.  * Do Decomp here
  157.  */
  158. frame_size = this->decaps->NextVideoFrame(this->input_buffer);
  159. if(frame_size == -2) {
  160. /*
  161.  * We're at the end of the file
  162.  */
  163. return;
  164. }
  165. this->codec->Drop(this->input_buffer, 
  166.     frame_size, 
  167.   this->frames[0]);
  168. break;
  169. case VIDEO_BUFFER_ACTIVE:
  170. break;
  171. }
  172. }