core/vidl/vidl_dshow_file_istream.h
Go to the documentation of this file.
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_