*
* $Id$
*/
+
+#define __STDC_FORMAT_MACROS 1
+
#include "AtmoDefs.h"
#include "AtmoLiveView.h"
#include "AtmoOutputFilter.h"
#include "AtmoTools.h"
#if defined(_ATMO_VLC_PLUGIN_)
-# include <vlc/vlc.h>
+# include <vlc_common.h>
#else
# include "AtmoGdiDisplayCaptureInput.h"
#endif
#include "AtmoExternalCaptureInput.h"
-
#if defined(_ATMO_VLC_PLUGIN_)
CAtmoLiveView::CAtmoLiveView(CAtmoDynData *pAtmoDynData) :
CThread(pAtmoDynData->getAtmoFilter())
{
this->m_pAtmoDynData = pAtmoDynData;
- m_pAtmoInput = NULL;
}
#else
CAtmoLiveView::CAtmoLiveView(CAtmoDynData *pAtmoDynData)
{
this->m_pAtmoDynData = pAtmoDynData;
- m_LiveViewSource = lvsGDI;
- m_CurrentLiveViewSource = lvsGDI;
- m_InputChangedEvent = CreateEvent(NULL,ATMO_FALSE,ATMO_FALSE,NULL);
- m_pAtmoInput = NULL;
- InitializeCriticalSection(&m_InputChangeCriticalSection);
}
#endif
CAtmoLiveView::~CAtmoLiveView(void)
{
-#if !defined(_ATMO_VLC_PLUGIN_)
- DeleteCriticalSection(&m_InputChangeCriticalSection);
- CloseHandle(m_InputChangedEvent);
-#endif
}
-
-#if !defined(_ATMO_VLC_PLUGIN_)
-
-STDMETHODIMP CAtmoLiveView::setLiveViewSource(enum ComLiveViewSource dwModus)
-{
- if(dwModus != m_LiveViewSource) {
- m_LiveViewSource = dwModus;
- /*
- you may ask why I don't use a critical section here and directly acces the
- the variable of the Thread?
- Just because you would need very much / often entering / leaving the critical
- section ... and in this case It could be avoid ...
-
- assigning the value to the "mirror" variable m_LiveViewSource which is compare
- in every run of the thread with its current value ... if there is a change
- the thread can proceed switching the live source ... until this is done
- the thread calling this method is waiting...
- */
-
- // I don't expect that it will take longer than 500ms to switch...
- if(WaitForSingleObject(m_InputChangedEvent,500) == WAIT_TIMEOUT)
- return S_FALSE; // if not so the switch seems be have failed (badly)
- }
- return S_OK;
-}
-
-STDMETHODIMP CAtmoLiveView::getCurrentLiveViewSource(enum ComLiveViewSource *modus) {
- *modus = m_LiveViewSource;
- return S_OK;
-}
-
-#endif
-
-
DWORD CAtmoLiveView::Execute(void)
{
#if defined(_ATMO_VLC_PLUGIN_)
- mtime_t ticks;
+ mtime_t ticks;
+ mtime_t t;
+ mtime_t packet_time;
#else
- DWORD ticks;
+ DWORD ticks;
+ DWORD t;
+ DWORD packet_time;
#endif
- int i_frame_counter = 0;
- CAtmoInput *newInput,*oldInput;
- tColorPacket ColorPacket;
+ int i_frame_counter = -1;
- CAtmoConnection *pAtmoConnection = this->m_pAtmoDynData->getAtmoConnection();
- if((pAtmoConnection == NULL) || (pAtmoConnection->isOpen() == ATMO_FALSE)) return 0;
+ pColorPacket ColorPacket;
+ pColorPacket PreviousPacket = NULL;
- CAtmoConfig *pAtmoConfig = this->m_pAtmoDynData->getAtmoConfig();
+ CAtmoConnection *pAtmoConnection = this->m_pAtmoDynData->getAtmoConnection();
+ if((pAtmoConnection == NULL) || (pAtmoConnection->isOpen() == ATMO_FALSE)) return 0;
- /*
- this object does post processing of the pixel data
- like jump /scenechange detection fading over the colors
- */
- CAtmoOutputFilter *filter = new CAtmoOutputFilter(this->m_pAtmoDynData->getAtmoConfig());
+ CAtmoConfig *pAtmoConfig = this->m_pAtmoDynData->getAtmoConfig();
+ /*
+ this object does post processing of the pixel data
+ like jump /scenechange detection fading over the colors
+ */
+ CAtmoOutputFilter *filter = new CAtmoOutputFilter( this->m_pAtmoDynData->getAtmoConfig() );
+ CAtmoPacketQueue *pPacketQueue = this->m_pAtmoDynData->getLivePacketQueue();
+ int frameDelay = pAtmoConfig->getLiveView_FrameDelay();
#if defined(_ATMO_VLC_PLUGIN_)
- /* this thread is the data preprocess which gets the real 64x48 pixel
- and converts them into the RGB channel values - this is done in
- another thread to keep this thread at a constant timing - to that
- color output is updated 25 times a second
- */
- m_pAtmoInput = new CAtmoExternalCaptureInput(m_pAtmoDynData);
-#else
- if(m_LiveViewSource == lvsGDI)
- m_pAtmoInput = new CAtmoGdiDisplayCaptureInput(m_pAtmoDynData);
- else
- m_pAtmoInput = new CAtmoExternalCaptureInput(m_pAtmoDynData);
+ /*
+ because time function of vlc are working with us values instead of ms
+ */
+ frameDelay = frameDelay * 1000;
#endif
- if(m_pAtmoInput->Open() == ATMO_TRUE)
- {
- /*
- wait for the first frame to go in sync with the other thread
- */
+ /*
+ wait for the first frame to go in sync with the other thread
+ */
+ t = get_time;
+
+ if( pPacketQueue->WaitForNextPacket(3000) )
+ {
+ if( frameDelay > 0 )
+ do_sleep( frameDelay );
#if defined(_ATMO_VLC_PLUGIN_)
- msg_Dbg( m_pAtmoThread, "CAtmoLiveView::Execute(void)");
+ msg_Dbg( m_pAtmoThread, "First Packet got %"PRId64" ms", (get_time - t) / 1000 );
#endif
- m_pAtmoInput->WaitForNextFrame(500);
+ }
+
+ while(this->m_bTerminated == ATMO_FALSE)
+ {
+ i_frame_counter++;
+ if(i_frame_counter == 50) i_frame_counter = 0;
- while(this->m_bTerminated == ATMO_FALSE)
- {
- /* atmoInput - capture Thread Running... */
+ /* grab current Packet from InputQueue (working as FIFO)! */
#if defined(_ATMO_VLC_PLUGIN_)
- ticks = mdate();
+ ColorPacket = pPacketQueue->GetNextPacket(get_time - frameDelay, (i_frame_counter == 0), m_pAtmoThread, packet_time);
#else
- ticks = GetTickCount();
+ ColorPacket = pPacketQueue->GetNextPacket(get_time - frameDelay, (i_frame_counter == 0), packet_time);
#endif
-
- /* grab current Packet from Input! */
- ColorPacket = m_pAtmoInput->GetColorPacket();
-
- /* pass it through the outputfilters! */
- ColorPacket = filter->Filtering(ColorPacket);
-
- /* apply gamma later ;-) not implemented yet */
- ColorPacket = CAtmoTools::ApplyGamma(pAtmoConfig, ColorPacket);
-
- /*
- apply white calibration - only if it is not
- done by the hardware
- */
- if(pAtmoConfig->isUseSoftwareWhiteAdj())
- ColorPacket = CAtmoTools::WhiteCalibration(pAtmoConfig,
- ColorPacket);
-
- /* send color data to the the hardware... */
- pAtmoConnection->SendData(ColorPacket);
-
- /*
- experimental do sync every 100 Frames to the image producer
- thread because GetTickCount precision is really poor ;-)
- */
- i_frame_counter++;
- if(i_frame_counter == 100) {
- m_pAtmoInput->WaitForNextFrame(50);
- i_frame_counter = 0;
-#if !defined(WIN32)
-/* kludge for pthreads? when running GDB debugger using the same condition variable
- to often results in haging wait timedout...
-*/
-#ifdef _ATMO_KLUDGE_
- vlc_mutex_lock( &m_TerminateLock );
- vlc_cond_destroy( &m_TerminateCond );
- vlc_cond_init( m_pAtmoThread, &m_TerminateCond );
- vlc_mutex_unlock( &m_TerminateLock );
+ if(ColorPacket)
+ {
+ /*
+ create a packet copy - for later reuse if the input is slower than 25fps
+ */
+ if(PreviousPacket && (PreviousPacket->numColors == ColorPacket->numColors))
+ CopyColorPacket(ColorPacket, PreviousPacket)
+ else {
+ delete (char *)PreviousPacket;
+ DupColorPacket(PreviousPacket, ColorPacket )
+ }
+ } else {
+ /*
+ packet queue was empty for the given point of time
+ */
+ if(i_frame_counter == 0)
+ {
+#if defined(_ATMO_VLC_PLUGIN_)
+ msg_Dbg( m_pAtmoThread, "wait for delayed packet..." );
#endif
+ t = get_time;
+ if( pPacketQueue->WaitForNextPacket(200) )
+ {
+ if( frameDelay > 0 )
+ do_sleep( frameDelay );
+#if defined(_ATMO_VLC_PLUGIN_)
+ msg_Dbg( m_pAtmoThread, "got delayed packet %"PRId64" ms", (mdate() - t) / 1000 );
#endif
- continue;
- }
-
-
-#if !defined(_ATMO_VLC_PLUGIN_)
- /*
- Check if Input Source has changed - through an async
- call from the com interface?
- */
- if(m_CurrentLiveViewSource != m_LiveViewSource) {
- oldInput = m_pAtmoInput;
- m_pAtmoInput = NULL;
-
- if(m_LiveViewSource == lvsGDI) {
- // create new GDI Input Source...
- newInput = new CAtmoGdiDisplayCaptureInput(m_pAtmoDynData);
- newInput->Open(); // should not fail now... hope is the best!
- } else if(m_LiveViewSource == lvsExternal) {
- newInput = new CAtmoExternalCaptureInput(m_pAtmoDynData);
- newInput->Open();
- }
- m_CurrentLiveViewSource = m_LiveViewSource;
-
- m_pAtmoInput = newInput;
-
- oldInput->Close();
- delete oldInput;
-
- /*
- signal the call to the method "setLiveViewSource" the source
- was switched...
- */
- SetEvent(m_InputChangedEvent);
- // do sync with input thread
- m_pAtmoInput->WaitForNextFrame(100);
- continue;
+ continue;
}
-#endif
-
- /*
- calculate RunTime of thread abbove (doesn't work well - so
- this threads comes out of sync with Image producer and the
- framerate (25fps) drifts away
- */
+ }
+ /*
+ reuse previous color packet
+ */
+ DupColorPacket(ColorPacket, PreviousPacket)
+ }
+
+ ticks = get_time;
+
+ if(ColorPacket)
+ {
+ /* pass it through the outputfilters! */
+ // Info Filtering will possible free the colorpacket and alloc a new one!
+ ColorPacket = filter->Filtering(ColorPacket);
+
+ /* apply gamma correction - only if the hardware isnt capable doing this */
+ ColorPacket = CAtmoTools::ApplyGamma(pAtmoConfig, ColorPacket);
+
+ /*
+ apply white calibration - only if it is not
+ done by the hardware
+ */
+ if(pAtmoConfig->isUseSoftwareWhiteAdj())
+ ColorPacket = CAtmoTools::WhiteCalibration(pAtmoConfig, ColorPacket);
+
+ /* send color data to the the hardware... */
+ pAtmoConnection->SendData(ColorPacket);
+
+ delete (char *)ColorPacket;
+ }
+
+ /*
+ calculate RunTime of thread abbove (doesn't work well - so
+ this threads comes out of sync with Image producer and the
+ framerate (25fps) drifts away
+ */
#if defined(_ATMO_VLC_PLUGIN_)
- ticks = ((mdate() - ticks) + 999)/1000;
+ ticks = ((mdate() - ticks) + 999)/1000;
#else
- ticks = GetTickCount() - ticks;
+ ticks = GetTickCount() - ticks;
#endif
- if(ticks < 40)
- {
- // ThreadSleep -> AtmoThread.cpp
- if(this->ThreadSleep(40 - ticks)==ATMO_FALSE)
- break;
- }
- }
+ if(ticks < 40)
+ {
+ if( ThreadSleep( 40 - ticks ) == ATMO_FALSE )
+ break;
+ }
+ }
- /* shutdown the input processor thread */
- m_pAtmoInput->Close();
- }
+#if defined(_ATMO_VLC_PLUGIN_)
+ msg_Dbg( m_pAtmoThread, "DWORD CAtmoLiveView::Execute(void) terminates");
+ pPacketQueue->ShowQueueStatus( m_pAtmoThread );
+#endif
- delete m_pAtmoInput;
- m_pAtmoInput = NULL;
+ delete (char *)PreviousPacket;
-#if !defined(_ATMO_VLC_PLUGIN_)
- /*
- if there is a pending call to setLiveViewSource let him surely return before
- destroying the thread and this class instance...
- */
- SetEvent(m_InputChangedEvent);
-#endif
- delete filter;
- return 0;
+ delete filter;
+ return 0;
}