smartcache.c
上传用户:hhs829
上传日期:2022-06-17
资源大小:586k
文件大小:5k
源码类别:

DirextX编程

开发平台:

Visual C++

  1. //
  2. // smartcache.c
  3. // 2002-12-05
  4. // Added by Lu Qiming(luqiming@263.net), to do smart input buffer
  5. #include "global.h"
  6. #include "smartcache.h"
  7. #include <malloc.h>
  8. #include <stdio.h>
  9. ///////////////////////////////////////////////////////////////////
  10. // There is a serious problem, Because the different instances of 
  11. // this decoder filter will shart all global variables.
  12. // It's very dangerous!
  13. // So this decoder filter is forbidden to be used more than twice 
  14. // in one application, even if intelligent connecting.
  15. // The same potential problems with the C-CODE MPEG DECODING. 
  16. // 2002-12-26
  17. ////////////////////////////////////////////////////////////////////
  18. unsigned char * gInputCache = NULL;
  19. static long gCacheSize   = 1024 * 1024;
  20. static long gMinWorkSize = 10 * 1024;
  21. static long gReadingOffset = 0;
  22. static long gWritingOffset = 0;
  23. static BOOL gIsFlushing = FALSE;
  24. static CRITICAL_SECTION singleAccess;
  25. static BOOL inputWaiting  = FALSE;
  26. static BOOL outputWaiting = FALSE;
  27. static BOOL cacheChecking = TRUE;
  28. static int  waitingCounter;
  29. static void MakeSpace(void);
  30. static long HasEnoughSpace(long inNeedSize);
  31. static long HasEnoughData(long inNeedSize);
  32. //FILE * fp = NULL;
  33. long InitSmartCache(void)
  34. {
  35. gInputCache = malloc(gCacheSize);
  36. gReadingOffset = 0;
  37. gWritingOffset = 0;
  38. inputWaiting  = FALSE;
  39. outputWaiting = FALSE;
  40. cacheChecking = TRUE;  // When checking, maybe return to the cache header
  41. // Critical section to access smart cache
  42. InitializeCriticalSection(&singleAccess); 
  43. return (gInputCache != NULL);
  44. }
  45. void ReleaseSmartCache(void)
  46. {
  47. DeleteCriticalSection(&singleAccess);
  48. if (gInputCache)
  49. {
  50. free(gInputCache);
  51. gInputCache = NULL;
  52. }
  53. }
  54. // Blocking receive...
  55. long ReceiveToSmartCache(unsigned char * inData, long inLength)
  56. {
  57. while (!gIsFlushing && !HasEnoughSpace(inLength))
  58. {
  59. inputWaiting = TRUE;
  60. MakeSpace();
  61. Sleep(2);
  62. // fp = fopen("C:\hqmpgdectime.txt", "a");
  63. // fprintf(fp, "Receiving sleep, current data length: %10d!n", gWritingOffset - gReadingOffset);
  64. // fclose(fp);
  65. }
  66. inputWaiting = FALSE;
  67. if (!gIsFlushing && HasEnoughSpace(inLength))
  68. {
  69. EnterCriticalSection(&singleAccess); // Enter
  70. memcpy(gInputCache + gWritingOffset, inData, inLength);
  71. gWritingOffset += inLength;
  72. LeaveCriticalSection(&singleAccess); // Leave
  73. return 1;
  74. }
  75. return 0;
  76. }
  77. // Blocking read...
  78. long FetchDataFromSmartCache(BYTE * outBuffer, ULONG inLength)
  79. {
  80. if (inLength <= 0)
  81. return 0;
  82. while (!gIsFlushing && !HasEnoughData(inLength))
  83. {
  84. outputWaiting = TRUE;
  85. Sleep(1);
  86. }
  87. outputWaiting = FALSE;
  88. if (!gIsFlushing && HasEnoughData(inLength))
  89. {
  90. EnterCriticalSection(&singleAccess); // Enter
  91. memcpy(outBuffer, gInputCache + gReadingOffset, inLength);
  92. gReadingOffset += inLength;
  93. LeaveCriticalSection(&singleAccess); // Leave
  94. return inLength;
  95. }
  96. return 0;
  97. }
  98. long GetAvailableInSmartCache(void)
  99. {
  100. return (gWritingOffset - gReadingOffset);
  101. }
  102. // Determine whether enough space to hold coming mpeg data
  103. static long HasEnoughSpace(long inNeedSize)
  104. {
  105. return (inNeedSize <= gCacheSize - gWritingOffset);
  106. }
  107. // Determine data in smart cache at this moment is enough to decode
  108. static long HasEnoughData(long inNeedSize)
  109. {
  110. return (inNeedSize <= gWritingOffset - gReadingOffset);
  111. }
  112. static void MakeSpace(void)
  113. {
  114. long workingSize = gWritingOffset - gReadingOffset;
  115. // When cache checking, don't drop any data
  116. if (!cacheChecking && workingSize < gMinWorkSize)
  117. {
  118. EnterCriticalSection(&singleAccess); // Enter
  119. memmove(gInputCache, gInputCache + gReadingOffset, workingSize);
  120. gReadingOffset = 0;
  121. gWritingOffset = workingSize;
  122. LeaveCriticalSection(&singleAccess); // Leave
  123. }
  124. }
  125. void BeginFlushSmartCache(void)
  126. {
  127. gIsFlushing = TRUE;
  128. waitingCounter = 0;
  129. while (inputWaiting && waitingCounter < 15)  // Make sure NOT block in receiving or reading
  130. {
  131. waitingCounter++;
  132. Sleep(1);
  133. }
  134. waitingCounter = 0;
  135. while (outputWaiting && waitingCounter < 15)
  136. {
  137. waitingCounter++;
  138. Sleep(1);
  139. }
  140. // Sleep(10);
  141. EnterCriticalSection(&singleAccess); // Enter
  142. gReadingOffset = 0;
  143. gWritingOffset = 0;
  144. LeaveCriticalSection(&singleAccess); // Leave
  145. }
  146. void EndFlushSmartCache(void)
  147. {
  148. gIsFlushing = FALSE;
  149. }
  150. BOOL CheckInputWaiting(void)
  151. {
  152. return inputWaiting;
  153. }
  154. BOOL CheckOutputWaiting(void)
  155. {
  156. return outputWaiting;
  157. }
  158. // We can reuse the data having been read out
  159. void SetCacheChecking(void)
  160. {
  161. cacheChecking = TRUE;
  162. }
  163. void ResetCacheChecking(void)
  164. {
  165. cacheChecking = FALSE;
  166. EnterCriticalSection(&singleAccess); // Enter
  167. gReadingOffset = 0;
  168. LeaveCriticalSection(&singleAccess); // Leave
  169. }