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

📄 cpi_circlebuffer.c

📁 VC++视频开发实例集锦(包括“远程视频监控”"语音识别系统"等13个经典例子)
💻 C
字号:




#include "stdafx.h"
#include "globals.h"
#include "CPI_CircleBuffer.h"


#define CIC_WAITTIMEOUT		3000
void CircleBufferUninitialise(CPs_CircleBuffer* pCBuffer);
void CircleBufferWrite(CPs_CircleBuffer* pCBuffer, const void* pSourceBuffer, const unsigned int iNumBytes);
BOOL CircleBufferRead(CPs_CircleBuffer* pCBuffer, void* pDestBuffer, const unsigned int iBytesToRead, unsigned int* pbBytesRead);
void CircleFlush(CPs_CircleBuffer* pCBuffer);
unsigned int CircleGetFreeSpace(CPs_CircleBuffer* pCBuffer);
unsigned int CircleGetUsedSpace(CPs_CircleBuffer* pCBuffer);
void CircleSetComplete(CPs_CircleBuffer* pCBuffer);
BOOL CircleIsComplete(CPs_CircleBuffer* pCBuffer);
////////////////////////////////////////////////////////////////////////////////

CPs_CircleBuffer* CP_CreateCircleBuffer(const unsigned int iBufferSize)
{
    CPs_CircleBuffer* pNewBuffer = (CPs_CircleBuffer*)malloc(sizeof(CPs_CircleBuffer));

    pNewBuffer->Uninitialise = CircleBufferUninitialise;
    pNewBuffer->Write = CircleBufferWrite;
    pNewBuffer->Read = CircleBufferRead;
    pNewBuffer->Flush = CircleFlush;
    pNewBuffer->GetUsedSize = CircleGetUsedSpace;
    pNewBuffer->GetFreeSize = CircleGetFreeSpace;
    pNewBuffer->SetComplete = CircleSetComplete;
    pNewBuffer->IsComplete = CircleIsComplete;

    pNewBuffer->m_iBufferSize = iBufferSize;
    pNewBuffer->m_pBuffer = (BYTE*)malloc(iBufferSize);
    pNewBuffer->m_iReadCursor = 0;
    pNewBuffer->m_iWriteCursor = 0;
    pNewBuffer->m_bComplete = FALSE;
    pNewBuffer->m_evtDataAvailable = CreateEvent(NULL, FALSE, FALSE, NULL);
    InitializeCriticalSection(&pNewBuffer->m_csCircleBuffer);

    return pNewBuffer;
}
//
//
//
void CircleBufferUninitialise(CPs_CircleBuffer* pCBuffer)
{
    CP_CHECKOBJECT(pCBuffer);
    DeleteCriticalSection(&pCBuffer->m_csCircleBuffer);
    CloseHandle(pCBuffer->m_evtDataAvailable);
    free(pCBuffer->m_pBuffer);
    free(pCBuffer);
}
//
//
//
void CircleBufferWrite(CPs_CircleBuffer* pCBuffer, const void* _pSourceBuffer, const unsigned int _iNumBytes)
{
    unsigned int iBytesToWrite = _iNumBytes;
    BYTE* pReadCursor = (BYTE*)_pSourceBuffer;

    CP_ASSERT(iBytesToWrite <= pCBuffer->GetFreeSize(pCBuffer));
    CP_ASSERT(pCBuffer->m_bComplete == FALSE);

    EnterCriticalSection(&pCBuffer->m_csCircleBuffer);

    if(pCBuffer->m_iWriteCursor >= pCBuffer->m_iReadCursor)
    {
        unsigned int iChunkSize = pCBuffer->m_iBufferSize - pCBuffer->m_iWriteCursor;
        if(iChunkSize > iBytesToWrite)
            iChunkSize = iBytesToWrite;

        memcpy(pCBuffer->m_pBuffer + pCBuffer->m_iWriteCursor,
               pReadCursor, iChunkSize);
        pReadCursor += iChunkSize;
        iBytesToWrite -= iChunkSize;

        pCBuffer->m_iWriteCursor += iChunkSize;
        if(pCBuffer->m_iWriteCursor >= pCBuffer->m_iBufferSize)
            pCBuffer->m_iWriteCursor -= pCBuffer->m_iBufferSize;
    }

    if(iBytesToWrite)
    {
        memcpy(pCBuffer->m_pBuffer + pCBuffer->m_iWriteCursor,
               pReadCursor, iBytesToWrite);
        pCBuffer->m_iWriteCursor += iBytesToWrite;
        CP_ASSERT(pCBuffer->m_iWriteCursor < pCBuffer->m_iBufferSize);
    }

    SetEvent(pCBuffer->m_evtDataAvailable);
    LeaveCriticalSection(&pCBuffer->m_csCircleBuffer);
}
//

