]> git.sesse.net Git - vlc/blob - modules/video_filter/atmo/AtmoLiveView.cpp
Plugins: include vlc_common.h directly instead of vlc/vlc.h
[vlc] / modules / video_filter / atmo / AtmoLiveView.cpp
1 /*
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..
5  *
6  * See the README.txt file for copyright information and how to reach the author(s).
7  *
8  * $Id$
9  */
10 #include "AtmoDefs.h"
11 #include "AtmoLiveView.h"
12 #include "AtmoOutputFilter.h"
13 #include "AtmoTools.h"
14
15 #if defined(_ATMO_VLC_PLUGIN_)
16 # include <vlc_common.h>
17 #else
18 #  include "AtmoGdiDisplayCaptureInput.h"
19 #endif
20
21 #include "AtmoExternalCaptureInput.h"
22
23
24 #if defined(_ATMO_VLC_PLUGIN_)
25
26 CAtmoLiveView::CAtmoLiveView(CAtmoDynData *pAtmoDynData) :
27                CThread(pAtmoDynData->getAtmoFilter())
28 {
29     this->m_pAtmoDynData    = pAtmoDynData;
30     m_pAtmoInput = NULL;
31 }
32
33 #else
34
35 CAtmoLiveView::CAtmoLiveView(CAtmoDynData *pAtmoDynData)
36 {
37     this->m_pAtmoDynData  = pAtmoDynData;
38     m_LiveViewSource = lvsGDI;
39     m_CurrentLiveViewSource = lvsGDI;
40     m_InputChangedEvent = CreateEvent(NULL,ATMO_FALSE,ATMO_FALSE,NULL);
41     m_pAtmoInput = NULL;
42     InitializeCriticalSection(&m_InputChangeCriticalSection);
43 }
44
45 #endif
46
47
48 CAtmoLiveView::~CAtmoLiveView(void)
49 {
50 #if !defined(_ATMO_VLC_PLUGIN_)
51    DeleteCriticalSection(&m_InputChangeCriticalSection);
52    CloseHandle(m_InputChangedEvent);
53 #endif
54 }
55
56
57
58 #if !defined(_ATMO_VLC_PLUGIN_)
59
60 STDMETHODIMP CAtmoLiveView::setLiveViewSource(enum ComLiveViewSource dwModus)
61 {
62     if(dwModus != m_LiveViewSource) {
63        m_LiveViewSource = dwModus;
64        /*
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 ...
69
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...
74        */
75
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)
79     }
80     return S_OK;
81 }
82
83 STDMETHODIMP CAtmoLiveView::getCurrentLiveViewSource(enum ComLiveViewSource *modus) {
84      *modus = m_LiveViewSource;
85      return S_OK;
86 }
87
88 #endif
89
90
91 DWORD CAtmoLiveView::Execute(void)
92 {
93 #if defined(_ATMO_VLC_PLUGIN_)
94       mtime_t ticks;
95 #else
96       DWORD ticks;
97 #endif
98       int i_frame_counter = 0;
99       CAtmoInput *newInput,*oldInput;
100       tColorPacket ColorPacket;
101
102       CAtmoConnection *pAtmoConnection = this->m_pAtmoDynData->getAtmoConnection();
103       if((pAtmoConnection == NULL) || (pAtmoConnection->isOpen() == ATMO_FALSE)) return 0;
104
105       CAtmoConfig *pAtmoConfig = this->m_pAtmoDynData->getAtmoConfig();
106
107       /*
108          this object does post processing of the pixel data
109          like jump /scenechange detection fading over the colors
110       */
111       CAtmoOutputFilter *filter = new CAtmoOutputFilter(this->m_pAtmoDynData->getAtmoConfig());
112
113
114
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
120       */
121       m_pAtmoInput = new CAtmoExternalCaptureInput(m_pAtmoDynData);
122 #else
123       if(m_LiveViewSource == lvsGDI)
124          m_pAtmoInput = new CAtmoGdiDisplayCaptureInput(m_pAtmoDynData);
125       else
126          m_pAtmoInput = new CAtmoExternalCaptureInput(m_pAtmoDynData);
127 #endif
128
129       if(m_pAtmoInput->Open() == ATMO_TRUE)
130       {
131           /*
132             wait for the first frame to go in sync with the other thread
133           */
134 #if defined(_ATMO_VLC_PLUGIN_)
135           msg_Dbg( m_pAtmoThread, "CAtmoLiveView::Execute(void)");
136 #endif
137           m_pAtmoInput->WaitForNextFrame(500);
138
139           while(this->m_bTerminated == ATMO_FALSE)
140           {
141               /*  atmoInput - capture Thread Running... */
142 #if defined(_ATMO_VLC_PLUGIN_)
143                 ticks = mdate();
144 #else
145                 ticks = GetTickCount();
146 #endif
147
148                 /* grab current Packet from Input! */
149                 ColorPacket = m_pAtmoInput->GetColorPacket();
150
151                 /* pass it through the outputfilters! */
152                 ColorPacket = filter->Filtering(ColorPacket);
153
154                 /* apply gamma later ;-) not implemented yet */
155                 ColorPacket = CAtmoTools::ApplyGamma(pAtmoConfig, ColorPacket);
156
157                 /*
158                    apply white calibration - only if it is not
159                    done by the hardware
160                  */
161                 if(pAtmoConfig->isUseSoftwareWhiteAdj())
162                    ColorPacket = CAtmoTools::WhiteCalibration(pAtmoConfig,
163                                                               ColorPacket);
164
165                 /* send color data to the the hardware... */
166                 pAtmoConnection->SendData(ColorPacket);
167
168                 /*
169                    experimental do sync every 100 Frames to the image producer
170                    thread because GetTickCount precision is really poor ;-)
171                 */
172                 i_frame_counter++;
173                 if(i_frame_counter == 100) {
174                    m_pAtmoInput->WaitForNextFrame(50);
175                    i_frame_counter = 0;
176 #if !defined(WIN32)
177 /* kludge for pthreads? when running GDB debugger using the same condition variable
178    to often results in haging wait timedout...
179 */
180 #ifdef _ATMO_KLUDGE_
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 );
185 #endif
186 #endif
187                    continue;
188                 }
189
190
191 #if !defined(_ATMO_VLC_PLUGIN_)
192                 /*
193                   Check if Input Source has changed - through an async
194                   call from the com interface?
195                 */
196                 if(m_CurrentLiveViewSource != m_LiveViewSource) {
197                    oldInput = m_pAtmoInput;
198                    m_pAtmoInput = NULL;
199
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);
206                       newInput->Open();
207                    }
208                    m_CurrentLiveViewSource = m_LiveViewSource;
209
210                    m_pAtmoInput = newInput;
211
212                    oldInput->Close();
213                    delete oldInput;
214
215                    /*
216                      signal the call to the method "setLiveViewSource" the source
217                      was switched...
218                    */
219                    SetEvent(m_InputChangedEvent);
220                    // do sync with input thread
221                    m_pAtmoInput->WaitForNextFrame(100);
222                    continue;
223                 }
224 #endif
225
226                 /*
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
230                */
231 #if defined(_ATMO_VLC_PLUGIN_)
232                 ticks = ((mdate() - ticks) + 999)/1000;
233 #else
234                 ticks = GetTickCount() - ticks;
235 #endif
236                 if(ticks < 40)
237                 {
238                     // ThreadSleep -> AtmoThread.cpp
239                     if(this->ThreadSleep(40 - ticks)==ATMO_FALSE)
240                       break;
241                 }
242           }
243
244           /* shutdown the input processor thread */
245           m_pAtmoInput->Close();
246       }
247
248       delete m_pAtmoInput;
249       m_pAtmoInput = NULL;
250
251 #if !defined(_ATMO_VLC_PLUGIN_)
252       /*
253         if there is a pending call to setLiveViewSource let him surely return before
254         destroying the thread and this class instance...
255       */
256       SetEvent(m_InputChangedEvent);
257 #endif
258       delete filter;
259       return 0;
260 }
261