# ratectl.h

Go to the documentation of this file.

    00001 /*
    00002  * ratectl.h
    00003  *
    00004  * Video rate controller
    00005  *
    00006  * Open Phone Abstraction Library (OPAL)
    00007  *
    00008  * Copyright (C) 2007 Matthias Schneider
    00009  * Copyright (C) 2008 Post Increment
    00010  *
    00011  * The contents of this file are subject to the Mozilla Public License
    00012  * Version 1.0 (the "License"); you may not use this file except in
    00013  * compliance with the License. You may obtain a copy of the License at
    00014  * http://www.mozilla.org/MPL/
    00015  *
    00016  * Software distributed under the License is distributed on an "AS IS"
    00017  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
    00018  * the License for the specific language governing rights and limitations
    00019  * under the License.
    00020  *
    00021  * The Original Code is Open Phone Abstraction Library.
    00022  *
    00023  * The Initial Developer of the Original Code is Matthias Schneider
    00024  *
    00025  * Contributor(s): Post Increment
    00026  *
    00027  * $Revision: 27094 $
    00028  * $Author: rjongbloed $
    00029  * $Date: 2012-03-01 22:04:35 -0600 (Thu, 01 Mar 2012) $
    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 #include <deque>
    00046
    00047 extern double OpalCalcSNR(const BYTE * src1, const BYTE * src2, PINDEX dataLen);
    00048
    00053 class OpalBitRateCalculator
    00054 {
    00055   public:
    00058     OpalBitRateCalculator();
    00059
    00062     void Reset();
    00063
    00066     void SetQuanta(
    00067       unsigned quanta_
    00068     );
    00069
    00072     unsigned GetQuanta() const
    00073     { return m_quanta; }
    00074
    00077     void AddPacket(PINDEX size, bool marker);
    00078
    00081     unsigned GetBitRate();
    00082
    00085     unsigned GetAverageBitRate();
    00086
    00089     unsigned GetAveragePacketSize();
    00090
    00093     unsigned GetTrialBitRate(PINDEX size);
    00094
    00097     PInt64 GetTotalSize() const;
    00098
    00101     PInt64 GetTotalTime() const;
    00102
    00105     size_t GetHistoryCount() const
    00106     { return m_history.size(); }
    00107
    00110     unsigned GetHistorySize() const
    00111     { return m_historySize; }
    00112
    00115     PInt64 GetEarliestHistoryTime() const
    00116     { if (m_history.size() == 0) return 0; return m_history.begin()->m_timeStamp; }
    00117
    00120     unsigned GetHistoryFrames() const;
    00121
    00122     // flush old data from history
    00123     void Flush();
    00124
    00125     // used to get "now"
    00126     static PInt64 GetNow();
    00127
    00128   protected:
    00129
    00130     void Flush(PInt64 now);
    00131
    00132     struct History {
    00133       History(PINDEX size_, PInt64 timeStamp_, bool marker_)
    00134         : m_size(size_), m_timeStamp(timeStamp_), m_marker(marker_)
    00135       { }
    00136
    00137       PINDEX m_size;
    00138       PInt64 m_timeStamp;
    00139       bool m_marker;
    00140     };
    00141
    00142     std::deque<History> m_history;
    00143
    00144     PINDEX m_historySize;
    00145     PInt64 m_totalSize;
    00146     PINDEX m_historyFrames;
    00147
    00148     unsigned m_quanta;
    00149     unsigned m_bitRate;
    00150     bool m_first;
    00151     PInt64 m_baseTimeStamp;
    00152 };
    00153
    00154 //
    00155 //  Declare a generic video rate controller class.
    00156 //  A rate controller seeks to maintain a constant bit rate by manipulating
    00157 //  the parameters of the video stream
    00158 //
    00159 //  Before encoding a potential output frame, use the SkipFrame function to determine if the
    00160 //  frame should be skipped.
    00161 //
    00162 //  If the frame is not skipped, encode the frame and call PushFrame to add the frame to the rate controller queue
    00163 //  PopFrame can then be called to retreive frames to transmit
    00164 //
    00165 //  PushFrame must always be called with packets from a single video frame, but PopFrame may return packets
    00166 //  from multiple video frames
    00167 //
    00168
    00169 class OpalMediaFormat;
    00170
    00171 class OpalVideoRateController
    00172 {
    00173   public:
    00174     OpalVideoRateController();
    00175
    00176     virtual ~OpalVideoRateController();
    00177
    00180     virtual void Open(
    00181       const OpalMediaFormat & mediaFormat
    00182     );
    00183
    00188     virtual bool SkipFrame(
    00189       bool & forceIFrame
    00190     ) = 0;
    00191
    00194     virtual void Push(
    00195       RTP_DataFrameList & inputFrames,
    00196       bool iFrame
    00197     );
    00198
    00201     virtual bool Pop(
    00202       RTP_DataFrameList & outputPackets,
    00203       bool & iFrame,
    00204       bool force
    00205     );
    00206
    00209     OpalBitRateCalculator m_bitRateCalc;
    00210
    00211   protected:
    00212     unsigned m_targetBitRate;
    00213     unsigned m_outputFrameTime;
    00214     PInt64   m_inputFrameCount;
    00215     PInt64   m_outputFrameCount;
    00216
    00217     struct PacketEntry {
    00218       PacketEntry(RTP_DataFrame * rtp_, bool iFrame_)
    00219         : m_rtp(rtp_), m_iFrame(iFrame_)
    00220       { }
    00221
    00222       RTP_DataFrame * m_rtp;
    00223       bool m_iFrame;
    00224     };
    00225     std::deque<PacketEntry> m_packets;
    00226 };
    00227
    00228 namespace PWLibStupidLinkerHacks {
    00229   extern int rateControlKickerVal;
    00230 //  static class RateControlKicker { public: RateControlKicker() { rateControlKickerVal = 1; } } rateControlKicker;
    00231 };
    00232
    00233 #endif // OPAL_VIDEO
    00234
    00235 #endif // OPAL_RATE_CONTROL_H