📄 syncfifo.cpp
字号:
/*
* H.264/AVC Streaming Server(HSS), ver 1.0
* Copyright (c) KCC-Eoun Information Center
*
* File: SyncFifo.cpp
* Description: Declare the fifo buffer.
*
* The Initial Writer of Original Code is Song Chol.Jo
*
* $Log: SyncFifo.cpp, v $
* Revision 1.0 2006-08-10 Song Chol.Jo
* Initial version
*/
#include <windows.h>
#include "SyncFifo.h"
#include "Log.h"
#define _USE_FIFO_USING_EVENT_
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//##ModelId=4753B7E90251
CSyncFifo::CSyncFifo( UINT nChunkSize, UINT nChunkNum, UINT nEmptyJitterNum, UINT nFullJitterNum, BOOL bIsPushInfinite, BOOL bIsPopInfinite )
{
InitFifo(nChunkSize, nChunkNum, nEmptyJitterNum, nFullJitterNum, bIsPushInfinite, bIsPopInfinite);
}
//##ModelId=4753B7E90261
CSyncFifo::~CSyncFifo()
{
RemoveFifo();
}
/************************************************************************/
/* */
/************************************************************************/
// Function :
// Parameter:
// Return :
//##ModelId=4753B7E90263
PVOID CSyncFifo::GetPushBuffer(UINT nSize)
{
unsigned long ulRet;
if(m_bIsPushInfinite)
{
#ifdef _USE_FIFO_USING_EVENT_
HANDLE hEventSet[2];
hEventSet[0] = m_hNotUseFifoEvent;
hEventSet[1] = m_hNotFullEvent;
ulRet = WaitForMultipleObjects(2, hEventSet, TRUE, INFINITE);
ResetEvent(m_hNotUseFifoEvent);
#else
ulRet = WaitForSingleObject(m_hNotFullEvent, INFINITE);
#endif _USE_FIFO_USING_EVENT_
}
else
{
ulRet = WaitForSingleObject(m_hNotFullEvent, 0);
if(ulRet != WAIT_OBJECT_0)
{
return NULL;
}
}
if(m_pPushChunk == NULL)
return NULL;
if(nSize <= m_nFreeMem)
{
if(m_pPushChunk->nPos >= m_pPopChunk->nPos)
{
UINT nRemFree = m_nFifoSize - m_pPushChunk->nPos;
if(nSize > nRemFree)
{
m_nFreeMem -= nRemFree;
m_nEndFreeMem = nRemFree;
m_pPushChunk->nPos = 0;
if(nSize > m_nFreeMem)
goto FULL_POS;
}
}
PVOID pPushBuffer = (PVOID)((BYTE*)m_pFifoMem + m_pPushChunk->nPos);
m_pPushChunk->bIsUsing = TRUE;
#ifdef _USE_FIFO_USING_EVENT_
SetEvent(m_hNotUseFifoEvent);
#endif _USE_FIFO_USING_EVENT_
return pPushBuffer;
}
FULL_POS:
ResetEvent(m_hNotFullEvent);
#ifdef _USE_FIFO_USING_EVENT_
SetEvent(m_hNotUseFifoEvent);
#endif _USE_FIFO_USING_EVENT_
return GetPushBuffer(nSize);
}
/************************************************************************/
/* */
/************************************************************************/
// Function :
// Parameter:
// Return :
//##ModelId=4753B7E90265
void CSyncFifo::Push(UINT nSize, UINT nTime)
{
#ifdef _USE_FIFO_USING_EVENT_
unsigned long ulRet;
ulRet = WaitForSingleObject(m_hNotUseFifoEvent, INFINITE);
#endif _USE_FIFO_USING_EVENT_
if(m_pPushChunk == NULL)
return;
m_pPushChunk->nSize = nSize;
m_pPushChunk->nTime = nTime;
m_nFreeMem -= nSize;
// PushChunk狼 菊狼 Chunk啊 泅犁 府侩吝捞扼搁...
if(m_pPushChunk->pNextChunk == NULL)
return;
if(m_pPushChunk->pNextChunk->bIsUsing)
{
InsertFifoChunk();
}
m_nCurChunkNum ++;
m_pPushChunk->pNextChunk->nPos = m_pPushChunk->nPos + m_pPushChunk->nSize;
m_pPushChunk = m_pPushChunk->pNextChunk;
if(m_nCurChunkNum >= m_nEmptyJitterNum)
{
SetEvent(m_hNotEmptyEvent);
}
#ifdef _USE_FIFO_USING_EVENT_
SetEvent(m_hNotUseFifoEvent);
#endif _USE_FIFO_USING_EVENT_
}
/************************************************************************/
/* */
/************************************************************************/
// Function :
// Parameter:
// Return :
//##ModelId=4753B7E90273
PVOID CSyncFifo::Pop(UINT *nSize, UINT *nTime)
{
unsigned long ulRet;
if(m_bIsPopInfinite)
{
#ifdef _USE_FIFO_USING_EVENT_
HANDLE hEventSet[2];
hEventSet[0] = m_hNotUseFifoEvent;
hEventSet[1] = m_hNotEmptyEvent;
ulRet = WaitForMultipleObjects(2, hEventSet, TRUE, INFINITE);
ResetEvent(m_hNotUseFifoEvent);
#else
ulRet = WaitForSingleObject(m_hNotEmptyEvent, INFINITE);
#endif _USE_FIFO_USING_EVENT_
}else{
ulRet = WaitForSingleObject(m_hNotEmptyEvent, 0);
if(ulRet != WAIT_OBJECT_0)
{
return NULL;
}
}
if(m_pPopChunk == NULL)
return NULL;
PVOID pPopBuffer;
*nSize = m_pPopChunk->nSize;
if(nTime)
*nTime = m_pPopChunk->nTime;
pPopBuffer = (PVOID)((BYTE*)m_pFifoMem + m_pPopChunk->nPos);
if(m_bPopFirst)
{
m_bPopFirst = FALSE;
}
else
{
m_nFreeMem += m_pPopChunk->pPrevChunk->nSize;
m_pPopChunk->pPrevChunk->bIsUsing = FALSE;
}
if((m_pPopChunk->nPos == 0)&&(m_nEndFreeMem != 0))
{
m_nFreeMem += m_nEndFreeMem;
m_nEndFreeMem = 0;
}
m_nCurChunkNum --;
m_pPopChunk = m_pPopChunk->pNextChunk;
// Check for empty.
if(m_nCurChunkNum == 0)
{
ResetEvent(m_hNotEmptyEvent);
LogMsg(LOG_DEBUG, HCLN, "Fifo is empty!");
}
// Check for full.
SetEvent(m_hNotFullEvent);
#ifdef _USE_FIFO_USING_EVENT_
SetEvent(m_hNotUseFifoEvent);
#endif _USE_FIFO_USING_EVENT_
return pPopBuffer;
}
/************************************************************************/
/* */
/************************************************************************/
// Function :
// Parameter:
// Return :
//##ModelId=4753B7E90294
BOOL CSyncFifo::InitFifo( UINT nChunkSize, UINT nChunkNum, UINT nEmptyJitterNum, UINT nFullJitterNum, BOOL bIsPushInfinite, BOOL bIsPopInfinite )
{
m_pPushChunk = NULL;
m_pPopChunk = NULL;
m_nCurFifoChunkNum = 0;
m_nCurChunkNum = 0;
m_nChunkSize = nChunkSize;
m_nRestoreEmptyJitterNum = m_nEmptyJitterNum = nEmptyJitterNum;
m_nRestoreFullJitterNum = m_nFullJitterNum = nFullJitterNum;
m_bPushFirst = TRUE;
m_bPopFirst = TRUE;
m_bIsPushInfinite = bIsPushInfinite;
m_bIsPopInfinite = bIsPopInfinite;
// Create the FifoMemory.
m_nFifoSize = nChunkSize * nChunkNum;
m_nFreeMem = m_nFifoSize;
m_nEndFreeMem = 0;
m_pFifoMem = new unsigned char[m_nFifoSize];
if(!m_pFifoMem)
{
LogMsg(LOG_CRIT, HCLN, "Cannot allocate the fifo memory!");
return FALSE;
}
// Configure the fifo chunk list.
PFIFOCHUNK pTempFifoChunk;
pTempFifoChunk = new FIFOCHUNK;
memset(pTempFifoChunk, 0, sizeof(FIFOCHUNK));
pTempFifoChunk->nID = 0;
m_pPushChunk = pTempFifoChunk;
m_pPopChunk = pTempFifoChunk;
m_nCurFifoChunkNum ++;
for(UINT count = 1; count <= nChunkNum; count ++)
{
pTempFifoChunk = new FIFOCHUNK;
memset(pTempFifoChunk, 0, sizeof(FIFOCHUNK));
pTempFifoChunk->nID = count;
m_pPopChunk->pNextChunk = pTempFifoChunk;
pTempFifoChunk->pPrevChunk = m_pPopChunk;
m_pPopChunk = pTempFifoChunk;
m_nCurFifoChunkNum ++;
}
m_pPopChunk->pNextChunk = m_pPushChunk;
m_pPushChunk->pPrevChunk = m_pPopChunk;
m_pPopChunk = m_pPushChunk;
m_pInitChunk = m_pPushChunk;
// Create the Events.
#ifdef _USE_FIFO_USING_EVENT_
m_hNotUseFifoEvent = CreateEvent(NULL, TRUE,TRUE,NULL);
if(m_hNotUseFifoEvent == NULL)
{
LogMsg(LOG_CRIT, HCLN, "Cannot create the event!");
return FALSE;
}
#endif _USE_FIFO_USING_EVENT_
m_hNotFullEvent = CreateEvent(NULL, TRUE,TRUE,NULL);
if(m_hNotFullEvent == NULL)
{
LogMsg(LOG_CRIT, HCLN, "Cannot create the event!");
#ifdef _USE_FIFO_USING_EVENT_
CloseHandle(m_hNotUseFifoEvent);
m_hNotUseFifoEvent = NULL;
#endif _USE_FIFO_USING_EVENT_
return FALSE;
}
m_hNotEmptyEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
if(m_hNotEmptyEvent == NULL)
{
LogMsg(LOG_CRIT, HCLN, "Cannot create the event!");
#ifdef _USE_FIFO_USING_EVENT_
CloseHandle(m_hNotUseFifoEvent);
m_hNotUseFifoEvent = NULL;
#endif _USE_FIFO_USING_EVENT_
CloseHandle(m_hNotFullEvent);
m_hNotFullEvent = NULL;
return FALSE;
}
return TRUE;
}
/************************************************************************/
/* */
/************************************************************************/
// Function :
// Parameter:
// Return :
//##ModelId=4753B7E902A3
void CSyncFifo::RemoveFifo()
{
PFIFOCHUNK pTempChunk;
// Free the allocated chunk list.
for(UINT count = 0; count < m_nCurFifoChunkNum; count ++)
{
pTempChunk = m_pPopChunk->pNextChunk;
delete m_pPopChunk;
m_pPopChunk = pTempChunk;
}
pTempChunk = NULL;
m_pPushChunk = NULL;
m_pPopChunk = NULL;
// Free the fifo memory.
delete m_pFifoMem;
m_pFifoMem = NULL;
#ifdef _USE_FIFO_USING_EVENT_
CloseHandle(m_hNotUseFifoEvent);
m_hNotUseFifoEvent = NULL;
#endif _USE_FIFO_USING_EVENT_
CloseHandle(m_hNotFullEvent);
m_hNotFullEvent = NULL;
CloseHandle(m_hNotEmptyEvent);
m_hNotEmptyEvent = NULL;
return;
}
/************************************************************************/
/* */
/************************************************************************/
// Function :
// Parameter:
// Return :
//##ModelId=4753B7E90272
UINT CSyncFifo::GetPopTime()
{
if(m_pPopChunk != NULL)
return m_pPopChunk->nTime;
return ERROR_CODE;
}
/************************************************************************/
/* */
/************************************************************************/
// Function :
// Parameter:
// Return :
//##ModelId=4753B7E90276
HANDLE CSyncFifo::GetEventHandle()
{
return m_hNotEmptyEvent;
}
/************************************************************************/
/* */
/************************************************************************/
// Function :
// Parameter:
// Return :
//##ModelId=4753B7E902A4
void CSyncFifo::InsertFifoChunk()
{
PFIFOCHUNK pTempFifoChunk;
pTempFifoChunk = new FIFOCHUNK;
memset(pTempFifoChunk, 0, sizeof(FIFOCHUNK));
pTempFifoChunk->nID = m_nCurFifoChunkNum;
pTempFifoChunk->pNextChunk = m_pPushChunk->pNextChunk;
pTempFifoChunk->pPrevChunk = m_pPushChunk;
m_pPushChunk->pNextChunk = pTempFifoChunk;
m_nCurFifoChunkNum ++;
}
//##ModelId=4753B7E90291
BOOL CSyncFifo::IsJitterFull()
{
if(m_nFreeMem < m_nFullJitterNum * m_nChunkSize)
return TRUE;
else
return FALSE;
}
//##ModelId=4753B7E90290
BOOL CSyncFifo::IsJitterEmpty()
{
if(m_nCurChunkNum <= m_nEmptyJitterNum)
return TRUE;
else
return FALSE;
}
//##ModelId=4753B7E90286
void CSyncFifo::Empty()
{
LogMsg(LOG_INFO, HCLN, "SyncFifo is emptyed before state CurChunkNums= %d FreeMem = %d", m_nCurChunkNum, m_nFreeMem);
m_pInitChunk->nPos = 0;
m_pPopChunk = m_pPushChunk = m_pInitChunk;
m_nCurChunkNum = 0;
// m_nCurFifoChunkNum = 0;
m_nFreeMem = m_nFifoSize;
m_nEndFreeMem = 0;
PFIFOCHUNK pTemp = m_pInitChunk;
for(UINT nCount = 0; nCount < m_nCurFifoChunkNum; nCount++ )
{
pTemp->bIsUsing = FALSE;
pTemp->nSize = 0;
pTemp->nTime = 0;
pTemp = pTemp->pNextChunk;
}
memset(m_pFifoMem, 0, m_nFifoSize);
ResetEvent(m_hNotEmptyEvent);
SetEvent(m_hNotFullEvent);
}
//##ModelId=4753B7E90284
void CSyncFifo::SetEmptyJitterNum(UINT nEmptyJitterNum)
{
m_nRestoreEmptyJitterNum = m_nEmptyJitterNum;
m_nEmptyJitterNum = nEmptyJitterNum;
}
//##ModelId=4753B7E90282
void CSyncFifo::SetFullJitterNum(UINT nFullJitterNum)
{
m_nRestoreFullJitterNum = m_nFullJitterNum;
m_nFullJitterNum = nFullJitterNum;
}
//##ModelId=4753B7E90281
void CSyncFifo::RestoreEmptyJitterNum()
{
m_nEmptyJitterNum = m_nRestoreEmptyJitterNum;
}
//##ModelId=4753B7E90280
void CSyncFifo::RestoreFullJitterNum()
{
m_nFullJitterNum = m_nRestoreFullJitterNum;
}
//##ModelId=4753B7E90292
BOOL CSyncFifo::CheckIsBuffering(UINT &nPercent)
{
unsigned long ulRet;
ulRet = WaitForSingleObject(m_hNotEmptyEvent, 0);
if(ulRet != WAIT_OBJECT_0)
{
nPercent = m_nCurChunkNum * 100 / m_nEmptyJitterNum;
return TRUE;
}
nPercent = m_nCurChunkNum;
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -