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

📄 syncfifo.cpp

📁 播放被H264_AAC所压缩的avi文件的播放器。
💻 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 + -