00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef CVD_READAHEADVIDEOBUFFER_H
00023 #define CVD_READAHEADVIDEOBUFFER_H
00024
00025 #include <cvd/config.h>
00026 #include <cvd/videobuffer.h>
00027
00028 #ifdef CVD_HAVE_PTHREAD
00029 #include <deque>
00030 #include <cvd/thread.h>
00031 #include <cvd/synchronized.h>
00032 #include <cvd/eventobject.h>
00033 #endif
00034
00035 namespace CVD {
00036 #ifndef CVD_HAVE_PTHREAD
00037 #warning ReadAheadVideoBuffer will not do any read-ahead because threads are not supported in this build
00038 template <class T>
00039 class ReadAheadVideoBuffer : public VideoBuffer<T>
00040 {
00041 private:
00042 VideoBuffer<T>& vbuffer;
00043 public:
00044 virtual ~ReadAheadVideoBuffer() {}
00045 ReadAheadVideoBuffer(VideoBuffer<T>& vb, size_t maxReadAhead=10)
00046 : VideoBuffer<T>(vb.type()),vbuffer(vb) {}
00048 ImageRef size() { return vbuffer.size(); }
00050 VideoFrame<T>* get_frame() { return vbuffer.get_frame(); }
00053 void put_frame(VideoFrame<T>* f) { vbuffer.put_frame(f); }
00055 bool frame_pending() { return vbuffer.frame_pending(); }
00057 double frame_rate() { return vbuffer.frame_rate(); }
00060 void seek_to(double t){ vbuffer.seek_to(t); }
00061 };
00062 #else
00069 template <class T>
00070 class ReadAheadVideoBuffer : public VideoBuffer<T>, public Runnable
00071 {
00072 private:
00073 VideoBuffer<T>& vbuffer;
00074 size_t maxRA;
00075 std::deque<VideoFrame<T>*> q, putq;
00076 Synchronized vblock;
00077 EventObject qevent;
00078 Thread thread;
00079
00080
00081 static VideoBufferType::Type type_update(VideoBufferType::Type t)
00082 {
00083 if(t== VideoBufferType::NotLive)
00084 return t;
00085 else
00086 return VideoBufferType::Flushable;
00087 }
00088
00089 public:
00090 virtual ~ReadAheadVideoBuffer() {
00091 qevent.lock();
00092 thread.stop();
00093 qevent.trigger();
00094 qevent.unlock();
00095 thread.join();
00096 }
00097 ReadAheadVideoBuffer(VideoBuffer<T>& vb, size_t maxReadAhead=10)
00098 : VideoBuffer<T>(type_update(vb.type())), vbuffer(vb), maxRA(maxReadAhead) {
00099 thread.start(this);
00100 }
00101
00102 void run() {
00103 while (!thread.shouldStop())
00104 {
00105
00106 { Lock l(qevent);
00107 for (size_t i=0; i<putq.size(); i++)
00108 vbuffer.put_frame(putq[i]);
00109 putq.resize(0);
00110 while (q.size() >= maxRA) {
00111 qevent.wait();
00112 if (thread.shouldStop())
00113 return;
00114 }
00115 }
00116
00117 { Lock l(vblock);
00118 VideoFrame<T>* frame = vbuffer.get_frame();
00119
00120 { Lock l(qevent);
00121 q.push_back(frame);
00122 qevent.trigger();
00123 }
00124 }
00125 }
00126 }
00128 ImageRef size() { return vbuffer.size(); }
00130 VideoFrame<T>* get_frame() {
00131 VideoFrame<T>* frame = 0;
00132 Lock l(qevent);
00133 while (q.empty())
00134 qevent.wait();
00135 frame = q.front();
00136 q.pop_front();
00137 qevent.trigger();
00138 return frame;
00139 }
00142 void put_frame(VideoFrame<T>* f) { Lock l(qevent); putq.push_back(f); }
00144 bool frame_pending() {
00145 return !q.empty();
00146 }
00148 double frame_rate() { return vbuffer.frame_rate(); }
00151 void seek_to(double t){
00152 Lock vbl(vblock);
00153 Lock ql(qevent);
00154 for (size_t i=0; i<q.size(); i++)
00155 putq.push_back(q[i]);
00156 q.resize(0);
00157 qevent.triggerAll();
00158 vbuffer.seek_to(t);
00159 }
00160 };
00161 #endif
00162 }
00163
00164 #endif