diff options
author | austriancoder <austriancoder> | 2004-08-05 23:05:21 +0000 |
---|---|---|
committer | austriancoder <austriancoder> | 2004-08-05 23:05:21 +0000 |
commit | c47666d42f7972e1b51f9de61ce0fa27c72f3127 (patch) | |
tree | e34a87e37901b7f892fb6f330ccb15bcba30039b /dxr3outputthread.c | |
download | vdr-plugin-dxr3-c47666d42f7972e1b51f9de61ce0fa27c72f3127.tar.gz vdr-plugin-dxr3-c47666d42f7972e1b51f9de61ce0fa27c72f3127.tar.bz2 |
initial import
Diffstat (limited to 'dxr3outputthread.c')
-rw-r--r-- | dxr3outputthread.c | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/dxr3outputthread.c b/dxr3outputthread.c new file mode 100644 index 0000000..d4a4a8e --- /dev/null +++ b/dxr3outputthread.c @@ -0,0 +1,279 @@ +/* + * dxr3outputthread.c: + * + * See the main source file 'dxr3.c' for copyright information and + * how to reach the author. + * + */ + +#include <stdio.h> +#include <unistd.h> +#include <time.h> +#include <pthread.h> +#include "dxr3outputthread.h" +#include "dxr3log.h" + +// ================================== +const int AUDIO_OFFSET = 4500; +#define SCR m_dxr3Device.GetSysClock() +// ================================== + +// ================================== +// constr. +cDxr3OutputThread::cDxr3OutputThread(cDxr3Interface& dxr3Device, cDxr3SyncBuffer& buffer) : +cThread(), m_dxr3Device(dxr3Device), m_buffer(buffer), m_bStopThread(false), m_bNeedResync(false) +{ +} + +// ================================== +// send stop signal +void cDxr3OutputThread::SetStopSignal() +{ + Lock(); + m_bStopThread = true; + Unlock(); +} + +// ================================== +// was stop signal send? +bool cDxr3OutputThread::GetStopSignal() +{ + bool ret = false; + Lock(); + ret = m_bStopThread; + Unlock(); + + return ret; +} + +// ================================== +// constr. +cDxr3AudioOutThread::cDxr3AudioOutThread(cDxr3Interface& dxr3Device, cDxr3SyncBuffer& buffer) : +cDxr3OutputThread(dxr3Device, buffer) +{ +} + +// ================================== +// thread action +void cDxr3AudioOutThread::Action() +{ + bool resync = false; + uint32_t pts = 0; + + cLog::Instance() << "cDxr3AudioOutThread::Action Thread started\n"; + + sched_param temp; + temp.sched_priority = 2; + + if (!pthread_setschedparam(pthread_self(), SCHED_RR, &temp)) + { + cLog::Instance() << "cDxr3AudioOutThread::Action(): Error can't set priority\n"; + } + + while (!GetStopSignal()) + { + pts = 0; + cFixedLengthFrame* pNext = m_buffer.Get(); + + if (pNext) pts = pNext->GetPts(); + + if (pts && abs((int)pts-(int)SCR) > 30000 || m_dxr3Device.IsExternalReleased()) + { + if (cDxr3ConfigData::Instance().GetDebugEverything()) + { + cLog::Instance() << "cDxr3AudioOutThread::Action " << "pts = " << pts << " scr = " << SCR << "\n"; + } + m_buffer.Clear(); + m_bNeedResync = true; + } + else if (pNext) + { + if (!pts || pts < SCR) + { + if (cDxr3ConfigData::Instance().GetDebugEverything()) + { +// if (pts) cLog::Instance() << "cDxr3AudioOutThread::Action pts " << pNext->GetPts() << " scr " << SCR << " delta " << (pts - SCR) << "\n"; + } + if (!pts && resync) + { + continue; + } + else + { + resync = false; + } + + if (pts && (pts < SCR) && ((SCR - pts) > 5000)) + { + if (cDxr3ConfigData::Instance().GetDebugEverything()) + { +// cLog::Instance() << "cDxr3AudioOutThread::Action pts audio too small " << (SCR - pts) << "\n"; + } + m_dxr3Device.SetSysClock(pts+ 1 * AUDIO_OFFSET); + m_dxr3Device.PlayAudioFrame(pNext); + if (m_buffer.IsPolled()) + { + m_buffer.Clear(); + m_bNeedResync = true; + } + } + else + { + if (cDxr3ConfigData::Instance().GetDebugEverything()) + { +// cLog::Instance() << "cDxr3AudioOutThread::Action write audio\n"; + } + m_dxr3Device.PlayAudioFrame(pNext); + m_buffer.Pop(); + } + } + else + { + if (abs((int)pts - (int)SCR) < (AUDIO_OFFSET )) + { + if (cDxr3ConfigData::Instance().GetDebugEverything()) + { +// if (pts) cLog::Instance() << "cDxr3AudioOutThread::Action pts " << pNext->GetPts() << " scr " << SCR << " delta " << (pts - SCR) << "\n"; + } + m_dxr3Device.PlayAudioFrame(pNext); + m_buffer.Pop(); + } + } + } + + if ((pts > SCR && abs((int)pts - (int)SCR) > AUDIO_OFFSET)) + { + if (cDxr3ConfigData::Instance().GetDebugEverything()) + { +// cLog::Instance() << "cDxr3AudioOutThread::Action Stopping audio " << SCR << " " << pts << "\n"; + } + + usleep(10000); + + if (cDxr3ConfigData::Instance().GetDebugEverything()) + { +// cLog::Instance() << "cDxr3AudioOutThread::Action Starting audio " << SCR << " " << pts << "\n"; + } + } + } +} + +// ================================== +// constr. +cDxr3VideoOutThread::cDxr3VideoOutThread(cDxr3Interface& dxr3Device, cDxr3SyncBuffer& buffer) : +cDxr3OutputThread(dxr3Device, buffer) +{ +} + +// ================================== +// thread action +void cDxr3VideoOutThread::Action() +{ + uint32_t pts = 0; + static uint32_t lastPts = 0; + + cLog::Instance() << "cDxr3VideoOutThread::Action Thread started\n"; + + sched_param temp; + temp.sched_priority = 1; + + if (!pthread_setschedparam(pthread_self(), SCHED_RR, &temp)) + { +// cLog::Instance() << "cDxr3VideoOutThread::Action(): Error can't set priority\n"; + } + + while (!GetStopSignal()) + { + cFixedLengthFrame* pNext = m_buffer.Get(); + if (pNext) + { + pts = pNext->GetPts(); + if (pts == lastPts) pts = 0; + + if (pts > SCR && abs((int)pts - (int)SCR) < 7500) + { + m_dxr3Device.SetPts(pts); + } + + if (!pts || pts < SCR) + { + if (m_buffer.Available()) + { + m_dxr3Device.PlayVideoFrame(pNext); + m_buffer.Pop(); + } + } + else + { + if ((pts > SCR) && abs((int)pts - (int)SCR) < 7500) + { + if (cDxr3ConfigData::Instance().GetDebugEverything()) + { +// cLog::Instance() << "cDxr3VideoOutThread::Action pts " << pts << " scr " << SCR << " delta " << (pts - SCR) << "\n"; + } + + m_dxr3Device.SetPts(pts); + + if (cDxr3ConfigData::Instance().GetDebugEverything()) + { +// cLog::Instance() << "cDxr3VideoOutThread::Action done\n"; + } + + if (m_buffer.Available() && pNext->GetData() && pNext->GetCount()) + { + m_dxr3Device.PlayVideoFrame(pNext); + + if (cDxr3ConfigData::Instance().GetDebugEverything()) + { +// cLog::Instance() << "cDxr3VideoOutThread::Action write\n"; + } + + m_buffer.Pop(); + + if (cDxr3ConfigData::Instance().GetDebugEverything()) + { +// cLog::Instance() << "cDxr3VideoOutThread::Action done pop\n"; + } + } + if (cDxr3ConfigData::Instance().GetDebug()) + { +// cLog::Instance() << "cDxr3VideoOutThread::Action done complete\n"; + } + } + else + { + if (pts < SCR) + { + m_dxr3Device.PlayVideoFrame(pNext); + m_buffer.Pop(); + } + } + } + + + if (m_dxr3Device.IsExternalReleased()) + { + m_bNeedResync = true; + m_buffer.Clear(); + } + + if ((pts > SCR && abs((int)pts - (int)SCR) > 7500 )) + { + if (cDxr3ConfigData::Instance().GetDebugEverything()) + { +// cLog::Instance() << "cDxr3VideoOutThread::Action Stopping video " << SCR << " " << pts << "\n"; + } + + usleep(10000); + + if (cDxr3ConfigData::Instance().GetDebugEverything()) + { +// cLog::Instance() << "cDxr3VideoOutThread::Action Starting video " << SCR << " " << pts << "\n"; + } + } + } + } +} + + +#undef SCR |