00001
00002
00003 #ifndef __VIDEOBUFFERS_H__
00004 #define __VIDEOBUFFERS_H__
00005
00006 extern "C" {
00007 #include "frame.h"
00008 }
00009 #include <vector>
00010 #include <map>
00011 #include <qmutex.h>
00012 #include <qstring.h>
00013 #include <qwaitcondition.h>
00014 #include "mythdeque.h"
00015
00016 #ifdef USING_XVMC
00017 #include <qwindowdefs.h>
00018 #endif // USING_XVMC
00019
00020 typedef MythDeque<VideoFrame*> frame_queue_t;
00021 typedef vector<VideoFrame> frame_vector_t;
00022 typedef map<const VideoFrame*, frame_queue_t> frame_map_t;
00023 typedef map<const void*, VideoFrame*> surf_to_frame_map_t;
00024 typedef map<const unsigned char*, void*> buffer_map_t;
00025 typedef map<const VideoFrame*, uint> vbuffer_map_t;
00026 typedef map<const VideoFrame*, QMutex*> frame_lock_map_t;
00027 typedef map<const VideoFrame*, VideoFrame*> frame_to_frame_map_t;
00028 typedef vector<unsigned char*> uchar_vector_t;
00029
00030
00031 const QString& DebugString(const VideoFrame *frame, bool short_str=false);
00032 const QString& DebugString(uint str_num, bool short_str=false);
00033 const QString DebugString(const frame_queue_t& list);
00034 const QString DebugString(const vector<const VideoFrame*>& list);
00035
00036 enum BufferType
00037 {
00038 kVideoBuffer_avail = 0x00000001,
00039 kVideoBuffer_limbo = 0x00000002,
00040 kVideoBuffer_used = 0x00000004,
00041 kVideoBuffer_pause = 0x00000008,
00042 kVideoBuffer_displayed = 0x00000010,
00043 kVideoBuffer_decode = 0x00000020,
00044 kVideoBuffer_all = 0x0000001F,
00045 };
00046
00047 class YUVInfo
00048 {
00049 public:
00050 YUVInfo(uint w, uint h, uint size, const int *p, const int *o);
00051
00052 public:
00053 uint width;
00054 uint height;
00055 uint size;
00056 uint pitches[3];
00057 uint offsets[3];
00058 };
00059
00060 class VideoBuffers
00061 {
00062 public:
00063 VideoBuffers();
00064 virtual ~VideoBuffers();
00065
00066 void Init(uint numdecode, bool extra_for_pause,
00067 uint need_free, uint needprebuffer_normal,
00068 uint needprebuffer_small, uint keepprebuffer,
00069 bool enable_frame_locking = false);
00070
00071 bool CreateBuffers(int width, int height,
00072 vector<unsigned char*> bufs,
00073 vector<YUVInfo> yuvinfo);
00074 bool CreateBuffers(int width, int height);
00075 void DeleteBuffers(void);
00076
00077 void Reset(void);
00078 void DiscardFrames(bool next_frame_keyframe);
00079 void ClearAfterSeek(void);
00080
00081 void SetPrebuffering(bool normal);
00082
00083 VideoFrame *GetNextFreeFrame(bool with_lock, bool allow_unsafe,
00084 BufferType enqueue_to = kVideoBuffer_limbo);
00085 void ReleaseFrame(VideoFrame *frame);
00086 void DeLimboFrame(VideoFrame *frame);
00087 void StartDisplayingFrame(void);
00088 void DoneDisplayingFrame(void);
00089 void DiscardFrame(VideoFrame *frame);
00090
00091 VideoFrame *at(uint i) { return &buffers[i]; }
00092 VideoFrame *dequeue(BufferType);
00093 VideoFrame *head(BufferType);
00094 VideoFrame *tail(BufferType);
00095 void requeue(BufferType dst, BufferType src, int num = 1);
00096 void enqueue(BufferType, VideoFrame*);
00097 void safeEnqueue(BufferType, VideoFrame* frame);
00098 void remove(BufferType, VideoFrame *);
00099 frame_queue_t::iterator begin_lock(BufferType);
00100 frame_queue_t::iterator end(BufferType);
00101 void end_lock() { global_lock.unlock(); }
00102 uint size(BufferType type) const;
00103 bool contains(BufferType type, VideoFrame*) const;
00104
00105 VideoFrame *GetScratchFrame(void);
00106 const VideoFrame *GetScratchFrame() const;
00107 VideoFrame *GetLastDecodedFrame(void) { return at(vpos); }
00108 VideoFrame *GetLastShownFrame(void) { return at(rpos); }
00109 void SetLastShownFrameToScratch() { rpos = size(); }
00110 bool WaitForAvailable(uint w) { return available_wait.wait(w); }
00111
00112 uint ValidVideoFrames(void) const { return size(kVideoBuffer_used); }
00113 uint FreeVideoFrames(void) const { return size(kVideoBuffer_avail); }
00114 bool EnoughFreeFrames(void) const
00115 { return size(kVideoBuffer_avail) >= needfreeframes; }
00116 bool EnoughDecodedFrames(void) const
00117 { return size(kVideoBuffer_used) >= needprebufferframes; }
00118 bool EnoughPrebufferedFrames(void) const
00119 { return size(kVideoBuffer_used) >= keepprebufferframes; }
00120
00121 const VideoFrame *at(uint i) const { return &buffers[i]; }
00122 const VideoFrame *GetLastDecodedFrame(void) const { return at(vpos); }
00123 const VideoFrame *GetLastShownFrame(void) const { return at(rpos); }
00124 uint size() const { return numbuffers; }
00125 uint allocSize() const { return buffers.size(); }
00126
00127 void LockFrame(const VideoFrame *, const char* owner);
00128 void LockFrames(vector<const VideoFrame*>&, const char* owner);
00129 bool TryLockFrame(const VideoFrame *, const char* owner);
00130 void UnlockFrame(const VideoFrame *, const char* owner);
00131 void UnlockFrames(vector<const VideoFrame*>&, const char* owner);
00132
00133 void AddInheritence(const VideoFrame *frame);
00134 void RemoveInheritence(const VideoFrame *frame);
00135 frame_queue_t Children(const VideoFrame *frame);
00136 bool HasChildren(const VideoFrame *frame);
00137
00138 void Clear(uint i, int fourcc);
00139 void Clear(int fourcc);
00140
00141 #ifdef USING_XVMC
00142 VideoFrame* PastFrame(const VideoFrame *frame);
00143 VideoFrame* FutureFrame(const VideoFrame *frame);
00144 VideoFrame* GetOSDFrame(const VideoFrame *frame);
00145 void SetOSDFrame(VideoFrame *frame, VideoFrame *osd);
00146 VideoFrame* GetOSDParent(const VideoFrame *osd);
00147 bool CreateBuffers(int width, int height,
00148 Display *disp,
00149 void* xvmc_ctx,
00150 void* xvmc_surf_info,
00151 vector<void*> surfs);
00152 #endif
00153
00154 QString GetStatus(int n=-1) const;
00155 private:
00156 frame_queue_t *queue(BufferType type);
00157 const frame_queue_t *queue(BufferType type) const;
00158 VideoFrame *GetNextFreeFrameInternal(
00159 bool with_lock, bool allow_unsafe, BufferType enqueue_to);
00160
00161 frame_queue_t available, used, limbo, pause, displayed, decode;
00162 vbuffer_map_t vbufferMap;
00163 frame_vector_t buffers;
00164 uchar_vector_t allocated_structs;
00165 uchar_vector_t allocated_arrays;
00166 frame_map_t parents;
00167 frame_map_t children;
00168
00169 QWaitCondition available_wait;
00170
00171 uint numbuffers;
00172 uint needfreeframes;
00173 uint needprebufferframes;
00174 uint needprebufferframes_normal;
00175 uint needprebufferframes_small;;
00176 uint keepprebufferframes;
00177 bool need_extra_for_pause;
00178
00179 uint rpos;
00180 uint vpos;
00181
00182 mutable QMutex global_lock;
00183
00184 bool use_frame_locks;
00185 QMutex frame_lock;
00186 frame_lock_map_t frame_locks;
00187
00188 #ifdef USING_XVMC
00189 surf_to_frame_map_t xvmc_surf_to_frame;
00190 frame_to_frame_map_t xvmc_osd_parent;
00191 #endif
00192 };
00193
00194 #endif // __VIDEOBUFFERS_H__