00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 #ifndef OPAL_RATE_CONTROL_H
00033 #define OPAL_RATE_CONTROL_H
00034 
00035 #ifdef P_USE_PRAGMA
00036 #pragma interface
00037 #endif
00038 
00039 #include <opal/buildopts.h>
00040 
00041 #if OPAL_VIDEO
00042 
00043 #include <rtp/rtp.h>
00044 
00045 extern double OpalCalcSNR(const BYTE * src1, const BYTE * src2, PINDEX dataLen);
00046 
00051 class OpalBitRateCalculator
00052 {
00053   public:
00056     OpalBitRateCalculator();
00057 
00060     void Reset();
00061 
00064     void SetQuanta(
00065       unsigned quanta_
00066     );
00067 
00070     unsigned GetQuanta() const
00071     { return m_quanta; }
00072 
00075     void AddPacket(PINDEX size, bool marker);
00076 
00079     unsigned GetBitRate();
00080 
00083     unsigned GetAverageBitRate();
00084 
00087     unsigned GetAveragePacketSize();
00088 
00091     unsigned GetTrialBitRate(PINDEX size);
00092 
00095     PInt64 GetTotalSize() const;
00096 
00099     PInt64 GetTotalTime() const;
00100 
00103     size_t GetHistoryCount() const
00104     { return m_history.size(); }
00105 
00108     unsigned GetHistorySize() const
00109     { return m_historySize; }
00110 
00113     PInt64 GetEarliestHistoryTime() const
00114     { if (m_history.size() == 0) return 0; return m_history.begin()->m_timeStamp; }
00115 
00118     unsigned GetHistoryFrames() const;
00119 
00120     
00121     void Flush();
00122 
00123     
00124     static PInt64 GetNow();
00125 
00126   protected:
00127 
00128     void Flush(PInt64 now);
00129 
00130     struct History {
00131       History(PINDEX size_, PInt64 timeStamp_, bool marker_)
00132         : m_size(size_), m_timeStamp(timeStamp_), m_marker(marker_)
00133       { }
00134 
00135       PINDEX m_size;
00136       PInt64 m_timeStamp;
00137       bool m_marker;
00138     };
00139 
00140     std::deque<History> m_history;
00141 
00142     PINDEX m_historySize;
00143     PInt64 m_totalSize;
00144     PINDEX m_historyFrames;
00145 
00146     unsigned m_quanta;
00147     unsigned m_bitRate;
00148     bool m_first;
00149     PInt64 m_baseTimeStamp;
00150 };
00151 
00152 
00153 
00154 
00155 
00156 
00157 
00158 
00159 
00160 
00161 
00162 
00163 
00164 
00165 
00166 
00167 class OpalMediaFormat;
00168 
00169 class OpalVideoRateController
00170 {
00171   public:
00172     OpalVideoRateController();
00173 
00174     virtual ~OpalVideoRateController();
00175 
00178     virtual void Open(
00179       const OpalMediaFormat & mediaFormat
00180     );
00181 
00186     virtual bool SkipFrame(
00187       bool & forceIFrame
00188     ) = 0;
00189 
00192     virtual void Push(
00193       RTP_DataFrameList & inputFrames, 
00194       bool iFrame
00195     );
00196 
00199     virtual bool Pop(
00200       RTP_DataFrameList & outputPackets, 
00201       bool & iFrame, 
00202       bool force
00203     );
00204 
00207     OpalBitRateCalculator m_bitRateCalc;
00208 
00209   protected:
00210     unsigned m_targetBitRate;
00211     unsigned m_outputFrameTime;
00212     PInt64   m_inputFrameCount;
00213     PInt64   m_outputFrameCount;
00214 
00215     struct PacketEntry {
00216       PacketEntry(RTP_DataFrame * rtp_, bool iFrame_)
00217         : m_rtp(rtp_), m_iFrame(iFrame_)
00218       { }
00219 
00220       RTP_DataFrame * m_rtp;
00221       bool m_iFrame;
00222     };
00223     std::deque<PacketEntry> m_packets;
00224 };
00225 
00226 namespace PWLibStupidLinkerHacks {
00227   extern int rateControlKickerVal;
00228 
00229 };
00230 
00231 #endif // OPAL_VIDEO
00232 
00233 #endif // OPAL_RATE_CONTROL_H