• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 #include "modules/video_coding/codecs/av1/scalability_structure_l1t2.h"
11 
12 #include <utility>
13 #include <vector>
14 
15 #include "absl/base/macros.h"
16 #include "api/transport/rtp/dependency_descriptor.h"
17 #include "rtc_base/checks.h"
18 #include "rtc_base/logging.h"
19 
20 namespace webrtc {
21 namespace {
22 
23 constexpr auto kNotPresent = DecodeTargetIndication::kNotPresent;
24 constexpr auto kDiscardable = DecodeTargetIndication::kDiscardable;
25 constexpr auto kSwitch = DecodeTargetIndication::kSwitch;
26 
27 constexpr DecodeTargetIndication kDtis[3][2] = {
28     {kSwitch, kSwitch},           // KeyFrame
29     {kNotPresent, kDiscardable},  // DeltaFrame T1
30     {kSwitch, kSwitch},           // DeltaFrame T0
31 };
32 
33 }  // namespace
34 
35 ScalabilityStructureL1T2::~ScalabilityStructureL1T2() = default;
36 
37 ScalableVideoController::StreamLayersConfig
StreamConfig() const38 ScalabilityStructureL1T2::StreamConfig() const {
39   StreamLayersConfig result;
40   result.num_spatial_layers = 1;
41   result.num_temporal_layers = 2;
42   return result;
43 }
44 
DependencyStructure() const45 FrameDependencyStructure ScalabilityStructureL1T2::DependencyStructure() const {
46   FrameDependencyStructure structure;
47   structure.num_decode_targets = 2;
48   structure.num_chains = 1;
49   structure.decode_target_protected_by_chain = {0, 0};
50   structure.templates.resize(3);
51   structure.templates[0].T(0).Dtis("SS").ChainDiffs({0});
52   structure.templates[1].T(0).Dtis("SS").ChainDiffs({2}).FrameDiffs({2});
53   structure.templates[2].T(1).Dtis("-D").ChainDiffs({1}).FrameDiffs({1});
54   return structure;
55 }
56 
57 std::vector<ScalableVideoController::LayerFrameConfig>
NextFrameConfig(bool restart)58 ScalabilityStructureL1T2::NextFrameConfig(bool restart) {
59   if (!active_decode_targets_[0]) {
60     RTC_LOG(LS_WARNING) << "No bitrate allocated for temporal layer 0, yet "
61                            "frame is requested. No frame will be encoded.";
62     return {};
63   }
64   if (restart) {
65     next_pattern_ = kKeyFrame;
66   } else if (!active_decode_targets_[1]) {
67     next_pattern_ = kDeltaFrameT0;
68   }
69   std::vector<LayerFrameConfig> result(1);
70 
71   switch (next_pattern_) {
72     case kKeyFrame:
73       result[0].Id(0).T(0).Keyframe().Update(0);
74       next_pattern_ = kDeltaFrameT1;
75       break;
76     case kDeltaFrameT1:
77       result[0].Id(1).T(1).Reference(0);
78       next_pattern_ = kDeltaFrameT0;
79       break;
80     case kDeltaFrameT0:
81       result[0].Id(2).T(0).ReferenceAndUpdate(0);
82       next_pattern_ = kDeltaFrameT1;
83       break;
84   }
85   return result;
86 }
87 
OnEncodeDone(LayerFrameConfig config)88 absl::optional<GenericFrameInfo> ScalabilityStructureL1T2::OnEncodeDone(
89     LayerFrameConfig config) {
90   // Encoder may have generated a keyframe even when not asked for it. Treat
91   // such frame same as requested keyframe, in particular restart the sequence.
92   if (config.IsKeyframe()) {
93     config = NextFrameConfig(/*restart=*/true).front();
94   }
95 
96   absl::optional<GenericFrameInfo> frame_info;
97   if (config.Id() < 0 || config.Id() >= int{ABSL_ARRAYSIZE(kDtis)}) {
98     RTC_LOG(LS_ERROR) << "Unexpected config id " << config.Id();
99     return frame_info;
100   }
101   frame_info.emplace();
102   frame_info->temporal_id = config.TemporalId();
103   frame_info->encoder_buffers = config.Buffers();
104   frame_info->decode_target_indications.assign(std::begin(kDtis[config.Id()]),
105                                                std::end(kDtis[config.Id()]));
106   frame_info->part_of_chain = {config.TemporalId() == 0};
107   frame_info->active_decode_targets = active_decode_targets_;
108   return frame_info;
109 }
110 
OnRatesUpdated(const VideoBitrateAllocation & bitrates)111 void ScalabilityStructureL1T2::OnRatesUpdated(
112     const VideoBitrateAllocation& bitrates) {
113   if (bitrates.GetBitrate(0, 0) == 0) {
114     // It is unclear what frame can be produced when base layer is disabled,
115     // so mark all decode targets as inactive to produce no frames.
116     active_decode_targets_.reset();
117     return;
118   }
119   active_decode_targets_.set(0, true);
120   active_decode_targets_.set(1, bitrates.GetBitrate(0, 1) > 0);
121 }
122 
123 }  // namespace webrtc
124