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

📄 manager.cpp

📁 神龙卡 SDK_84xx_DShow_145_02.zip 这个是 windows 上二个是linux
💻 CPP
字号:
/***********************************************************************/
/* manager.cpp : Implementation of Memory Manager
*  REALmagic Quasar Hardware Library
*  Created by Kevin Vo
*  Copyright Sigma Designs Inc
*  Sigma Designs Proprietary and confidential
*  Created on 3/20/01
*  Description: It will maintain the FreeBuffer and MediaSample lists.
/************************************************************************/

/****h* MMDemux/MemManager
 * NAME
 *  MemManager
 * DESCRIPTION
 *  Memory Manager implementation.
 * COPYRIGHT
 *  Copyright 2000 Sigma Designs Inc. 
 *  355 Fairview Way, Milpitas, CA 95035-3024 USA. All Rights Reserved.  
 *  Sigma Designs Proprietary and Confidential
/*************************************************************************/


#include "pch.h"
#include "manager.h"
#include "mmutils.h"

#define TSBUFFER_SIZE 0x800     // Do not change this value
#define TSBUFFER_NUMBER 100     // Number of buffers in transport stream buffer list

////////////////////////////////////////////////////////////////////
/****f* MMDemux/MemManager::MemManager
 * USAGE
 *  MemManager (int uiNumOfBuffer, int uiNumOfMediaSample, DWORD dwBufferSize)
 * DESCRIPTION
 *  Constructor of the Memory Manager. It allocates memory of the buffer list
 *    and media sample list.
 * PARAMETERS
 *  int uiNumOfBuffer - Number of buffers to be allocated.
 *  int uiNumOfMediaSample - Number of MediaSamples to be allocated.
 *  DWORD dwBufferSize - The size of each buffer (32KB).
 * RETURN VALUE
 *  None
/**********************************************************************/
MemManager::MemManager(int iNumOfBuffer, int iNumOfMediaSample, 
	unsigned long dwBufferSize)
{
	int i = 0;
	CBuffer *pBuffer = 0;
	CIMediaSample *pMedia = 0;

	if (dwBufferSize == TSBUFFER_SIZE)
		dwBufferSize = TSBUFFER_SIZE + 1;

	m_iNumOfBuffer = iNumOfBuffer;
	m_iNumOfMediaSample = iNumOfMediaSample;

	m_iCurrentNumOfBuffer = iNumOfBuffer;
	m_iCurrentNumOfMediaSample = iNumOfMediaSample;

	m_dwDemuxBufferSize = dwBufferSize;
	m_dwTSBufferSize = TSBUFFER_SIZE;
	m_iNumOfTSBuffer = TSBUFFER_NUMBER;

	m_pDemuxBuffer = new BYTE[(iNumOfBuffer * dwBufferSize) + (TSBUFFER_NUMBER * TSBUFFER_SIZE)];
	if (m_pDemuxBuffer == 0)
		return;

	m_pCBufferList = new CBufferList();
	m_pTSCBufferList = new CBufferList();
	m_pCIMediaSampleList = new CIMediaSampleList();

	unsigned char* pTempPtr = m_pDemuxBuffer;
	// Buffers for demux
	for (i = 0; i < iNumOfBuffer; i++)
	{
		pBuffer = new CBuffer(this, m_dwDemuxBufferSize, pTempPtr);
		m_pCBufferList->SetBuffer(pBuffer);		
		pTempPtr += m_dwDemuxBufferSize;
	}
	// Transport stream buffers
	for (i = 0; i < m_iNumOfTSBuffer; i++)
	{
		pBuffer = new CBuffer (this, m_dwTSBufferSize, pTempPtr);
		m_pTSCBufferList->SetBuffer(pBuffer);
		pTempPtr += m_dwTSBufferSize;
	}
	for (i = 0; i < iNumOfMediaSample; i++)
	{
		pMedia = new CIMediaSample(this);
		m_pCIMediaSampleList->SetMediaSample(pMedia);
	}

	OSInitializeCriticalSection(&crBuffer);
	OSInitializeCriticalSection(&crTSBuffer);
	OSInitializeCriticalSection(&crMediaSample);
	m_hBufferSemaphore = CreateSemaphore(NULL, m_iNumOfBuffer, m_iNumOfBuffer, NULL);
	m_hTSBufferSemaphore = CreateSemaphore(NULL, m_iNumOfTSBuffer, m_iNumOfTSBuffer, NULL);
	m_hMediaSampleSemaphore = CreateSemaphore(NULL, m_iNumOfMediaSample, m_iNumOfMediaSample, NULL);
	if (m_hBufferSemaphore == NULL)
		MmDebugLogfile((MmDebugLevelLog, "CreateSemaphore - BufferSemaphore Error %ld", GetLastError()));
	if (m_hTSBufferSemaphore == NULL)
		MmDebugLogfile((MmDebugLevelLog, "CreateSemaphore - TSBufferSemaphore Error %ld", GetLastError()));
	if (m_hMediaSampleSemaphore == NULL)
		MmDebugLogfile((MmDebugLevelLog, "CreateSemaphore - m_hMediaSampleSemaphore Error %ld", GetLastError()));
}	

