contrib/mul/mvl2/mvl2_video_to_avi_linux.cxx
Go to the documentation of this file.
00001 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00002 #pragma implementation
00003 #endif
00004 //:
00005 // \file
00006 // \brief A class for writing videos
00007 // \author Franck Bettinger
00008 
00009 #include "mvl2_video_to_avi_linux.h"
00010 #include <vcl_cstring.h>
00011 #include <vil/vil_resample_bilin.h>
00012 
00013 mvl2_video_to_avi::mvl2_video_to_avi()
00014 {
00015   is_initialized_=false;
00016   current_frame_=0;
00017   fourcc_=fccDIVX;
00018   frame_rate_=25.0;
00019   quality_=10000;
00020   bgr_=false;
00021   upside_down_=true;
00022 }
00023 
00024 mvl2_video_to_avi::~mvl2_video_to_avi()
00025 {
00026   close();
00027 }
00028 
00029 bool mvl2_video_to_avi::set_codec(char a, char b, char c, char d)
00030 {
00031   // TO DO : verify if the codec is supported for video writing.
00032   fourcc_=mmioFOURCC(a,b,c,d);
00033 
00034   // hack to get correct color with mjpg codec
00035   if (fourcc_==fccmjpg)
00036   {
00037     bgr_=true;
00038   }
00039   else
00040   {
00041     bgr_=false;
00042   }
00043 
00044   // hack to get correct orientation with DIVX codec
00045   if (fourcc_==fccDIVX)
00046   {
00047     upside_down_=false;
00048   }
00049   else
00050   {
00051     upside_down_=true;
00052   }
00053 
00054   return true;
00055 }
00056 
00057 void mvl2_video_to_avi::set_quality(int qual)
00058 {
00059   quality_=qual;
00060 }
00061 
00062 bool mvl2_video_to_avi::open( int width, int height,
00063                               vcl_string format, vcl_string file_name)
00064 {
00065   if (is_initialized_) return false;
00066 
00067   width_=width%2?width+1:width;
00068   height_=height;
00069 
00070   moviefile_ = CreateIAviWriteFile(file_name.c_str());
00071 
00072   BitmapInfo bh(width_,height_,24);
00073   moviestream_ = moviefile_->AddVideoStream(
00074             fourcc_, &bh,
00075             (int)(1000000.0/frame_rate_));
00076 
00077   moviestream_->SetQuality( quality_ );
00078   moviestream_->SetKeyFrame(1);
00079   moviestream_->Start();
00080 
00081   is_initialized_=true;
00082 
00083   return is_initialized_;
00084 }
00085 
00086 void mvl2_video_to_avi::close()
00087 {
00088   if (!is_initialized_) return;
00089 
00090   moviestream_->Stop();
00091   delete moviefile_;
00092   is_initialized_=false;
00093 }
00094 
00095 int mvl2_video_to_avi::get_width() const
00096 {
00097   return width_;
00098 }
00099 
00100 int mvl2_video_to_avi::get_height() const
00101 {
00102   return height_;
00103 }
00104 
00105 void mvl2_video_to_avi::set_frame_rate(double frame_rate)
00106 {
00107   frame_rate_=frame_rate;
00108 }
00109 
00110 void mvl2_video_to_avi::write_frame(vil_image_view<vxl_byte>& image)
00111 {
00112   if (width_==(int)image.ni() && height_==(int)image.nj() &&
00113       image.pixel_format()==VIL_PIXEL_FORMAT_RGB_BYTE )
00114   {
00115     BitmapInfo bi=BitmapInfo(width_,height_,24);
00116     CImage* im24;
00117     im24 = new CImage(&bi,image.top_left_ptr(),false);
00118     moviestream_->AddFrame(im24);
00119   }
00120   else
00121   {
00122     double xratio=(double)width_/image.ni();
00123     double yratio=(double)height_/image.nj();
00124     double ratio=1.0/(yratio>xratio?yratio:xratio);
00125 
00126     vil_image_view<vxl_byte> resampled_image(width_,height_,image.nplanes());
00127     vil_resample_bilin(image,resampled_image,0.0,0.0,
00128                        ratio,0.0,0.0,ratio,width_,height_);
00129 
00130     vcl_cout << "write frame "<< current_frame_+1 << " ... "
00131              << image.ni()<<'x'<<image.nj()<<" -> "
00132              << width_<<'x'<<height_<< vcl_endl;
00133 
00134     uint8_t data[width_*height_*3];
00135     vcl_memset(data,0,width_*height_*3*sizeof(uint8_t));
00136 
00137     BitmapInfo bi=BitmapInfo(width_,height_,24);
00138     CImage* im24;
00139     im24 = new CImage(&bi,data,false);
00140 
00141     for (int y=0;y<height_;++y)
00142       for (int x=0;x<width_;++x)
00143       {
00144         if (image.nplanes()==3)
00145         {
00146           im24->At(x,y)[bgr_?2:0] = resampled_image(x,
00147               upside_down_?y:(height_-y-1),2);
00148           im24->At(x,y)[1] = resampled_image(x,
00149               upside_down_?y:(height_-y-1),1);
00150           im24->At(x,y)[bgr_?0:2] = resampled_image(x,
00151               upside_down_?y:(height_-y-1),0);
00152         }
00153         else
00154         {
00155           im24->At(x,y)[bgr_?2:0] = resampled_image(x,
00156               upside_down_?y:(height_-y-1),0);
00157           im24->At(x,y)[1] = resampled_image(x,
00158               upside_down_?y:(height_-y-1),0);
00159           im24->At(x,y)[bgr_?0:2] = resampled_image(x,
00160               upside_down_?y:(height_-y-1),0);
00161         }
00162       }
00163 
00164     moviestream_->AddFrame(im24);
00165   }
00166 
00167   current_frame_++;
00168 }
00169 
00170 vcl_string mvl2_video_to_avi::is_a() const
00171 {
00172   return vcl_string("mvl2_video_to_avi");
00173 }
00174 
00175 mvl2_video_writer* mvl2_video_to_avi::clone() const
00176 {
00177   return new mvl2_video_to_avi(*this);
00178 }