19115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org/* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
29115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org*
39115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org*  Use of this source code is governed by a BSD-style license
49115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org*  that can be found in the LICENSE file in the root of the source
59115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org*  tree. An additional intellectual property rights grant can be found
69115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org*  in the file PATENTS.  All contributing project authors may
79115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org*  be found in the AUTHORS file in the root of the source tree.
89115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org*/
99115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org
109115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org#include "webrtc/modules/video_coding/codecs/vp8/screenshare_layers.h"
119115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org
129115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org#include <stdlib.h>
139115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org
14cce46fc108a70336f0477fd58d41f38e547eeb25philipel#include <algorithm>
15cce46fc108a70336f0477fd58d41f38e547eeb25philipel
162c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng#include "webrtc/base/checks.h"
179115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org#include "vpx/vpx_encoder.h"
189115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org#include "vpx/vp8cx.h"
192557b86e7648ffebc5781df9f093ca5a84efc219Henrik Kjellander#include "webrtc/modules/video_coding/include/video_codec_interface.h"
209115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org
219115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.orgnamespace webrtc {
229115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org
232c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språngstatic const int kOneSecond90Khz = 90000;
242c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språngstatic const int kMinTimeBetweenSyncs = kOneSecond90Khz * 5;
252c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språngstatic const int kMaxTimeBetweenSyncs = kOneSecond90Khz * 10;
262c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språngstatic const int kQpDeltaThresholdForSync = 8;
279115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org
2870f74f3f7b8c6ee440d46748468ea14b5046134fsprang@webrtc.orgconst double ScreenshareLayers::kMaxTL0FpsReduction = 2.5;
2970f74f3f7b8c6ee440d46748468ea14b5046134fsprang@webrtc.orgconst double ScreenshareLayers::kAcceptableTargetOvershoot = 2.0;
3070f74f3f7b8c6ee440d46748468ea14b5046134fsprang@webrtc.org
312c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng// Since this is TL0 we only allow updating and predicting from the LAST
322c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng// reference frame.
332c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språngconst int ScreenshareLayers::kTl0Flags =
342c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF |
352c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    VP8_EFLAG_NO_REF_ARF;
362c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng
372c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng// Allow predicting from both TL0 and TL1.
382c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språngconst int ScreenshareLayers::kTl1Flags =
392c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
402c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng
412c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng// Allow predicting from only TL0 to allow participants to switch to the high
422c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng// bitrate stream. This means predicting only from the LAST reference frame, but
432c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng// only updating GF to not corrupt TL0.
442c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språngconst int ScreenshareLayers::kTl1SyncFlags =
452c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_ARF |
462c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    VP8_EFLAG_NO_UPD_LAST;
472c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng
489115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.orgScreenshareLayers::ScreenshareLayers(int num_temporal_layers,
492c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng                                     uint8_t initial_tl0_pic_idx)
502c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    : number_of_temporal_layers_(num_temporal_layers),
519115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org      last_base_layer_sync_(false),
529115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org      tl0_pic_idx_(initial_tl0_pic_idx),
532c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      active_layer_(-1),
542c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      last_timestamp_(-1),
552c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      last_sync_timestamp_(-1),
562c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      min_qp_(-1),
572c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      max_qp_(-1),
582c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      max_debt_bytes_(0),
592c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      frame_rate_(-1) {
609115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org  assert(num_temporal_layers > 0);
619115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org  assert(num_temporal_layers <= 2);
629115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org}
639115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org
649115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.orgint ScreenshareLayers::CurrentLayerId() const {
659115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org  // Codec does not use temporal layers for screenshare.
669115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org  return 0;
679115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org}
689115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org
699115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.orgint ScreenshareLayers::EncodeFlags(uint32_t timestamp) {
709115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org  if (number_of_temporal_layers_ <= 1) {
719115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org    // No flags needed for 1 layer screenshare.
729115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org    return 0;
739115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org  }
742c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng
752c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp);
769115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org  int flags = 0;
772c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng
782c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  if (active_layer_ == -1 ||
792c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      layers_[active_layer_].state != TemporalLayer::State::kDropped) {
802c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    if (layers_[0].debt_bytes_ > max_debt_bytes_) {
812c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      // Must drop TL0, encode TL1 instead.
822c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      if (layers_[1].debt_bytes_ > max_debt_bytes_) {
832c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng        // Must drop both TL0 and TL1.
842c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng        active_layer_ = -1;
859115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org      } else {
862c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng        active_layer_ = 1;
879115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org      }
882c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    } else {
892c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      active_layer_ = 0;
909115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org    }
919115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org  }
922c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng
932c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  switch (active_layer_) {
942c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    case 0:
952c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      flags = kTl0Flags;
962c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      break;
972c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    case 1:
982c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      if (TimeToSync(unwrapped_timestamp)) {
992c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng        last_sync_timestamp_ = unwrapped_timestamp;
1002c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng        flags = kTl1SyncFlags;
1012c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      } else {
1022c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng        flags = kTl1Flags;
1032c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      }
1042c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      break;
1052c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    case -1:
1062c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      flags = -1;
1072c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      break;
1082c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    default:
1092c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      flags = -1;
1102c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      RTC_NOTREACHED();
1112c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  }
1122c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng
1139115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org  // Make sure both frame droppers leak out bits.
1142c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  int64_t ts_diff;
1152c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  if (last_timestamp_ == -1) {
1162c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    ts_diff = kOneSecond90Khz / (frame_rate_ <= 0 ? 5 : frame_rate_);
1172c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  } else {
1182c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    ts_diff = unwrapped_timestamp - last_timestamp_;
1192c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  }
1202c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng
1212c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  layers_[0].UpdateDebt(ts_diff / 90);
1222c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  layers_[1].UpdateDebt(ts_diff / 90);
1232c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  last_timestamp_ = timestamp;
1249115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org  return flags;
1259115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org}
1269115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org
1272c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språngbool ScreenshareLayers::ConfigureBitrates(int bitrate_kbps,
1282c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng                                          int max_bitrate_kbps,
1299115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org                                          int framerate,
1309115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org                                          vpx_codec_enc_cfg_t* cfg) {
1312c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  layers_[0].target_rate_kbps_ = bitrate_kbps;
1322c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  layers_[1].target_rate_kbps_ = max_bitrate_kbps;
1338904290aca8860cca4efb3a06f1557254b2401fbpbos@webrtc.org
1342c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  int target_bitrate_kbps = bitrate_kbps;
13570f74f3f7b8c6ee440d46748468ea14b5046134fsprang@webrtc.org
1368904290aca8860cca4efb3a06f1557254b2401fbpbos@webrtc.org  if (cfg != nullptr) {
137ef7228cfa00cd6eb72754e923b1ac7348c1dfb22sprang    if (number_of_temporal_layers_ > 1) {
138ef7228cfa00cd6eb72754e923b1ac7348c1dfb22sprang      // Calculate a codec target bitrate. This may be higher than TL0, gaining
139ef7228cfa00cd6eb72754e923b1ac7348c1dfb22sprang      // quality at the expense of frame rate at TL0. Constraints:
140ef7228cfa00cd6eb72754e923b1ac7348c1dfb22sprang      // - TL0 frame rate no less than framerate / kMaxTL0FpsReduction.
141ef7228cfa00cd6eb72754e923b1ac7348c1dfb22sprang      // - Target rate * kAcceptableTargetOvershoot should not exceed TL1 rate.
142ef7228cfa00cd6eb72754e923b1ac7348c1dfb22sprang      target_bitrate_kbps =
143ef7228cfa00cd6eb72754e923b1ac7348c1dfb22sprang          std::min(bitrate_kbps * kMaxTL0FpsReduction,
144ef7228cfa00cd6eb72754e923b1ac7348c1dfb22sprang                   max_bitrate_kbps / kAcceptableTargetOvershoot);
145ef7228cfa00cd6eb72754e923b1ac7348c1dfb22sprang
146ef7228cfa00cd6eb72754e923b1ac7348c1dfb22sprang      cfg->rc_target_bitrate = std::max(bitrate_kbps, target_bitrate_kbps);
147ef7228cfa00cd6eb72754e923b1ac7348c1dfb22sprang    }
1482c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng
1492c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    // Don't reconfigure qp limits during quality boost frames.
1502c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    if (layers_[active_layer_].state != TemporalLayer::State::kQualityBoost) {
1512c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      min_qp_ = cfg->rc_min_quantizer;
1522c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      max_qp_ = cfg->rc_max_quantizer;
1532c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      // After a dropped frame, a frame with max qp will be encoded and the
1542c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      // quality will then ramp up from there. To boost the speed of recovery,
1552c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      // encode the next frame with lower max qp. TL0 is the most important to
1562c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      // improve since the errors in this layer will propagate to TL1.
1572c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      // Currently, reduce max qp by 20% for TL0 and 15% for TL1.
1582c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      layers_[0].enhanced_max_qp = min_qp_ + (((max_qp_ - min_qp_) * 80) / 100);
1592c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      layers_[1].enhanced_max_qp = min_qp_ + (((max_qp_ - min_qp_) * 85) / 100);
1602c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    }
16170f74f3f7b8c6ee440d46748468ea14b5046134fsprang@webrtc.org  }
16270f74f3f7b8c6ee440d46748468ea14b5046134fsprang@webrtc.org
1632c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  int avg_frame_size = (target_bitrate_kbps * 1000) / (8 * framerate);
1642c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  max_debt_bytes_ = 4 * avg_frame_size;
1652c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng
1669115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org  return true;
1679115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org}
1689115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org
1692c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språngvoid ScreenshareLayers::FrameEncoded(unsigned int size,
1702c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng                                     uint32_t timestamp,
1712c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng                                     int qp) {
1722c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  if (size == 0) {
1732c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    layers_[active_layer_].state = TemporalLayer::State::kDropped;
1742c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    return;
1752c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  }
176ef7228cfa00cd6eb72754e923b1ac7348c1dfb22sprang
1772c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  if (layers_[active_layer_].state == TemporalLayer::State::kDropped) {
1782c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    layers_[active_layer_].state = TemporalLayer::State::kQualityBoost;
1792c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  }
1802c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng
1812c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  if (qp != -1)
1822c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    layers_[active_layer_].last_qp = qp;
1832c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng
1849115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org  if (active_layer_ == 0) {
1852c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    layers_[0].debt_bytes_ += size;
1862c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    layers_[1].debt_bytes_ += size;
1872c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  } else if (active_layer_ == 1) {
1882c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    layers_[1].debt_bytes_ += size;
1899115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org  }
1909115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org}
1919115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org
1929115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.orgvoid ScreenshareLayers::PopulateCodecSpecific(bool base_layer_sync,
193cce46fc108a70336f0477fd58d41f38e547eeb25philipel                                              CodecSpecificInfoVP8* vp8_info,
1949115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org                                              uint32_t timestamp) {
1952c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp);
1969115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org  if (number_of_temporal_layers_ == 1) {
1979115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org    vp8_info->temporalIdx = kNoTemporalIdx;
1989115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org    vp8_info->layerSync = false;
1999115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org    vp8_info->tl0PicIdx = kNoTl0PicIdx;
2009115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org  } else {
2019115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org    vp8_info->temporalIdx = active_layer_;
2029115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org    if (base_layer_sync) {
2039115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org      vp8_info->temporalIdx = 0;
2042c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      last_sync_timestamp_ = unwrapped_timestamp;
2059115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org    } else if (last_base_layer_sync_ && vp8_info->temporalIdx != 0) {
2069115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org      // Regardless of pattern the frame after a base layer sync will always
2079115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org      // be a layer sync.
2082c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      last_sync_timestamp_ = unwrapped_timestamp;
2099115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org    }
2102c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    vp8_info->layerSync = last_sync_timestamp_ != -1 &&
2112c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng                          last_sync_timestamp_ == unwrapped_timestamp;
2129115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org    if (vp8_info->temporalIdx == 0) {
2139115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org      tl0_pic_idx_++;
2149115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org    }
2159115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org    last_base_layer_sync_ = base_layer_sync;
2169115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org    vp8_info->tl0PicIdx = tl0_pic_idx_;
2179115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org  }
2189115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org}
2199115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org
2202c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språngbool ScreenshareLayers::TimeToSync(int64_t timestamp) const {
2212c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  if (active_layer_ != 1) {
2222c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    RTC_NOTREACHED();
2232c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    return false;
2242c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  }
22591d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg  RTC_DCHECK_NE(-1, layers_[0].last_qp);
2262c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  if (layers_[1].last_qp == -1) {
2272c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    // First frame in TL1 should only depend on TL0 since there are no
2282c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    // previous frames in TL1.
2292c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    return true;
2302c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  }
2312c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng
23291d6edef35e7275879c30ce16ecb8b6dc73c6e4ahenrikg  RTC_DCHECK_NE(-1, last_sync_timestamp_);
2332c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  int64_t timestamp_diff = timestamp - last_sync_timestamp_;
2342c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  if (timestamp_diff > kMaxTimeBetweenSyncs) {
2352c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    // After a certain time, force a sync frame.
2362c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    return true;
2372c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  } else if (timestamp_diff < kMinTimeBetweenSyncs) {
2382c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    // If too soon from previous sync frame, don't issue a new one.
2392c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    return false;
2402c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  }
2412c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  // Issue a sync frame if difference in quality between TL0 and TL1 isn't too
2422c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  // large.
2432c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  if (layers_[0].last_qp - layers_[1].last_qp < kQpDeltaThresholdForSync)
2442c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    return true;
2452c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  return false;
2469115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org}
2479115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org
2482c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språngbool ScreenshareLayers::UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) {
249ef7228cfa00cd6eb72754e923b1ac7348c1dfb22sprang  if (max_qp_ == -1 || number_of_temporal_layers_ <= 1)
2502c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    return false;
2512c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng
2522c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  // If layer is in the quality boost state (following a dropped frame), update
2532c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  // the configuration with the adjusted (lower) qp and set the state back to
2542c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  // normal.
2552c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  unsigned int adjusted_max_qp;
2562c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  if (layers_[active_layer_].state == TemporalLayer::State::kQualityBoost &&
2572c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      layers_[active_layer_].enhanced_max_qp != -1) {
2582c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    adjusted_max_qp = layers_[active_layer_].enhanced_max_qp;
2592c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    layers_[active_layer_].state = TemporalLayer::State::kNormal;
2602c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  } else {
2612c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    if (max_qp_ == -1)
2622c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng      return false;
2632c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    adjusted_max_qp = max_qp_;  // Set the normal max qp.
2649115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org  }
2652c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng
2662c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  if (adjusted_max_qp == cfg->rc_max_quantizer)
2672c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    return false;
2682c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng
2692c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  cfg->rc_max_quantizer = adjusted_max_qp;
2702c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  return true;
2712c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng}
2722c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng
2732c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språngvoid ScreenshareLayers::TemporalLayer::UpdateDebt(int64_t delta_ms) {
2742c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  uint32_t debt_reduction_bytes = target_rate_kbps_ * delta_ms / 8;
2752c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  if (debt_reduction_bytes >= debt_bytes_) {
2762c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    debt_bytes_ = 0;
2772c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng  } else {
2782c4c9148191a10c0e82c9a209d454c6b1ebbaf20Erik Språng    debt_bytes_ -= debt_reduction_bytes;
2799115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org  }
2809115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org}
28170f74f3f7b8c6ee440d46748468ea14b5046134fsprang@webrtc.org
2829115cde6c9c8f5d749b349d7d10a570e4cb32803pbos@webrtc.org}  // namespace webrtc
283