CRITICAL_SECTION g_CriticalSection = {0};
char gStreamBuffer[STREAM_BUFFER_LEN];
static char* pStreamBegin = gStreamBuffer;
static char* pStreamEnd = gStreamBuffer;
int putStreamData(LPBYTE p, DWORD len)
{
EnterCriticalSection(&g_CriticalSection);
if((pStreamEnd < gStreamBuffer)||(pStreamEnd >= gStreamBuffer + STREAM_BUFFER_LEN))
{
printf("invalid pointer pStreamEnd\n");
return -1;//invalid pointer
}
if((pStreamBegin < gStreamBuffer)||(pStreamBegin >= gStreamBuffer + STREAM_BUFFER_LEN))
{
printf("invalid pointer pStreamBegin\n");
return -1;//invalid pointer
}
if(pStreamEnd >= pStreamBegin)
{
//normal case
if((len + pStreamEnd - pStreamBegin) > STREAM_BUFFER_LEN)
{
printf("Input stream is too long 1, pointer = 0x%x, length = %d, buffer available bytes %d \n", p, len, STREAM_BUFFER_LEN + pStreamBegin - pStreamEnd);
LeaveCriticalSection(&g_CriticalSection);
return -1;//over flow
}
//now we can receive the data from tuner
if((pStreamEnd + len) < (gStreamBuffer + STREAM_BUFFER_LEN))
{
//just put the pStreamEnd pointer afterward
memcpy(pStreamEnd, p, len);
pStreamEnd += len;
LeaveCriticalSection(&g_CriticalSection);
return len;
}
else
{
//we need turn the pStreamEnd pointer to the start of gStreamBuffer
//when the all the buffer are be filled.
int nLenToTail = 0;
nLenToTail = gStreamBuffer + STREAM_BUFFER_LEN - pStreamEnd;
memcpy(pStreamEnd, p, nLenToTail);
memcpy(gStreamBuffer, p + nLenToTail, len - nLenToTail);
pStreamEnd = gStreamBuffer + len - nLenToTail - 1;
LeaveCriticalSection(&g_CriticalSection);
return len;
}
}
else
{
// case the used buffer reach the end and turn around
if(len > (pStreamBegin - pStreamEnd))
{
printf("Input stream is too long 2, pointer = 0x%x, length = %d, buffer available bytes %d \n", p, len, pStreamBegin - pStreamEnd);
LeaveCriticalSection(&g_CriticalSection);
return -1;//over flow
}
//just copy data to pSteamEnd
memcpy(pStreamEnd, p, len);
pStreamEnd += len;
LeaveCriticalSection(&g_CriticalSection);
return len;
}
}
/*
function: get stream data from gStreamBuffer
*/
int getStreamData(LPBYTE p, DWORD len)
{
int nBufFilled = 0;
EnterCriticalSection(&g_CriticalSection);
if((pStreamEnd < gStreamBuffer)||(pStreamEnd >= gStreamBuffer + STREAM_BUFFER_LEN))
{
return -1;//invalid pointer
}
if((pStreamBegin < gStreamBuffer)||(pStreamBegin >= gStreamBuffer + STREAM_BUFFER_LEN))
{
return -1;//invalid pointer
}
if(len < 0)
{
return -2;//parameter error
}
if(NULL == p)
{
return -2;//parameter error
}
//get filled byte number in Stream Buffer
if (pStreamBegin <= pStreamEnd)
{
nBufFilled = pStreamEnd - pStreamBegin;
ASSERT(nBufFilled >= 0);
//select the buffer length we can send to SDK
if(len >= nBufFilled)
{
memcpy(p, pStreamBegin, nBufFilled);
pStreamBegin += nBufFilled;
LeaveCriticalSection(&g_CriticalSection);
return nBufFilled;
}
else
{
memcpy(p, pStreamBegin, len);
pStreamBegin += len;
LeaveCriticalSection(&g_CriticalSection);
return len;
}
}
else
{
nBufFilled = pStreamEnd + STREAM_BUFFER_LEN - pStreamBegin;
ASSERT(nBufFilled >= 0);
//select the buffer length we can send to SDK
if(len >= nBufFilled)
{
//the buffer length is nBufFilled, all filled buffer will be copy to caller
memcpy(p, pStreamBegin, gStreamBuffer + STREAM_BUFFER_LEN - pStreamBegin);
memcpy(p+ (STREAM_BUFFER_LEN + gStreamBuffer - pStreamBegin), gStreamBuffer, nBufFilled - (gStreamBuffer + STREAM_BUFFER_LEN - pStreamBegin));
pStreamBegin = pStreamEnd;
LeaveCriticalSection(&g_CriticalSection);
return nBufFilled;
}
else
{
if(pStreamBegin + len < gStreamBuffer + STREAM_BUFFER_LEN)
{
//don't need to rotate
memcpy(p, pStreamBegin, len);
pStreamBegin += len;
LeaveCriticalSection(&g_CriticalSection);
return len;
}
else
{
//do rotation
memcpy(p, pStreamBegin, gStreamBuffer + STREAM_BUFFER_LEN - pStreamBegin);
memcpy(p + (STREAM_BUFFER_LEN + gStreamBuffer - pStreamBegin), gStreamBuffer, len - (gStreamBuffer + STREAM_BUFFER_LEN - pStreamBegin));
pStreamBegin = len + pStreamBegin - STREAM_BUFFER_LEN;
LeaveCriticalSection(&g_CriticalSection);
return len;
}
}
}
LeaveCriticalSection(&g_CriticalSection);
return 0;
}
char gStreamBuffer[STREAM_BUFFER_LEN];
static char* pStreamBegin = gStreamBuffer;
static char* pStreamEnd = gStreamBuffer;
int putStreamData(LPBYTE p, DWORD len)
{
EnterCriticalSection(&g_CriticalSection);
if((pStreamEnd < gStreamBuffer)||(pStreamEnd >= gStreamBuffer + STREAM_BUFFER_LEN))
{
printf("invalid pointer pStreamEnd\n");
return -1;//invalid pointer
}
if((pStreamBegin < gStreamBuffer)||(pStreamBegin >= gStreamBuffer + STREAM_BUFFER_LEN))
{
printf("invalid pointer pStreamBegin\n");
return -1;//invalid pointer
}
if(pStreamEnd >= pStreamBegin)
{
//normal case
if((len + pStreamEnd - pStreamBegin) > STREAM_BUFFER_LEN)
{
printf("Input stream is too long 1, pointer = 0x%x, length = %d, buffer available bytes %d \n", p, len, STREAM_BUFFER_LEN + pStreamBegin - pStreamEnd);
LeaveCriticalSection(&g_CriticalSection);
return -1;//over flow
}
//now we can receive the data from tuner
if((pStreamEnd + len) < (gStreamBuffer + STREAM_BUFFER_LEN))
{
//just put the pStreamEnd pointer afterward
memcpy(pStreamEnd, p, len);
pStreamEnd += len;
LeaveCriticalSection(&g_CriticalSection);
return len;
}
else
{
//we need turn the pStreamEnd pointer to the start of gStreamBuffer
//when the all the buffer are be filled.
int nLenToTail = 0;
nLenToTail = gStreamBuffer + STREAM_BUFFER_LEN - pStreamEnd;
memcpy(pStreamEnd, p, nLenToTail);
memcpy(gStreamBuffer, p + nLenToTail, len - nLenToTail);
pStreamEnd = gStreamBuffer + len - nLenToTail - 1;
LeaveCriticalSection(&g_CriticalSection);
return len;
}
}
else
{
// case the used buffer reach the end and turn around
if(len > (pStreamBegin - pStreamEnd))
{
printf("Input stream is too long 2, pointer = 0x%x, length = %d, buffer available bytes %d \n", p, len, pStreamBegin - pStreamEnd);
LeaveCriticalSection(&g_CriticalSection);
return -1;//over flow
}
//just copy data to pSteamEnd
memcpy(pStreamEnd, p, len);
pStreamEnd += len;
LeaveCriticalSection(&g_CriticalSection);
return len;
}
}
/*
function: get stream data from gStreamBuffer
*/
int getStreamData(LPBYTE p, DWORD len)
{
int nBufFilled = 0;
EnterCriticalSection(&g_CriticalSection);
if((pStreamEnd < gStreamBuffer)||(pStreamEnd >= gStreamBuffer + STREAM_BUFFER_LEN))
{
return -1;//invalid pointer
}
if((pStreamBegin < gStreamBuffer)||(pStreamBegin >= gStreamBuffer + STREAM_BUFFER_LEN))
{
return -1;//invalid pointer
}
if(len < 0)
{
return -2;//parameter error
}
if(NULL == p)
{
return -2;//parameter error
}
//get filled byte number in Stream Buffer
if (pStreamBegin <= pStreamEnd)
{
nBufFilled = pStreamEnd - pStreamBegin;
ASSERT(nBufFilled >= 0);
//select the buffer length we can send to SDK
if(len >= nBufFilled)
{
memcpy(p, pStreamBegin, nBufFilled);
pStreamBegin += nBufFilled;
LeaveCriticalSection(&g_CriticalSection);
return nBufFilled;
}
else
{
memcpy(p, pStreamBegin, len);
pStreamBegin += len;
LeaveCriticalSection(&g_CriticalSection);
return len;
}
}
else
{
nBufFilled = pStreamEnd + STREAM_BUFFER_LEN - pStreamBegin;
ASSERT(nBufFilled >= 0);
//select the buffer length we can send to SDK
if(len >= nBufFilled)
{
//the buffer length is nBufFilled, all filled buffer will be copy to caller
memcpy(p, pStreamBegin, gStreamBuffer + STREAM_BUFFER_LEN - pStreamBegin);
memcpy(p+ (STREAM_BUFFER_LEN + gStreamBuffer - pStreamBegin), gStreamBuffer, nBufFilled - (gStreamBuffer + STREAM_BUFFER_LEN - pStreamBegin));
pStreamBegin = pStreamEnd;
LeaveCriticalSection(&g_CriticalSection);
return nBufFilled;
}
else
{
if(pStreamBegin + len < gStreamBuffer + STREAM_BUFFER_LEN)
{
//don't need to rotate
memcpy(p, pStreamBegin, len);
pStreamBegin += len;
LeaveCriticalSection(&g_CriticalSection);
return len;
}
else
{
//do rotation
memcpy(p, pStreamBegin, gStreamBuffer + STREAM_BUFFER_LEN - pStreamBegin);
memcpy(p + (STREAM_BUFFER_LEN + gStreamBuffer - pStreamBegin), gStreamBuffer, len - (gStreamBuffer + STREAM_BUFFER_LEN - pStreamBegin));
pStreamBegin = len + pStreamBegin - STREAM_BUFFER_LEN;
LeaveCriticalSection(&g_CriticalSection);
return len;
}
}
}
LeaveCriticalSection(&g_CriticalSection);
return 0;
}
loop's blog