2 * AtmoLiveView.cpp: this effect outputs colors as result of a picture
3 * content (most complex effect) see thread.c of the linux VDR version -
4 * to fully understand what happens here..
6 * See the README.txt file for copyright information and how to reach the author(s).
11 #include "AtmoLiveView.h"
12 #include "AtmoOutputFilter.h"
13 #include "AtmoTools.h"
15 #if defined(_ATMO_VLC_PLUGIN_)
18 # include "AtmoGdiDisplayCaptureInput.h"
21 #include "AtmoExternalCaptureInput.h"
24 #if defined(_ATMO_VLC_PLUGIN_)
26 CAtmoLiveView::CAtmoLiveView(CAtmoDynData *pAtmoDynData) :
27 CThread(pAtmoDynData->getAtmoFilter())
29 this->m_pAtmoDynData = pAtmoDynData;
35 CAtmoLiveView::CAtmoLiveView(CAtmoDynData *pAtmoDynData)
37 this->m_pAtmoDynData = pAtmoDynData;
38 m_LiveViewSource = lvsGDI;
39 m_CurrentLiveViewSource = lvsGDI;
40 m_InputChangedEvent = CreateEvent(NULL,ATMO_FALSE,ATMO_FALSE,NULL);
42 InitializeCriticalSection(&m_InputChangeCriticalSection);
48 CAtmoLiveView::~CAtmoLiveView(void)
50 #if !defined(_ATMO_VLC_PLUGIN_)
51 DeleteCriticalSection(&m_InputChangeCriticalSection);
52 CloseHandle(m_InputChangedEvent);
58 #if !defined(_ATMO_VLC_PLUGIN_)
60 STDMETHODIMP CAtmoLiveView::setLiveViewSource(enum ComLiveViewSource dwModus)
62 if(dwModus != m_LiveViewSource) {
63 m_LiveViewSource = dwModus;
65 you may ask why I don't use a critical section here and directly acces the
66 the variable of the Thread?
67 Just because you would need very much / often entering / leaving the critical
68 section ... and in this case It could be avoid ...
70 assigning the value to the "mirror" variable m_LiveViewSource which is compare
71 in every run of the thread with its current value ... if there is a change
72 the thread can proceed switching the live source ... until this is done
73 the thread calling this method is waiting...
76 // I don't expect that it will take longer than 500ms to switch...
77 if(WaitForSingleObject(m_InputChangedEvent,500) == WAIT_TIMEOUT)
78 return S_FALSE; // if not so the switch seems be have failed (badly)
83 STDMETHODIMP CAtmoLiveView::getCurrentLiveViewSource(enum ComLiveViewSource *modus) {
84 *modus = m_LiveViewSource;
91 DWORD CAtmoLiveView::Execute(void)
93 #if defined(_ATMO_VLC_PLUGIN_)
98 int i_frame_counter = 0;
99 CAtmoInput *newInput,*oldInput;
100 tColorPacket ColorPacket;
102 CAtmoConnection *pAtmoConnection = this->m_pAtmoDynData->getAtmoConnection();
103 if((pAtmoConnection == NULL) || (pAtmoConnection->isOpen() == ATMO_FALSE)) return 0;
105 CAtmoConfig *pAtmoConfig = this->m_pAtmoDynData->getAtmoConfig();
108 this object does post processing of the pixel data
109 like jump /scenechange detection fading over the colors
111 CAtmoOutputFilter *filter = new CAtmoOutputFilter(this->m_pAtmoDynData->getAtmoConfig());
115 #if defined(_ATMO_VLC_PLUGIN_)
116 /* this thread is the data preprocess which gets the real 64x48 pixel
117 and converts them into the RGB channel values - this is done in
118 another thread to keep this thread at a constant timing - to that
119 color output is updated 25 times a second
121 m_pAtmoInput = new CAtmoExternalCaptureInput(m_pAtmoDynData);
123 if(m_LiveViewSource == lvsGDI)
124 m_pAtmoInput = new CAtmoGdiDisplayCaptureInput(m_pAtmoDynData);
126 m_pAtmoInput = new CAtmoExternalCaptureInput(m_pAtmoDynData);
129 if(m_pAtmoInput->Open() == ATMO_TRUE)
132 wait for the first frame to go in sync with the other thread
134 #if defined(_ATMO_VLC_PLUGIN_)
135 msg_Dbg( m_pAtmoThread, "CAtmoLiveView::Execute(void)");
137 m_pAtmoInput->WaitForNextFrame(500);
139 while(this->m_bTerminated == ATMO_FALSE)
141 /* atmoInput - capture Thread Running... */
142 #if defined(_ATMO_VLC_PLUGIN_)
145 ticks = GetTickCount();
148 /* grab current Packet from Input! */
149 ColorPacket = m_pAtmoInput->GetColorPacket();
151 /* pass it through the outputfilters! */
152 ColorPacket = filter->Filtering(ColorPacket);
154 /* apply gamma later ;-) not implemented yet */
155 ColorPacket = CAtmoTools::ApplyGamma(pAtmoConfig, ColorPacket);
158 apply white calibration - only if it is not
161 if(pAtmoConfig->isUseSoftwareWhiteAdj())
162 ColorPacket = CAtmoTools::WhiteCalibration(pAtmoConfig,
165 /* send color data to the the hardware... */
166 pAtmoConnection->SendData(ColorPacket);
169 experimental do sync every 100 Frames to the image producer
170 thread because GetTickCount precision is really poor ;-)
173 if(i_frame_counter == 100) {
174 m_pAtmoInput->WaitForNextFrame(50);
177 /* kludge for pthreads? when running GDB debugger using the same condition variable
178 to often results in haging wait timedout...
181 vlc_mutex_lock( &m_TerminateLock );
182 vlc_cond_destroy( &m_TerminateCond );
183 vlc_cond_init( m_pAtmoThread, &m_TerminateCond );
184 vlc_mutex_unlock( &m_TerminateLock );
191 #if !defined(_ATMO_VLC_PLUGIN_)
193 Check if Input Source has changed - through an async
194 call from the com interface?
196 if(m_CurrentLiveViewSource != m_LiveViewSource) {
197 oldInput = m_pAtmoInput;
200 if(m_LiveViewSource == lvsGDI) {
201 // create new GDI Input Source...
202 newInput = new CAtmoGdiDisplayCaptureInput(m_pAtmoDynData);
203 newInput->Open(); // should not fail now... hope is the best!
204 } else if(m_LiveViewSource == lvsExternal) {
205 newInput = new CAtmoExternalCaptureInput(m_pAtmoDynData);
208 m_CurrentLiveViewSource = m_LiveViewSource;
210 m_pAtmoInput = newInput;
216 signal the call to the method "setLiveViewSource" the source
219 SetEvent(m_InputChangedEvent);
220 // do sync with input thread
221 m_pAtmoInput->WaitForNextFrame(100);
227 calculate RunTime of thread abbove (doesn't work well - so
228 this threads comes out of sync with Image producer and the
229 framerate (25fps) drifts away
231 #if defined(_ATMO_VLC_PLUGIN_)
232 ticks = ((mdate() - ticks) + 999)/1000;
234 ticks = GetTickCount() - ticks;
238 // ThreadSleep -> AtmoThread.cpp
239 if(this->ThreadSleep(40 - ticks)==ATMO_FALSE)
244 /* shutdown the input processor thread */
245 m_pAtmoInput->Close();
251 #if !defined(_ATMO_VLC_PLUGIN_)
253 if there is a pending call to setLiveViewSource let him surely return before
254 destroying the thread and this class instance...
256 SetEvent(m_InputChangedEvent);