diff options
Diffstat (limited to 'dxr3syncbuffer.c')
-rw-r--r-- | dxr3syncbuffer.c | 487 |
1 files changed, 247 insertions, 240 deletions
diff --git a/dxr3syncbuffer.c b/dxr3syncbuffer.c index d21f40c..d7fe170 100644 --- a/dxr3syncbuffer.c +++ b/dxr3syncbuffer.c @@ -20,8 +20,9 @@ */ /* - ToDo: - - cDxr3SyncBuffer::Push: XXX This is only a workaround until a sufficient control algorithm is implemented + ToDo: + - cDxr3SyncBuffer::Push: XXX This is only a workaround until a + sufficient control algorithm is implemented */ #include <unistd.h> @@ -33,8 +34,9 @@ const int DXR3_MAX_AUDIO_FRAME_LENGTH = 4096; // ================================== //! constructor -cFixedLengthFrame::cFixedLengthFrame() : -m_count(0), m_length(0), m_pts(0), m_type(ftUnknown) { +cFixedLengthFrame::cFixedLengthFrame() : + m_count(0), m_length(0), m_pts(0), m_type(ftUnknown) +{ m_audioChannelCount = UNKNOWN_CHANNEL_COUNT; m_audioDataRate = UNKNOWN_DATA_RATE; @@ -44,62 +46,63 @@ m_count(0), m_length(0), m_pts(0), m_type(ftUnknown) { // ================================== cFixedLengthFrame::~cFixedLengthFrame() { - if (m_pData) - { - delete[] m_pData; - } + if (m_pData) + { + delete[] m_pData; + } } // ================================== // ! setup our frame void cFixedLengthFrame::Init(uint32_t lenght) { - m_length = lenght; - m_pData = new uint8_t[lenght]; - - // allocation ok? - if (!m_pData) - { - cLog::Instance() << "Failed to allocate memory in cFixedLengthFrame (m_pData) - will stop now"; - exit(1); - } + m_length = lenght; + m_pData = new uint8_t[lenght]; + + // allocation ok? + if (!m_pData) + { + cLog::Instance() << "Failed to allocate memory in cFixedLengthFrame (m_pData) - will stop now"; + exit(1); + } } // ================================== -void cFixedLengthFrame::CopyFrame(const uint8_t* pStart, int length, uint32_t pts, eFrameType type) +void cFixedLengthFrame::CopyFrame(const uint8_t* pStart, int length, + uint32_t pts, eFrameType type) { - if (length > m_length) - { - delete[] m_pData; - m_pData = new uint8_t[length]; - m_length = length; + if (length > m_length) + { + delete[] m_pData; + m_pData = new uint8_t[length]; + m_length = length; } m_type = type; m_count = length; m_pts = pts; - dxr3_memcpy((void*) m_pData,(void*) pStart, length); + dxr3_memcpy((void*) m_pData, (void*) pStart, length); } // ================================== -uint8_t* cFixedLengthFrame::GetData(void) +uint8_t* cFixedLengthFrame::GetData(void) { return m_pData; } // ================================== -int cFixedLengthFrame::GetCount(void) +int cFixedLengthFrame::GetCount(void) { return m_count; } // ================================== -uint32_t cFixedLengthFrame::GetPts(void) +uint32_t cFixedLengthFrame::GetPts(void) { - return m_pts; + return m_pts; } // ================================== -void cFixedLengthFrame::SetPts(uint32_t pts) +void cFixedLengthFrame::SetPts(uint32_t pts) { m_pts = pts; } @@ -111,24 +114,26 @@ uint32_t cFixedLengthFrame::m_staticAudioDataRate = 0; // ================================== //! constructor -cDxr3SyncBuffer::cDxr3SyncBuffer(int frameCount, int frameLength, cDxr3Interface& dxr3Device) : cRingBuffer(frameCount, true), m_dxr3Device(dxr3Device) +cDxr3SyncBuffer::cDxr3SyncBuffer(int frameCount, int frameLength, + cDxr3Interface& dxr3Device) : + cRingBuffer(frameCount, true), m_dxr3Device(dxr3Device) { m_pBuffer = new cFixedLengthFrame[frameCount]; - // got we a valid m_pBuffer? - if (!m_pBuffer) - { - cLog::Instance() << "Failed to allocate memory in cDxr3SyncBuffer (m_pBuffer) - will stop now"; - exit(1); - } + // got we a valid m_pBuffer? + if (!m_pBuffer) + { + cLog::Instance() << "Failed to allocate memory in cDxr3SyncBuffer (m_pBuffer) - will stop now"; + exit(1); + } - // init our new m_pBuffer; - for (int i = 0; i < frameCount; i++) - { - m_pBuffer[i].Init(frameLength); - } + // init our new m_pBuffer; + for (int i = 0; i < frameCount; i++) + { + m_pBuffer[i].Init(frameLength); + } - // set some default values + // set some default values m_count = 0; m_nextFree = 0; m_next = 0; @@ -146,24 +151,24 @@ cDxr3SyncBuffer::cDxr3SyncBuffer(int frameCount, int frameLength, cDxr3Interface } // ================================== -cDxr3SyncBuffer::~cDxr3SyncBuffer() +cDxr3SyncBuffer::~cDxr3SyncBuffer() { - if (m_pBuffer) - { - delete[] m_pBuffer; - } + if (m_pBuffer) + { + delete[] m_pBuffer; + } } // ================================== -int cDxr3SyncBuffer::Available(void) +int cDxr3SyncBuffer::Available(void) { int ret = 0; #if VDRVERSNUM < 10313 - Lock(); + Lock(); #endif ret = m_count; #if VDRVERSNUM < 10313 - Unlock(); + Unlock(); #endif return ret; } @@ -173,182 +178,184 @@ const int BUFFER_LIMIT = 5; const int BUFFER_LIMIT_2 = 10; // ================================== -bool cDxr3SyncBuffer::Poll(int TimeoutMs) +bool cDxr3SyncBuffer::Poll(int TimeoutMs) { bool retVal = true; uint32_t currTime = m_dxr3Device.GetSysClock(); m_bPollSync = true; - if (m_demuxMode == DXR3_DEMUX_REPLAY_MODE) + if (m_demuxMode == DXR3_DEMUX_REPLAY_MODE) + { + if (Available() >= Size() - (Size()*BUFFER_LIMIT/100)) { - if (Available() >= Size() - (Size()*BUFFER_LIMIT/100)) - { - m_bPollSync = true; - while ((Available() >= Size() - (Size()*BUFFER_LIMIT_2)/100) && ((m_dxr3Device.GetSysClock() - currTime) < ((uint32_t)TimeoutMs * (uint32_t)45))) - { - m_bPutBlock = true; - EnableGet(); - m_bWaitPts = false; - WaitForPut(); - } - if (Available() >= Size() - (Size()*BUFFER_LIMIT_2)/100) - { - retVal = false; - } - } + m_bPollSync = true; + while ((Available() >= Size() - (Size()*BUFFER_LIMIT_2)/100) && + ((m_dxr3Device.GetSysClock() - currTime) < + ((uint32_t)TimeoutMs * (uint32_t)45))) + { + m_bPutBlock = true; + EnableGet(); + m_bWaitPts = false; + WaitForPut(); + } + if (Available() >= Size() - (Size()*BUFFER_LIMIT_2)/100) + { + retVal = false; + } + } } return retVal; } // ================================== -cFixedLengthFrame* cDxr3SyncBuffer::Push(const uint8_t* pStart, int length, uint32_t pts, eFrameType type) throw (eSyncBufferException) +cFixedLengthFrame* cDxr3SyncBuffer::Push(const uint8_t* pStart, int length, uint32_t pts, eFrameType type) throw (eSyncBufferException) { int lastIndex = 0; - switch (m_demuxMode) + switch (m_demuxMode) + { + case DXR3_DEMUX_TRICK_MODE: + break; + + case DXR3_DEMUX_TV_MODE: + case DXR3_DEMUX_REPLAY_MODE: + default: + + while ((Available() >= Size() - (Size()*10)/100)) { - case DXR3_DEMUX_TRICK_MODE: - break; - - case DXR3_DEMUX_TV_MODE: - case DXR3_DEMUX_REPLAY_MODE: - default: - - while ((Available() >= Size() - (Size()*10)/100)) - { - m_bPutBlock = true; - EnableGet(); - m_bWaitPts = false; - WaitForPut(); - } - - #if VDRVERSNUM < 10313 - Lock(); - #endif - if (pts == m_lastPts) - { - pts = 0; - } - else - { - m_lastPts = pts; - } - lastIndex = m_nextFree; - m_pBuffer[m_nextFree].CopyFrame(pStart, length, pts, type); - m_pBuffer[m_nextFree].SetChannelCount(UNKNOWN_CHANNEL_COUNT); - m_pBuffer[m_nextFree].SetDataRate(UNKNOWN_DATA_RATE); - m_pBuffer[m_nextFree].SetAspectRatio(UNKNOWN_ASPECT_RATIO); - m_nextFree++; - m_count++; - m_nextFree %= Size(); - - if (m_nextFree == m_next) - { - cLog::Instance() << "Buffer overrun\n"; -// cLog::Instance() << "cDxr3SyncBuffer::Push m_demuxMode: " << (int)m_demuxMode << endl; -// cLog::Instance() << "cDxr3SyncBuffer::Push Available(): " << Available() << endl; -// cLog::Instance() << "cDxr3SyncBuffer::Push Size(): " << Size() << endl; - - Clear(); // XXX This is only a workaround until a sufficient control algorithm is implemented - throw(SYNC_BUFFER_OVERRUN); - } - if (!m_bWaitPts) - { - if (m_bStartReceiver) - { - EnableGet(); - } - } - else - { - if (m_waitPts < m_dxr3Device.GetSysClock() || - m_waitPts - m_dxr3Device.GetSysClock() < m_waitDelta) - { - EnableGet(); - m_bWaitPts = false; - } - } - #if VDRVERSNUM < 10313 - Unlock(); - #endif - break; + m_bPutBlock = true; + EnableGet(); + m_bWaitPts = false; + WaitForPut(); + } + +#if VDRVERSNUM < 10313 + Lock(); +#endif + if (pts == m_lastPts) + { + pts = 0; + } + else + { + m_lastPts = pts; + } + lastIndex = m_nextFree; + m_pBuffer[m_nextFree].CopyFrame(pStart, length, pts, type); + m_pBuffer[m_nextFree].SetChannelCount(UNKNOWN_CHANNEL_COUNT); + m_pBuffer[m_nextFree].SetDataRate(UNKNOWN_DATA_RATE); + m_pBuffer[m_nextFree].SetAspectRatio(UNKNOWN_ASPECT_RATIO); + m_nextFree++; + m_count++; + m_nextFree %= Size(); + + if (m_nextFree == m_next) + { + cLog::Instance() << "Buffer overrun\n"; + //cLog::Instance() << "cDxr3SyncBuffer::Push m_demuxMode: " << (int)m_demuxMode << endl; + //cLog::Instance() << "cDxr3SyncBuffer::Push Available(): " << Available() << endl; + //cLog::Instance() << "cDxr3SyncBuffer::Push Size(): " << Size() << endl; + + Clear(); // XXX This is only a workaround until a sufficient control algorithm is implemented + throw(SYNC_BUFFER_OVERRUN); + } + if (!m_bWaitPts) + { + if (m_bStartReceiver) + { + EnableGet(); + } + } + else + { + if (m_waitPts < m_dxr3Device.GetSysClock() || + m_waitPts - m_dxr3Device.GetSysClock() < m_waitDelta) + { + EnableGet(); + m_bWaitPts = false; + } + } +#if VDRVERSNUM < 10313 + Unlock(); +#endif + break; } return &m_pBuffer[lastIndex]; } // ================================== -void cDxr3SyncBuffer::Pop(void) +void cDxr3SyncBuffer::Pop(void) { #if VDRVERSNUM < 10313 - Lock(); + Lock(); #endif - if (m_count) + if (m_count) + { + uint32_t nextPts = 0; + uint32_t tmpBuffer = m_next; + for (int i = 0; i < m_count && nextPts == 0; ++i) + { + if (tmpBuffer) tmpBuffer = --tmpBuffer ? tmpBuffer : (Size() - 1); + nextPts = m_pBuffer[tmpBuffer].GetPts(); + } + if (nextPts != 30) { - uint32_t nextPts = 0; - uint32_t tmpBuffer = m_next; - for (int i = 0; i < m_count && nextPts == 0; ++i) - { - if (tmpBuffer) tmpBuffer = --tmpBuffer ? tmpBuffer : (Size() - 1); - nextPts = m_pBuffer[tmpBuffer].GetPts(); - } - if (nextPts != 30) - { - cDxr3NextPts::Instance().SetNextPts(nextPts); - } - - m_next++; - m_count--; - m_next %= Size(); - if (m_next == m_nextFree) - { - m_next = m_nextFree = m_count = 0; - } + cDxr3NextPts::Instance().SetNextPts(nextPts); + } + + m_next++; + m_count--; + m_next %= Size(); + if (m_next == m_nextFree) + { + m_next = m_nextFree = m_count = 0; + } } EnablePut(); #if VDRVERSNUM < 10313 - Unlock(); + Unlock(); #endif } // ================================== -cFixedLengthFrame* cDxr3SyncBuffer::Get(void) +cFixedLengthFrame* cDxr3SyncBuffer::Get(void) { cFixedLengthFrame* pRet = 0; - - if (!m_bStopped) + + if (!m_bStopped) + { + while ((!Available() || !m_bStartReceiver) && !m_bStopped) { - while ((!Available() || !m_bStartReceiver) && !m_bStopped) - { - m_bGetBlock = true; - ReceiverStopped(); - WaitForGet(); - } - - #if VDRVERSNUM < 10313 - Lock(); - #endif - if (m_nextFree != m_next) - { - pRet = &m_pBuffer[m_next]; - } - #if VDRVERSNUM < 10313 - Unlock(); - #endif - } - else + m_bGetBlock = true; + ReceiverStopped(); + WaitForGet(); + } + +#if VDRVERSNUM < 10313 + Lock(); +#endif + if (m_nextFree != m_next) { - WaitForGet(); + pRet = &m_pBuffer[m_next]; + } +#if VDRVERSNUM < 10313 + Unlock(); +#endif + } + else + { + WaitForGet(); } return pRet; } // ================================== -void cDxr3SyncBuffer::Clear(void) +void cDxr3SyncBuffer::Clear(void) { #if VDRVERSNUM < 10313 - Lock(); + Lock(); #endif m_next = 0; m_nextFree = 0; @@ -357,108 +364,108 @@ void cDxr3SyncBuffer::Clear(void) m_bWaitPts = false; m_bStartReceiver = false; m_bPollSync = false; - if (m_bPutBlock) - { - EnablePut(); - m_bPutBlock = false; + if (m_bPutBlock) + { + EnablePut(); + m_bPutBlock = false; } cFixedLengthFrame::Clear(); cDxr3NextPts::Instance().Clear(); #if VDRVERSNUM < 10313 - Unlock(); + Unlock(); #endif } // ================================== -void cDxr3SyncBuffer::WaitForSysClock(uint32_t pts, uint32_t delta) +void cDxr3SyncBuffer::WaitForSysClock(uint32_t pts, uint32_t delta) { m_waitPts = pts; m_waitDelta = delta; - if (!m_bPutBlock) - { - #if VDRVERSNUM < 10313 - Lock(); - #endif - m_bWaitPts = true; - #if VDRVERSNUM < 10313 - Unlock(); - #endif - m_bGetBlock = true; - ReceiverStopped(); - WaitForGet(); + if (!m_bPutBlock) + { +#if VDRVERSNUM < 10313 + Lock(); +#endif + m_bWaitPts = true; +#if VDRVERSNUM < 10313 + Unlock(); +#endif + m_bGetBlock = true; + ReceiverStopped(); + WaitForGet(); } - else - { - usleep(1); //* (pts - pSysClock->GetSysClock())); + else + { + usleep(1); //* (pts - pSysClock->GetSysClock())); } } // ================================== -void cDxr3SyncBuffer::WaitForNextPut(void) +void cDxr3SyncBuffer::WaitForNextPut(void) { - if (!m_bPutBlock) - { - m_bGetBlock = true; - ReceiverStopped(); - WaitForGet(); + if (!m_bPutBlock) + { + m_bGetBlock = true; + ReceiverStopped(); + WaitForGet(); } - else - { - usleep(1); + else + { + usleep(1); } } // ================================== -void cDxr3SyncBuffer::Start(void) +void cDxr3SyncBuffer::Start(void) { m_bStartReceiver = true; m_bStopped = false; - if (Available()) - { - EnableGet(); + if (Available()) + { + EnableGet(); } } // ================================== -void cDxr3SyncBuffer::WakeUp(void) +void cDxr3SyncBuffer::WakeUp(void) { #if VDRVERSNUM < 10313 - Lock(); + Lock(); #endif - if (m_bStartReceiver == true) + if (m_bStartReceiver == true) + { + if (!m_bWaitPts) + { + EnableGet(); + } + else { - if (!m_bWaitPts) - { - EnableGet(); - } - else - { - if (m_waitPts < m_dxr3Device.GetSysClock() || - m_waitPts - m_dxr3Device.GetSysClock() < m_waitDelta) - { - EnableGet(); - m_bWaitPts = false; - } - } + if (m_waitPts < m_dxr3Device.GetSysClock() || + m_waitPts - m_dxr3Device.GetSysClock() < m_waitDelta) + { + EnableGet(); + m_bWaitPts = false; + } + } } #if VDRVERSNUM < 10313 - Unlock(); + Unlock(); #endif } // ================================== -void cDxr3SyncBuffer::WaitForReceiverStopped(void) +void cDxr3SyncBuffer::WaitForReceiverStopped(void) { - if (!m_bGetBlock) - { - receiverStoppedMutex.Lock(); - receiverStopped.Wait(receiverStoppedMutex); - receiverStoppedMutex.Unlock(); + if (!m_bGetBlock) + { + receiverStoppedMutex.Lock(); + receiverStopped.Wait(receiverStoppedMutex); + receiverStoppedMutex.Unlock(); } } // ================================== -void cDxr3SyncBuffer::ReceiverStopped(void) +void cDxr3SyncBuffer::ReceiverStopped(void) { receiverStopped.Broadcast(); } |