⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smartcache_old.c

📁 mpeg2 decoder filter过滤服务端
💻 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 + -