frame_dropper.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. #include "../video_coding/frame_dropper.h"
  2. #include "../video_coding/base/exp_filter.h"
  3. #include "../video_coding/base/video_coding_log.h"
  4. #include <algorithm>
  5. namespace video_coding {
  6. static const float kDefaultFrameSizeAlpha = 0.9f;
  7. static const float kDefaultKeyFrameRatioAlpha = 0.99f;
  8. // 1 key frame every 10th second in 30 fps.
  9. static const float kDefaultKeyFrameRatioValue = 1 / 300.0f;
  10. static const float kDefaultDropRatioAlpha = 0.9f;
  11. static const float kDefaultDropRatioValue = 0.96f;
  12. // Maximum duration over which frames are continuously dropped.
  13. static const float kDefaultMaxDropDurationSecs = 4.0f;
  14. // Default target bitrate.
  15. // TODO(isheriff): Should this be higher to avoid dropping too many packets when
  16. // the bandwidth is unknown at the start ?
  17. static const float kDefaultTargetBitrateKbps = 300.0f;
  18. static const float kDefaultIncomingFrameRate = 30;
  19. static const float kLeakyBucketSizeSeconds = 0.5f;
  20. // A delta frame that is bigger than |kLargeDeltaFactor| times the average
  21. // delta frame is a large frame that is spread out for accumulation.
  22. static const int kLargeDeltaFactor = 3;
  23. // Cap on the frame size accumulator to prevent excessive drops.
  24. static const float kAccumulatorCapBufferSizeSecs = 3.0f;
  25. struct _FrameDropper {
  26. ExpFilter *key_frame_ratio_;
  27. ExpFilter *delta_frame_size_avg_kbits_;
  28. // Key frames and large delta frames are not immediately accumulated in the
  29. // bucket since they can immediately overflow the bucket leading to large
  30. // drops on the following packets that may be much smaller. Instead these
  31. // large frames are accumulated over several frames when the bucket leaks.
  32. // |large_frame_accumulation_spread_| represents the number of frames over
  33. // which a large frame is accumulated.
  34. float large_frame_accumulation_spread_;
  35. // |large_frame_accumulation_count_| represents the number of frames left
  36. // to finish accumulating a large frame.
  37. int large_frame_accumulation_count_;
  38. // |large_frame_accumulation_chunk_size_| represents the size of a single
  39. // chunk for large frame accumulation.
  40. float large_frame_accumulation_chunk_size_;
  41. float accumulator_;
  42. float accumulator_max_;
  43. float target_bitrate_;
  44. bool drop_next_;
  45. ExpFilter *drop_ratio_;
  46. int drop_count_;
  47. float incoming_frame_rate_;
  48. bool was_below_max_;
  49. bool enabled_;
  50. float max_drop_duration_secs_;
  51. };
  52. static void frame_dropper_update_ratio(FrameDropper *obj);
  53. static void frame_dropper_cap_accumulator(FrameDropper *obj);
  54. FrameDropper *frame_dropper_new() {
  55. FrameDropper *obj = (FrameDropper *)malloc(sizeof(FrameDropper));
  56. memset(obj, 0, sizeof(FrameDropper));
  57. obj->key_frame_ratio_ = exp_filter_new(kDefaultKeyFrameRatioAlpha);
  58. obj->delta_frame_size_avg_kbits_ = exp_filter_new(kDefaultFrameSizeAlpha);
  59. obj->drop_ratio_ = exp_filter_new(kDefaultDropRatioAlpha, kDefaultDropRatioValue);
  60. obj->enabled_ = true;
  61. obj->max_drop_duration_secs_ = kDefaultMaxDropDurationSecs;
  62. video_coding_debug(VIDEO_CODING_DEBUG_ENABLE, "frame_dropper_new key_frame_ratio: %f delta_frame_size_avg_kbits_ratio: %f drop_ratio: %f max_drop_duration_secs: %f.",
  63. kDefaultKeyFrameRatioAlpha, kDefaultFrameSizeAlpha, kDefaultDropRatioAlpha, kDefaultMaxDropDurationSecs);
  64. frame_dropper_reset(obj);
  65. return obj;
  66. }
  67. void frame_dropper_destroy(FrameDropper *obj) {
  68. if (obj != NULL) {
  69. exp_filter_destroy(obj->key_frame_ratio_);
  70. exp_filter_destroy(obj->delta_frame_size_avg_kbits_);
  71. exp_filter_destroy(obj->drop_ratio_);
  72. free(obj);
  73. video_coding_debug(VIDEO_CODING_DEBUG_ENABLE, "frame_dropper_destroy.");
  74. }
  75. }
  76. void frame_dropper_reset(FrameDropper *obj) {
  77. exp_filter_reset(obj->key_frame_ratio_, kDefaultKeyFrameRatioAlpha);
  78. exp_filter_apply(obj->key_frame_ratio_, 1.0f, kDefaultKeyFrameRatioValue);
  79. exp_filter_reset(obj->delta_frame_size_avg_kbits_, kDefaultFrameSizeAlpha);
  80. obj->accumulator_ = 0.0f;
  81. obj->accumulator_max_ = kDefaultTargetBitrateKbps / 2;
  82. obj->target_bitrate_ = kDefaultTargetBitrateKbps;
  83. obj->incoming_frame_rate_ = kDefaultIncomingFrameRate;
  84. obj->large_frame_accumulation_count_ = 0;
  85. obj->large_frame_accumulation_chunk_size_ = 0;
  86. obj->large_frame_accumulation_spread_ = 0.5 * kDefaultIncomingFrameRate;
  87. obj->drop_next_ = false;
  88. exp_filter_reset(obj->drop_ratio_, 0.9f);
  89. exp_filter_apply(obj->drop_ratio_, 0.0f, 0.0f);
  90. obj->drop_count_ = 0;
  91. obj->was_below_max_ = true;
  92. video_coding_debug(VIDEO_CODING_DEBUG_ENABLE, "frame_dropper_reset.");
  93. }
  94. void frame_dropper_enable(FrameDropper *obj, bool enable) {
  95. obj->enabled_ = enable;
  96. video_coding_debug(VIDEO_CODING_DEBUG_FRAME_DROPPER, "frame_dropper_enable enable: %d.", enable);
  97. }
  98. //deltaFrame : 0:key frame 1:P frame
  99. //编码后,帧大小累加到accumulator_中
  100. void frame_dropper_fill(FrameDropper *obj, size_t framesize_bytes, bool delta_frame) {
  101. if (!obj->enabled_) {
  102. return;
  103. }
  104. float framesize_kbits = 8.0f * static_cast<float>(framesize_bytes) / 1000.0f;
  105. if (!delta_frame) {
  106. exp_filter_apply(obj->key_frame_ratio_, 1.0, 1.0);
  107. // Do not spread if we are already doing it (or we risk dropping bits that
  108. // need accumulation). Given we compute the key frame ratio and spread
  109. // based on that, this should not normally happen.
  110. if (obj->large_frame_accumulation_count_ == 0) {
  111. if (exp_filter_filtered(obj->key_frame_ratio_) > 1e-5 &&
  112. 1 / exp_filter_filtered(obj->key_frame_ratio_) < obj->large_frame_accumulation_spread_) {
  113. obj->large_frame_accumulation_count_ =
  114. static_cast<int32_t>(1 / exp_filter_filtered(obj->key_frame_ratio_) + 0.5);
  115. }
  116. else {
  117. obj->large_frame_accumulation_count_ =
  118. static_cast<int32_t>(obj->large_frame_accumulation_spread_ + 0.5);
  119. }
  120. obj->large_frame_accumulation_chunk_size_ =
  121. framesize_kbits / obj->large_frame_accumulation_count_;
  122. framesize_kbits = 0;
  123. }
  124. }
  125. else {
  126. // Identify if it is an unusually large delta frame and spread accumulation
  127. // if that is the case. // >3*delta_frame_size_avg_kbits_的帧不参与accumulator_计算
  128. if (exp_filter_filtered(obj->delta_frame_size_avg_kbits_) != -1 &&
  129. (framesize_kbits >
  130. kLargeDeltaFactor * exp_filter_filtered(obj->delta_frame_size_avg_kbits_)) &&
  131. obj->large_frame_accumulation_count_ == 0) {
  132. obj->large_frame_accumulation_count_ =
  133. static_cast<int32_t>(obj->large_frame_accumulation_spread_ + 0.5);
  134. obj->large_frame_accumulation_chunk_size_ =
  135. framesize_kbits / obj->large_frame_accumulation_count_;
  136. framesize_kbits = 0;
  137. }
  138. else {
  139. exp_filter_apply(obj->delta_frame_size_avg_kbits_, 1, framesize_kbits);
  140. }
  141. exp_filter_apply(obj->key_frame_ratio_, 1.0, 0.0);
  142. }
  143. // Change the level of the accumulator (bucket)
  144. obj->accumulator_ += framesize_kbits;
  145. video_coding_debug(VIDEO_CODING_DEBUG_FRAME_DROPPER, "frame_dropper_fill accumulator: %f.", obj->accumulator_);
  146. frame_dropper_cap_accumulator(obj);
  147. }
  148. //编码前accumulator_-平均帧大小
  149. //根据输入帧率计算每帧大小,从accumulator_减去此平均帧大小
  150. void frame_dropper_leak(FrameDropper *obj, uint32_t input_framerate) {
  151. if (!obj->enabled_) {
  152. return;
  153. }
  154. if (input_framerate < 1) {
  155. return;
  156. }
  157. if (obj->target_bitrate_ < 0.0f) {
  158. return;
  159. }
  160. // Add lower bound for large frame accumulation spread.
  161. obj->large_frame_accumulation_spread_ = std::max<float>(0.5 * input_framerate, 5.0);
  162. // Expected bits per frame based on current input frame rate.
  163. float expected_bits_per_frame = obj->target_bitrate_ / input_framerate;
  164. if (obj->large_frame_accumulation_count_ > 0) {
  165. expected_bits_per_frame -= obj->large_frame_accumulation_chunk_size_;
  166. --obj->large_frame_accumulation_count_;
  167. }
  168. obj->accumulator_ -= expected_bits_per_frame;
  169. if (obj->accumulator_ < 0.0f) {
  170. obj->accumulator_ = 0.0f;
  171. }
  172. video_coding_debug(VIDEO_CODING_DEBUG_FRAME_DROPPER, "frame_dropper_leak accumulator: %f input_framerate: %u.",
  173. obj->accumulator_, input_framerate);
  174. frame_dropper_update_ratio(obj);
  175. }
  176. //accumulator_超过accumulator_max_,丢帧,否则不丢帧
  177. static void frame_dropper_update_ratio(FrameDropper *obj) {
  178. if (obj->accumulator_ > 1.3f * obj->accumulator_max_) {
  179. // Too far above accumulator max, react faster.
  180. exp_filter_update_base(obj->drop_ratio_, 0.8f);
  181. }
  182. else {
  183. // Go back to normal reaction.
  184. exp_filter_update_base(obj->drop_ratio_, 0.9f);
  185. }
  186. if (obj->accumulator_ > obj->accumulator_max_) {
  187. // We are above accumulator max, and should ideally drop a frame. Increase
  188. // the drop_ratio_ and drop the frame later.
  189. if (obj->was_below_max_) {
  190. obj->drop_next_ = true; //丢掉下一帧
  191. }
  192. exp_filter_apply(obj->drop_ratio_, 1.0f, 1.0f); //因为丢帧,所以sample为1
  193. exp_filter_update_base(obj->drop_ratio_, 0.9f);
  194. }
  195. else {
  196. exp_filter_apply(obj->drop_ratio_, 1.0f, 0.0f); //不丢帧,sample为0
  197. }
  198. obj->was_below_max_ = obj->accumulator_ < obj->accumulator_max_;
  199. video_coding_debug(VIDEO_CODING_DEBUG_FRAME_DROPPER, "frame_dropper_update_ratio accumulator: %f drop_ratio_: %f.",
  200. obj->accumulator_, exp_filter_filtered(obj->drop_ratio_));
  201. }
  202. // This function signals when to drop frames to the caller. It makes use of the
  203. // drop_ratio_ to smooth out the drops over time.
  204. bool frame_dropper_drop_frame(FrameDropper *obj) {
  205. if (!obj->enabled_) {
  206. return false;
  207. }
  208. if (obj->drop_next_) {
  209. obj->drop_next_ = false;
  210. obj->drop_count_ = 0;
  211. }
  212. video_coding_debug(VIDEO_CODING_DEBUG_FRAME_DROPPER, "frame_dropper_leak drop_ratio_: %f drop_count: %d.",
  213. exp_filter_filtered(obj->drop_ratio_), obj->drop_count_);
  214. if (exp_filter_filtered(obj->drop_ratio_) >= 0.5f) { // Drops per keep //每隔若干帧丢limit帧 P***P其中limit为3,p为保留,*为丢
  215. // Limit is the number of frames we should drop between each kept frame
  216. // to keep our drop ratio. limit is positive in this case.
  217. float denom = 1.0f - exp_filter_filtered(obj->drop_ratio_);
  218. if (denom < 1e-5) {
  219. denom = 1e-5f;
  220. }
  221. int32_t limit = static_cast<int32_t>(1.0f / denom - 1.0f + 0.5f);
  222. // Put a bound on the max amount of dropped frames between each kept
  223. // frame, in terms of frame rate and window size (secs).
  224. int max_limit =
  225. static_cast<int>(obj->incoming_frame_rate_ * obj->max_drop_duration_secs_);
  226. if (limit > max_limit) {
  227. limit = max_limit;
  228. }
  229. if (obj->drop_count_ < 0) {
  230. // Reset the drop_count_ since it was negative and should be positive.
  231. obj->drop_count_ = -obj->drop_count_;
  232. }
  233. if (obj->drop_count_ < limit) {
  234. // As long we are below the limit we should drop frames.
  235. obj->drop_count_++;
  236. return true;
  237. }
  238. else {
  239. // Only when we reset drop_count_ a frame should be kept.
  240. obj->drop_count_ = 0;
  241. return false;
  242. }
  243. }
  244. else if (exp_filter_filtered(obj->drop_ratio_) > 0.0f &&
  245. exp_filter_filtered(obj->drop_ratio_) < 0.5f) { // Keeps per drop //每隔若干帧保留limit帧 *pppp*其中limit为4,p为保留,*为丢
  246. // Limit is the number of frames we should keep between each drop
  247. // in order to keep the drop ratio. limit is negative in this case,
  248. // and the drop_count_ is also negative.
  249. float denom = exp_filter_filtered(obj->drop_ratio_);
  250. if (denom < 1e-5) {
  251. denom = 1e-5f;
  252. }
  253. int32_t limit = -static_cast<int32_t>(1.0f / denom - 1.0f + 0.5f);
  254. if (obj->drop_count_ > 0) {
  255. // Reset the drop_count_ since we have a positive
  256. // drop_count_, and it should be negative.
  257. obj->drop_count_ = -obj->drop_count_;
  258. }
  259. if (obj->drop_count_ > limit) {
  260. if (obj->drop_count_ == 0) {
  261. // Drop frames when we reset drop_count_.
  262. obj->drop_count_--;
  263. return true;
  264. }
  265. else {
  266. // Keep frames as long as we haven't reached limit.
  267. obj->drop_count_--;
  268. return false;
  269. }
  270. }
  271. else {
  272. obj->drop_count_ = 0;
  273. return false;
  274. }
  275. }
  276. obj->drop_count_ = 0;
  277. return false;
  278. }
  279. void frame_dropper_set_rates(FrameDropper *obj, float bitrate, float incoming_frame_rate) {
  280. // Bit rate of -1 means infinite bandwidth.
  281. obj->accumulator_max_ = bitrate * kLeakyBucketSizeSeconds;
  282. if (obj->target_bitrate_ > 0.0f && bitrate < obj->target_bitrate_ &&
  283. obj->accumulator_ > obj->accumulator_max_) {
  284. // Rescale the accumulator level if the accumulator max decreases
  285. obj->accumulator_ = bitrate / obj->target_bitrate_ * obj->accumulator_;
  286. }
  287. obj->target_bitrate_ = bitrate;
  288. frame_dropper_cap_accumulator(obj);
  289. obj->incoming_frame_rate_ = incoming_frame_rate;
  290. video_coding_debug(VIDEO_CODING_DEBUG_FRAME_DROPPER, "frame_dropper_set_rates bitrate: %f incoming_frame_rate: %f.",
  291. bitrate, incoming_frame_rate);
  292. }
  293. // Put a cap on the accumulator, i.e., don't let it grow beyond some level.
  294. // This is a temporary fix for screencasting where very large frames from
  295. // encoder will cause very slow response (too many frame drops).
  296. // TODO(isheriff): Remove this now that large delta frames are also spread out ?
  297. static void frame_dropper_cap_accumulator(FrameDropper *obj) {
  298. float max_accumulator = obj->target_bitrate_ * kAccumulatorCapBufferSizeSecs;
  299. if (obj->accumulator_ > max_accumulator) {
  300. obj->accumulator_ = max_accumulator;
  301. }
  302. }
  303. }