1 /* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
2 *
3 *  Use of this source code is governed by a BSD-style license
4 *  that can be found in the LICENSE file in the root of the source
5 *  tree. An additional intellectual property rights grant can be found
6 *  in the file PATENTS.  All contributing project authors may
7 *  be found in the AUTHORS file in the root of the source tree.
8 */
9 
10 #include <algorithm>
11 #include "webrtc/modules/video_coding/codecs/vp9/screenshare_layers.h"
12 #include "webrtc/base/checks.h"
13 
14 namespace webrtc {
15 
ScreenshareLayersVP9(uint8_t num_layers)16 ScreenshareLayersVP9::ScreenshareLayersVP9(uint8_t num_layers)
17     : num_layers_(num_layers),
18       start_layer_(0),
19       last_timestamp_(0),
20       timestamp_initialized_(false) {
21   RTC_DCHECK_GT(num_layers, 0);
22   RTC_DCHECK_LE(num_layers, kMaxVp9NumberOfSpatialLayers);
23   memset(bits_used_, 0, sizeof(bits_used_));
24   memset(threshold_kbps_, 0, sizeof(threshold_kbps_));
25 }
26 
GetStartLayer() const27 uint8_t ScreenshareLayersVP9::GetStartLayer() const {
28   return start_layer_;
29 }
30 
ConfigureBitrate(int threshold_kbps,uint8_t layer_id)31 void ScreenshareLayersVP9::ConfigureBitrate(int threshold_kbps,
32                                             uint8_t layer_id) {
33   // The upper layer is always the layer we spill frames
34   // to when the bitrate becomes to high, therefore setting
35   // a max limit is not allowed. The top layer bitrate is
36   // never used either so configuring it makes no difference.
37   RTC_DCHECK_LT(layer_id, num_layers_ - 1);
38   threshold_kbps_[layer_id] = threshold_kbps;
39 }
40 
LayerFrameEncoded(unsigned int size_bytes,uint8_t layer_id)41 void ScreenshareLayersVP9::LayerFrameEncoded(unsigned int size_bytes,
42                                              uint8_t layer_id) {
43   RTC_DCHECK_LT(layer_id, num_layers_);
44   bits_used_[layer_id] += size_bytes * 8;
45 }
46 
47 VP9EncoderImpl::SuperFrameRefSettings
GetSuperFrameSettings(uint32_t timestamp,bool is_keyframe)48 ScreenshareLayersVP9::GetSuperFrameSettings(uint32_t timestamp,
49                                             bool is_keyframe) {
50   VP9EncoderImpl::SuperFrameRefSettings settings;
51   if (!timestamp_initialized_) {
52     last_timestamp_ = timestamp;
53     timestamp_initialized_ = true;
54   }
55   float time_diff = (timestamp - last_timestamp_) / 90.f;
56   float total_bits_used = 0;
57   float total_threshold_kbps = 0;
58   start_layer_ = 0;
59 
60   // Up to (num_layers - 1) because we only have
61   // (num_layers - 1) thresholds to check.
62   for (int layer_id = 0; layer_id < num_layers_ - 1; ++layer_id) {
63     bits_used_[layer_id] = std::max(
64         0.f, bits_used_[layer_id] - time_diff * threshold_kbps_[layer_id]);
65     total_bits_used += bits_used_[layer_id];
66     total_threshold_kbps += threshold_kbps_[layer_id];
67 
68     // If this is a keyframe then there should be no
69     // references to any previous frames.
70     if (!is_keyframe) {
71       settings.layer[layer_id].ref_buf1 = layer_id;
72       if (total_bits_used > total_threshold_kbps * 1000)
73         start_layer_ = layer_id + 1;
74     }
75 
76     settings.layer[layer_id].upd_buf = layer_id;
77   }
78   // Since the above loop does not iterate over the last layer
79   // the reference of the last layer has to be set after the loop,
80   // and if this is a keyframe there should be no references to
81   // any previous frames.
82   if (!is_keyframe)
83     settings.layer[num_layers_ - 1].ref_buf1 = num_layers_ - 1;
84 
85   settings.layer[num_layers_ - 1].upd_buf = num_layers_ - 1;
86   settings.is_keyframe = is_keyframe;
87   settings.start_layer = start_layer_;
88   settings.stop_layer = num_layers_ - 1;
89   last_timestamp_ = timestamp;
90   return settings;
91 }
92 
93 }  // namespace webrtc
94