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 using namespace std;
00012
00013 #include <QMutex>
00014 #include <QString>
00015 #include <QWaitCondition>
00016
00017 #include "mythdeque.h"
00018
00019 #ifdef USING_X11
00020 class MythXDisplay;
00021 #endif
00022
00023 typedef MythDeque<VideoFrame*> frame_queue_t;
00024 typedef vector<VideoFrame> frame_vector_t;
00025 typedef map<const unsigned char*, void*> buffer_map_t;
00026 typedef map<const VideoFrame*, uint> vbuffer_map_t;
00027 typedef map<const VideoFrame*, QMutex*> frame_lock_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_finished = 0x00000020,
00044 kVideoBuffer_decode = 0x00000040,
00045 kVideoBuffer_all = 0x0000003F,
00046 };
00047
00048 class YUVInfo
00049 {
00050 public:
00051 YUVInfo(uint w, uint h, uint size, const int *p, const int *o);
00052
00053 public:
00054 uint width;
00055 uint height;
00056 uint size;
00057 uint pitches[3];
00058 uint offsets[3];
00059 };
00060
00061 class VideoBuffers
00062 {
00063 public:
00064 VideoBuffers();
00065 virtual ~VideoBuffers();
00066
00067 void Init(uint numdecode, bool extra_for_pause,
00068 uint need_free, uint needprebuffer_normal,
00069 uint needprebuffer_small, uint keepprebuffer);
00070
00071 bool CreateBuffers(VideoFrameType type, int width, int height,
00072 vector<unsigned char*> bufs,
00073 vector<YUVInfo> yuvinfo);
00074 bool CreateBuffers(VideoFrameType type, 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(BufferType enqueue_to = kVideoBuffer_limbo);
00084 void ReleaseFrame(VideoFrame *frame);
00085 void DeLimboFrame(VideoFrame *frame);
00086 void StartDisplayingFrame(void);
00087 void DoneDisplayingFrame(VideoFrame *frame);
00088 void DiscardFrame(VideoFrame *frame);
00089
00090 VideoFrame *at(uint i) { return &buffers[i]; }
00091 VideoFrame *dequeue(BufferType);
00092 VideoFrame *head(BufferType);
00093 VideoFrame *tail(BufferType);
00094 void requeue(BufferType dst, BufferType src, int num = 1);
00095 void enqueue(BufferType, VideoFrame*);
00096 void safeEnqueue(BufferType, VideoFrame* frame);
00097 void remove(BufferType, VideoFrame *);
00098 frame_queue_t::iterator begin_lock(BufferType);
00099 frame_queue_t::iterator end(BufferType);
00100 void end_lock() { global_lock.unlock(); }
00101 uint size(BufferType type) const;
00102 bool contains(BufferType type, VideoFrame*) const;
00103
00104 VideoFrame *GetScratchFrame(void);
00105 VideoFrame *GetLastDecodedFrame(void) { return at(vpos); }
00106 VideoFrame *GetLastShownFrame(void) { return at(rpos); }
00107 void SetLastShownFrameToScratch(void);
00108
00109 uint ValidVideoFrames(void) const { return size(kVideoBuffer_used); }
00110 uint FreeVideoFrames(void) const { return size(kVideoBuffer_avail); }
00111 bool EnoughFreeFrames(void) const
00112 { return size(kVideoBuffer_avail) >= needfreeframes; }
00113 bool EnoughDecodedFrames(void) const
00114 { return size(kVideoBuffer_used) >= needprebufferframes; }
00115 bool EnoughPrebufferedFrames(void) const
00116 { return size(kVideoBuffer_used) >= keepprebufferframes; }
00117
00118 const VideoFrame *at(uint i) const { return &buffers[i]; }
00119 const VideoFrame *GetLastDecodedFrame(void) const { return at(vpos); }
00120 const VideoFrame *GetLastShownFrame(void) const { return at(rpos); }
00121 uint Size() const { return buffers.size(); }
00122
00123 void Clear(uint i);
00124 void Clear(void);
00125
00126 bool CreateBuffer(int width, int height, uint num, void *data,
00127 VideoFrameType fmt);
00128 uint AddBuffer(int width, int height, void* data,
00129 VideoFrameType fmt);
00130
00131 QString GetStatus(int n=-1) const;
00132 private:
00133 frame_queue_t *queue(BufferType type);
00134 const frame_queue_t *queue(BufferType type) const;
00135 VideoFrame *GetNextFreeFrameInternal(BufferType enqueue_to);
00136
00137 frame_queue_t available, used, limbo, pause, displayed, decode, finished;
00138 vbuffer_map_t vbufferMap;
00139 frame_vector_t buffers;
00140 uchar_vector_t allocated_arrays;
00141
00142 uint needfreeframes;
00143 uint needprebufferframes;
00144 uint needprebufferframes_normal;
00145 uint needprebufferframes_small;;
00146 uint keepprebufferframes;
00147 bool createdpauseframe;
00148
00149 uint rpos;
00150 uint vpos;
00151
00152 mutable QMutex global_lock;
00153 };
00154
00155 #endif // __VIDEOBUFFERS_H__