📄 smartcache_old.c
字号:
//
// 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
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -