2015-02-26 13:59:22 +00:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2012 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.
|
|
|
|
|
*/
|
|
|
|
|
|
2018-06-08 14:03:44 +02:00
|
|
|
#include "api/video_codecs/video_codec.h"
|
2015-02-26 13:59:22 +00:00
|
|
|
|
|
|
|
|
#include <string.h>
|
2019-07-05 19:08:33 +02:00
|
|
|
|
2018-06-08 14:03:44 +02:00
|
|
|
#include <string>
|
2015-02-26 13:59:22 +00:00
|
|
|
|
2018-10-19 15:29:54 +02:00
|
|
|
#include "absl/strings/match.h"
|
2024-08-19 01:13:31 -07:00
|
|
|
#include "absl/types/optional.h"
|
|
|
|
|
#include "api/video/video_codec_type.h"
|
|
|
|
|
#include "api/video_codecs/scalability_mode.h"
|
|
|
|
|
#include "api/video_codecs/simulcast_stream.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "rtc_base/checks.h"
|
2024-02-14 18:08:26 +01:00
|
|
|
#include "rtc_base/strings/string_builder.h"
|
2016-11-22 10:16:57 -08:00
|
|
|
|
2015-02-26 13:59:22 +00:00
|
|
|
namespace webrtc {
|
2019-11-27 13:59:41 +01:00
|
|
|
namespace {
|
|
|
|
|
constexpr char kPayloadNameVp8[] = "VP8";
|
|
|
|
|
constexpr char kPayloadNameVp9[] = "VP9";
|
2021-09-09 15:09:11 +02:00
|
|
|
constexpr char kPayloadNameAv1[] = "AV1";
|
2021-10-29 17:15:11 +02:00
|
|
|
// TODO(bugs.webrtc.org/13166): Remove AV1X when backwards compatibility is not
|
|
|
|
|
// needed.
|
2021-09-09 15:09:11 +02:00
|
|
|
constexpr char kPayloadNameAv1x[] = "AV1X";
|
2019-11-27 13:59:41 +01:00
|
|
|
constexpr char kPayloadNameH264[] = "H264";
|
|
|
|
|
constexpr char kPayloadNameGeneric[] = "Generic";
|
2023-09-20 13:10:31 +08:00
|
|
|
constexpr char kPayloadNameH265[] = "H265";
|
2019-11-27 13:59:41 +01:00
|
|
|
} // namespace
|
2015-02-26 13:59:22 +00:00
|
|
|
|
2018-03-19 13:48:44 +01:00
|
|
|
bool VideoCodecVP8::operator==(const VideoCodecVP8& other) const {
|
2022-05-17 13:51:01 +02:00
|
|
|
return (numberOfTemporalLayers == other.numberOfTemporalLayers &&
|
2018-03-19 13:48:44 +01:00
|
|
|
denoisingOn == other.denoisingOn &&
|
|
|
|
|
automaticResizeOn == other.automaticResizeOn &&
|
|
|
|
|
keyFrameInterval == other.keyFrameInterval);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool VideoCodecVP9::operator==(const VideoCodecVP9& other) const {
|
2022-05-17 13:51:01 +02:00
|
|
|
return (numberOfTemporalLayers == other.numberOfTemporalLayers &&
|
2018-03-19 13:48:44 +01:00
|
|
|
denoisingOn == other.denoisingOn &&
|
|
|
|
|
keyFrameInterval == other.keyFrameInterval &&
|
|
|
|
|
adaptiveQpMode == other.adaptiveQpMode &&
|
|
|
|
|
automaticResizeOn == other.automaticResizeOn &&
|
|
|
|
|
numberOfSpatialLayers == other.numberOfSpatialLayers &&
|
|
|
|
|
flexibleMode == other.flexibleMode);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool VideoCodecH264::operator==(const VideoCodecH264& other) const {
|
2022-05-17 15:39:41 +02:00
|
|
|
return (keyFrameInterval == other.keyFrameInterval &&
|
2019-04-11 13:26:25 +02:00
|
|
|
numberOfTemporalLayers == other.numberOfTemporalLayers);
|
2018-03-19 13:48:44 +01:00
|
|
|
}
|
|
|
|
|
|
2016-10-25 09:05:06 -07:00
|
|
|
VideoCodec::VideoCodec()
|
2018-08-16 14:35:26 +02:00
|
|
|
: codecType(kVideoCodecGeneric),
|
2016-10-25 09:05:06 -07:00
|
|
|
width(0),
|
|
|
|
|
height(0),
|
|
|
|
|
startBitrate(0),
|
|
|
|
|
maxBitrate(0),
|
|
|
|
|
minBitrate(0),
|
|
|
|
|
maxFramerate(0),
|
2018-01-17 13:55:14 -08:00
|
|
|
active(true),
|
2016-10-25 09:05:06 -07:00
|
|
|
qpMax(0),
|
|
|
|
|
numberOfSimulcastStreams(0),
|
|
|
|
|
simulcastStream(),
|
|
|
|
|
spatialLayers(),
|
2018-06-13 11:52:16 +02:00
|
|
|
mode(VideoCodecMode::kRealtimeVideo),
|
2016-11-16 16:41:30 +01:00
|
|
|
expect_encode_from_texture(false),
|
2017-06-19 07:18:55 -07:00
|
|
|
timing_frame_thresholds({0, 0}),
|
2020-08-04 11:40:23 +02:00
|
|
|
legacy_conference_mode(false),
|
2022-05-17 13:51:01 +02:00
|
|
|
codec_specific_(),
|
|
|
|
|
complexity_(VideoCodecComplexity::kComplexityNormal) {}
|
2016-10-25 09:05:06 -07:00
|
|
|
|
2024-02-14 18:08:26 +01:00
|
|
|
std::string VideoCodec::ToString() const {
|
|
|
|
|
char string_buf[2048];
|
|
|
|
|
rtc::SimpleStringBuilder ss(string_buf);
|
|
|
|
|
|
|
|
|
|
ss << "VideoCodec {" << "type: " << CodecTypeToPayloadString(codecType)
|
|
|
|
|
<< ", mode: "
|
|
|
|
|
<< (mode == VideoCodecMode::kRealtimeVideo ? "RealtimeVideo"
|
|
|
|
|
: "Screensharing");
|
|
|
|
|
if (IsSinglecast()) {
|
|
|
|
|
absl::optional<ScalabilityMode> scalability_mode = GetScalabilityMode();
|
|
|
|
|
if (scalability_mode.has_value()) {
|
|
|
|
|
ss << ", Singlecast: {" << width << "x" << height << " "
|
|
|
|
|
<< ScalabilityModeToString(*scalability_mode)
|
|
|
|
|
<< (active ? ", active" : ", inactive") << "}";
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
ss << ", Simulcast: {";
|
|
|
|
|
for (size_t i = 0; i < numberOfSimulcastStreams; ++i) {
|
|
|
|
|
const SimulcastStream stream = simulcastStream[i];
|
2024-02-28 16:09:24 +01:00
|
|
|
absl::optional<ScalabilityMode> scalability_mode =
|
2024-02-29 08:00:33 +01:00
|
|
|
stream.GetScalabilityMode();
|
2024-02-28 16:09:24 +01:00
|
|
|
if (scalability_mode.has_value()) {
|
|
|
|
|
ss << "[" << stream.width << "x" << stream.height << " "
|
|
|
|
|
<< ScalabilityModeToString(*scalability_mode)
|
|
|
|
|
<< (stream.active ? ", active" : ", inactive") << "]";
|
|
|
|
|
}
|
2024-02-14 18:08:26 +01:00
|
|
|
}
|
|
|
|
|
ss << "}";
|
|
|
|
|
}
|
|
|
|
|
ss << "}";
|
|
|
|
|
return ss.str();
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-25 09:05:06 -07:00
|
|
|
VideoCodecVP8* VideoCodec::VP8() {
|
|
|
|
|
RTC_DCHECK_EQ(codecType, kVideoCodecVP8);
|
2016-11-16 23:23:04 -08:00
|
|
|
return &codec_specific_.VP8;
|
2016-10-25 09:05:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const VideoCodecVP8& VideoCodec::VP8() const {
|
|
|
|
|
RTC_DCHECK_EQ(codecType, kVideoCodecVP8);
|
2016-11-16 23:23:04 -08:00
|
|
|
return codec_specific_.VP8;
|
2016-10-25 09:05:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VideoCodecVP9* VideoCodec::VP9() {
|
|
|
|
|
RTC_DCHECK_EQ(codecType, kVideoCodecVP9);
|
2016-11-16 23:23:04 -08:00
|
|
|
return &codec_specific_.VP9;
|
2016-10-25 09:05:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const VideoCodecVP9& VideoCodec::VP9() const {
|
|
|
|
|
RTC_DCHECK_EQ(codecType, kVideoCodecVP9);
|
2016-11-16 23:23:04 -08:00
|
|
|
return codec_specific_.VP9;
|
2016-10-25 09:05:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VideoCodecH264* VideoCodec::H264() {
|
|
|
|
|
RTC_DCHECK_EQ(codecType, kVideoCodecH264);
|
2016-11-16 23:23:04 -08:00
|
|
|
return &codec_specific_.H264;
|
2016-10-25 09:05:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const VideoCodecH264& VideoCodec::H264() const {
|
|
|
|
|
RTC_DCHECK_EQ(codecType, kVideoCodecH264);
|
2016-11-16 23:23:04 -08:00
|
|
|
return codec_specific_.H264;
|
2016-10-25 09:05:06 -07:00
|
|
|
}
|
|
|
|
|
|
2023-09-13 14:44:23 +02:00
|
|
|
VideoCodecAV1* VideoCodec::AV1() {
|
|
|
|
|
RTC_DCHECK_EQ(codecType, kVideoCodecAV1);
|
|
|
|
|
return &codec_specific_.AV1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const VideoCodecAV1& VideoCodec::AV1() const {
|
|
|
|
|
RTC_DCHECK_EQ(codecType, kVideoCodecAV1);
|
|
|
|
|
return codec_specific_.AV1;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-24 03:52:48 -07:00
|
|
|
const char* CodecTypeToPayloadString(VideoCodecType type) {
|
2016-11-16 16:41:30 +01:00
|
|
|
switch (type) {
|
|
|
|
|
case kVideoCodecVP8:
|
2017-08-24 03:52:48 -07:00
|
|
|
return kPayloadNameVp8;
|
2016-11-16 16:41:30 +01:00
|
|
|
case kVideoCodecVP9:
|
2017-08-24 03:52:48 -07:00
|
|
|
return kPayloadNameVp9;
|
2019-11-27 13:59:41 +01:00
|
|
|
case kVideoCodecAV1:
|
|
|
|
|
return kPayloadNameAv1;
|
2016-11-16 16:41:30 +01:00
|
|
|
case kVideoCodecH264:
|
2017-08-24 03:52:48 -07:00
|
|
|
return kPayloadNameH264;
|
2019-11-27 13:59:41 +01:00
|
|
|
case kVideoCodecGeneric:
|
2017-08-24 03:52:48 -07:00
|
|
|
return kPayloadNameGeneric;
|
2023-09-20 13:10:31 +08:00
|
|
|
case kVideoCodecH265:
|
|
|
|
|
return kPayloadNameH265;
|
2016-11-16 16:41:30 +01:00
|
|
|
}
|
2020-11-08 00:49:37 +01:00
|
|
|
RTC_CHECK_NOTREACHED();
|
2016-11-16 16:41:30 +01:00
|
|
|
}
|
|
|
|
|
|
2017-08-24 03:52:48 -07:00
|
|
|
VideoCodecType PayloadStringToCodecType(const std::string& name) {
|
2018-10-23 10:07:25 +02:00
|
|
|
if (absl::EqualsIgnoreCase(name, kPayloadNameVp8))
|
2017-08-24 03:52:48 -07:00
|
|
|
return kVideoCodecVP8;
|
2018-10-23 10:07:25 +02:00
|
|
|
if (absl::EqualsIgnoreCase(name, kPayloadNameVp9))
|
2017-08-24 03:52:48 -07:00
|
|
|
return kVideoCodecVP9;
|
2021-09-09 15:09:11 +02:00
|
|
|
if (absl::EqualsIgnoreCase(name, kPayloadNameAv1) ||
|
|
|
|
|
absl::EqualsIgnoreCase(name, kPayloadNameAv1x))
|
2019-11-27 13:59:41 +01:00
|
|
|
return kVideoCodecAV1;
|
2018-10-23 10:07:25 +02:00
|
|
|
if (absl::EqualsIgnoreCase(name, kPayloadNameH264))
|
2017-08-24 03:52:48 -07:00
|
|
|
return kVideoCodecH264;
|
2023-09-20 13:10:31 +08:00
|
|
|
if (absl::EqualsIgnoreCase(name, kPayloadNameH265))
|
|
|
|
|
return kVideoCodecH265;
|
2017-08-24 03:52:48 -07:00
|
|
|
return kVideoCodecGeneric;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-19 16:48:50 -06:00
|
|
|
VideoCodecComplexity VideoCodec::GetVideoEncoderComplexity() const {
|
2022-05-17 13:51:01 +02:00
|
|
|
return complexity_;
|
2022-02-19 16:48:50 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VideoCodec::SetVideoEncoderComplexity(
|
|
|
|
|
VideoCodecComplexity complexity_setting) {
|
|
|
|
|
complexity_ = complexity_setting;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-12 16:16:39 +02:00
|
|
|
bool VideoCodec::GetFrameDropEnabled() const {
|
2022-05-17 15:39:41 +02:00
|
|
|
return frame_drop_enabled_;
|
2022-05-12 16:16:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VideoCodec::SetFrameDropEnabled(bool enabled) {
|
|
|
|
|
frame_drop_enabled_ = enabled;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-26 13:59:22 +00:00
|
|
|
} // namespace webrtc
|