////////////////////////////////////////////////////////////////////
/****f* MMDemux/MemManager::MemManager
 * USAGE
 *  MemManager (unsigned char* buffer, unsigned long dwBufferSize)
 * DESCRIPTION
 *  Constructor of the Memory Manager. It allocates memory of the buffer list
 *    and media sample list. The demux will use 1/3 of the buffer for 
 *    Transport stream and 2/3 for demux.
 * PARAMETERS
 *  unsigned char* buffer - A pointer to the pre-allocated buffer.
 *  unsigned long dwBufferSize - Size of the buffer.
 * RETURN VALUE
 *  None
/**********************************************************************/
MemManager::MemManager(unsigned char* buffer, unsigned long dwBufferSize)
{
	int i = 0;
	CBuffer *pBuffer = 0;
	CIMediaSample *pMedia = 0;

	if (dwBufferSize < 0x8000)
	{
		MmDebugLogfile((MmDebugLevelTrace|MmDebugLevelLog, "Buffer is too small!!!"));
		return;
	}
	else
	{
		// Reserve 1/3 of the buffer for Transport Stream.
		m_iNumOfTSBuffer = (dwBufferSize / 3) / TSBUFFER_SIZE;
		m_dwTSBufferSize = (dwBufferSize / 3) / m_iNumOfTSBuffer;
		// Make 2/3 of the buffer as the demux buffer and devide it into 10 separate small buffers.
		m_iNumOfBuffer = 8;
		m_iNumOfMediaSample = (dwBufferSize / 2048) * 2;
		m_dwDemuxBufferSize = (dwBufferSize / 3 * 2) / m_iNumOfBuffer;
		if (m_dwTSBufferSize == m_dwDemuxBufferSize)
			m_dwTSBufferSize--;
	}

	m_iCurrentNumOfBuffer = m_iNumOfBuffer;
	m_iCurrentNumOfMediaSample = m_iNumOfMediaSample;

	m_pDemuxBuffer = 0;

	m_pCBufferList = new CBufferList();
	m_pTSCBufferList = new CBufferList();
	m_pCIMediaSampleList = new CIMediaSampleList();

	unsigned char* pTempPtr = buffer;
	// Buffer for demux
	for (i = 0; i < m_iNumOfBuffer; i++)
	{
		pBuffer = new CBuffer(this, m_dwDemuxBufferSize, pTempPtr);
		m_pCBufferList->SetBuffer(pBuffer);
		pTempPtr += m_dwDemuxBufferSize;
	}
	// Transport stream buffer
	for (i = 0; i < m_iNumOfTSBuffer; i++)
	{
		pBuffer = new CBuffer (this, m_dwTSBufferSize, pTempPtr);
		m_pTSCBufferList->SetBuffer(pBuffer);
		pTempPtr += m_dwTSBufferSize;
	}
	for (i = 0; i < m_iNumOfMediaSample; i++)
	{
		pMedia = new CIMediaSample(this);
		m_pCIMediaSampleList->SetMediaSample(pMedia);
	}

	OSInitializeCriticalSection(&crBuffer);
	OSInitializeCriticalSection(&crTSBuffer);
	OSInitializeCriticalSection(&crMediaSample);
	m_hBufferSemaphore = CreateSemaphore(NULL, m_iNumOfBuffer, m_iNumOfBuffer, NULL);
	m_hTSBufferSemaphore = CreateSemaphore(NULL, m_iNumOfTSBuffer, m_iNumOfTSBuffer, NULL);
	m_hMediaSampleSemaphore = CreateSemaphore(NULL, m_iNumOfMediaSample, m_iNumOfMediaSample, NULL);
	if (m_hBufferSemaphore == NULL)
		MmDebugLogfile((MmDebugLevelLog, "CreateSemaphore - BufferSemaphore Error %ld", GetLastError()));
	if (m_hTSBufferSemaphore == NULL)
		MmDebugLogfile((MmDebugLevelLog, "CreateSemaphore - TSBufferSemaphore Error %ld", GetLastError()));
	if (m_hMediaSampleSemaphore == NULL)
		MmDebugLogfile((MmDebugLevelLog, "CreateSemaphore - m_hMediaSampleSemaphore Error %ld", GetLastError()));
}

