vdr  1.7.27
ringbuffer.h
Go to the documentation of this file.
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