smartcache.c
上传用户:hhs829
上传日期:2022-06-17
资源大小:586k
文件大小:5k
- //
- // smartcache.c
- // 2002-12-05
- // Added by Lu Qiming(luqiming@263.net), to do smart input buffer
- #include "global.h"
- #include "smartcache.h"
- #include <malloc.h>
- #include <stdio.h>
- ///////////////////////////////////////////////////////////////////
- // There is a serious problem, Because the different instances of
- // this decoder filter will shart all global variables.
- // It's very dangerous!
- // So this decoder filter is forbidden to be used more than twice
- // in one application, even if intelligent connecting.
- // The same potential problems with the C-CODE MPEG DECODING.
- // 2002-12-26
- ////////////////////////////////////////////////////////////////////
- unsigned char * gInputCache = NULL;
- static long gCacheSize = 1024 * 1024;
- static long gMinWorkSize = 10 * 1024;
- static long gReadingOffset = 0;
- static long gWritingOffset = 0;
- static BOOL gIsFlushing = FALSE;
- static CRITICAL_SECTION singleAccess;
- static BOOL inputWaiting = FALSE;
- static BOOL outputWaiting = FALSE;
- static BOOL cacheChecking = TRUE;
- static int waitingCounter;
- static void MakeSpace(void);
- static long HasEnoughSpace(long inNeedSize);
- static long HasEnoughData(long inNeedSize);
- //FILE * fp = NULL;
- long InitSmartCache(void)
- {
- gInputCache = malloc(gCacheSize);
- gReadingOffset = 0;
- gWritingOffset = 0;
- inputWaiting = FALSE;
- outputWaiting = FALSE;
- cacheChecking = TRUE; // When checking, maybe return to the cache header
- // Critical section to access smart cache
- InitializeCriticalSection(&singleAccess);
- return (gInputCache != NULL);
- }
- void ReleaseSmartCache(void)
- {
- DeleteCriticalSection(&singleAccess);
- if (gInputCache)
- {
- free(gInputCache);
- gInputCache = NULL;
- }
- }
- // Blocking receive...
- long ReceiveToSmartCache(unsigned char * inData, long inLength)
- {
- while (!gIsFlushing && !HasEnoughSpace(inLength))
- {
- inputWaiting = TRUE;
- MakeSpace();
- Sleep(2);
- // fp = fopen("C:\hqmpgdectime.txt", "a");
- // fprintf(fp, "Receiving sleep, current data length: %10d!n", gWritingOffset - gReadingOffset);
- // fclose(fp);
- }
- inputWaiting = FALSE;
- if (!gIsFlushing && HasEnoughSpace(inLength))
- {
- EnterCriticalSection(&singleAccess); // Enter
- memcpy(gInputCache + gWritingOffset, inData, inLength);
- gWritingOffset += inLength;
- LeaveCriticalSection(&singleAccess); // Leave
- return 1;
- }
- return 0;
- }
- // Blocking read...
- long FetchDataFromSmartCache(BYTE * outBuffer, ULONG inLength)
- {
- if (inLength <= 0)
- return 0;
- while (!gIsFlushing && !HasEnoughData(inLength))
- {
- outputWaiting = TRUE;
- Sleep(1);
- }
- outputWaiting = FALSE;
-
- if (!gIsFlushing && HasEnoughData(inLength))
- {
- EnterCriticalSection(&singleAccess); // Enter
- memcpy(outBuffer, gInputCache + gReadingOffset, inLength);
- gReadingOffset += inLength;
- LeaveCriticalSection(&singleAccess); // Leave
- return inLength;
- }
- return 0;
- }
- long GetAvailableInSmartCache(void)
- {
- return (gWritingOffset - gReadingOffset);
- }
- // Determine whether enough space to hold coming mpeg data
- static long HasEnoughSpace(long inNeedSize)
- {
- return (inNeedSize <= gCacheSize - gWritingOffset);
- }
- // Determine data in smart cache at this moment is enough to decode
- static long HasEnoughData(long inNeedSize)
- {
- return (inNeedSize <= gWritingOffset - gReadingOffset);
- }
- static void MakeSpace(void)
- {
- long workingSize = gWritingOffset - gReadingOffset;
- // When cache checking, don't drop any data
- if (!cacheChecking && workingSize < gMinWorkSize)
- {
- EnterCriticalSection(&singleAccess); // Enter
- memmove(gInputCache, gInputCache + gReadingOffset, workingSize);
- gReadingOffset = 0;
- gWritingOffset = workingSize;
- LeaveCriticalSection(&singleAccess); // Leave
- }
- }
- void BeginFlushSmartCache(void)
- {
- gIsFlushing = TRUE;
- waitingCounter = 0;
- while (inputWaiting && waitingCounter < 15) // Make sure NOT block in receiving or reading
- {
- waitingCounter++;
- Sleep(1);
- }
- waitingCounter = 0;
- while (outputWaiting && waitingCounter < 15)
- {
- waitingCounter++;
- Sleep(1);
- }
- // Sleep(10);
- EnterCriticalSection(&singleAccess); // Enter
- gReadingOffset = 0;
- gWritingOffset = 0;
- LeaveCriticalSection(&singleAccess); // Leave
- }
- void EndFlushSmartCache(void)
- {
- gIsFlushing = FALSE;
- }
- BOOL CheckInputWaiting(void)
- {
- return inputWaiting;
- }
- BOOL CheckOutputWaiting(void)
- {
- return outputWaiting;
- }
- // We can reuse the data having been read out
- void SetCacheChecking(void)
- {
- cacheChecking = TRUE;
- }
- void ResetCacheChecking(void)
- {
- cacheChecking = FALSE;
- EnterCriticalSection(&singleAccess); // Enter
- gReadingOffset = 0;
- LeaveCriticalSection(&singleAccess); // Leave
- }