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