00001 // This is core/vidl/vidl_dshow_file_istream.h 00002 #ifndef vidl_dshow_file_istream_h_ 00003 #define vidl_dshow_file_istream_h_ 00004 //========================================================================= 00005 //: 00006 // \file 00007 // \brief DirectShow file input stream support. 00008 // \author Paul Crane 00009 // \author Miguel A. Figueroa-Villanueva (miguelf at ieee dot org) 00010 // 00011 // This file includes experimental support for DirectShow file input in vidl. 00012 // 00013 // \verbatim 00014 // TODO 00015 // - A few things... write them down! 00016 // \endverbatim 00017 // 00018 // \verbatim 00019 // Modifications 00020 // 01/19/2006 - DirectShow code contributed by Paul Crane. (miguelfv) 00021 // 03/07/2006 - File imported to vxl repository with some modifications 00022 // and extensions to Paul's code. (miguelfv) 00023 // \endverbatim 00024 // 00025 //========================================================================= 00026 00027 #include <vidl/vidl_istream.h> 00028 #include <vidl/vidl_frame_sptr.h> 00029 #include <vidl/vidl_pixel_format.h> 00030 00031 #include <vcl_string.h> 00032 #include <vcl_vector.h> 00033 00034 #include <atlbase.h> 00035 #include <dshow.h> 00036 #include <qedit.h> 00037 00038 //------------------------------------------------------------------------- 00039 //: DirectShow file input stream object. 00040 // 00041 // This is still in an experimental stage, but should be usable. It should 00042 // be able to open avi and wmv files as long as the system has the 00043 // available decoder, in the case of compressed video. 00044 // 00045 // DirectShow is very flexible and complex. Therefore we have taken the 00046 // approach to throw an exception or abort in the case where something 00047 // that is not supported fails, rather than try to parse through every 00048 // error and provide an alternative. However, we welcome any feedback on 00049 // desired features to make vidl_dshow_file_istream more usable in the 00050 // VXL context. 00051 //------------------------------------------------------------------------- 00052 class vidl_dshow_file_istream : public vidl_istream 00053 { 00054 public: 00055 //: Constructor - from a string containing the file name. 00056 vidl_dshow_file_istream(const vcl_string& name); 00057 00058 //: Destructor. 00059 virtual ~vidl_dshow_file_istream(); 00060 00061 //: Return true if the stream is open for reading. 00062 // ***** if closed, should return false 00063 virtual bool is_open() const { return true; } 00064 00065 //: Return true if the stream is in a valid state. 00066 virtual bool is_valid() const { return is_valid_; } 00067 00068 //: Return true if the stream supports seeking. 00069 virtual bool is_seekable() const { return true; } 00070 00071 //: Return the number of frames if known 00072 // returns -1 for non-seekable streams 00073 // TODO this needs to be implemented 00074 virtual int num_frames() const { return -1; } 00075 00076 //: Return the current frame number. 00077 virtual unsigned int frame_number() const { return frame_index_; } 00078 00079 //: Return the width of each frame 00080 virtual unsigned int width() const { return buffer_width_; } 00081 00082 //: Return the height of each frame 00083 virtual unsigned int height() const { return buffer_height_; } 00084 00085 //: Return the pixel format 00086 virtual vidl_pixel_format format() const { return buffer_pixel_format_; } 00087 00088 //: Return the frame rate (FPS, 0.0 if unspecified) 00089 // TODO return a valid framerate 00090 virtual double frame_rate() const { return 0.0; } 00091 00092 //: Return the duration in seconds (0.0 if unknown) 00093 // TODO implement this 00094 virtual double duration() const { return 0.0; } 00095 00096 //: Close the stream. 00097 virtual void close(); 00098 00099 // ***** did we decide to keep the alias? 00100 00101 //: Advance to the next frame (but don't acquire an image). 00102 virtual bool advance() { return advance_wait(); } 00103 00104 //: Initiate advance and wait for completion; synchronous advance. 00105 virtual bool advance_wait(); 00106 00107 //: Initiate advance and return immediately; asynchronous advance. 00108 virtual bool advance_start(); 00109 00110 //: Returns true if the advance has finished and a frame is available. 00111 virtual bool is_frame_available() const; 00112 00113 //: Read the next frame from the stream (advance and acquire). 00114 virtual vidl_frame_sptr read_frame(); 00115 00116 //: Return the current frame in the stream. 00117 virtual vidl_frame_sptr current_frame(); 00118 00119 //: Seek to the given frame number 00120 // \returns true if successful 00121 virtual bool seek_frame(unsigned int frame_number); 00122 00123 private: 00124 // Disable assignment and copy-construction. 00125 vidl_dshow_file_istream(const vidl_dshow_file_istream&); 00126 vidl_dshow_file_istream& operator=(const vidl_dshow_file_istream&); 00127 00128 //: Open a video file. 00129 void open(const vcl_string& filename); 00130 00131 // Handles to the COM interfaces. 00132 CComPtr<IFilterGraph2> filter_graph_; 00133 CComPtr<IMediaControl> media_control_; 00134 CComPtr<IMediaSeeking> media_seeking_; 00135 CComPtr<IMediaEventEx> media_event_; 00136 CComPtr<ISampleGrabber> sample_grabber_; 00137 00138 // Internal frame buffer information. 00139 vcl_vector<unsigned char> buffer_[2]; 00140 double buffer_time_[2]; 00141 unsigned char buffer_index_; 00142 unsigned int buffer_width_; 00143 unsigned int buffer_height_; 00144 vidl_pixel_format buffer_pixel_format_; 00145 00146 // Some status checking flags and counters. 00147 unsigned int frame_index_; 00148 REFERENCE_TIME end_position_; 00149 bool is_time_format_frame_; 00150 bool is_valid_; 00151 00152 //: ID in Running Object Table (ROT), for debugging with GraphEdit. 00153 DWORD register_; 00154 }; 00155 00156 #endif // vidl_dshow_file_istream_h_