zoukankan      html  css  js  c++  java
  • simple circular buffer

    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;
    }
    loop's blog
  • 相关阅读:
    2016.7.26
    2016.7.25
    2016.7.24
    C/C++基本数据类型所占字节数
    几个STL算法:includes,set_difference、set_intersection、set_symmetric_difference、set_union, pre_permutation, next_permutation
    h5 如何打包apk
    Ajax XMLHttpRequest对象的三个属性以及open和send方法
    twisted 使用
    python 的内建函数
    python中的 json 模块使用
  • 原文地址:https://www.cnblogs.com/goodloop/p/1631413.html
Copyright © 2011-2022 走看看