////////////////////////////////////////////////////////////////////

MemManager::~MemManager()
{	
	delete m_pCBufferList;
	delete m_pTSCBufferList;
	delete m_pCIMediaSampleList;
	if (m_pDemuxBuffer != 0)
		delete m_pDemuxBuffer;

#ifdef _LINUXAPPS_
	LinuxCloseSemaphore(m_hBufferSemaphore);
	LinuxCloseSemaphore(m_hTSBufferSemaphore);
	LinuxCloseSemaphore(m_hMediaSampleSemaphore); 
#else // _LINUXAPPS_
	CloseHandle(m_hBufferSemaphore);
	CloseHandle(m_hTSBufferSemaphore);
	CloseHandle(m_hMediaSampleSemaphore); 
#endif // _LINUXAPPS_
	OSDeleteCriticalSection(&crBuffer);
	OSDeleteCriticalSection(&crTSBuffer);
	OSDeleteCriticalSection(&crMediaSample);
}

////////////////////////////////////////////////////////////////////
/****f* MMDemux/MemManager::GetBuffer
 * USAGE
 *  CBuffer *GetBuffer()
 * DESCRIPTION
 *  Get an empty buffer from the buffer list. Only the main thread is
 *    calling this function.
 * PARAMETERS
 *  None.
 * RETURN VALUE
 *  A pointer to CBuffer.
 *  NULL if there isn't any buffer in the list.
/**********************************************************************/
CBuffer *MemManager::GetBuffer(void)
{
	if (WaitForSingleObject(m_hBufferSemaphore, INFINITE) == WAIT_FAILED)
	{
		MmDebugLogfile((MmDebugLevelLog, "GetBuffer - WaitForSingleObject Error %d", GetLastError()));
		return NULL;
	}

	CBuffer *pCBuffer = 0;
	OSEnterCriticalSection(&crBuffer);
	// Returns the top buffer from FreeBuffer list
	pCBuffer = m_pCBufferList->GetBuffer();
	pCBuffer->AddRef();
	OSLeaveCriticalSection(&crBuffer);

	return pCBuffer;
}

////////////////////////////////////////////////////////////////////
/****f* MMDemux/MemManager::GetMediaSample
 * USAGE
 *  void GetMediaSample (CBuffer *pBuffer, CIMediaSample **pMedia)
 * DESCRIPTION
 *  Get a MediaSample from the media sample list and sets a pointer to the
 *    buffer that this media sample will point to. Only the main thread is
 *    calling this function.
 * PARAMETERS
 *  CBuffer *pBuffer - A pointer to the CBuffer that this MediaSample will point to.
 *  CIMediaSample **pMedia - A pointer to the pointer to MediaSample. It's NULL
 *    initially.
 * RETURN VALUE
 *  None
/**********************************************************************/
void MemManager::GetMediaSample(CBuffer *pBuffer, CIMediaSample **pMedia)
{
	if (WaitForSingleObject(m_hMediaSampleSemaphore, INFINITE) == WAIT_FAILED)
	{
		MmDebugLogfile((MmDebugLevelLog, "GetMediaSample - WaitForSingleObject Error %d", GetLastError()));
		return;
	}

	OSEnterCriticalSection(&crMediaSample);
	if ((*pMedia = m_pCIMediaSampleList->GetMediaSample()) != NULL)
	{
		(*pMedia)->SetCBuffer(pBuffer);
		pBuffer->AddRef();
		(*pMedia)->AddRef();
	}
	OSLeaveCriticalSection(&crMediaSample);
}

