2 * AtmoPacketQueue.cpp: works as connection between the framegrabber (color-preprocessor)
3 * and the live output thread. It works as a FIFO for the colorpackets - helps also
4 * to synchronize between grabber and liveview threads.
5 * especially if the grabber has another framerate as the liveview (25fps)
7 * See the README.txt file for copyright information and how to reach the author(s).
13 #include "AtmoPacketQueue.h"
15 #if defined(_ATMO_VLC_PLUGIN_)
16 # include <vlc_common.h>
17 #define MAX_PACKET_TOO_LATE -30000
18 #define MAX_PACKET_TOO_EARLY 30000
19 #define MIN_SLEEP_TIME 15000
21 #define MAX_PACKET_TOO_LATE -30
22 #define MAX_PACKET_TOO_EARLY 30
23 #define MIN_SLEEP_TIME 15
27 #if defined(_ATMO_VLC_PLUGIN_)
29 CAtmoPacketQueue::CAtmoPacketQueue()
41 vlc_cond_init( &m_PacketArrivedCond );
42 vlc_mutex_init( &m_PacketArrivedLock );
43 vlc_mutex_init( &m_Lock );
44 m_PacketArrived = ATMO_FALSE;
49 CAtmoPacketQueue::CAtmoPacketQueue(CAtmoPacketQueueStatus *statusMonitor)
61 m_StatusMonitor = statusMonitor;
63 InitializeCriticalSection(&m_lock);
64 m_hPacketArrivedEvent = CreateEvent(NULL,ATMO_FALSE,ATMO_FALSE,NULL);
70 CAtmoPacketQueue::~CAtmoPacketQueue(void)
74 #if defined(_ATMO_VLC_PLUGIN_)
76 vlc_cond_destroy( &m_PacketArrivedCond );
77 vlc_mutex_destroy( &m_Lock );
81 DeleteCriticalSection( &m_lock );
82 CloseHandle(m_hPacketArrivedEvent);
84 m_StatusMonitor->destroyWindow();
89 void CAtmoPacketQueue::Lock()
91 #if defined(_ATMO_VLC_PLUGIN_)
92 vlc_mutex_lock( &m_Lock );
94 EnterCriticalSection( &m_lock );
98 void CAtmoPacketQueue::Unlock()
100 #if defined(_ATMO_VLC_PLUGIN_)
101 vlc_mutex_unlock( &m_Lock );
103 LeaveCriticalSection( &m_lock );
107 void CAtmoPacketQueue::SignalEvent()
109 #if defined(_ATMO_VLC_PLUGIN_)
110 vlc_mutex_lock( &m_PacketArrivedLock );
111 m_PacketArrived = ATMO_TRUE;
112 vlc_cond_signal( &m_PacketArrivedCond );
113 vlc_mutex_unlock( &m_PacketArrivedLock );
115 SetEvent( m_hPacketArrivedEvent );
119 void CAtmoPacketQueue::UnSignalEvent()
121 #if defined(_ATMO_VLC_PLUGIN_)
124 ResetEvent( m_hPacketArrivedEvent );
128 void CAtmoPacketQueue::AddPacket(pColorPacket newPacket)
130 pColorPacketItem temp = new ColorPacketItem;
131 temp->packet = newPacket;
133 #if defined(_ATMO_VLC_PLUGIN_)
134 temp->tickcount = mdate();
136 temp->tickcount = GetTickCount();
151 pColorPacketItem CAtmoPacketQueue::GetNextPacketContainer()
153 pColorPacketItem temp = NULL;
158 m_first = m_first->next;
168 pColorPacket CAtmoPacketQueue::GetNextPacket()
170 pColorPacketItem item = GetNextPacketContainer();
172 pColorPacket temp = item->packet;
179 #if defined(_ATMO_VLC_PLUGIN_)
180 void CAtmoPacketQueue::ShowQueueStatus(atmo_thread_t *p_this)
183 show some statistics for the whole time...
185 msg_Dbg( p_this, "Skipped Packets: %d", m_skipcounter );
186 if( m_skipcounter > 0 )
187 msg_Dbg( p_this, "Average Delay: %d ms", (int)(m_avgDelay/m_skipcounter)/1000 );
188 msg_Dbg( p_this, "Waited Packets: %d", m_waitcounter );
189 if( m_waitcounter > 0 )
190 msg_Dbg( p_this, "Average Wait: %d ms", (int)(m_avgWait/m_waitcounter)/1000 );
191 msg_Dbg( p_this, "Used Packets: %d", m_framecounter );
192 msg_Dbg( p_this, "Null Packets: %d", m_nullpackets );
196 #if defined(_ATMO_VLC_PLUGIN_)
197 pColorPacket CAtmoPacketQueue::GetNextPacket(mtime_t timecode, ATMO_BOOL withWait, atmo_thread_t *p_this, mtime_t &packet_time)
199 pColorPacket CAtmoPacketQueue::GetNextPacket(DWORD timecode, ATMO_BOOL withWait, DWORD &packet_time)
202 #if !defined(_ATMO_VLC_PLUGIN_)
203 if(timecode & 0x80000000) // GetTickCount - delay < 0 ;-)
216 timeDiff = m_first->tickcount - timecode;
217 packet_time = m_first->tickcount;
220 if(timeDiff >= MAX_PACKET_TOO_EARLY) // packet should be process in 35ms or later (usually we are to early for it)
227 if(timeDiff <= MAX_PACKET_TOO_LATE) {
228 // we are more than -35ms too late for this packet, skip it and throw it away!
229 #if defined(_ATMO_VLC_PLUGIN_)
230 msg_Dbg( p_this, "getNextPacket skip late %d ms", timeDiff / 1000 );
232 pColorPacket skip = GetNextPacket();
236 m_avgDelay += abs(timeDiff);
242 if(withWait && timeDiff > MIN_SLEEP_TIME)
244 // if this is a sync call, to get in sync with frame source again we wait untils its time!
245 #if defined(_ATMO_VLC_PLUGIN_)
246 msg_Dbg( p_this, "getNextPacket Sleep %d ms", timeDiff / 1000 );
248 do_sleep( timeDiff );
250 m_avgWait += timeDiff;
255 #if !defined(_ATMO_VLC_PLUGIN_)
259 m_StatusMonitor->UpdateValues(m_waitcounter, m_skipcounter, m_framecounter, m_nullpackets, m_avgWait, m_avgDelay);
263 return GetNextPacket();
267 #if !defined(_ATMO_VLC_PLUGIN_)
271 m_StatusMonitor->UpdateValues(m_waitcounter, m_skipcounter, m_framecounter, m_nullpackets, m_avgWait, m_avgDelay);
277 ATMO_BOOL CAtmoPacketQueue::WaitForNextPacket(DWORD timeout)
281 #if !defined(_ATMO_VLC_PLUGIN_)
283 return ( WaitForSingleObject( m_hPacketArrivedEvent, timeout ) == WAIT_OBJECT_0 );
287 mtime_t maxWait = mdate() + timeout * 1000;
289 vlc_mutex_lock( &m_PacketArrivedLock );
290 m_PacketArrived = ATMO_FALSE;
291 while(vlc_cond_timedwait( &m_PacketArrivedCond, &m_PacketArrivedLock, maxWait) == 0)
294 condition was set -> but may be an old signal from previous AddPacket
295 which is still left - so if m_PacketArrived is still false, wait again
297 if(mdate() >= maxWait)
299 if( m_PacketArrived )
302 vlc_mutex_unlock( &m_PacketArrivedLock );
303 return m_PacketArrived;
308 void CAtmoPacketQueue::ClearQueue()
310 pColorPacketItem next;
316 next = m_first->next;
317 delete (char *)(m_first->packet);