Update the changelog
[opencv] / otherlibs / cvcam / src / windows / cvcamavi.cpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                        Intel License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 //   * Redistribution's of source code must retain the above copyright notice,
20 //     this list of conditions and the following disclaimer.
21 //
22 //   * Redistribution's in binary form must reproduce the above copyright notice,
23 //     this list of conditions and the following disclaimer in the documentation
24 //     and/or other materials provided with the distribution.
25 //
26 //   * The name of Intel Corporation may not be used to endorse or promote products
27 //     derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41
42 #define WM_GRAPHNOTIFY  WM_USER+13
43
44
45 #include <objbase.h>
46 #include <streams.h>
47 #include "iProxyTrans.h"
48 #include "ProxyTransuids.h"
49 #include "highgui.h"
50 #include "cvcamavi.h"
51
52 IPin* get_pin( IBaseFilter* pFilter, PIN_DIRECTION dir );
53 HWND _cvcamCreateWindow();
54
55 const int FRAMES_FORMAT = 0;
56 const int TIME_FORMAT = 1;
57
58
59 cvcamSourceFile::cvcamSourceFile(const char* file , void (*callback)(void*) ):
60 Iusecom(),
61 m_pGraph(NULL),
62 m_pMediaControl(NULL),
63 m_pEvent(NULL),
64 m_pVideoWindow(NULL),
65 m_pPin(NULL),
66 m_pBasicVideo(NULL),
67 m_pSFilter(NULL),
68 m_pProxyTrans(NULL),
69 m_pSourceOut(NULL),
70 m_pProxyIn(NULL),
71 m_pProxyOut(NULL),
72 m_pEnumPins(NULL),
73 m_pProxyBase(NULL),
74 m_file(),
75 m_pcallback(NULL),
76 m_width(0),
77 m_height(0),
78 IsValid(true),
79 m_hr(),
80 m_hWnd(NULL),
81 m_pMediaSeeking(NULL)
82
83 {
84     try
85     {
86     
87     //Get the file
88     if (file) 
89     {
90         m_file = file;
91     }
92     else
93     {
94         char path[256];
95         memset(path,0,256);
96
97         OPENFILENAME fn;
98         
99         fn.lStructSize = sizeof(OPENFILENAME);
100         fn.hwndOwner = NULL;
101         fn.lpstrFilter = NULL;
102         fn.lpstrFile = path;
103         fn.nMaxFile = 256;
104         fn.lpstrFileTitle = NULL;
105         fn.lpstrInitialDir = NULL;
106         fn.lpstrTitle = NULL;
107         fn.Flags = NULL;
108         fn.lpstrDefExt = "avi";
109         fn.hInstance = DLLhinst;
110         fn.lpfnHook = NULL;
111         fn.lpstrCustomFilter = NULL;
112         fn.lCustData = NULL;
113         
114         
115         if(!GetOpenFileName(&fn))
116             throw 1;
117
118         m_file = path;
119        
120     }//else after if(file)
121
122     // Create the filter graph manager and query for interfaces.
123     CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
124         IID_IGraphBuilder, (void **)&m_pGraph);
125     
126     // Build the graph.
127     wchar_t wpath[256];
128     mbstowcs(wpath, m_file.c_str(), strlen(m_file.c_str())+1);
129     
130     
131     m_hr = m_pGraph->AddSourceFilter(wpath,L"source",&m_pSFilter);
132     
133     
134     // Create a proxy transform filter 
135     if(FAILED(CoCreateInstance(CLSID_ProxyTransform, NULL, CLSCTX_INPROC_SERVER, 
136         IID_IProxyTransform, (void**)&m_pProxyTrans)))
137     {
138         throw 1;
139     }
140     
141     //set callback
142     m_hr = m_pProxyTrans->set_transform((void(__cdecl*)(void*))m_pcallback, 0);
143     
144     //Get Source output pin
145     m_hr = m_pSFilter->EnumPins(&m_pEnumPins);
146     
147     unsigned long fetched(0);
148     m_hr = m_pEnumPins->Next(1,&m_pSourceOut,&fetched);
149     if(!fetched)
150         throw 1 ;
151     
152     m_pEnumPins = NULL;
153     
154     //Put ProxyTrans into graph
155     m_hr = m_pProxyTrans->QueryInterface(IID_IBaseFilter,(void**)&m_pProxyBase);
156     m_hr = m_pGraph->AddFilter(m_pProxyBase.value(),L"proxy");
157     
158     //Get ProxyTrans Pins
159     m_pProxyIn = get_pin( m_pProxyBase.value(), PINDIR_INPUT );
160     m_pProxyOut= get_pin( m_pProxyBase.value(), PINDIR_OUTPUT );
161     
162     m_hr = m_pGraph->Connect(m_pSourceOut.value(),m_pProxyIn.value());
163     
164     m_hr = m_pGraph->Render(m_pProxyOut.value());
165     
166     
167     
168     //Gain additional interfaces
169     m_hr = m_pGraph->QueryInterface(IID_IMediaControl, (void **)&m_pMediaControl);
170     m_hr = m_pGraph->QueryInterface(IID_IMediaEventEx, (void **)&m_pEvent);
171     m_hr = m_pGraph->QueryInterface(IID_IVideoWindow, (void **)&m_pVideoWindow);
172     m_hr = m_pGraph->QueryInterface(IID_IMediaSeeking, (void**)&m_pMediaSeeking);
173     
174     if(!m_pMediaControl.is_valid() ||!m_pEvent.is_valid() ||!m_pVideoWindow.is_valid())
175         throw 1;
176     
177
178
179 }//try
180 catch (...) 
181 {
182     IsValid = false;
183     return;
184 }//catch
185
186
187
188
189 }//cvcamSourceFile()
190
191
192 bool cvcamSourceFile::IsRunning()
193 {
194     long evCode;
195     
196     HRESULT hr = m_pEvent->WaitForCompletion(0, &evCode);
197     
198     if(SUCCEEDED(hr))
199     {
200         if(!evCode)
201             return true;
202     }
203     
204     return false;
205 }
206
207 HRESULT cvcamSourceFile::SetWindow(const HWND window)
208 {
209     
210     
211     if(IsRunning())
212         return E_FAIL;
213         
214     m_hWnd = window;
215     
216     if (!m_hWnd) 
217     {
218         m_hWnd = _cvcamCreateWindow();  
219     }
220
221     return S_OK;
222     
223    
224 }
225
226 HRESULT cvcamSourceFile::Start()
227 {
228     try
229     {
230     
231     if (IsRunning())
232     {
233         return NOERROR;
234     }
235
236     //Set up the window
237     
238     m_hr = m_pVideoWindow->put_Owner((OAHWND)m_hWnd);
239     long flags;
240     m_hr = m_pEvent->SetNotifyWindow((OAHWND)m_hWnd, WM_GRAPHNOTIFY, 0);
241     m_hr = m_pEvent->SetNotifyFlags(0x00);
242     m_hr = m_pEvent->CancelDefaultHandling(EC_COMPLETE);
243     m_hr = m_pVideoWindow->get_WindowStyle(&flags);
244     m_hr = m_pVideoWindow->put_WindowStyle(flags & (~WS_CAPTION) | WS_CHILD);
245     m_hr = m_pVideoWindow->put_MessageDrain((OAHWND)m_hWnd);
246
247     // Get the rectangle dimensions and resize the client window
248     m_hr = m_pGraph->QueryInterface(IID_IBasicVideo,(void**)&m_pBasicVideo);
249      
250     long left, top, w, h;
251     m_pBasicVideo->GetSourcePosition(&left, &top,&w,&h);
252     m_pBasicVideo->SetDestinationPosition(0, 0, m_width?m_width:w, m_height?m_height:h);
253     m_pVideoWindow->SetWindowPosition(0,0,m_width?m_width:w,m_height?m_height:h);
254     const char* name = cvGetWindowName(m_hWnd);
255     cvResizeWindow(name, m_width?m_width:w, m_height?m_height:h);
256         
257         
258     
259     // Run the graph.
260     m_hr = m_pMediaControl->Run();
261     
262     return S_OK;
263     
264     }//try
265     catch(HrExeption exp)
266     {
267         return exp.hr;
268     }//catch
269
270 }
271
272 HRESULT cvcamSourceFile::Stop()
273 {
274     if( m_pMediaControl.is_valid() )
275     {
276         OAFilterState fs;
277         m_pMediaControl->GetState(0,&fs);
278         if(fs == State_Stopped)
279             return NOERROR;
280         
281         
282         m_pMediaControl->StopWhenReady();
283         
284         
285         
286         if(m_pVideoWindow.is_valid() )
287         {
288             m_pVideoWindow->put_Visible(OAFALSE);
289             m_pVideoWindow->put_Owner(NULL);
290             m_pVideoWindow->put_MessageDrain(0);
291         }
292     }           
293 return S_OK;
294 }
295
296 HRESULT cvcamSourceFile::Pause()
297 {
298     if( m_pMediaControl.is_valid() )
299     {
300         OAFilterState fs;
301         m_pMediaControl->GetState(0,&fs);
302         if(fs == State_Stopped)
303             return S_OK;
304         m_pMediaControl->Pause();
305     }   
306     
307     
308     
309     return S_OK;
310 }
311
312 HRESULT cvcamSourceFile::Resume()
313 {
314     if( m_pMediaControl.is_valid() )
315     {
316         OAFilterState fs;
317         m_pMediaControl->GetState(0,&fs);
318         if(fs == State_Stopped)
319             return S_OK;
320         
321         m_pMediaControl->Run();
322     }
323     
324     
325     return S_OK;
326 }
327
328 HRESULT cvcamSourceFile::SetCallBack(void (__cdecl *callback)(void *))
329 {
330     if(IsRunning())
331         return E_FAIL;
332
333     m_pcallback = callback;
334     
335     m_pProxyTrans->set_transform((void(__cdecl*)(void*))m_pcallback, 0);
336
337     return S_OK;
338 }
339
340 HRESULT cvcamSourceFile::SetHeight(const int height)
341 {
342     m_height = height;
343
344     return S_OK;
345 }
346
347 HRESULT cvcamSourceFile::SetWidth(const int width)
348 {
349     m_width = width;
350
351     return S_OK;
352 }
353
354 HRESULT cvcamSourceFile::WaitForCompletion()
355 {
356     long evCode;
357
358     return m_pEvent->WaitForCompletion(INFINITE, &evCode);
359
360 }
361
362 HRESULT cvcamSourceFile::SetTimeFormat(const int format)
363 {
364     if (format == FRAMES_FORMAT) 
365     {
366         return m_pMediaSeeking->SetTimeFormat(&TIME_FORMAT_FRAME );
367     }else
368     if (format == TIME_FORMAT) 
369         
370     {
371         
372         return m_pMediaSeeking->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME);
373     }else
374         return E_FAIL;
375 }
376
377 HRESULT cvcamSourceFile::GetDuration(LONGLONG *pDuration)
378 {
379     return m_pMediaSeeking->GetDuration(pDuration);
380 }
381
382 HRESULT cvcamSourceFile::GetCurrentPosition(LONGLONG *pCurrent)
383 {
384     
385     return m_pMediaSeeking->GetCurrentPosition(pCurrent);
386 }
387
388 HRESULT cvcamSourceFile::SetPosition(LONGLONG *pCurrent)
389 {
390
391     return m_pMediaSeeking->SetPositions(pCurrent,AM_SEEKING_AbsolutePositioning,NULL,
392                                                             AM_SEEKING_NoPositioning);
393 }