blob: 61e58b766fb5c3410dcc4ad85c5bf963d215eb2c [file] [log] [blame]
kwiberg@webrtc.orgac2d27d2015-02-26 13:59:22 +00001/*
2 * Copyright (c) 2012 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
Mirko Bonadei71207422017-09-15 13:58:09 +020011#include "common_types.h" // NOLINT(build/include)
kwiberg@webrtc.orgac2d27d2015-02-26 13:59:22 +000012
13#include <string.h>
eladalond0244c22017-06-08 04:19:13 -070014#include <algorithm>
danilchapef8d7732017-04-19 02:59:48 -070015#include <limits>
16#include <type_traits>
kwiberg@webrtc.orgac2d27d2015-02-26 13:59:22 +000017
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "rtc_base/checks.h"
19#include "rtc_base/stringutils.h"
magjed10165ab2016-11-22 10:16:57 -080020
kwiberg@webrtc.orgac2d27d2015-02-26 13:59:22 +000021namespace webrtc {
22
hta257dc392016-10-25 09:05:06 -070023VideoCodec::VideoCodec()
24 : codecType(kVideoCodecUnknown),
25 plName(),
26 plType(0),
27 width(0),
28 height(0),
29 startBitrate(0),
30 maxBitrate(0),
31 minBitrate(0),
32 targetBitrate(0),
33 maxFramerate(0),
Seth Hampsonf6464c92018-01-17 13:55:14 -080034 active(true),
hta257dc392016-10-25 09:05:06 -070035 qpMax(0),
36 numberOfSimulcastStreams(0),
37 simulcastStream(),
38 spatialLayers(),
39 mode(kRealtimeVideo),
Erik Språng08127a92016-11-16 16:41:30 +010040 expect_encode_from_texture(false),
ilnik04f4d122017-06-19 07:18:55 -070041 timing_frame_thresholds({0, 0}),
hta527d3472016-11-16 23:23:04 -080042 codec_specific_() {}
hta257dc392016-10-25 09:05:06 -070043
44VideoCodecVP8* VideoCodec::VP8() {
45 RTC_DCHECK_EQ(codecType, kVideoCodecVP8);
hta527d3472016-11-16 23:23:04 -080046 return &codec_specific_.VP8;
hta257dc392016-10-25 09:05:06 -070047}
48
49const VideoCodecVP8& VideoCodec::VP8() const {
50 RTC_DCHECK_EQ(codecType, kVideoCodecVP8);
hta527d3472016-11-16 23:23:04 -080051 return codec_specific_.VP8;
hta257dc392016-10-25 09:05:06 -070052}
53
54VideoCodecVP9* VideoCodec::VP9() {
55 RTC_DCHECK_EQ(codecType, kVideoCodecVP9);
hta527d3472016-11-16 23:23:04 -080056 return &codec_specific_.VP9;
hta257dc392016-10-25 09:05:06 -070057}
58
59const VideoCodecVP9& VideoCodec::VP9() const {
60 RTC_DCHECK_EQ(codecType, kVideoCodecVP9);
hta527d3472016-11-16 23:23:04 -080061 return codec_specific_.VP9;
hta257dc392016-10-25 09:05:06 -070062}
63
64VideoCodecH264* VideoCodec::H264() {
65 RTC_DCHECK_EQ(codecType, kVideoCodecH264);
hta527d3472016-11-16 23:23:04 -080066 return &codec_specific_.H264;
hta257dc392016-10-25 09:05:06 -070067}
68
69const VideoCodecH264& VideoCodec::H264() const {
70 RTC_DCHECK_EQ(codecType, kVideoCodecH264);
hta527d3472016-11-16 23:23:04 -080071 return codec_specific_.H264;
hta257dc392016-10-25 09:05:06 -070072}
73
Erik Språng08127a92016-11-16 16:41:30 +010074static const char* kPayloadNameVp8 = "VP8";
75static const char* kPayloadNameVp9 = "VP9";
76static const char* kPayloadNameH264 = "H264";
77static const char* kPayloadNameI420 = "I420";
78static const char* kPayloadNameRED = "RED";
79static const char* kPayloadNameULPFEC = "ULPFEC";
80static const char* kPayloadNameGeneric = "Generic";
Emircan Uysaler0a375472017-12-11 12:21:02 +053081static const char* kPayloadNameStereo = "Stereo";
Erik Språng08127a92016-11-16 16:41:30 +010082
magjed10165ab2016-11-22 10:16:57 -080083static bool CodecNamesEq(const char* name1, const char* name2) {
84 return _stricmp(name1, name2) == 0;
85}
86
kthelgason1cdddc92017-08-24 03:52:48 -070087const char* CodecTypeToPayloadString(VideoCodecType type) {
Erik Språng08127a92016-11-16 16:41:30 +010088 switch (type) {
89 case kVideoCodecVP8:
kthelgason1cdddc92017-08-24 03:52:48 -070090 return kPayloadNameVp8;
Erik Språng08127a92016-11-16 16:41:30 +010091 case kVideoCodecVP9:
kthelgason1cdddc92017-08-24 03:52:48 -070092 return kPayloadNameVp9;
Erik Språng08127a92016-11-16 16:41:30 +010093 case kVideoCodecH264:
kthelgason1cdddc92017-08-24 03:52:48 -070094 return kPayloadNameH264;
Erik Språng08127a92016-11-16 16:41:30 +010095 case kVideoCodecI420:
kthelgason1cdddc92017-08-24 03:52:48 -070096 return kPayloadNameI420;
Erik Språng08127a92016-11-16 16:41:30 +010097 case kVideoCodecRED:
kthelgason1cdddc92017-08-24 03:52:48 -070098 return kPayloadNameRED;
Erik Språng08127a92016-11-16 16:41:30 +010099 case kVideoCodecULPFEC:
kthelgason1cdddc92017-08-24 03:52:48 -0700100 return kPayloadNameULPFEC;
Emircan Uysaler0a375472017-12-11 12:21:02 +0530101 // Other codecs default to generic.
102 case kVideoCodecStereo:
103 case kVideoCodecFlexfec:
104 case kVideoCodecGeneric:
105 case kVideoCodecUnknown:
kthelgason1cdddc92017-08-24 03:52:48 -0700106 return kPayloadNameGeneric;
Erik Språng08127a92016-11-16 16:41:30 +0100107 }
Emircan Uysaler0a375472017-12-11 12:21:02 +0530108 return kPayloadNameGeneric;
Erik Språng08127a92016-11-16 16:41:30 +0100109}
110
kthelgason1cdddc92017-08-24 03:52:48 -0700111VideoCodecType PayloadStringToCodecType(const std::string& name) {
magjed10165ab2016-11-22 10:16:57 -0800112 if (CodecNamesEq(name.c_str(), kPayloadNameVp8))
kthelgason1cdddc92017-08-24 03:52:48 -0700113 return kVideoCodecVP8;
magjed10165ab2016-11-22 10:16:57 -0800114 if (CodecNamesEq(name.c_str(), kPayloadNameVp9))
kthelgason1cdddc92017-08-24 03:52:48 -0700115 return kVideoCodecVP9;
magjed10165ab2016-11-22 10:16:57 -0800116 if (CodecNamesEq(name.c_str(), kPayloadNameH264))
kthelgason1cdddc92017-08-24 03:52:48 -0700117 return kVideoCodecH264;
magjed10165ab2016-11-22 10:16:57 -0800118 if (CodecNamesEq(name.c_str(), kPayloadNameI420))
kthelgason1cdddc92017-08-24 03:52:48 -0700119 return kVideoCodecI420;
magjed10165ab2016-11-22 10:16:57 -0800120 if (CodecNamesEq(name.c_str(), kPayloadNameRED))
kthelgason1cdddc92017-08-24 03:52:48 -0700121 return kVideoCodecRED;
magjed10165ab2016-11-22 10:16:57 -0800122 if (CodecNamesEq(name.c_str(), kPayloadNameULPFEC))
kthelgason1cdddc92017-08-24 03:52:48 -0700123 return kVideoCodecULPFEC;
Emircan Uysaler0a375472017-12-11 12:21:02 +0530124 if (CodecNamesEq(name.c_str(), kPayloadNameStereo))
125 return kVideoCodecStereo;
kthelgason1cdddc92017-08-24 03:52:48 -0700126 return kVideoCodecGeneric;
127}
128
Erik Språng08127a92016-11-16 16:41:30 +0100129const uint32_t BitrateAllocation::kMaxBitrateBps =
130 std::numeric_limits<uint32_t>::max();
131
erikvarga@webrtc.org01f2ec32017-11-15 14:58:23 +0100132BitrateAllocation::BitrateAllocation() : sum_(0), bitrates_{}, has_bitrate_{} {}
Erik Språng08127a92016-11-16 16:41:30 +0100133
134bool BitrateAllocation::SetBitrate(size_t spatial_index,
135 size_t temporal_index,
136 uint32_t bitrate_bps) {
sprang6d314c72016-12-06 06:08:53 -0800137 RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
138 RTC_CHECK_LT(temporal_index, kMaxTemporalStreams);
139 RTC_CHECK_LE(bitrates_[spatial_index][temporal_index], sum_);
Erik Språng08127a92016-11-16 16:41:30 +0100140 uint64_t new_bitrate_sum_bps = sum_;
141 new_bitrate_sum_bps -= bitrates_[spatial_index][temporal_index];
142 new_bitrate_sum_bps += bitrate_bps;
143 if (new_bitrate_sum_bps > kMaxBitrateBps)
144 return false;
145
146 bitrates_[spatial_index][temporal_index] = bitrate_bps;
erikvarga@webrtc.org01f2ec32017-11-15 14:58:23 +0100147 has_bitrate_[spatial_index][temporal_index] = true;
Erik Språng08127a92016-11-16 16:41:30 +0100148 sum_ = static_cast<uint32_t>(new_bitrate_sum_bps);
149 return true;
150}
151
erikvarga@webrtc.org01f2ec32017-11-15 14:58:23 +0100152bool BitrateAllocation::HasBitrate(size_t spatial_index,
153 size_t temporal_index) const {
154 RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
155 RTC_CHECK_LT(temporal_index, kMaxTemporalStreams);
156 return has_bitrate_[spatial_index][temporal_index];
157}
158
Erik Språng08127a92016-11-16 16:41:30 +0100159uint32_t BitrateAllocation::GetBitrate(size_t spatial_index,
160 size_t temporal_index) const {
sprang6d314c72016-12-06 06:08:53 -0800161 RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
162 RTC_CHECK_LT(temporal_index, kMaxTemporalStreams);
Erik Språng08127a92016-11-16 16:41:30 +0100163 return bitrates_[spatial_index][temporal_index];
164}
165
erikvarga@webrtc.org01f2ec32017-11-15 14:58:23 +0100166// Whether the specific spatial layers has the bitrate set in any of its
167// temporal layers.
168bool BitrateAllocation::IsSpatialLayerUsed(size_t spatial_index) const {
169 RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
170 for (int i = 0; i < kMaxTemporalStreams; ++i) {
171 if (has_bitrate_[spatial_index][i])
172 return true;
173 }
174 return false;
175}
176
Erik Språng08127a92016-11-16 16:41:30 +0100177// Get the sum of all the temporal layer for a specific spatial layer.
178uint32_t BitrateAllocation::GetSpatialLayerSum(size_t spatial_index) const {
sprang6d314c72016-12-06 06:08:53 -0800179 RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
Erik Språng08127a92016-11-16 16:41:30 +0100180 uint32_t sum = 0;
181 for (int i = 0; i < kMaxTemporalStreams; ++i)
182 sum += bitrates_[spatial_index][i];
183 return sum;
184}
185
sprangd0fc37a2017-06-22 05:40:25 -0700186std::string BitrateAllocation::ToString() const {
187 if (sum_ == 0)
188 return "BitrateAllocation [ [] ]";
189
190 // TODO(sprang): Replace this stringstream with something cheaper.
191 std::ostringstream oss;
192 oss << "BitrateAllocation [";
193 uint32_t spatial_cumulator = 0;
194 for (int si = 0; si < kMaxSpatialLayers; ++si) {
195 RTC_DCHECK_LE(spatial_cumulator, sum_);
196 if (spatial_cumulator == sum_)
197 break;
198
199 const uint32_t layer_sum = GetSpatialLayerSum(si);
200 if (layer_sum == sum_) {
201 oss << " [";
202 } else {
203 if (si > 0)
204 oss << ",";
205 oss << std::endl << " [";
206 }
207 spatial_cumulator += layer_sum;
208
209 uint32_t temporal_cumulator = 0;
210 for (int ti = 0; ti < kMaxTemporalStreams; ++ti) {
211 RTC_DCHECK_LE(temporal_cumulator, layer_sum);
212 if (temporal_cumulator == layer_sum)
213 break;
214
215 if (ti > 0)
216 oss << ", ";
217
218 uint32_t bitrate = bitrates_[si][ti];
219 oss << bitrate;
220 temporal_cumulator += bitrate;
221 }
222 oss << "]";
223 }
224
225 RTC_DCHECK_EQ(spatial_cumulator, sum_);
226 oss << " ]";
227 return oss.str();
228}
229
230std::ostream& BitrateAllocation::operator<<(std::ostream& os) const {
231 os << ToString();
232 return os;
233}
234
kwiberg@webrtc.orgac2d27d2015-02-26 13:59:22 +0000235} // namespace webrtc