00001 // This is brl/bbas/vidl2/vidl2_dshow_live_istream.h 00002 #ifndef vidl2_dshow_live_istream_h_ 00003 #define vidl2_dshow_live_istream_h_ 00004 //========================================================================= 00005 //: 00006 // \file 00007 // \brief DirectShow live video input stream support. 00008 // \author Paul Crane 00009 // \author Miguel A. Figueroa-Villanueva (miguelf at ieee dot org) 00010 // 00011 // This file includes experimetal support for DirectShow live video input 00012 // in vidl2 (e.g., from cameras and/or frame grabbers). 00013 // 00014 // \verbatim 00015 // Modifications 00016 // 01/19/2006 - DirectShow code contributed by Paul Crane. (miguelf) 00017 // 03/09/2006 - File imported to vxl repository with some modifications 00018 // and extensions to Paul's code. (miguelf) 00019 // \endverbatim 00020 // 00021 //========================================================================= 00022 00023 #include <vidl2/vidl2_istream.h> 00024 #include <vidl2/vidl2_frame.h> 00025 #include <vidl2/vidl2_frame_sptr.h> 00026 #include <vidl2/vidl2_pixel_format.h> 00027 00028 #include <vcl_string.h> 00029 #include <vcl_vector.h> 00030 00031 #include <atlbase.h> 00032 #include <dshow.h> 00033 #include <qedit.h> 00034 00035 //------------------------------------------------------------------------- 00036 // ***** probably move this from here??? 00037 //------------------------------------------------------------------------- 00038 class sample_grabber_cb : public ISampleGrabberCB 00039 { 00040 public: 00041 //: Constructor. 00042 sample_grabber_cb(); 00043 00044 // IUnknown interface 00045 STDMETHODIMP_(ULONG) AddRef() { return 1; } // fake ref counting 00046 STDMETHODIMP_(ULONG) Release() { return 2; } // fake ref counting 00047 STDMETHODIMP QueryInterface(REFIID riid, void **target); 00048 00049 // ISampleGrabberCB interface 00050 STDMETHODIMP SampleCB(double time, IMediaSample *sample); 00051 STDMETHODIMP BufferCB(double time, BYTE* buffer, long buffer_size); 00052 00053 // vidl2 helpers 00054 void advance(); 00055 vidl2_frame_sptr current_frame(); 00056 00057 private: 00058 // Internal frame buffer information. 00059 vcl_vector<unsigned char> buffer_[3]; 00060 double buffer_time_[3]; 00061 00062 // Some status checking flags and counters. 00063 unsigned int busy_index_; 00064 unsigned int curr_index_; 00065 unsigned int next_index_; 00066 00067 HANDLE mutex_; 00068 }; 00069 00070 //------------------------------------------------------------------------- 00071 //: DirectShow live video input stream support. 00072 // 00073 // This is still in an experimental stage, but should be usable. It should 00074 // be able to open avi and wmv files as long as the system has the 00075 // available decoder, in the case of compressed video. 00076 // 00077 // DirectShow is very flexible and complex. Therefore we have taken the 00078 // approach to throw an exception or abort in the case where something 00079 // that is not supported fails, rather than try to parse through every 00080 // error and provide an alternative. However, we welcome any feedback on 00081 // desired features to make vidl2_dshow_file_istream more usable in the 00082 // VXL context. 00083 //------------------------------------------------------------------------- 00084 template <class ParamsObject> 00085 class vidl2_dshow_live_istream : public vidl2_istream 00086 { 00087 public: 00088 //: Constructor - default 00089 vidl2_dshow_live_istream(); 00090 00091 //: Constructor - from a string containing a device name. 00092 vidl2_dshow_live_istream(const vcl_string& device_name); 00093 00094 //: Constructor - from a parameter object. 00095 vidl2_dshow_live_istream(const ParamsObject& params); 00096 00097 //: Destructor. 00098 virtual ~vidl2_dshow_live_istream() { close(); } 00099 00100 //: Return true if the stream is open for reading. 00101 // ***** if closed, should return false 00102 virtual bool is_open() const { return is_valid_; } 00103 00104 //: Return true if the stream is in a valid state. 00105 virtual bool is_valid() const { return is_valid_; } 00106 00107 //: Return true if the stream support seeking. 00108 virtual bool is_seekable() const { return false; } 00109 00110 //: Return the current frame number. 00111 // ***** through exception ?? 00112 virtual unsigned int frame_number() const { return 0; } 00113 00114 //: Close the stream. 00115 virtual void close(); 00116 00117 // ***** did we decide to keep the alias? 00118 00119 //: Advance to the next frame (but don't acquire an image). 00120 virtual bool advance() { return advance_wait(); } 00121 00122 //: Read the next frame from the stream (advance and acquire). 00123 virtual vidl2_frame_sptr read_frame(); 00124 00125 //: Return the current frame in the stream. 00126 virtual vidl2_frame_sptr current_frame(); 00127 00128 //: Seek to the given frame number. 00129 // ***** throw exception ?? 00130 virtual bool seek_frame(unsigned int frame_number) { return false; } 00131 00132 void run(void); 00133 void pause(void); 00134 void stop(void); 00135 00136 private: 00137 // Disable assignment and copy-construction. 00138 vidl2_dshow_live_istream(const vidl2_dshow_live_istream&); 00139 vidl2_dshow_live_istream& operator=(const vidl2_dshow_live_istream&); 00140 00141 //: Parameters that define the input stream process. 00142 ParamsObject params_; 00143 00144 //: Connect to a device using its FriendlyName (in params_ object). 00145 void connect(void); 00146 00147 //: If hr == S_FALSE, wait for the state change to complete. 00148 void wait_for_state_change(HRESULT hr); 00149 00150 //: ***** Callback method... 00151 sample_grabber_cb sample_grabber_callback_; 00152 00153 // Handles to the COM interfaces. 00154 CComPtr<IFilterGraph2> filter_graph_; 00155 CComPtr<IMoniker> moniker_; 00156 CComPtr<IMediaControl> media_control_; 00157 00158 // Internal frame buffer information. 00159 vidl2_frame_sptr buffer_; 00160 unsigned int buffer_width_; 00161 unsigned int buffer_height_; 00162 vidl2_pixel_format buffer_pixel_format_; 00163 00164 // Some status checking flags and counters. 00165 bool is_valid_; 00166 00167 //: ID in Running Object Table (ROT), for debugging with GraphEdit. 00168 DWORD register_; 00169 00170 // ***** we're considering removing this from API... 00171 00172 //: Initiate advance and wait for completion; synchronous advance. 00173 bool advance_wait(); 00174 //: Initiate advance and return immediately; asynchronous advance. 00175 bool advance_start(); 00176 //: Advance to the next frame (but don't acquire an image). 00177 bool is_frame_available() const; 00178 }; 00179 00180 #endif // vidl2_dshow_live_istream_h_
1.4.4