aboutsummaryrefslogtreecommitdiff
path: root/modules/video_coding/codecs/av1/scalable_video_controller.h
blob: 01678207984bea57af69019974482ead8da953da (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
 *  Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
#ifndef MODULES_VIDEO_CODING_CODECS_AV1_SCALABLE_VIDEO_CONTROLLER_H_
#define MODULES_VIDEO_CODING_CODECS_AV1_SCALABLE_VIDEO_CONTROLLER_H_

#include <vector>

#include "absl/container/inlined_vector.h"
#include "absl/types/optional.h"
#include "api/transport/rtp/dependency_descriptor.h"
#include "api/video/video_bitrate_allocation.h"
#include "common_video/generic_frame_descriptor/generic_frame_info.h"

namespace webrtc {

// Controls how video should be encoded to be scalable. Outputs results as
// buffer usage configuration for encoder and enough details to communicate the
// scalability structure via dependency descriptor rtp header extension.
class ScalableVideoController {
 public:
  struct StreamLayersConfig {
    int num_spatial_layers = 1;
    int num_temporal_layers = 1;
    // Spatial layers scaling. Frames with spatial_id = i expected to be encoded
    // with original_resolution * scaling_factor_num[i] / scaling_factor_den[i].
    int scaling_factor_num[DependencyDescriptor::kMaxSpatialIds] = {1, 1, 1, 1};
    int scaling_factor_den[DependencyDescriptor::kMaxSpatialIds] = {1, 1, 1, 1};
  };
  class LayerFrameConfig {
   public:
    // Builders/setters.
    LayerFrameConfig& Id(int value);
    LayerFrameConfig& Keyframe();
    LayerFrameConfig& S(int value);
    LayerFrameConfig& T(int value);
    LayerFrameConfig& Reference(int buffer_id);
    LayerFrameConfig& Update(int buffer_id);
    LayerFrameConfig& ReferenceAndUpdate(int buffer_id);

    // Getters.
    int Id() const { return id_; }
    bool IsKeyframe() const { return is_keyframe_; }
    int SpatialId() const { return spatial_id_; }
    int TemporalId() const { return temporal_id_; }
    const absl::InlinedVector<CodecBufferUsage, kMaxEncoderBuffers>& Buffers()
        const {
      return buffers_;
    }

   private:
    // Id to match configuration returned by NextFrameConfig with
    // (possibly modified) configuration passed back via OnEncoderDone.
    // The meaning of the id is an implementation detail of
    // the ScalableVideoController.
    int id_ = 0;

    // Indication frame should be encoded as a key frame. In particular when
    // `is_keyframe=true` property `CodecBufferUsage::referenced` should be
    // ignored and treated as false.
    bool is_keyframe_ = false;

    int spatial_id_ = 0;
    int temporal_id_ = 0;
    // Describes how encoder which buffers encoder allowed to reference and
    // which buffers encoder should update.
    absl::InlinedVector<CodecBufferUsage, kMaxEncoderBuffers> buffers_;
  };

  virtual ~ScalableVideoController() = default;

  // Returns video structure description for encoder to configure itself.
  virtual StreamLayersConfig StreamConfig() const = 0;

  // Returns video structure description in format compatible with
  // dependency descriptor rtp header extension.
  virtual FrameDependencyStructure DependencyStructure() const = 0;

  // Notifies Controller with updated bitrates per layer. In particular notifies
  // when certain layers should be disabled.
  // Controller shouldn't produce LayerFrameConfig for disabled layers.
  // TODO(bugs.webrtc.org/11404): Make pure virtual when implemented by all
  // structures.
  virtual void OnRatesUpdated(const VideoBitrateAllocation& bitrates) {}

  // When `restart` is true, first `LayerFrameConfig` should have `is_keyframe`
  // set to true.
  // Returned vector shouldn't be empty.
  virtual std::vector<LayerFrameConfig> NextFrameConfig(bool restart) = 0;

  // Returns configuration to pass to EncoderCallback.
  virtual absl::optional<GenericFrameInfo> OnEncodeDone(
      LayerFrameConfig config) = 0;
};

// Below are implementation details.
inline ScalableVideoController::LayerFrameConfig&
ScalableVideoController::LayerFrameConfig::Id(int value) {
  id_ = value;
  return *this;
}
inline ScalableVideoController::LayerFrameConfig&
ScalableVideoController::LayerFrameConfig::Keyframe() {
  is_keyframe_ = true;
  return *this;
}
inline ScalableVideoController::LayerFrameConfig&
ScalableVideoController::LayerFrameConfig::S(int value) {
  spatial_id_ = value;
  return *this;
}
inline ScalableVideoController::LayerFrameConfig&
ScalableVideoController::LayerFrameConfig::T(int value) {
  temporal_id_ = value;
  return *this;
}
inline ScalableVideoController::LayerFrameConfig&
ScalableVideoController::LayerFrameConfig::Reference(int buffer_id) {
  buffers_.emplace_back(buffer_id, /*referenced=*/true, /*updated=*/false);
  return *this;
}
inline ScalableVideoController::LayerFrameConfig&
ScalableVideoController::LayerFrameConfig::Update(int buffer_id) {
  buffers_.emplace_back(buffer_id, /*referenced=*/false, /*updated=*/true);
  return *this;
}
inline ScalableVideoController::LayerFrameConfig&
ScalableVideoController::LayerFrameConfig::ReferenceAndUpdate(int buffer_id) {
  buffers_.emplace_back(buffer_id, /*referenced=*/true, /*updated=*/true);
  return *this;
}

}  // namespace webrtc

#endif  // MODULES_VIDEO_CODING_CODECS_AV1_SCALABLE_VIDEO_CONTROLLER_H_