///////////////////////////////////////////////////////////////////
/****f* MMDemux/MemManager::GetTSBuffer
 * USAGE
 *  CBuffer *GetTSBuffer()
 * DESCRIPTION
 *  Get an empty buffer from the buffer list. Splitter will call this
 *    function if the file is of Transport Stream type.
 * PARAMETERS
 *  None.
 * RETURN VALUE
 *  A pointer to CBuffer.
 *  NULL if there isn't any buffer in the list.
/**********************************************************************/
CBuffer *MemManager::GetTSBuffer(void)
{
	if (WaitForSingleObject(m_hTSBufferSemaphore, INFINITE) == WAIT_FAILED)
	{
		MmDebugLogfile((MmDebugLevelLog, "GetTBuffer - WaitForSingleObject Error %d", GetLastError()));
		return NULL;
	}

	CBuffer *pCBuffer = 0;
	OSEnterCriticalSection(&crTSBuffer);
	// Returns the top buffer from FreeBuffer list
	pCBuffer = m_pTSCBufferList->GetBuffer();
	pCBuffer->AddRef();
	OSLeaveCriticalSection(&crTSBuffer);

	return pCBuffer;
}

////////////////////////////////////////////////////////////////////
/****f* MMDemux/MemManager::ReleaseMediaSample
 * USAGE
 *  void ReleaseMediaSample (CIMediaSample *pMedia)
 * DESCRIPTION
 *  Put the MediaSample back to MediaSample list. The COM thread will call
 *    this function if the application is using COM; otherwise, the SendToHardware
 *    function will call it.
 * PARAMETERS
 *  CIMediaSample *pMedia - A pointer to the CIMediaSample that will be inserted
 *    to the MediaSample list.
 * RETURN VALUE
 *  None
/**********************************************************************/
void MemManager::ReleaseMediaSample(CIMediaSample *pMedia)
{
	if (pMedia != NULL)
	{
		OSEnterCriticalSection(&crMediaSample);
		CBuffer *pBuffer = pMedia->GetCBuffer();
		pBuffer->Release();
		m_pCIMediaSampleList->SetMediaSample(pMedia);
		if (ReleaseSemaphore(m_hMediaSampleSemaphore, 1, NULL) == 0)
			MmDebugLogfile((MmDebugLevelLog, "ReleaseMediaSample - ReleaseSemaphore Error %ld", GetLastError()));
		OSLeaveCriticalSection(&crMediaSample);
	}
}

////////////////////////////////////////////////////////////////////
/****f* MMDemux/MemManager::ReleaseBuffer
 * USAGE
 *  void ReleaseBuffer (CBuffer *pBuffer)
 * DESCRIPTION
 *  Put the buffer back to the buffer list. The COM thread will call this function.
 * PARAMETERS
 *  CBuffer *pBuffer - A pointer to the CBuffer that will be inserted into
 *    the buffer list.
 * RETURN VALUE
 *  None
/**********************************************************************/
void MemManager::ReleaseBuffer(CBuffer *pBuffer)
{
	if (pBuffer != NULL)
	{
		// Transport stream buffer. The other buffer is 32Kb by default. This's 2Kb.
		if (pBuffer->GetSize() == m_dwTSBufferSize)
		{
			OSEnterCriticalSection(&crTSBuffer);
			m_pTSCBufferList->SetBuffer(pBuffer);
			if (ReleaseSemaphore(m_hTSBufferSemaphore, 1, 0) == 0)
				MmDebugLogfile((MmDebugLevelLog, "ReleaseTBuffer - ReleaseSemaphore Error %ld", GetLastError()));
			OSLeaveCriticalSection(&crTSBuffer);
//			MmDebugLogfile((MmDebugLevelTrace, "Rel %X", pBuffer));
		}
		else
		{
			OSEnterCriticalSection(&crBuffer);
			m_pCBufferList->SetBuffer(pBuffer);
			if (ReleaseSemaphore(m_hBufferSemaphore, 1, (long*)&m_iCurrentNumOfBuffer) == 0)
				MmDebugLogfile((MmDebugLevelLog, "ReleaseBuffer - ReleaseSemaphore Error %ld", GetLastError()));
			OSLeaveCriticalSection(&crBuffer);
//			MmDebugLogfile((MmDebugLevelTrace, "Rel %X %d", pBuffer, m_iCurrentNumOfBuffer + 1));
		}
	}
}

///////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -