cvd/videofilebuffer.h

00001 /*                       
00002     This file is part of the CVD Library.
00003 
00004     Copyright (C) 2005 The Authors
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Lesser General Public
00008     License as published by the Free Software Foundation; either
00009     version 2.1 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Lesser General Public License for more details.
00015 
00016     You should have received a copy of the GNU Lesser General Public
00017     License along with this library; if not, write to the Free Software
00018     Foundation, Inc., 
00019     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 */
00021 
00022 #ifndef CVD_VIDEOFILEBUFFER_H
00023 #define CVD_VIDEOFILEBUFFER_H
00024 
00025 #include <vector>
00026 #include <string>
00027 #include <fstream>
00028 #include <errno.h>
00029 
00030 #include <cvd/localvideobuffer.h>
00031 #include <cvd/videobufferflags.h>
00032 #include <cvd/videofilebuffer_frame.h>
00033 #include <cvd/image_io.h>
00034 
00035 #include <cvd/byte.h>
00036 #include <cvd/rgb.h>
00037 
00038 #include <cvd/config.h>
00039 
00040 extern "C" {
00041 #ifdef CVD_INTERNAL_HAVE_FFMPEG_OLD_HEADERS
00042     #include <ffmpeg/avcodec.h>
00043     #include <ffmpeg/avformat.h>
00044     #include <ffmpeg/swscale.h>
00045 #else
00046     #include <libavcodec/avcodec.h>
00047     #include <libavformat/avformat.h>
00048     #include <libswscale/swscale.h>
00049 #endif
00050 }
00051 
00052 struct AVFormatContext;
00053 struct AVFrame; 
00054 
00055 namespace CVD
00056 {
00057     namespace Exceptions
00058     {
00061         namespace VideoFileBuffer
00062         {
00065             struct All: public CVD::Exceptions::VideoBuffer::All { };
00068             struct FileOpen: public All { FileOpen(const std::string& file, const std::string& error); 
00069             };
00072             struct BadFrameAlloc: public All { BadFrameAlloc(); };
00075             struct BadDecode: public All { BadDecode(double t); 
00076             };
00079             struct EndOfFile: public All { EndOfFile(); };
00082             struct BadSeek: public All { BadSeek(double t); 
00083             };
00084         }
00085     }
00086 
00088     namespace VFB
00089     {
00090 
00091     #ifndef DOXYGEN_IGNORE_INTERNAL
00092     template<class C> struct rgb
00093     {
00094         static const bool p=C::Error__type_not_valid___Use_byte_or_rgb_of_byte;
00095     };
00096 
00097     template<> struct rgb<CVD::byte>
00098     {   
00099         static const bool p=false;
00100     };
00101 
00102     template<> struct rgb<CVD::Rgb<CVD::byte> >
00103     {   
00104         static const bool p=true;
00105     };
00106     #endif 
00107 
00108 
00109     class A_Frame;
00110 
00113     class RawVideoFileBuffer 
00114     {
00115         public:
00119             RawVideoFileBuffer(const std::string& file, bool is_rgb);
00120             ~RawVideoFileBuffer();
00121         
00123             ImageRef size()
00124             {
00125                 return my_size;
00126             }
00127 
00129             void* get_frame();
00132             void put_frame(void* f);
00133 
00135             bool frame_pending()
00136             {
00137                 return frame_ready;
00138             }
00139 
00142             void seek_to(double t);
00143             
00146             void on_end_of_buffer(VideoBufferFlags::OnEndOfBuffer behaviour) 
00147             {
00148                 end_of_buffer_behaviour = behaviour;
00149             }
00150         
00152             double frames_per_second() 
00153             {
00154                         #if LIBAVCODEC_BUILD >= 4754
00155               return pCodecContext->time_base.den / static_cast<double>(pCodecContext->time_base.num);
00156                         #else
00157                     return pCodecContext->frame_rate / static_cast<double>(pCodecContext->frame_rate_base);
00158             #endif
00159             };
00160             
00162             std::string file_name() 
00163             {
00164                 return pFormatContext->filename;
00165             }
00166             
00168             std::string codec_name() 
00169             {
00170                 return pCodecContext->codec_name;
00171             }
00172         
00173         private:
00174             bool read_next_frame();
00175                 
00176         private:
00177             ImageRef my_size;
00178             VideoBufferFlags::OnEndOfBuffer end_of_buffer_behaviour;
00179             double start_time;
00180             bool frame_ready;
00181 
00182             AVFormatContext* pFormatContext;
00183             int video_stream;
00184             AVCodecContext* pCodecContext;
00185             AVFrame* pFrame; 
00186             AVFrame* pFrameRGB;
00187             SwsContext *img_convert_ctx;
00188             
00189             CVD::Image<CVD::Rgb<byte> > next_frame_rgb;
00190             CVD::Image<CVD::byte> next_frame;
00191             
00192             double frame_time;
00193             bool is_rgb;
00194     };
00195     }
00196 
00206     template<typename T> 
00207     class VideoFileBuffer : public CVD::LocalVideoBuffer<T>
00208     {
00209         private:
00210             VFB::RawVideoFileBuffer vf;
00211             
00212     
00213         public:
00216             VideoFileBuffer(const std::string& file)
00217             :LocalVideoBuffer<T>(VideoBufferType::NotLive),vf(file, VFB::rgb<T>::p)
00218             {
00219             }
00220 
00221             ~VideoFileBuffer()
00222             {
00223             }
00224         
00225             virtual ImageRef size()
00226             {
00227                 return vf.size();
00228             }
00229 
00230             virtual bool frame_pending()
00231             { 
00232                 return vf.frame_pending();
00233             }
00234 
00237             virtual void on_end_of_buffer(VideoBufferFlags::OnEndOfBuffer behaviour) 
00238             {
00239                 vf.on_end_of_buffer(behaviour);
00240             }
00241 
00242             virtual void seek_to(double t)
00243             {
00244                 vf.seek_to(t);
00245             }
00246 
00247             virtual VideoFileFrame<T> * get_frame()
00248             {
00249                 return reinterpret_cast<VideoFileFrame<T>*>(vf.get_frame());
00250             }
00251 
00252             virtual void put_frame(VideoFrame<T>* f)
00253             {
00254                 vf.put_frame(f);
00255             }
00256             
00257             // This class additions 
00258         
00259             double frame_rate() 
00260             {
00261                 return vf.frames_per_second();
00262             }
00263 
00265             std::string file_name() 
00266             {
00267                 return vf.file_name();
00268             }
00269 
00271             std::string codec_name() 
00272             {
00273                 return vf.codec_name();
00274             }
00275         
00276         private:
00277     };
00278 }
00279 
00280 #endif

Generated on Wed Feb 18 10:23:02 2009 for CVD by  doxygen 1.5.3