123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- /**********************************************************************************
- *
- * Copyright (c) 2019-2020 Beijing AXera Technology Co., Ltd. All Rights Reserved.
- *
- * This source file is the property of Beijing AXera Technology Co., Ltd. and
- * may not be copied or distributed in any isomorphic form without the prior
- * written consent of Beijing AXera Technology Co., Ltd.
- *
- **********************************************************************************/
- #ifndef _RING_BUFFER_3246FC57_D0F1_4176_A1C3_3A16FC46D1CF_H_
- #define _RING_BUFFER_3246FC57_D0F1_4176_A1C3_3A16FC46D1CF_H_
- #include "ax_base_type.h"
- #include <tuple>
- #include <mutex>
- #define COMM_RING_PRT(fmt...) \
- do {\
- printf("[RING][%s]: ", __FUNCTION__);\
- printf(fmt);\
- printf("\n");\
- }while(0)
- class CAXRingBuffer;
- class CAXRingElement {
- public:
- CAXRingElement() {
- this->pBuf = nullptr;
- this->nSize = 0;
- this->nChannel = 0;
- this->bIFrame = AX_FALSE;
- this->nPts = 0;
- this->nRefCount = 0;
- this->pParent = nullptr;
- }
- CAXRingElement(AX_U8* pBuf, AX_U32 nSize, AX_U32 nChn, AX_U64 u64PTS = 0, AX_BOOL isIFrame = AX_FALSE) {
- this->nIndex = -1;
- this->pBuf = pBuf;
- this->nSize = nSize;
- this->nChannel = nChn;
- this->nPts = u64PTS;
- this->bIFrame = isIFrame;
- this->nRefCount = 0;
- this->pParent = nullptr;
- }
- AX_VOID CopyFrom(CAXRingElement &element) {
- if(this->pBuf) {
- memcpy(this->pBuf, element.pBuf, element.nSize);
- }
- this->nSize = element.nSize;
- this->nChannel = element.nChannel;
- this->nPts = element.nPts;
- this->bIFrame = element.bIFrame;
- this->nRefCount = 0;
- this->pParent = nullptr;
- }
- AX_S32 IncreaseRefCount() {
- return ++nRefCount;
- }
- AX_S32 DecreaseRefCount(AX_BOOL bForceClear) {
- if (bForceClear) {
- nRefCount = 0;
- }
- else {
- --nRefCount;
- if (nRefCount < 0) {
- nRefCount = 0;
- }
- }
- return nRefCount;
- }
- AX_S32 GetRefCount() {
- return nRefCount;
- }
- AX_S32 GetIndex() {
- return nIndex;
- }
- AX_S32 SetIndex(AX_S32 nIndex) {
- return this->nIndex = nIndex;
- }
- private:
- AX_VOID Clear() {
- this->nSize = 0;
- this->nChannel = 0;
- this->bIFrame = AX_FALSE;
- this->nPts = 0;
- this->nRefCount = 0;
- }
- public:
- AX_U8* pBuf;
- AX_U32 nSize;
- AX_U32 nChannel;
- AX_U64 nPts;
- AX_BOOL bIFrame;
- CAXRingBuffer * pParent;
- private:
- AX_S32 nRefCount;
- AX_S32 nIndex;
- };
- #define AXRING "RING"
- class CAXRingBuffer
- {
- public:
- CAXRingBuffer(AX_U32 nElementBuffSize, AX_U32 nElementCount, const char * pszName=nullptr ) {
- m_nElementCount = nElementCount;
- m_nElementBuffSize = nElementBuffSize;
- m_pRing = new CAXRingElement[m_nElementCount];
- for (AX_U32 i = 0; i < m_nElementCount; i++) {
- m_pRing[i].pBuf = new AX_U8[m_nElementBuffSize];
- memset((AX_VOID *)m_pRing[i].pBuf, 0x0, m_nElementBuffSize);
- m_pRing[i].nSize = 0;
- m_pRing[i].pParent = this;
- m_pRing[i].SetIndex(i);
- }
- m_nHeader = 0;
- m_nTail = 0;
- m_bHasLost = AX_FALSE;
- m_szName[0] = 0;
- if (pszName && strlen(pszName)) {
- strncpy(m_szName, pszName, sizeof(m_szName));
- }
- }
- ~CAXRingBuffer(AX_VOID) {
- m_nHeader = 0;
- m_nTail = 0;
- if (nullptr == m_pRing) {
- return;
- }
- m_mutex.lock();
- for (AX_U32 i = 0; i < m_nElementCount; i++) {
- if (nullptr != m_pRing[i].pBuf) {
- delete[] m_pRing[i].pBuf;
- }
- }
- delete[] m_pRing;
- m_mutex.unlock();
- }
- AX_BOOL IsFull() {
- std::lock_guard<std::mutex> lck (m_mutex);
- return (m_nTail - m_nHeader) == m_nElementCount ? AX_TRUE : AX_FALSE;
- }
- AX_BOOL IsEmpty() {
- std::lock_guard<std::mutex> lck (m_mutex);
- return (m_nTail == m_nHeader) ? AX_TRUE : AX_FALSE;
- }
- AX_BOOL Put(CAXRingElement &element) {
- std::lock_guard<std::mutex> lck (m_mutex);
- //LOG_M(AXRING, "[%s] +++, tail=%llu, head=%llu, iFrame=%d", m_szName, m_nTail, m_nHeader,element.bIFrame);
- if (!m_pRing || element.nSize > m_nElementBuffSize) {
- // must not go to here
- if (element.bIFrame) {
- m_bHasLost = AX_TRUE;
- }
- COMM_RING_PRT("[%s] ---, drop one frame for size is big", m_szName);
- return AX_FALSE;
- }
- if ((m_nTail - m_nHeader) == m_nElementCount) {
- // is full
- COMM_RING_PRT("[%s] is full, tail=%llu, head=%llu", m_szName, m_nTail, m_nHeader);
- if (element.bIFrame) {
- // replace the tail with new I Frame
- AX_U64 nIndex = (m_nTail - 1) % m_nElementCount;
- AX_S32 nRefCount= m_pRing[nIndex].GetRefCount();
- if (nRefCount == 0) {
- m_nTail--;
- m_bHasLost = AX_FALSE;
- COMM_RING_PRT("[%s] ---, replace last one with i frame for is full", m_szName);
- } else {
- m_bHasLost = AX_TRUE;
- COMM_RING_PRT("[%s] ---, drop one i frame for is full", m_szName);
- return AX_FALSE;
- }
- }
- else {
- m_bHasLost = AX_TRUE; // mark to lost all behind P Frame
- COMM_RING_PRT("[%s] ---, drop one p frame for is full", m_szName);
- return AX_FALSE;
- }
- } else {
- if (element.bIFrame) {
- m_bHasLost = AX_FALSE; // add new I frame
- }
- else {
- if (m_bHasLost) {
- // drop this P Frame
- COMM_RING_PRT("[%s] ---, drop one p frame for lost yet", m_szName);
- return AX_FALSE;
- }
- }
- }
- AX_U64 nIndex = m_nTail % m_nElementCount;
- AX_S32 nRefCount= m_pRing[nIndex].GetRefCount();
- if (nRefCount != 0) {
- m_bHasLost = AX_TRUE;
- COMM_RING_PRT("[%s] ---, drop one frame for refcount is none zero, nIndex=%llu, nRefCount=%d", m_szName, nIndex, nRefCount);
- return AX_FALSE;
- }
- m_pRing[nIndex].CopyFrom(element);
- m_pRing[nIndex].IncreaseRefCount();
- m_pRing[nIndex].pParent = this;
- m_nTail++;
- //LOG_M(AXRING, "[%s] ---, tail=%llu, head=%llu, pBuf=%p, size=%u", m_szName, m_nTail, m_nHeader, m_pRing[nIndex].pBuf, m_pRing[nIndex].nSize);
- return AX_TRUE;
- }
- CAXRingElement* Get() {
- CAXRingElement* element = nullptr;
- std::lock_guard<std::mutex> lck (m_mutex);
- //LOG_M(AXRING, "[%s] +++, tail=%llu, head=%llu", m_szName, m_nTail, m_nHeader);
- if (m_nHeader == m_nTail) {
- // is emtpy
- //LOG_M(AXRING, "[%s] ---, empty, tail=%llu, head=%llu", m_szName, m_nTail, m_nHeader);
- return element;
- }
- AX_U64 nIndex = m_nHeader % m_nElementCount;
- m_pRing[nIndex].IncreaseRefCount();
- // AX_S32 nRefCount = m_pRing[nIndex].IncreaseRefCount();
- element = &m_pRing[nIndex];
- // LOG_M(AXRING, "[%s] ---, tail=%llu, head=%llu, pBuf=%p, size=%u, nRef=%d", m_szName, m_nTail, m_nHeader, element->pBuf, element->nSize, nRefCount);
- return element;
- }
- AX_BOOL Pop(AX_BOOL bForce=AX_TRUE) {
- std::lock_guard<std::mutex> lck (m_mutex);
- // LOG_M(AXRING, "[%s] +++, tail=%llu, head=%llu", m_szName, m_nTail, m_nHeader);
- if (m_nHeader == m_nTail) {
- // is emtpy
- //LOG_M(AXRING, "[%s] ---, no element to be pop, tail=%llu, head=%llu", m_szName, m_nTail, m_nHeader);
- return AX_FALSE;
- }
- AX_U64 nIndex = m_nHeader % m_nElementCount;
- // AX_S32 nRefCount = m_pRing[nIndex].DecreaseRefCount(bForce);
- m_pRing[nIndex].DecreaseRefCount(bForce);
- m_nHeader++;
- // LOG_M(AXRING, "[%s] ---, tail=%llu, head=%llu, nRef=%d", m_szName, m_nTail, m_nHeader, nRefCount);
- return AX_TRUE;
- }
- AX_VOID Free(CAXRingElement* ele, AX_BOOL bForce=AX_FALSE) {
- if(!ele) {
- return;
- }
- std::lock_guard<std::mutex> lck (m_mutex);
- AX_S32 nIndex = ele->GetIndex();
- if (nIndex >= 0 && nIndex < (AX_S32)m_nElementCount) {
- m_pRing[nIndex].DecreaseRefCount(bForce);
- // AX_S32 nRefCount= m_pRing[nIndex].DecreaseRefCount(bForce);
- // LOG_M(AXRING, "[%s] nIndex=%d, nRefCount=%d", m_szName, nIndex, nRefCount);
- }
- }
- AX_U32 Size() {
- if (m_nTail < m_nHeader) {
- return 0;
- }
- return m_nTail-m_nHeader;
- }
- private:
- CAXRingElement* m_pRing;
- AX_U32 m_nElementCount;
- AX_U32 m_nElementBuffSize;
- AX_U64 m_nHeader;
- AX_U64 m_nTail;
- AX_BOOL m_bHasLost;
- std::mutex m_mutex;
- char m_szName[64];
- };
- #endif // _RING_BUFFER_3246FC57_D0F1_4176_A1C3_3A16FC46D1CF_H_
|