contrib/mul/mvl2/mvl2_video_from_avi_windows.cxx
Go to the documentation of this file.
00001 //:
00002 // \file
00003 // \brief A class for reading video files on windows platform
00004 // \author Louise Butcher
00005 
00006 #include "mvl2_video_from_avi_windows.h"
00007 #include <vil/vil_flip.h>
00008 #include <vil/vil_convert.h>
00009 #include <vcl_cstdlib.h>
00010 
00011 mvl2_video_from_avi::mvl2_video_from_avi()
00012 {
00013   is_initialized_=false;
00014   current_frame_=0;
00015 }
00016 
00017 mvl2_video_from_avi::~mvl2_video_from_avi()
00018 {
00019 }
00020 
00021 vcl_string mvl2_video_from_avi::is_a() const
00022 {
00023   return vcl_string("mvl2_video_from_avi");
00024 }
00025 
00026 mvl2_video_reader* mvl2_video_from_avi::clone() const
00027 {
00028   return new mvl2_video_from_avi(*this);
00029 }
00030 
00031 // possible options : Grey
00032 bool mvl2_video_from_avi::initialize( int /* width */, int /* height */,
00033                                       vcl_string format, vcl_string file_name)
00034 {
00035   if (!format.find(vcl_string("Grey"))) use_colour_=false;
00036   AVIFileInit();
00037   ppavi_=0;
00038   LPCTSTR szFile;
00039   szFile=(LPCTSTR)file_name.c_str();
00040   DWORD fccType=streamtypeVIDEO;
00041   LONG lParam=0;
00042   UINT mode=OF_READ;
00043   CLSID * pclsidHandler=NULL;
00044   bool success;
00045   current_frame_=0;
00046   success=!(AVIStreamOpenFromFile(&ppavi_,szFile,fccType,lParam,mode,pclsidHandler));
00047   if (success)
00048   {
00049     is_initialized_=true;
00050   }
00051   else
00052   {
00053     is_initialized_=false;
00054     AVIFileExit();
00055   }
00056   return success;
00057 }
00058 
00059 void mvl2_video_from_avi::uninitialize()
00060 {
00061   AVIStreamRelease(ppavi_);
00062   AVIFileExit();
00063   is_initialized_=false;
00064 }
00065 
00066 int mvl2_video_from_avi::next_frame()
00067 {
00068   if (!is_initialized_) return -1;
00069 
00070   return ++current_frame_;
00071 }
00072 
00073 int mvl2_video_from_avi::seek(int frame_number)
00074 {
00075   if (!is_initialized_ || frame_number<0)
00076     return -1;
00077   reset_frame();
00078   bool b;
00079   do {
00080     vil_image_view<vxl_byte> im;
00081     b = get_frame(im);
00082     if (b) ++current_frame_;
00083   } while (b && frame_number--);
00084 
00085   return current_frame_;
00086 }
00087 
00088 bool mvl2_video_from_avi::get_frame(vil_image_view<vxl_byte>& image)
00089 {
00090   //nb doesn't allow you to load in colour videos as grey scale
00091   //only loads videos according to number of planes in each frame!
00092   if (!is_initialized_) return false;
00093   BITMAPINFO bmp_info;
00094   BITMAPINFO* img;
00095   bool colour_vid;
00096 
00097   getVideoFormat(bmp_info);
00098   PGETFRAME g_frame=AVIStreamGetFrameOpen(ppavi_,NULL);
00099   LPVOID img_data=AVIStreamGetFrame(g_frame,current_frame_);
00100   if (!img_data) return false;
00101   img=(BITMAPINFO* )img_data;
00102 
00103   int nx = bmp_info.bmiHeader.biWidth;
00104   int ny = bmp_info.bmiHeader.biHeight;
00105   int bpp= bmp_info.bmiHeader.biBitCount;
00106   int bplanes= bmp_info.bmiHeader.biBitCount/8;
00107 
00108   if (bplanes==1)
00109     colour_vid=false;
00110   else
00111     colour_vid=true;
00112 
00113   int ystep=(nx*(bpp/8) + 3)& -4;
00114   int xstep=bpp/8;
00115 
00116   unsigned char* data=(unsigned char*)(img_data)+img->
00117     bmiHeader.biSize+img->bmiHeader.biClrUsed*sizeof(RGBQUAD);
00118   vil_image_view<vxl_byte> temp_img;
00119   if (colour_vid)
00120     temp_img.set_to_memory(data+2,nx,ny,bplanes,xstep,ystep,-1);
00121   else
00122     temp_img.set_to_memory(data,nx,ny,bplanes,xstep,ystep,0);
00123 
00124 
00125   vil_image_view<vxl_byte> image_tmp_;
00126   image_tmp_=vil_flip_ud(temp_img);
00127 
00128   if ( colour_vid == use_colour_ )
00129   {
00130     image.deep_copy(image_tmp_);
00131   }
00132   else if ( colour_vid && !use_colour_ )
00133   {
00134     vil_convert_planes_to_grey( image_tmp_, image );
00135   }
00136   else
00137   {
00138     vcl_cout<<"ERROR: mvl2_video_from_avi_windows.cxx\n"
00139             <<"Requested colour video, but only grey scale available\n";
00140     vcl_abort();
00141   }
00142 
00143   AVIStreamGetFrameClose(g_frame);
00144   return true;
00145 }
00146 
00147 void mvl2_video_from_avi::reset_frame()
00148 {
00149   current_frame_=0;
00150 }
00151 
00152 void mvl2_video_from_avi::set_frame_rate(double /*frame_rate*/)
00153 {
00154   vcl_cerr << "mvl2_video_from_avi::set_frame_rate() NYI\n";
00155 }
00156 
00157 double mvl2_video_from_avi::get_frame_rate() const
00158 {
00159   AVISTREAMINFO avis;
00160   AVIStreamInfo(ppavi_, &avis, sizeof(avis));
00161   return frame_rate_=(avis.dwRate)/(avis.dwScale);
00162 }
00163 
00164 int mvl2_video_from_avi::get_width() const
00165 {
00166   BITMAPINFO bmp_info;
00167   getVideoFormat(bmp_info);
00168   return width_=bmp_info.bmiHeader.biWidth;
00169 }
00170 
00171 int mvl2_video_from_avi::get_height() const
00172 {
00173   BITMAPINFO bmp_info;
00174   getVideoFormat(bmp_info);
00175   return height_=bmp_info.bmiHeader.biHeight;
00176 }
00177 
00178 void mvl2_video_from_avi::set_capture_size(int /*width*/,int /*height*/)
00179 {
00180   vcl_cerr << "mvl2_video_from_avi::set_capture_size() NYI\n";
00181 }
00182 
00183 void mvl2_video_from_avi::getVideoFormat(BITMAPINFO& bmp_info ) const
00184 {
00185   long lStreamSize;
00186   AVIStreamFormatSize(ppavi_, 0, &lStreamSize);
00187 
00188   BITMAPINFO* vfmt = (LPBITMAPINFO)LocalAlloc(LPTR, lStreamSize);
00189 
00190   /* HRESULT hr = */
00191   AVIStreamReadFormat(ppavi_, 0, vfmt, &lStreamSize); // Read format
00192   bmp_info=*vfmt;
00193   LocalFree(vfmt);
00194   return;
00195 }