00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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