Thanks to visit codestin.com
Credit goes to webrtc.googlesource.com

blob: 03d5d675ec70aa30d7eb08ed6d61db20793b9193 [file] [log] [blame]
[email protected]ac2d27d2015-02-26 13:59:221/*
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 11:58:0911#include "common_types.h" // NOLINT(build/include)
[email protected]ac2d27d2015-02-26 13:59:2212
13#include <string.h>
eladalond0244c22017-06-08 11:19:1314#include <algorithm>
danilchapef8d7732017-04-19 09:59:4815#include <limits>
16#include <type_traits>
[email protected]ac2d27d2015-02-26 13:59:2217
Mirko Bonadei92ea95e2017-09-15 04:47:3118#include "rtc_base/checks.h"
19#include "rtc_base/stringutils.h"
magjed10165ab2016-11-22 18:16:5720
[email protected]ac2d27d2015-02-26 13:59:2221namespace webrtc {
22
hta257dc392016-10-25 16:05:0623VideoCodec::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 21:55:1434 active(true),
hta257dc392016-10-25 16:05:0635 qpMax(0),
36 numberOfSimulcastStreams(0),
37 simulcastStream(),
38 spatialLayers(),
39 mode(kRealtimeVideo),
Erik Språng08127a92016-11-16 15:41:3040 expect_encode_from_texture(false),
ilnik04f4d122017-06-19 14:18:5541 timing_frame_thresholds({0, 0}),
hta527d3472016-11-17 07:23:0442 codec_specific_() {}
hta257dc392016-10-25 16:05:0643
44VideoCodecVP8* VideoCodec::VP8() {
45 RTC_DCHECK_EQ(codecType, kVideoCodecVP8);
hta527d3472016-11-17 07:23:0446 return &codec_specific_.VP8;
hta257dc392016-10-25 16:05:0647}
48
49const VideoCodecVP8& VideoCodec::VP8() const {
50 RTC_DCHECK_EQ(codecType, kVideoCodecVP8);
hta527d3472016-11-17 07:23:0451 return codec_specific_.VP8;
hta257dc392016-10-25 16:05:0652}
53
54VideoCodecVP9* VideoCodec::VP9() {
55 RTC_DCHECK_EQ(codecType, kVideoCodecVP9);
hta527d3472016-11-17 07:23:0456 return &codec_specific_.VP9;
hta257dc392016-10-25 16:05:0657}
58
59const VideoCodecVP9& VideoCodec::VP9() const {
60 RTC_DCHECK_EQ(codecType, kVideoCodecVP9);
hta527d3472016-11-17 07:23:0461 return codec_specific_.VP9;
hta257dc392016-10-25 16:05:0662}
63
64VideoCodecH264* VideoCodec::H264() {
65 RTC_DCHECK_EQ(codecType, kVideoCodecH264);
hta527d3472016-11-17 07:23:0466 return &codec_specific_.H264;
hta257dc392016-10-25 16:05:0667}
68
69const VideoCodecH264& VideoCodec::H264() const {
70 RTC_DCHECK_EQ(codecType, kVideoCodecH264);
hta527d3472016-11-17 07:23:0471 return codec_specific_.H264;
hta257dc392016-10-25 16:05:0672}
73
Erik Språng08127a92016-11-16 15:41:3074static 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 Uysalerd7ae3c32018-01-25 21:01:0981static const char* kPayloadNameMultiplex = "Multiplex";
Erik Språng08127a92016-11-16 15:41:3082
magjed10165ab2016-11-22 18:16:5783static bool CodecNamesEq(const char* name1, const char* name2) {
84 return _stricmp(name1, name2) == 0;
85}
86
kthelgason1cdddc92017-08-24 10:52:4887const char* CodecTypeToPayloadString(VideoCodecType type) {
Erik Språng08127a92016-11-16 15:41:3088 switch (type) {
89 case kVideoCodecVP8:
kthelgason1cdddc92017-08-24 10:52:4890 return kPayloadNameVp8;
Erik Språng08127a92016-11-16 15:41:3091 case kVideoCodecVP9:
kthelgason1cdddc92017-08-24 10:52:4892 return kPayloadNameVp9;
Erik Språng08127a92016-11-16 15:41:3093 case kVideoCodecH264:
kthelgason1cdddc92017-08-24 10:52:4894 return kPayloadNameH264;
Erik Språng08127a92016-11-16 15:41:3095 case kVideoCodecI420:
kthelgason1cdddc92017-08-24 10:52:4896 return kPayloadNameI420;
Erik Språng08127a92016-11-16 15:41:3097 case kVideoCodecRED:
kthelgason1cdddc92017-08-24 10:52:4898 return kPayloadNameRED;
Erik Språng08127a92016-11-16 15:41:3099 case kVideoCodecULPFEC:
kthelgason1cdddc92017-08-24 10:52:48100 return kPayloadNameULPFEC;
Emircan Uysaler0a375472017-12-11 06:51:02101 // Other codecs default to generic.
Emircan Uysalerd7ae3c32018-01-25 21:01:09102 case kVideoCodecMultiplex:
Emircan Uysaler0a375472017-12-11 06:51:02103 case kVideoCodecFlexfec:
104 case kVideoCodecGeneric:
105 case kVideoCodecUnknown:
kthelgason1cdddc92017-08-24 10:52:48106 return kPayloadNameGeneric;
Erik Språng08127a92016-11-16 15:41:30107 }
Emircan Uysaler0a375472017-12-11 06:51:02108 return kPayloadNameGeneric;
Erik Språng08127a92016-11-16 15:41:30109}
110
kthelgason1cdddc92017-08-24 10:52:48111VideoCodecType PayloadStringToCodecType(const std::string& name) {
magjed10165ab2016-11-22 18:16:57112 if (CodecNamesEq(name.c_str(), kPayloadNameVp8))
kthelgason1cdddc92017-08-24 10:52:48113 return kVideoCodecVP8;
magjed10165ab2016-11-22 18:16:57114 if (CodecNamesEq(name.c_str(), kPayloadNameVp9))
kthelgason1cdddc92017-08-24 10:52:48115 return kVideoCodecVP9;
magjed10165ab2016-11-22 18:16:57116 if (CodecNamesEq(name.c_str(), kPayloadNameH264))
kthelgason1cdddc92017-08-24 10:52:48117 return kVideoCodecH264;
magjed10165ab2016-11-22 18:16:57118 if (CodecNamesEq(name.c_str(), kPayloadNameI420))
kthelgason1cdddc92017-08-24 10:52:48119 return kVideoCodecI420;
magjed10165ab2016-11-22 18:16:57120 if (CodecNamesEq(name.c_str(), kPayloadNameRED))
kthelgason1cdddc92017-08-24 10:52:48121 return kVideoCodecRED;
magjed10165ab2016-11-22 18:16:57122 if (CodecNamesEq(name.c_str(), kPayloadNameULPFEC))
kthelgason1cdddc92017-08-24 10:52:48123 return kVideoCodecULPFEC;
Emircan Uysalerd7ae3c32018-01-25 21:01:09124 if (CodecNamesEq(name.c_str(), kPayloadNameMultiplex))
125 return kVideoCodecMultiplex;
kthelgason1cdddc92017-08-24 10:52:48126 return kVideoCodecGeneric;
127}
128
Erik Språng08127a92016-11-16 15:41:30129const uint32_t BitrateAllocation::kMaxBitrateBps =
130 std::numeric_limits<uint32_t>::max();
131
[email protected]01f2ec32017-11-15 13:58:23132BitrateAllocation::BitrateAllocation() : sum_(0), bitrates_{}, has_bitrate_{} {}
Erik Språng08127a92016-11-16 15:41:30133
134bool BitrateAllocation::SetBitrate(size_t spatial_index,
135 size_t temporal_index,
136 uint32_t bitrate_bps) {
sprang6d314c72016-12-06 14:08:53137 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 15:41:30140 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;
[email protected]01f2ec32017-11-15 13:58:23147 has_bitrate_[spatial_index][temporal_index] = true;
Erik Språng08127a92016-11-16 15:41:30148 sum_ = static_cast<uint32_t>(new_bitrate_sum_bps);
149 return true;
150}
151
[email protected]01f2ec32017-11-15 13:58:23152bool 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 15:41:30159uint32_t BitrateAllocation::GetBitrate(size_t spatial_index,
160 size_t temporal_index) const {
sprang6d314c72016-12-06 14:08:53161 RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
162 RTC_CHECK_LT(temporal_index, kMaxTemporalStreams);
Erik Språng08127a92016-11-16 15:41:30163 return bitrates_[spatial_index][temporal_index];
164}
165
[email protected]01f2ec32017-11-15 13:58:23166// 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 15:41:30177// 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 14:08:53179 RTC_CHECK_LT(spatial_index, kMaxSpatialLayers);
Erik Språng08127a92016-11-16 15:41:30180 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 12:40:25186std::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
[email protected]ac2d27d2015-02-26 13:59:22235} // namespace webrtc