BOOL CircleBufferRead(CPs_CircleBuffer* pCBuffer, void* pDestBuffer, const unsigned int _iBytesToRead, unsigned int* pbBytesRead)
{
    unsigned int iBytesToRead = _iBytesToRead;
    unsigned int iBytesRead = 0;
    DWORD dwWaitResult;
    BOOL bComplete = FALSE;
    CP_CHECKOBJECT(pCBuffer);

    while(iBytesToRead > 0 && bComplete == FALSE)
    {
        dwWaitResult = WaitForSingleObject(pCBuffer->m_evtDataAvailable, CIC_WAITTIMEOUT);
        if(dwWaitResult == WAIT_TIMEOUT)
        {
            CP_TRACE0("Circle buffer - did not fill in time!");
            *pbBytesRead = iBytesRead;
            return FALSE;
        }

        EnterCriticalSection(&pCBuffer->m_csCircleBuffer);

        if(pCBuffer->m_iReadCursor > pCBuffer->m_iWriteCursor)
        {
            unsigned int iChunkSize = pCBuffer->m_iBufferSize - pCBuffer->m_iReadCursor;
            if(iChunkSize > iBytesToRead)
                iChunkSize = iBytesToRead;

            memcpy((BYTE*)pDestBuffer + iBytesRead,
                   pCBuffer->m_pBuffer + pCBuffer->m_iReadCursor,
                   iChunkSize);

            iBytesRead += iChunkSize;
            iBytesToRead -= iChunkSize;

            pCBuffer->m_iReadCursor += iChunkSize;
            if(pCBuffer->m_iReadCursor >= pCBuffer->m_iBufferSize)
                pCBuffer->m_iReadCursor -= pCBuffer->m_iBufferSize;
        }

        if(iBytesToRead && pCBuffer->m_iReadCursor < pCBuffer->m_iWriteCursor)
        {
            unsigned int iChunkSize = pCBuffer->m_iWriteCursor - pCBuffer->m_iReadCursor;
            if(iChunkSize > iBytesToRead)
                iChunkSize = iBytesToRead;

            memcpy((BYTE*)pDestBuffer + iBytesRead,
                   pCBuffer->m_pBuffer + pCBuffer->m_iReadCursor,
                   iChunkSize);

            iBytesRead += iChunkSize;
            iBytesToRead -= iChunkSize;
            pCBuffer->m_iReadCursor += iChunkSize;
        }

        if(pCBuffer->m_iReadCursor == pCBuffer->m_iWriteCursor)
        {
            if(pCBuffer->m_bComplete)
                bComplete = TRUE;
        }
        else
            SetEvent(pCBuffer->m_evtDataAvailable);

        LeaveCriticalSection(&pCBuffer->m_csCircleBuffer);
    }

    *pbBytesRead = iBytesRead;
    return bComplete ? FALSE : TRUE;
}
//
//
//
void CircleFlush(CPs_CircleBuffer* pCBuffer)
{
    CP_CHECKOBJECT(pCBuffer);

    EnterCriticalSection(&pCBuffer->m_csCircleBuffer);
    pCBuffer->m_iReadCursor = 0;
    pCBuffer->m_iWriteCursor = 0;
    LeaveCriticalSection(&pCBuffer->m_csCircleBuffer);
}
//
//
//
unsigned int CircleGetFreeSpace(CPs_CircleBuffer* pCBuffer)
{
    unsigned int iNumBytesFree;

    CP_CHECKOBJECT(pCBuffer);
    EnterCriticalSection(&pCBuffer->m_csCircleBuffer);

    if(pCBuffer->m_iWriteCursor < pCBuffer->m_iReadCursor)
        iNumBytesFree = (pCBuffer->m_iReadCursor-1) - pCBuffer->m_iWriteCursor;
    else if(pCBuffer->m_iWriteCursor == pCBuffer->m_iReadCursor)
        iNumBytesFree = pCBuffer->m_iBufferSize;
    else
        iNumBytesFree = (pCBuffer->m_iReadCursor-1) + (pCBuffer->m_iBufferSize - pCBuffer->m_iWriteCursor);

    LeaveCriticalSection(&pCBuffer->m_csCircleBuffer);
    return iNumBytesFree;
}
//
//
//
unsigned int CircleGetUsedSpace(CPs_CircleBuffer* pCBuffer)
{
    return pCBuffer->m_iBufferSize - CircleGetFreeSpace(pCBuffer);
}
//
//
//
void CircleSetComplete(CPs_CircleBuffer* pCBuffer)
{
    CP_CHECKOBJECT(pCBuffer);

    EnterCriticalSection(&pCBuffer->m_csCircleBuffer);
    pCBuffer->m_bComplete = TRUE;
    SetEvent(pCBuffer->m_evtDataAvailable);
    LeaveCriticalSection(&pCBuffer->m_csCircleBuffer);
}
//
//
//
BOOL CircleIsComplete(CPs_CircleBuffer* pCBuffer)
{
    return pCBuffer->m_bComplete;
}
//
//
//

⌨️ 快捷键说明

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