vdr
1.7.27
|
00001 /* 00002 * ringbuffer.h: A ring buffer 00003 * 00004 * See the main source file 'vdr.c' for copyright information and 00005 * how to reach the author. 00006 * 00007 * $Id: ringbuffer.h 2.3 2011/12/04 13:38:17 kls Exp $ 00008 */ 00009 00010 #ifndef __RINGBUFFER_H 00011 #define __RINGBUFFER_H 00012 00013 #include "thread.h" 00014 #include "tools.h" 00015 00016 class cRingBuffer { 00017 private: 00018 cCondWait readyForPut, readyForGet; 00019 int putTimeout; 00020 int getTimeout; 00021 int size; 00022 time_t lastOverflowReport; 00023 int overflowCount; 00024 int overflowBytes; 00025 protected: 00026 tThreadId getThreadTid; 00027 int maxFill;//XXX 00028 int lastPercent; 00029 bool statistics;//XXX 00030 void UpdatePercentage(int Fill); 00031 void WaitForPut(void); 00032 void WaitForGet(void); 00033 void EnablePut(void); 00034 void EnableGet(void); 00035 virtual void Clear(void) = 0; 00036 virtual int Available(void) = 0; 00037 virtual int Free(void) { return Size() - Available() - 1; } 00038 int Size(void) { return size; } 00039 public: 00040 cRingBuffer(int Size, bool Statistics = false); 00041 virtual ~cRingBuffer(); 00042 void SetTimeouts(int PutTimeout, int GetTimeout); 00043 void ReportOverflow(int Bytes); 00044 }; 00045 00046 class cRingBufferLinear : public cRingBuffer { 00047 //#define DEBUGRINGBUFFERS 00048 #ifdef DEBUGRINGBUFFERS 00049 private: 00050 int lastHead, lastTail; 00051 int lastPut, lastGet; 00052 static cRingBufferLinear *RBLS[]; 00053 static void AddDebugRBL(cRingBufferLinear *RBL); 00054 static void DelDebugRBL(cRingBufferLinear *RBL); 00055 public: 00056 static void PrintDebugRBL(void); 00057 #endif 00058 private: 00059 int margin, head, tail; 00060 int gotten; 00061 uchar *buffer; 00062 char *description; 00063 protected: 00064 virtual int DataReady(const uchar *Data, int Count); 00070 public: 00071 cRingBufferLinear(int Size, int Margin = 0, bool Statistics = false, const char *Description = NULL); 00076 virtual ~cRingBufferLinear(); 00077 virtual int Available(void); 00078 virtual int Free(void) { return Size() - Available() - 1 - margin; } 00079 virtual void Clear(void); 00081 int Read(int FileHandle, int Max = 0); 00087 int Read(cUnbufferedFile *File, int Max = 0); 00089 int Put(const uchar *Data, int Count); 00092 uchar *Get(int &Count); 00097 void Del(int Count); 00101 }; 00102 00103 enum eFrameType { ftUnknown, ftVideo, ftAudio, ftDolby }; 00104 00105 class cFrame { 00106 friend class cRingBufferFrame; 00107 private: 00108 cFrame *next; 00109 uchar *data; 00110 int count; 00111 eFrameType type; 00112 int index; 00113 uint32_t pts; 00114 public: 00115 cFrame(const uchar *Data, int Count, eFrameType = ftUnknown, int Index = -1, uint32_t Pts = 0); 00119 ~cFrame(); 00120 uchar *Data(void) const { return data; } 00121 int Count(void) const { return count; } 00122 eFrameType Type(void) const { return type; } 00123 int Index(void) const { return index; } 00124 uint32_t Pts(void) const { return pts; } 00125 }; 00126 00127 class cRingBufferFrame : public cRingBuffer { 00128 private: 00129 cMutex mutex; 00130 cFrame *head; 00131 int currentFill; 00132 void Delete(cFrame *Frame); 00133 void Lock(void) { mutex.Lock(); } 00134 void Unlock(void) { mutex.Unlock(); } 00135 public: 00136 cRingBufferFrame(int Size, bool Statistics = false); 00137 virtual ~cRingBufferFrame(); 00138 virtual int Available(void); 00139 virtual void Clear(void); 00140 // Immediately clears the ring buffer. 00141 bool Put(cFrame *Frame); 00142 // Puts the Frame into the ring buffer. 00143 // Returns true if this was possible. 00144 cFrame *Get(void); 00145 // Gets the next frame from the ring buffer. 00146 // The actual data still remains in the buffer until Drop() is called. 00147 void Drop(cFrame *Frame); 00148 // Drops the Frame that has just been fetched with Get(). 00149 }; 00150 00151 #endif // __RINGBUFFER_H