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: 21293 $ 00028 * $Author: rjongbloed $ 00029 * $Date: 2008-10-13 10:24:41 +1100 (Mon, 13 Oct 2008) $ 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 <list> 00040 00041 #include <opal/buildopts.h> 00042 00043 // 00044 // This file implements a video rate controller that seeks to maintain a constant bit rate 00045 // by indicating when encoded video frames should be dropped 00046 // 00047 // To use the rate controller, open it with the appropriate parameters. 00048 // 00049 // Before encoding a potential output frame, use the SkipFrame function to determine if the 00050 // frame should be skipped. If the frame is not skipped, encode the frame and then call AddFrame 00051 // with the parameters of the final data. 00052 // 00053 00054 00055 class OpalVideoRateController 00056 { 00057 public: 00058 OpalVideoRateController(); 00059 00062 void Open( 00063 unsigned targetBitRate, 00064 int outputFrameTime = -1, 00065 unsigned windowSizeInMs = 500, 00066 unsigned maxConsecutiveFramesSkip = 5 00067 ); 00068 00071 bool SkipFrame(); 00072 00075 void AddFrame( 00076 PInt64 sizeInBytes, 00077 int packetPacketCount 00078 ); 00079 00080 protected: 00081 bool CheckFrameRate(bool reporting); 00082 bool CheckBitRate(bool reporting); 00083 00084 void Reset(); 00085 void AddFrame( 00086 PInt64 sizeInBytes, 00087 int packetPacketCount, 00088 PInt64 now); 00089 00090 unsigned byteRate; 00091 unsigned bitRateHistorySizeInMs; 00092 unsigned maxConsecutiveFramesSkip; 00093 int targetOutputFrameTime; 00094 00095 PInt64 targetBitRateHistorySize; 00096 PInt64 startTime; 00097 PInt64 inputFrameCount; 00098 PInt64 outputFrameCount; 00099 00100 unsigned consecutiveFramesSkipped; 00101 00102 PInt64 now; 00103 PInt64 lastReport; 00104 00105 struct FrameInfo { 00106 PInt64 time; 00107 PInt64 totalPayloadSize; 00108 int packetCount; 00109 }; 00110 00111 class FrameInfoList : public std::list<FrameInfo> 00112 { 00113 public: 00114 FrameInfoList() 00115 { reset(); } 00116 00117 void reset() 00118 { 00119 resize(0); 00120 bytes = packets = 0; 00121 } 00122 00123 void push(const FrameInfo & info) 00124 { 00125 bytes += info.totalPayloadSize; 00126 packets += info.packetCount; 00127 push_back(info); 00128 } 00129 00130 void pop() 00131 { 00132 bytes -= front().totalPayloadSize; 00133 packets -= front().packetCount; 00134 pop_front(); 00135 } 00136 00137 void remove_older_than(PInt64 now, PInt64 age) 00138 { 00139 while ((size() != 0) && ((now - begin()->time) > age)) 00140 pop(); 00141 } 00142 00143 PInt64 bytes; 00144 int packets; 00145 00146 }; 00147 00148 FrameInfoList bitRateHistory; 00149 FrameInfoList frameRateHistory; 00150 }; 00151 00152 extern double OpalCalcSNR(const BYTE * src1, const BYTE * src2, PINDEX dataLen); 00153 00154 #endif // OPAL_RATE_CONTROL_H