blob: 8ee5b1fdcd843dcb3f2cac503c04b9b1ca878d27 [file] [log] [blame]
/*
* 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.
*/
#include "api/video_codecs/video_codec.h"
#include <string.h>
#include <optional>
#include <string>
#include "absl/strings/match.h"
#include "api/video/video_codec_type.h"
#include "api/video_codecs/scalability_mode.h"
#include "api/video_codecs/simulcast_stream.h"
#include "rtc_base/checks.h"
#include "rtc_base/strings/string_builder.h"
namespace webrtc {
namespace {
constexpr char kPayloadNameVp8[] = "VP8";
constexpr char kPayloadNameVp9[] = "VP9";
constexpr char kPayloadNameAv1[] = "AV1";
// TODO(bugs.webrtc.org/13166): Remove AV1X when backwards compatibility is not
// needed.
constexpr char kPayloadNameAv1x[] = "AV1X";
constexpr char kPayloadNameH264[] = "H264";
constexpr char kPayloadNameGeneric[] = "Generic";
constexpr char kPayloadNameH265[] = "H265";
} // namespace
bool VideoCodecVP8::operator==(const VideoCodecVP8& other) const {
return (numberOfTemporalLayers == other.numberOfTemporalLayers &&
denoisingOn == other.denoisingOn &&
automaticResizeOn == other.automaticResizeOn &&
keyFrameInterval == other.keyFrameInterval);
}
bool VideoCodecVP9::operator==(const VideoCodecVP9& other) const {
return (numberOfTemporalLayers == other.numberOfTemporalLayers &&
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 {
return (keyFrameInterval == other.keyFrameInterval &&
numberOfTemporalLayers == other.numberOfTemporalLayers);
}
VideoCodec::VideoCodec()
: codecType(kVideoCodecGeneric),
width(0),
height(0),
startBitrate(0),
maxBitrate(0),
minBitrate(0),
maxFramerate(0),
active(true),
qpMax(0),
numberOfSimulcastStreams(0),
simulcastStream(),
spatialLayers(),
mode(VideoCodecMode::kRealtimeVideo),
expect_encode_from_texture(false),
timing_frame_thresholds({0, 0}),
legacy_conference_mode(false),
codec_specific_(),
complexity_(VideoCodecComplexity::kComplexityNormal) {}
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()) {
std::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];
std::optional<ScalabilityMode> scalability_mode =
stream.GetScalabilityMode();
if (scalability_mode.has_value()) {
ss << "[" << stream.width << "x" << stream.height << " "
<< ScalabilityModeToString(*scalability_mode)
<< (stream.active ? ", active" : ", inactive") << "]";
}
}
ss << "}";
}
ss << "}";
return ss.str();
}
VideoCodecVP8* VideoCodec::VP8() {
RTC_DCHECK_EQ(codecType, kVideoCodecVP8);
return &codec_specific_.VP8;
}
const VideoCodecVP8& VideoCodec::VP8() const {
RTC_DCHECK_EQ(codecType, kVideoCodecVP8);
return codec_specific_.VP8;
}
VideoCodecVP9* VideoCodec::VP9() {
RTC_DCHECK_EQ(codecType, kVideoCodecVP9);
return &codec_specific_.VP9;
}
const VideoCodecVP9& VideoCodec::VP9() const {
RTC_DCHECK_EQ(codecType, kVideoCodecVP9);
return codec_specific_.VP9;
}
VideoCodecH264* VideoCodec::H264() {
RTC_DCHECK_EQ(codecType, kVideoCodecH264);
return &codec_specific_.H264;
}
const VideoCodecH264& VideoCodec::H264() const {
RTC_DCHECK_EQ(codecType, kVideoCodecH264);
return codec_specific_.H264;
}
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;
}
const char* CodecTypeToPayloadString(VideoCodecType type) {
switch (type) {
case kVideoCodecVP8:
return kPayloadNameVp8;
case kVideoCodecVP9:
return kPayloadNameVp9;
case kVideoCodecAV1:
return kPayloadNameAv1;
case kVideoCodecH264:
return kPayloadNameH264;
case kVideoCodecGeneric:
return kPayloadNameGeneric;
case kVideoCodecH265:
return kPayloadNameH265;
}
RTC_CHECK_NOTREACHED();
}
VideoCodecType PayloadStringToCodecType(const std::string& name) {
if (absl::EqualsIgnoreCase(name, kPayloadNameVp8))
return kVideoCodecVP8;
if (absl::EqualsIgnoreCase(name, kPayloadNameVp9))
return kVideoCodecVP9;
if (absl::EqualsIgnoreCase(name, kPayloadNameAv1) ||
absl::EqualsIgnoreCase(name, kPayloadNameAv1x))
return kVideoCodecAV1;
if (absl::EqualsIgnoreCase(name, kPayloadNameH264))
return kVideoCodecH264;
if (absl::EqualsIgnoreCase(name, kPayloadNameH265))
return kVideoCodecH265;
return kVideoCodecGeneric;
}
VideoCodecComplexity VideoCodec::GetVideoEncoderComplexity() const {
return complexity_;
}
void VideoCodec::SetVideoEncoderComplexity(
VideoCodecComplexity complexity_setting) {
complexity_ = complexity_setting;
}
bool VideoCodec::GetFrameDropEnabled() const {
return frame_drop_enabled_;
}
void VideoCodec::SetFrameDropEnabled(bool enabled) {
frame_drop_enabled_ = enabled;
}
} // namespace webrtc