📄 buffer.cpp
字号:
/******************************************************************************** buffer.cpp: Buffers management*-------------------------------------------------------------------------------* (c)1999-2001 VideoLAN* $Id: buffer.cpp,v 1.4 2002/07/12 18:09:36 massiot Exp $** Authors: Benoit Steiner <benny@via.ecp.fr>** This program is free software; you can redistribute it and/or* modify it under the terms of the GNU General Public License* as published by the Free Software Foundation; either version 2* of the License, or (at your option) any later version.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the* GNU General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.**-------------------------------------------------------------------------------********************************************************************************///------------------------------------------------------------------------------// Preamble//------------------------------------------------------------------------------#include "../core/defs.h"#include "config.h"#include "../core/core.h"#include "../mpeg/mpeg.h"#include "../mpeg/ts.h"#include "buffer.h"//******************************************************************************// C_SyncFifo class//******************************************************************************// Works even if several threads push data and several ones pop them//******************************************************************************//------------------------------------------------------------------------------// Constructor//------------------------------------------------------------------------------C_SyncFifo::C_SyncFifo(unsigned int iSize) : m_cNotEmptySignal(0), m_cNotFullSignal(iSize), m_cFifo(iSize){ ASSERT(iSize > 1);}//------------------------------------------------------------------------------// Destructor//------------------------------------------------------------------------------C_SyncFifo::~C_SyncFifo(){}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_SyncFifo::HandlePacket(C_TsPacket* pPacket){ ASSERT(pPacket); // Push the data (wait for a pop if the fifo is full) int iRc = m_cNotFullSignal.Wait(); ASSERT(!iRc); iRc = m_cFifo.Push(pPacket); ASSERT(!iRc); // Warn the waiting threads if any that they have data to pop iRc = m_cNotEmptySignal.Post(); ASSERT(!iRc);/* unsigned int iSize = m_pFifo->Size(); // Push the data (wait for a pop if the fifo is full) pthread_mutex_lock(&m_sLock); unsigned int iStored = m_pFifo->Stored(); if(iStored >= iSize) { //printf("FIFO::Push() MUST WAIT !!!!!!!\n"); pthread_cond_wait(&m_sNotFullSignal, &m_sLock); } int iRc = m_pFifo->Push(pPacket); ASSERT(!iRc); // Warn the waiting threads if any that they have data to pop pthread_cond_signal(&m_sNotEmptySignal); pthread_mutex_unlock(&m_sLock);*/}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------C_TsPacket* C_SyncFifo::Pop(){ // Pop the data (wait for them is the fifo is empty) int iRc = m_cNotEmptySignal.Wait(); ASSERT(!iRc); C_TsPacket* pPacket = m_cFifo.Pop(); ASSERT(pPacket); // Warn the waiting threads if any that they have data to push iRc = m_cNotFullSignal.Post(); ASSERT(!iRc); return pPacket;/* pthread_mutex_lock(&m_sLock); unsigned int iStored = m_pFifo->Stored(); if(iStored <= 0) { printf("FIFO::Pop() MUST WAIT !!!!!!!\n"); pthread_cond_wait(&m_sNotEmptySignal, &m_sLock); } C_TsPacket* pPacket = m_pFifo->Pop(); ASSERT(pPacket); // Warn the waiting threads if any that they have data to push pthread_cond_signal(&m_sNotFullSignal); pthread_mutex_unlock(&m_sLock); return pPacket;*/}//******************************************************************************// C_NetList class//******************************************************************************////******************************************************************************//------------------------------------------------------------------------------// //------------------------------------------------------------------------------C_NetList::C_NetList(unsigned int iSize/* = 65536*/){ iBuffSize = iSize; // Create the buffer of TS packets aPackets = new C_TsPacket[iSize]; ASSERT(aPackets); // Create the buffer of pointers to free TS packets apFreePackets = new C_TsPacket* [iSize]; ASSERT(apFreePackets); // Now init the second buffer for(unsigned int iIndex = 0; iIndex < iSize; iIndex++) { apFreePackets[iIndex] = &aPackets[iIndex]; } // All the packets are free iFirstFree = 0;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------C_NetList::~C_NetList(){ ASSERT(aPackets); delete[] aPackets; ASSERT(apFreePackets); delete[] apFreePackets;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// Return the address of the fetched packet or NULL if the netlist is empty //------------------------------------------------------------------------------C_TsPacket* C_NetList::GetPacket(){ C_TsPacket* pFreePacket = NULL; m_sMutex.Lock(); // Get the addree of the first free packet if any if(iFirstFree < iBuffSize) { pFreePacket = apFreePackets[iFirstFree]; iFirstFree++; pFreePacket->Ref(); ASSERT(pFreePacket->RefCount() == 1); } m_sMutex.UnLock(); return pFreePacket;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------////------------------------------------------------------------------------------void C_NetList::RefPacket(C_TsPacket* pPacket){ ASSERT(pPacket); m_sMutex.Lock(); pPacket->Ref(); m_sMutex.UnLock();}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_NetList::ReleasePacket(C_TsPacket* pPacket){ ASSERT(pPacket); m_sMutex.Lock(); if(!pPacket->Unref()) { ASSERT(iFirstFree <= iBuffSize); // Check everything is OK ASSERT(iFirstFree > 0); iFirstFree--; apFreePackets[iFirstFree] = pPacket; } m_sMutex.UnLock();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -