Move h264_profile_level_id and vp9_profile to api/video_codecs
This is a refactor to simplify a follow-up CL of adding
SdpVideoFormat::IsSameCodec.
The original files media/base/h264_profile_level_id.* and
media/base/vp9_profile.h must be kept until downstream projects
stop using them.
Bug: chroimium:1187565
Change-Id: Ib39eca095a3d61939a914d9bffaf4b891ddd222f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/215236
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Kári Helgason <kthelgason@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Johannes Kron <kron@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33782}
diff --git a/api/test/DEPS b/api/test/DEPS
index d97ac49..2784fcb 100644
--- a/api/test/DEPS
+++ b/api/test/DEPS
@@ -35,7 +35,4 @@
"create_frame_generator\.h": [
"+system_wrappers/include/clock.h",
],
- "videocodec_test_fixture\.h": [
- "+media/base/h264_profile_level_id.h"
- ],
}
diff --git a/api/test/videocodec_test_fixture.h b/api/test/videocodec_test_fixture.h
index 379d46d..e0f804f 100644
--- a/api/test/videocodec_test_fixture.h
+++ b/api/test/videocodec_test_fixture.h
@@ -59,7 +59,7 @@
class EncodedFrameChecker {
public:
virtual ~EncodedFrameChecker() = default;
- virtual void CheckEncodedFrame(webrtc::VideoCodecType codec,
+ virtual void CheckEncodedFrame(VideoCodecType codec,
const EncodedImage& encoded_frame) const = 0;
};
@@ -123,16 +123,16 @@
bool encode_in_real_time = false;
// Codec settings to use.
- webrtc::VideoCodec codec_settings;
+ VideoCodec codec_settings;
// Name of the codec being tested.
std::string codec_name;
// H.264 specific settings.
struct H264CodecSettings {
- H264::Profile profile = H264::kProfileConstrainedBaseline;
+ H264Profile profile = H264Profile::kProfileConstrainedBaseline;
H264PacketizationMode packetization_mode =
- webrtc::H264PacketizationMode::NonInterleaved;
+ H264PacketizationMode::NonInterleaved;
} h264_codec_settings;
// Custom checker that will be called for each frame.
diff --git a/api/video_codecs/BUILD.gn b/api/video_codecs/BUILD.gn
index a990276..4e28cd7 100644
--- a/api/video_codecs/BUILD.gn
+++ b/api/video_codecs/BUILD.gn
@@ -15,6 +15,8 @@
rtc_library("video_codecs_api") {
visibility = [ "*" ]
sources = [
+ "h264_profile_level_id.cc",
+ "h264_profile_level_id.h",
"sdp_video_format.cc",
"sdp_video_format.h",
"spatial_layer.cc",
@@ -35,6 +37,8 @@
"vp8_frame_config.h",
"vp8_temporal_layers.cc",
"vp8_temporal_layers.h",
+ "vp9_profile.cc",
+ "vp9_profile.h",
]
deps = [
@@ -138,7 +142,6 @@
":video_codecs_api",
"..:fec_controller_api",
"../../api/video:video_frame",
- "../../media:rtc_h264_profile_id",
"../../media:rtc_media_base",
"../../modules/video_coding:video_codec_interface",
"../../modules/video_coding:video_coding_utility",
diff --git a/api/video_codecs/h264_profile_level_id.cc b/api/video_codecs/h264_profile_level_id.cc
new file mode 100644
index 0000000..fa47758
--- /dev/null
+++ b/api/video_codecs/h264_profile_level_id.cc
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2021 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/h264_profile_level_id.h"
+
+#include <cstdio>
+#include <cstdlib>
+#include <string>
+
+#include "rtc_base/arraysize.h"
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+namespace {
+
+const char kProfileLevelId[] = "profile-level-id";
+
+// For level_idc=11 and profile_idc=0x42, 0x4D, or 0x58, the constraint set3
+// flag specifies if level 1b or level 1.1 is used.
+const uint8_t kConstraintSet3Flag = 0x10;
+
+// Convert a string of 8 characters into a byte where the positions containing
+// character c will have their bit set. For example, c = 'x', str = "x1xx0000"
+// will return 0b10110000. constexpr is used so that the pattern table in
+// kProfilePatterns is statically initialized.
+constexpr uint8_t ByteMaskString(char c, const char (&str)[9]) {
+ return (str[0] == c) << 7 | (str[1] == c) << 6 | (str[2] == c) << 5 |
+ (str[3] == c) << 4 | (str[4] == c) << 3 | (str[5] == c) << 2 |
+ (str[6] == c) << 1 | (str[7] == c) << 0;
+}
+
+// Class for matching bit patterns such as "x1xx0000" where 'x' is allowed to be
+// either 0 or 1.
+class BitPattern {
+ public:
+ explicit constexpr BitPattern(const char (&str)[9])
+ : mask_(~ByteMaskString('x', str)),
+ masked_value_(ByteMaskString('1', str)) {}
+
+ bool IsMatch(uint8_t value) const { return masked_value_ == (value & mask_); }
+
+ private:
+ const uint8_t mask_;
+ const uint8_t masked_value_;
+};
+
+// Table for converting between profile_idc/profile_iop to H264Profile.
+struct ProfilePattern {
+ const uint8_t profile_idc;
+ const BitPattern profile_iop;
+ const H264Profile profile;
+};
+
+// This is from https://tools.ietf.org/html/rfc6184#section-8.1.
+constexpr ProfilePattern kProfilePatterns[] = {
+ {0x42, BitPattern("x1xx0000"), H264Profile::kProfileConstrainedBaseline},
+ {0x4D, BitPattern("1xxx0000"), H264Profile::kProfileConstrainedBaseline},
+ {0x58, BitPattern("11xx0000"), H264Profile::kProfileConstrainedBaseline},
+ {0x42, BitPattern("x0xx0000"), H264Profile::kProfileBaseline},
+ {0x58, BitPattern("10xx0000"), H264Profile::kProfileBaseline},
+ {0x4D, BitPattern("0x0x0000"), H264Profile::kProfileMain},
+ {0x64, BitPattern("00000000"), H264Profile::kProfileHigh},
+ {0x64, BitPattern("00001100"), H264Profile::kProfileConstrainedHigh}};
+
+struct LevelConstraint {
+ const int max_macroblocks_per_second;
+ const int max_macroblock_frame_size;
+ const H264Level level;
+};
+
+// This is from ITU-T H.264 (02/2016) Table A-1 – Level limits.
+static constexpr LevelConstraint kLevelConstraints[] = {
+ {1485, 99, H264Level::kLevel1},
+ {1485, 99, H264Level::kLevel1_b},
+ {3000, 396, H264Level::kLevel1_1},
+ {6000, 396, H264Level::kLevel1_2},
+ {11880, 396, H264Level::kLevel1_3},
+ {11880, 396, H264Level::kLevel2},
+ {19800, 792, H264Level::kLevel2_1},
+ {20250, 1620, H264Level::kLevel2_2},
+ {40500, 1620, H264Level::kLevel3},
+ {108000, 3600, H264Level::kLevel3_1},
+ {216000, 5120, H264Level::kLevel3_2},
+ {245760, 8192, H264Level::kLevel4},
+ {245760, 8192, H264Level::kLevel4_1},
+ {522240, 8704, H264Level::kLevel4_2},
+ {589824, 22080, H264Level::kLevel5},
+ {983040, 36864, H264Level::kLevel5_1},
+ {2073600, 36864, H264Level::kLevel5_2},
+};
+
+} // anonymous namespace
+
+absl::optional<H264ProfileLevelId> ParseH264ProfileLevelId(const char* str) {
+ // The string should consist of 3 bytes in hexadecimal format.
+ if (strlen(str) != 6u)
+ return absl::nullopt;
+ const uint32_t profile_level_id_numeric = strtol(str, nullptr, 16);
+ if (profile_level_id_numeric == 0)
+ return absl::nullopt;
+
+ // Separate into three bytes.
+ const uint8_t level_idc =
+ static_cast<uint8_t>(profile_level_id_numeric & 0xFF);
+ const uint8_t profile_iop =
+ static_cast<uint8_t>((profile_level_id_numeric >> 8) & 0xFF);
+ const uint8_t profile_idc =
+ static_cast<uint8_t>((profile_level_id_numeric >> 16) & 0xFF);
+
+ // Parse level based on level_idc and constraint set 3 flag.
+ H264Level level_casted = static_cast<H264Level>(level_idc);
+ H264Level level;
+
+ switch (level_casted) {
+ case H264Level::kLevel1_1:
+ level = (profile_iop & kConstraintSet3Flag) != 0 ? H264Level::kLevel1_b
+ : H264Level::kLevel1_1;
+ break;
+ case H264Level::kLevel1:
+ case H264Level::kLevel1_2:
+ case H264Level::kLevel1_3:
+ case H264Level::kLevel2:
+ case H264Level::kLevel2_1:
+ case H264Level::kLevel2_2:
+ case H264Level::kLevel3:
+ case H264Level::kLevel3_1:
+ case H264Level::kLevel3_2:
+ case H264Level::kLevel4:
+ case H264Level::kLevel4_1:
+ case H264Level::kLevel4_2:
+ case H264Level::kLevel5:
+ case H264Level::kLevel5_1:
+ case H264Level::kLevel5_2:
+ level = level_casted;
+ break;
+ default:
+ // Unrecognized level_idc.
+ return absl::nullopt;
+ }
+
+ // Parse profile_idc/profile_iop into a Profile enum.
+ for (const ProfilePattern& pattern : kProfilePatterns) {
+ if (profile_idc == pattern.profile_idc &&
+ pattern.profile_iop.IsMatch(profile_iop)) {
+ return H264ProfileLevelId(pattern.profile, level);
+ }
+ }
+
+ // Unrecognized profile_idc/profile_iop combination.
+ return absl::nullopt;
+}
+
+absl::optional<H264Level> H264SupportedLevel(int max_frame_pixel_count,
+ float max_fps) {
+ static const int kPixelsPerMacroblock = 16 * 16;
+
+ for (int i = arraysize(kLevelConstraints) - 1; i >= 0; --i) {
+ const LevelConstraint& level_constraint = kLevelConstraints[i];
+ if (level_constraint.max_macroblock_frame_size * kPixelsPerMacroblock <=
+ max_frame_pixel_count &&
+ level_constraint.max_macroblocks_per_second <=
+ max_fps * level_constraint.max_macroblock_frame_size) {
+ return level_constraint.level;
+ }
+ }
+
+ // No level supported.
+ return absl::nullopt;
+}
+
+absl::optional<H264ProfileLevelId> ParseSdpForH264ProfileLevelId(
+ const SdpVideoFormat::Parameters& params) {
+ // TODO(magjed): The default should really be kProfileBaseline and kLevel1
+ // according to the spec: https://tools.ietf.org/html/rfc6184#section-8.1. In
+ // order to not break backwards compatibility with older versions of WebRTC
+ // where external codecs don't have any parameters, use
+ // kProfileConstrainedBaseline kLevel3_1 instead. This workaround will only be
+ // done in an interim period to allow external clients to update their code.
+ // http://crbug/webrtc/6337.
+ static const H264ProfileLevelId kDefaultProfileLevelId(
+ H264Profile::kProfileConstrainedBaseline, H264Level::kLevel3_1);
+
+ const auto profile_level_id_it = params.find(kProfileLevelId);
+ return (profile_level_id_it == params.end())
+ ? kDefaultProfileLevelId
+ : ParseH264ProfileLevelId(profile_level_id_it->second.c_str());
+}
+
+absl::optional<std::string> H264ProfileLevelIdToString(
+ const H264ProfileLevelId& profile_level_id) {
+ // Handle special case level == 1b.
+ if (profile_level_id.level == H264Level::kLevel1_b) {
+ switch (profile_level_id.profile) {
+ case H264Profile::kProfileConstrainedBaseline:
+ return {"42f00b"};
+ case H264Profile::kProfileBaseline:
+ return {"42100b"};
+ case H264Profile::kProfileMain:
+ return {"4d100b"};
+ // Level 1b is not allowed for other profiles.
+ default:
+ return absl::nullopt;
+ }
+ }
+
+ const char* profile_idc_iop_string;
+ switch (profile_level_id.profile) {
+ case H264Profile::kProfileConstrainedBaseline:
+ profile_idc_iop_string = "42e0";
+ break;
+ case H264Profile::kProfileBaseline:
+ profile_idc_iop_string = "4200";
+ break;
+ case H264Profile::kProfileMain:
+ profile_idc_iop_string = "4d00";
+ break;
+ case H264Profile::kProfileConstrainedHigh:
+ profile_idc_iop_string = "640c";
+ break;
+ case H264Profile::kProfileHigh:
+ profile_idc_iop_string = "6400";
+ break;
+ // Unrecognized profile.
+ default:
+ return absl::nullopt;
+ }
+
+ char str[7];
+ snprintf(str, 7u, "%s%02x", profile_idc_iop_string, profile_level_id.level);
+ return {str};
+}
+
+bool H264IsSameProfile(const SdpVideoFormat::Parameters& params1,
+ const SdpVideoFormat::Parameters& params2) {
+ const absl::optional<H264ProfileLevelId> profile_level_id =
+ ParseSdpForH264ProfileLevelId(params1);
+ const absl::optional<H264ProfileLevelId> other_profile_level_id =
+ ParseSdpForH264ProfileLevelId(params2);
+ // Compare H264 profiles, but not levels.
+ return profile_level_id && other_profile_level_id &&
+ profile_level_id->profile == other_profile_level_id->profile;
+}
+
+} // namespace webrtc
diff --git a/api/video_codecs/h264_profile_level_id.h b/api/video_codecs/h264_profile_level_id.h
new file mode 100644
index 0000000..51d025c
--- /dev/null
+++ b/api/video_codecs/h264_profile_level_id.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2021 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 API_VIDEO_CODECS_H264_PROFILE_LEVEL_ID_H_
+#define API_VIDEO_CODECS_H264_PROFILE_LEVEL_ID_H_
+
+#include <string>
+
+#include "absl/types/optional.h"
+#include "api/video_codecs/sdp_video_format.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+enum class H264Profile {
+ kProfileConstrainedBaseline,
+ kProfileBaseline,
+ kProfileMain,
+ kProfileConstrainedHigh,
+ kProfileHigh,
+};
+
+// All values are equal to ten times the level number, except level 1b which is
+// special.
+enum class H264Level {
+ kLevel1_b = 0,
+ kLevel1 = 10,
+ kLevel1_1 = 11,
+ kLevel1_2 = 12,
+ kLevel1_3 = 13,
+ kLevel2 = 20,
+ kLevel2_1 = 21,
+ kLevel2_2 = 22,
+ kLevel3 = 30,
+ kLevel3_1 = 31,
+ kLevel3_2 = 32,
+ kLevel4 = 40,
+ kLevel4_1 = 41,
+ kLevel4_2 = 42,
+ kLevel5 = 50,
+ kLevel5_1 = 51,
+ kLevel5_2 = 52
+};
+
+struct H264ProfileLevelId {
+ constexpr H264ProfileLevelId(H264Profile profile, H264Level level)
+ : profile(profile), level(level) {}
+ H264Profile profile;
+ H264Level level;
+};
+
+// Parse profile level id that is represented as a string of 3 hex bytes.
+// Nothing will be returned if the string is not a recognized H264
+// profile level id.
+absl::optional<H264ProfileLevelId> ParseH264ProfileLevelId(const char* str);
+
+// Parse profile level id that is represented as a string of 3 hex bytes
+// contained in an SDP key-value map. A default profile level id will be
+// returned if the profile-level-id key is missing. Nothing will be returned if
+// the key is present but the string is invalid.
+RTC_EXPORT absl::optional<H264ProfileLevelId> ParseSdpForH264ProfileLevelId(
+ const SdpVideoFormat::Parameters& params);
+
+// Given that a decoder supports up to a given frame size (in pixels) at up to a
+// given number of frames per second, return the highest H.264 level where it
+// can guarantee that it will be able to support all valid encoded streams that
+// are within that level.
+RTC_EXPORT absl::optional<H264Level> H264SupportedLevel(
+ int max_frame_pixel_count,
+ float max_fps);
+
+// Returns canonical string representation as three hex bytes of the profile
+// level id, or returns nothing for invalid profile level ids.
+RTC_EXPORT absl::optional<std::string> H264ProfileLevelIdToString(
+ const H264ProfileLevelId& profile_level_id);
+
+// Returns true if the parameters have the same H264 profile (Baseline, High,
+// etc).
+RTC_EXPORT bool H264IsSameProfile(const SdpVideoFormat::Parameters& params1,
+ const SdpVideoFormat::Parameters& params2);
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_H264_PROFILE_LEVEL_ID_H_
diff --git a/api/video_codecs/test/BUILD.gn b/api/video_codecs/test/BUILD.gn
index cb810fc..ea8e6d5 100644
--- a/api/video_codecs/test/BUILD.gn
+++ b/api/video_codecs/test/BUILD.gn
@@ -13,6 +13,7 @@
testonly = true
sources = [
"builtin_video_encoder_factory_unittest.cc",
+ "h264_profile_level_id_unittest.cc",
"video_decoder_software_fallback_wrapper_unittest.cc",
"video_encoder_software_fallback_wrapper_unittest.cc",
]
diff --git a/api/video_codecs/test/h264_profile_level_id_unittest.cc b/api/video_codecs/test/h264_profile_level_id_unittest.cc
new file mode 100644
index 0000000..47098d2
--- /dev/null
+++ b/api/video_codecs/test/h264_profile_level_id_unittest.cc
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2021 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/h264_profile_level_id.h"
+
+#include <map>
+#include <string>
+
+#include "absl/types/optional.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+
+TEST(H264ProfileLevelId, TestParsingInvalid) {
+ // Malformed strings.
+ EXPECT_FALSE(ParseH264ProfileLevelId(""));
+ EXPECT_FALSE(ParseH264ProfileLevelId(" 42e01f"));
+ EXPECT_FALSE(ParseH264ProfileLevelId("4242e01f"));
+ EXPECT_FALSE(ParseH264ProfileLevelId("e01f"));
+ EXPECT_FALSE(ParseH264ProfileLevelId("gggggg"));
+
+ // Invalid level.
+ EXPECT_FALSE(ParseH264ProfileLevelId("42e000"));
+ EXPECT_FALSE(ParseH264ProfileLevelId("42e00f"));
+ EXPECT_FALSE(ParseH264ProfileLevelId("42e0ff"));
+
+ // Invalid profile.
+ EXPECT_FALSE(ParseH264ProfileLevelId("42e11f"));
+ EXPECT_FALSE(ParseH264ProfileLevelId("58601f"));
+ EXPECT_FALSE(ParseH264ProfileLevelId("64e01f"));
+}
+
+TEST(H264ProfileLevelId, TestParsingLevel) {
+ EXPECT_EQ(H264Level::kLevel3_1, ParseH264ProfileLevelId("42e01f")->level);
+ EXPECT_EQ(H264Level::kLevel1_1, ParseH264ProfileLevelId("42e00b")->level);
+ EXPECT_EQ(H264Level::kLevel1_b, ParseH264ProfileLevelId("42f00b")->level);
+ EXPECT_EQ(H264Level::kLevel4_2, ParseH264ProfileLevelId("42C02A")->level);
+ EXPECT_EQ(H264Level::kLevel5_2, ParseH264ProfileLevelId("640c34")->level);
+}
+
+TEST(H264ProfileLevelId, TestParsingConstrainedBaseline) {
+ EXPECT_EQ(H264Profile::kProfileConstrainedBaseline,
+ ParseH264ProfileLevelId("42e01f")->profile);
+ EXPECT_EQ(H264Profile::kProfileConstrainedBaseline,
+ ParseH264ProfileLevelId("42C02A")->profile);
+ EXPECT_EQ(H264Profile::kProfileConstrainedBaseline,
+ ParseH264ProfileLevelId("4de01f")->profile);
+ EXPECT_EQ(H264Profile::kProfileConstrainedBaseline,
+ ParseH264ProfileLevelId("58f01f")->profile);
+}
+
+TEST(H264ProfileLevelId, TestParsingBaseline) {
+ EXPECT_EQ(H264Profile::kProfileBaseline,
+ ParseH264ProfileLevelId("42a01f")->profile);
+ EXPECT_EQ(H264Profile::kProfileBaseline,
+ ParseH264ProfileLevelId("58A01F")->profile);
+}
+
+TEST(H264ProfileLevelId, TestParsingMain) {
+ EXPECT_EQ(H264Profile::kProfileMain,
+ ParseH264ProfileLevelId("4D401f")->profile);
+}
+
+TEST(H264ProfileLevelId, TestParsingHigh) {
+ EXPECT_EQ(H264Profile::kProfileHigh,
+ ParseH264ProfileLevelId("64001f")->profile);
+}
+
+TEST(H264ProfileLevelId, TestParsingConstrainedHigh) {
+ EXPECT_EQ(H264Profile::kProfileConstrainedHigh,
+ ParseH264ProfileLevelId("640c1f")->profile);
+}
+
+TEST(H264ProfileLevelId, TestSupportedLevel) {
+ EXPECT_EQ(H264Level::kLevel2_1, *H264SupportedLevel(640 * 480, 25));
+ EXPECT_EQ(H264Level::kLevel3_1, *H264SupportedLevel(1280 * 720, 30));
+ EXPECT_EQ(H264Level::kLevel4_2, *H264SupportedLevel(1920 * 1280, 60));
+}
+
+// Test supported level below level 1 requirements.
+TEST(H264ProfileLevelId, TestSupportedLevelInvalid) {
+ EXPECT_FALSE(H264SupportedLevel(0, 0));
+ // All levels support fps > 5.
+ EXPECT_FALSE(H264SupportedLevel(1280 * 720, 5));
+ // All levels support frame sizes > 183 * 137.
+ EXPECT_FALSE(H264SupportedLevel(183 * 137, 30));
+}
+
+TEST(H264ProfileLevelId, TestToString) {
+ EXPECT_EQ("42e01f", *H264ProfileLevelIdToString(H264ProfileLevelId(
+ H264Profile::kProfileConstrainedBaseline,
+ H264Level::kLevel3_1)));
+ EXPECT_EQ("42000a", *H264ProfileLevelIdToString(H264ProfileLevelId(
+ H264Profile::kProfileBaseline, H264Level::kLevel1)));
+ EXPECT_EQ("4d001f", H264ProfileLevelIdToString(H264ProfileLevelId(
+ H264Profile::kProfileMain, H264Level::kLevel3_1)));
+ EXPECT_EQ("640c2a",
+ *H264ProfileLevelIdToString(H264ProfileLevelId(
+ H264Profile::kProfileConstrainedHigh, H264Level::kLevel4_2)));
+ EXPECT_EQ("64002a", *H264ProfileLevelIdToString(H264ProfileLevelId(
+ H264Profile::kProfileHigh, H264Level::kLevel4_2)));
+}
+
+TEST(H264ProfileLevelId, TestToStringLevel1b) {
+ EXPECT_EQ("42f00b", *H264ProfileLevelIdToString(H264ProfileLevelId(
+ H264Profile::kProfileConstrainedBaseline,
+ H264Level::kLevel1_b)));
+ EXPECT_EQ("42100b",
+ *H264ProfileLevelIdToString(H264ProfileLevelId(
+ H264Profile::kProfileBaseline, H264Level::kLevel1_b)));
+ EXPECT_EQ("4d100b", *H264ProfileLevelIdToString(H264ProfileLevelId(
+ H264Profile::kProfileMain, H264Level::kLevel1_b)));
+}
+
+TEST(H264ProfileLevelId, TestToStringRoundTrip) {
+ EXPECT_EQ("42e01f",
+ *H264ProfileLevelIdToString(*ParseH264ProfileLevelId("42e01f")));
+ EXPECT_EQ("42e01f",
+ *H264ProfileLevelIdToString(*ParseH264ProfileLevelId("42E01F")));
+ EXPECT_EQ("4d100b",
+ *H264ProfileLevelIdToString(*ParseH264ProfileLevelId("4d100b")));
+ EXPECT_EQ("4d100b",
+ *H264ProfileLevelIdToString(*ParseH264ProfileLevelId("4D100B")));
+ EXPECT_EQ("640c2a",
+ *H264ProfileLevelIdToString(*ParseH264ProfileLevelId("640c2a")));
+ EXPECT_EQ("640c2a",
+ *H264ProfileLevelIdToString(*ParseH264ProfileLevelId("640C2A")));
+}
+
+TEST(H264ProfileLevelId, TestToStringInvalid) {
+ EXPECT_FALSE(H264ProfileLevelIdToString(
+ H264ProfileLevelId(H264Profile::kProfileHigh, H264Level::kLevel1_b)));
+ EXPECT_FALSE(H264ProfileLevelIdToString(H264ProfileLevelId(
+ H264Profile::kProfileConstrainedHigh, H264Level::kLevel1_b)));
+ EXPECT_FALSE(H264ProfileLevelIdToString(
+ H264ProfileLevelId(static_cast<H264Profile>(255), H264Level::kLevel3_1)));
+}
+
+TEST(H264ProfileLevelId, TestParseSdpProfileLevelIdEmpty) {
+ const absl::optional<H264ProfileLevelId> profile_level_id =
+ ParseSdpForH264ProfileLevelId(SdpVideoFormat::Parameters());
+ EXPECT_TRUE(profile_level_id);
+ EXPECT_EQ(H264Profile::kProfileConstrainedBaseline,
+ profile_level_id->profile);
+ EXPECT_EQ(H264Level::kLevel3_1, profile_level_id->level);
+}
+
+TEST(H264ProfileLevelId, TestParseSdpProfileLevelIdConstrainedHigh) {
+ SdpVideoFormat::Parameters params;
+ params["profile-level-id"] = "640c2a";
+ const absl::optional<H264ProfileLevelId> profile_level_id =
+ ParseSdpForH264ProfileLevelId(params);
+ EXPECT_TRUE(profile_level_id);
+ EXPECT_EQ(H264Profile::kProfileConstrainedHigh, profile_level_id->profile);
+ EXPECT_EQ(H264Level::kLevel4_2, profile_level_id->level);
+}
+
+TEST(H264ProfileLevelId, TestParseSdpProfileLevelIdInvalid) {
+ SdpVideoFormat::Parameters params;
+ params["profile-level-id"] = "foobar";
+ EXPECT_FALSE(ParseSdpForH264ProfileLevelId(params));
+}
+
+} // namespace webrtc
diff --git a/media/base/vp9_profile.cc b/api/video_codecs/vp9_profile.cc
similarity index 91%
rename from media/base/vp9_profile.cc
rename to api/video_codecs/vp9_profile.cc
index abf2502..d69f566 100644
--- a/media/base/vp9_profile.cc
+++ b/api/video_codecs/vp9_profile.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ * Copyright (c) 2021 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
@@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#include "media/base/vp9_profile.h"
+#include "api/video_codecs/vp9_profile.h"
#include <map>
#include <utility>
@@ -59,7 +59,7 @@
return StringToVP9Profile(profile_str);
}
-bool IsSameVP9Profile(const SdpVideoFormat::Parameters& params1,
+bool VP9IsSameProfile(const SdpVideoFormat::Parameters& params1,
const SdpVideoFormat::Parameters& params2) {
const absl::optional<VP9Profile> profile = ParseSdpForVP9Profile(params1);
const absl::optional<VP9Profile> other_profile =
diff --git a/api/video_codecs/vp9_profile.h b/api/video_codecs/vp9_profile.h
new file mode 100644
index 0000000..e632df4
--- /dev/null
+++ b/api/video_codecs/vp9_profile.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2021 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 API_VIDEO_CODECS_VP9_PROFILE_H_
+#define API_VIDEO_CODECS_VP9_PROFILE_H_
+
+#include <string>
+
+#include "absl/types/optional.h"
+#include "api/video_codecs/sdp_video_format.h"
+#include "rtc_base/system/rtc_export.h"
+
+namespace webrtc {
+
+// Profile information for VP9 video.
+extern RTC_EXPORT const char kVP9FmtpProfileId[];
+
+enum class VP9Profile {
+ kProfile0,
+ kProfile1,
+ kProfile2,
+};
+
+// Helper functions to convert VP9Profile to std::string. Returns "0" by
+// default.
+RTC_EXPORT std::string VP9ProfileToString(VP9Profile profile);
+
+// Helper functions to convert std::string to VP9Profile. Returns null if given
+// an invalid profile string.
+absl::optional<VP9Profile> StringToVP9Profile(const std::string& str);
+
+// Parse profile that is represented as a string of single digit contained in an
+// SDP key-value map. A default profile(kProfile0) will be returned if the
+// profile key is missing. Nothing will be returned if the key is present but
+// the string is invalid.
+RTC_EXPORT absl::optional<VP9Profile> ParseSdpForVP9Profile(
+ const SdpVideoFormat::Parameters& params);
+
+// Returns true if the parameters have the same VP9 profile, or neither contains
+// VP9 profile.
+bool VP9IsSameProfile(const SdpVideoFormat::Parameters& params1,
+ const SdpVideoFormat::Parameters& params2);
+
+} // namespace webrtc
+
+#endif // API_VIDEO_CODECS_VP9_PROFILE_H_
diff --git a/common_video/BUILD.gn b/common_video/BUILD.gn
index 2503f7f..8e53767 100644
--- a/common_video/BUILD.gn
+++ b/common_video/BUILD.gn
@@ -21,7 +21,6 @@
"h264/h264_common.h",
"h264/pps_parser.cc",
"h264/pps_parser.h",
- "h264/profile_level_id.h",
"h264/sps_parser.cc",
"h264/sps_parser.h",
"h264/sps_vui_rewriter.cc",
@@ -52,7 +51,7 @@
"../api/video:video_frame",
"../api/video:video_rtp_headers",
"../api/video_codecs:bitstream_parser_api",
- "../media:rtc_h264_profile_id",
+ "../api/video_codecs:video_codecs_api",
"../rtc_base",
"../rtc_base:checks",
"../rtc_base:rtc_task_queue",
@@ -90,7 +89,6 @@
"frame_rate_estimator_unittest.cc",
"h264/h264_bitstream_parser_unittest.cc",
"h264/pps_parser_unittest.cc",
- "h264/profile_level_id_unittest.cc",
"h264/sps_parser_unittest.cc",
"h264/sps_vui_rewriter_unittest.cc",
"libyuv/libyuv_unittest.cc",
@@ -105,7 +103,7 @@
"../api/video:video_frame",
"../api/video:video_frame_i010",
"../api/video:video_rtp_headers",
- "../media:rtc_h264_profile_id",
+ "../api/video_codecs:video_codecs_api",
"../rtc_base",
"../rtc_base:checks",
"../rtc_base:rtc_base_approved",
diff --git a/common_video/h264/profile_level_id.h b/common_video/h264/profile_level_id.h
deleted file mode 100644
index 07b49e5..0000000
--- a/common_video/h264/profile_level_id.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (c) 2016 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 COMMON_VIDEO_H264_PROFILE_LEVEL_ID_H_
-#define COMMON_VIDEO_H264_PROFILE_LEVEL_ID_H_
-
-#include "media/base/h264_profile_level_id.h"
-
-// TODO(zhihuang): Delete this file once dependent applications switch to
-// including "webrtc/media/base/h264_profile_level_id.h" directly.
-
-#endif // COMMON_VIDEO_H264_PROFILE_LEVEL_ID_H_
diff --git a/common_video/h264/profile_level_id_unittest.cc b/common_video/h264/profile_level_id_unittest.cc
deleted file mode 100644
index 957b434..0000000
--- a/common_video/h264/profile_level_id_unittest.cc
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (c) 2016 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 "common_video/h264/profile_level_id.h"
-
-#include <map>
-#include <string>
-
-#include "absl/types/optional.h"
-#include "media/base/h264_profile_level_id.h"
-#include "test/gtest.h"
-
-namespace webrtc {
-namespace H264 {
-
-TEST(H264ProfileLevelId, TestParsingInvalid) {
- // Malformed strings.
- EXPECT_FALSE(ParseProfileLevelId(""));
- EXPECT_FALSE(ParseProfileLevelId(" 42e01f"));
- EXPECT_FALSE(ParseProfileLevelId("4242e01f"));
- EXPECT_FALSE(ParseProfileLevelId("e01f"));
- EXPECT_FALSE(ParseProfileLevelId("gggggg"));
-
- // Invalid level.
- EXPECT_FALSE(ParseProfileLevelId("42e000"));
- EXPECT_FALSE(ParseProfileLevelId("42e00f"));
- EXPECT_FALSE(ParseProfileLevelId("42e0ff"));
-
- // Invalid profile.
- EXPECT_FALSE(ParseProfileLevelId("42e11f"));
- EXPECT_FALSE(ParseProfileLevelId("58601f"));
- EXPECT_FALSE(ParseProfileLevelId("64e01f"));
-}
-
-TEST(H264ProfileLevelId, TestParsingLevel) {
- EXPECT_EQ(kLevel3_1, ParseProfileLevelId("42e01f")->level);
- EXPECT_EQ(kLevel1_1, ParseProfileLevelId("42e00b")->level);
- EXPECT_EQ(kLevel1_b, ParseProfileLevelId("42f00b")->level);
- EXPECT_EQ(kLevel4_2, ParseProfileLevelId("42C02A")->level);
- EXPECT_EQ(kLevel5_2, ParseProfileLevelId("640c34")->level);
-}
-
-TEST(H264ProfileLevelId, TestParsingConstrainedBaseline) {
- EXPECT_EQ(kProfileConstrainedBaseline,
- ParseProfileLevelId("42e01f")->profile);
- EXPECT_EQ(kProfileConstrainedBaseline,
- ParseProfileLevelId("42C02A")->profile);
- EXPECT_EQ(kProfileConstrainedBaseline,
- ParseProfileLevelId("4de01f")->profile);
- EXPECT_EQ(kProfileConstrainedBaseline,
- ParseProfileLevelId("58f01f")->profile);
-}
-
-TEST(H264ProfileLevelId, TestParsingBaseline) {
- EXPECT_EQ(kProfileBaseline, ParseProfileLevelId("42a01f")->profile);
- EXPECT_EQ(kProfileBaseline, ParseProfileLevelId("58A01F")->profile);
-}
-
-TEST(H264ProfileLevelId, TestParsingMain) {
- EXPECT_EQ(kProfileMain, ParseProfileLevelId("4D401f")->profile);
-}
-
-TEST(H264ProfileLevelId, TestParsingHigh) {
- EXPECT_EQ(kProfileHigh, ParseProfileLevelId("64001f")->profile);
-}
-
-TEST(H264ProfileLevelId, TestParsingConstrainedHigh) {
- EXPECT_EQ(kProfileConstrainedHigh, ParseProfileLevelId("640c1f")->profile);
-}
-
-TEST(H264ProfileLevelId, TestSupportedLevel) {
- EXPECT_EQ(kLevel2_1, *SupportedLevel(640 * 480, 25));
- EXPECT_EQ(kLevel3_1, *SupportedLevel(1280 * 720, 30));
- EXPECT_EQ(kLevel4_2, *SupportedLevel(1920 * 1280, 60));
-}
-
-// Test supported level below level 1 requirements.
-TEST(H264ProfileLevelId, TestSupportedLevelInvalid) {
- EXPECT_FALSE(SupportedLevel(0, 0));
- // All levels support fps > 5.
- EXPECT_FALSE(SupportedLevel(1280 * 720, 5));
- // All levels support frame sizes > 183 * 137.
- EXPECT_FALSE(SupportedLevel(183 * 137, 30));
-}
-
-TEST(H264ProfileLevelId, TestToString) {
- EXPECT_EQ("42e01f", *ProfileLevelIdToString(ProfileLevelId(
- kProfileConstrainedBaseline, kLevel3_1)));
- EXPECT_EQ("42000a",
- *ProfileLevelIdToString(ProfileLevelId(kProfileBaseline, kLevel1)));
- EXPECT_EQ("4d001f",
- ProfileLevelIdToString(ProfileLevelId(kProfileMain, kLevel3_1)));
- EXPECT_EQ("640c2a", *ProfileLevelIdToString(
- ProfileLevelId(kProfileConstrainedHigh, kLevel4_2)));
- EXPECT_EQ("64002a",
- *ProfileLevelIdToString(ProfileLevelId(kProfileHigh, kLevel4_2)));
-}
-
-TEST(H264ProfileLevelId, TestToStringLevel1b) {
- EXPECT_EQ("42f00b", *ProfileLevelIdToString(ProfileLevelId(
- kProfileConstrainedBaseline, kLevel1_b)));
- EXPECT_EQ("42100b", *ProfileLevelIdToString(
- ProfileLevelId(kProfileBaseline, kLevel1_b)));
- EXPECT_EQ("4d100b",
- *ProfileLevelIdToString(ProfileLevelId(kProfileMain, kLevel1_b)));
-}
-
-TEST(H264ProfileLevelId, TestToStringRoundTrip) {
- EXPECT_EQ("42e01f", *ProfileLevelIdToString(*ParseProfileLevelId("42e01f")));
- EXPECT_EQ("42e01f", *ProfileLevelIdToString(*ParseProfileLevelId("42E01F")));
- EXPECT_EQ("4d100b", *ProfileLevelIdToString(*ParseProfileLevelId("4d100b")));
- EXPECT_EQ("4d100b", *ProfileLevelIdToString(*ParseProfileLevelId("4D100B")));
- EXPECT_EQ("640c2a", *ProfileLevelIdToString(*ParseProfileLevelId("640c2a")));
- EXPECT_EQ("640c2a", *ProfileLevelIdToString(*ParseProfileLevelId("640C2A")));
-}
-
-TEST(H264ProfileLevelId, TestToStringInvalid) {
- EXPECT_FALSE(ProfileLevelIdToString(ProfileLevelId(kProfileHigh, kLevel1_b)));
- EXPECT_FALSE(ProfileLevelIdToString(
- ProfileLevelId(kProfileConstrainedHigh, kLevel1_b)));
- EXPECT_FALSE(ProfileLevelIdToString(
- ProfileLevelId(static_cast<Profile>(255), kLevel3_1)));
-}
-
-TEST(H264ProfileLevelId, TestParseSdpProfileLevelIdEmpty) {
- const absl::optional<ProfileLevelId> profile_level_id =
- ParseSdpProfileLevelId(CodecParameterMap());
- EXPECT_TRUE(profile_level_id);
- EXPECT_EQ(kProfileConstrainedBaseline, profile_level_id->profile);
- EXPECT_EQ(kLevel3_1, profile_level_id->level);
-}
-
-TEST(H264ProfileLevelId, TestParseSdpProfileLevelIdConstrainedHigh) {
- CodecParameterMap params;
- params["profile-level-id"] = "640c2a";
- const absl::optional<ProfileLevelId> profile_level_id =
- ParseSdpProfileLevelId(params);
- EXPECT_TRUE(profile_level_id);
- EXPECT_EQ(kProfileConstrainedHigh, profile_level_id->profile);
- EXPECT_EQ(kLevel4_2, profile_level_id->level);
-}
-
-TEST(H264ProfileLevelId, TestParseSdpProfileLevelIdInvalid) {
- CodecParameterMap params;
- params["profile-level-id"] = "foobar";
- EXPECT_FALSE(ParseSdpProfileLevelId(params));
-}
-
-TEST(H264ProfileLevelId, TestGenerateProfileLevelIdForAnswerEmpty) {
- CodecParameterMap answer_params;
- GenerateProfileLevelIdForAnswer(CodecParameterMap(), CodecParameterMap(),
- &answer_params);
- EXPECT_TRUE(answer_params.empty());
-}
-
-TEST(H264ProfileLevelId,
- TestGenerateProfileLevelIdForAnswerLevelSymmetryCapped) {
- CodecParameterMap low_level;
- low_level["profile-level-id"] = "42e015";
- CodecParameterMap high_level;
- high_level["profile-level-id"] = "42e01f";
-
- // Level asymmetry is not allowed; test that answer level is the lower of the
- // local and remote levels.
- CodecParameterMap answer_params;
- GenerateProfileLevelIdForAnswer(low_level /* local_supported */,
- high_level /* remote_offered */,
- &answer_params);
- EXPECT_EQ("42e015", answer_params["profile-level-id"]);
-
- CodecParameterMap answer_params2;
- GenerateProfileLevelIdForAnswer(high_level /* local_supported */,
- low_level /* remote_offered */,
- &answer_params2);
- EXPECT_EQ("42e015", answer_params2["profile-level-id"]);
-}
-
-TEST(H264ProfileLevelId,
- TestGenerateProfileLevelIdForAnswerConstrainedBaselineLevelAsymmetry) {
- CodecParameterMap local_params;
- local_params["profile-level-id"] = "42e01f";
- local_params["level-asymmetry-allowed"] = "1";
- CodecParameterMap remote_params;
- remote_params["profile-level-id"] = "42e015";
- remote_params["level-asymmetry-allowed"] = "1";
- CodecParameterMap answer_params;
- GenerateProfileLevelIdForAnswer(local_params, remote_params, &answer_params);
- // When level asymmetry is allowed, we can answer a higher level than what was
- // offered.
- EXPECT_EQ("42e01f", answer_params["profile-level-id"]);
-}
-
-} // namespace H264
-} // namespace webrtc
diff --git a/media/BUILD.gn b/media/BUILD.gn
index f487c16..29ba403 100644
--- a/media/BUILD.gn
+++ b/media/BUILD.gn
@@ -23,20 +23,15 @@
defines = [ "HAVE_WEBRTC_VIDEO" ]
}
-rtc_library("rtc_h264_profile_id") {
+# Remove once downstream projects stop depend on this.
+rtc_source_set("rtc_h264_profile_id") {
visibility = [ "*" ]
sources = [
"base/h264_profile_level_id.cc",
"base/h264_profile_level_id.h",
]
-
- deps = [
- "../rtc_base",
- "../rtc_base:checks",
- "../rtc_base:rtc_base_approved",
- "../rtc_base/system:rtc_export",
- ]
- absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+ public_deps = # no-presubmit-check TODO(webrtc:8603)
+ [ "../api/video_codecs:video_codecs_api" ]
}
rtc_source_set("rtc_media_config") {
@@ -44,30 +39,24 @@
sources = [ "base/media_config.h" ]
}
-rtc_library("rtc_vp9_profile") {
+# Remove once downstream projects stop depend on this.
+rtc_source_set("rtc_vp9_profile") {
visibility = [ "*" ]
- sources = [
- "base/vp9_profile.cc",
- "base/vp9_profile.h",
- ]
-
- deps = [
- "../api/video_codecs:video_codecs_api",
- "../rtc_base:rtc_base_approved",
- "../rtc_base/system:rtc_export",
- ]
- absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+ sources = [ "base/vp9_profile.h" ]
+ public_deps = # no-presubmit-check TODO(webrtc:8603)
+ [ "../api/video_codecs:video_codecs_api" ]
}
-rtc_library("rtc_sdp_fmtp_utils") {
+rtc_library("rtc_sdp_video_format_utils") {
visibility = [ "*" ]
sources = [
- "base/sdp_fmtp_utils.cc",
- "base/sdp_fmtp_utils.h",
+ "base/sdp_video_format_utils.cc",
+ "base/sdp_video_format_utils.h",
]
deps = [
"../api/video_codecs:video_codecs_api",
+ "../rtc_base:checks",
"../rtc_base:stringutils",
]
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
@@ -78,9 +67,7 @@
defines = []
libs = []
deps = [
- ":rtc_h264_profile_id",
":rtc_media_config",
- ":rtc_vp9_profile",
"../api:array_view",
"../api:audio_options_api",
"../api:frame_transformer_interface",
@@ -221,7 +208,6 @@
libs = []
deps = [
":rtc_encoder_simulcast_proxy",
- ":rtc_h264_profile_id",
":rtc_media_base",
":rtc_simulcast_encoder_adapter",
"../api/video:encoded_image",
@@ -555,9 +541,8 @@
":rtc_media_base",
":rtc_media_engine_defaults",
":rtc_media_tests_utils",
- ":rtc_sdp_fmtp_utils",
+ ":rtc_sdp_video_format_utils",
":rtc_simulcast_encoder_adapter",
- ":rtc_vp9_profile",
"../api:create_simulcast_test_fixture_api",
"../api:libjingle_peerconnection_api",
"../api:mock_video_bitrate_allocator",
@@ -586,7 +571,6 @@
"../audio",
"../call:call_interfaces",
"../common_video",
- "../media:rtc_h264_profile_id",
"../modules/audio_device:mock_audio_device",
"../modules/audio_processing",
"../modules/audio_processing:api",
@@ -627,7 +611,7 @@
"base/codec_unittest.cc",
"base/media_engine_unittest.cc",
"base/rtp_utils_unittest.cc",
- "base/sdp_fmtp_utils_unittest.cc",
+ "base/sdp_video_format_utils_unittest.cc",
"base/stream_params_unittest.cc",
"base/turn_utils_unittest.cc",
"base/video_adapter_unittest.cc",
diff --git a/media/base/codec.cc b/media/base/codec.cc
index ab39592..e8a591e 100644
--- a/media/base/codec.cc
+++ b/media/base/codec.cc
@@ -12,8 +12,8 @@
#include "absl/algorithm/container.h"
#include "absl/strings/match.h"
-#include "media/base/h264_profile_level_id.h"
-#include "media/base/vp9_profile.h"
+#include "api/video_codecs/h264_profile_level_id.h"
+#include "api/video_codecs/vp9_profile.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/string_encode.h"
@@ -51,10 +51,10 @@
absl::EqualsIgnoreCase(name, name2);
};
if (either_name_matches(kH264CodecName))
- return webrtc::H264::IsSameH264Profile(params1, params2) &&
+ return webrtc::H264IsSameProfile(params1, params2) &&
IsSameH264PacketizationMode(params1, params2);
if (either_name_matches(kVp9CodecName))
- return webrtc::IsSameVP9Profile(params1, params2);
+ return webrtc::VP9IsSameProfile(params1, params2);
return true;
}
@@ -473,15 +473,16 @@
for (auto it = supported_formats->cbegin(); it != supported_formats->cend();
++it) {
if (it->name == cricket::kH264CodecName) {
- const absl::optional<webrtc::H264::ProfileLevelId> profile_level_id =
- webrtc::H264::ParseSdpProfileLevelId(it->parameters);
- if (profile_level_id && profile_level_id->profile !=
- webrtc::H264::kProfileConstrainedBaseline) {
+ const absl::optional<webrtc::H264ProfileLevelId> profile_level_id =
+ webrtc::ParseSdpForH264ProfileLevelId(it->parameters);
+ if (profile_level_id &&
+ profile_level_id->profile !=
+ webrtc::H264Profile::kProfileConstrainedBaseline) {
webrtc::SdpVideoFormat cbp_format = *it;
- webrtc::H264::ProfileLevelId cbp_profile = *profile_level_id;
- cbp_profile.profile = webrtc::H264::kProfileConstrainedBaseline;
+ webrtc::H264ProfileLevelId cbp_profile = *profile_level_id;
+ cbp_profile.profile = webrtc::H264Profile::kProfileConstrainedBaseline;
cbp_format.parameters[cricket::kH264FmtpProfileLevelId] =
- *webrtc::H264::ProfileLevelIdToString(cbp_profile);
+ *webrtc::H264ProfileLevelIdToString(cbp_profile);
cbr_supported_formats.push_back(cbp_format);
}
}
diff --git a/media/base/codec_unittest.cc b/media/base/codec_unittest.cc
index d41ed9b..3586760 100644
--- a/media/base/codec_unittest.cc
+++ b/media/base/codec_unittest.cc
@@ -12,8 +12,8 @@
#include <tuple>
-#include "media/base/h264_profile_level_id.h"
-#include "media/base/vp9_profile.h"
+#include "api/video_codecs/h264_profile_level_id.h"
+#include "api/video_codecs/vp9_profile.h"
#include "modules/video_coding/codecs/h264/include/h264.h"
#include "rtc_base/gunit.h"
@@ -457,10 +457,10 @@
TEST(CodecTest, H264CostrainedBaselineIsAddedIfH264IsSupported) {
const std::vector<webrtc::SdpVideoFormat> kExplicitlySupportedFormats = {
- webrtc::CreateH264Format(webrtc::H264::kProfileBaseline,
- webrtc::H264::kLevel3_1, "1"),
- webrtc::CreateH264Format(webrtc::H264::kProfileBaseline,
- webrtc::H264::kLevel3_1, "0")};
+ webrtc::CreateH264Format(webrtc::H264Profile::kProfileBaseline,
+ webrtc::H264Level::kLevel3_1, "1"),
+ webrtc::CreateH264Format(webrtc::H264Profile::kProfileBaseline,
+ webrtc::H264Level::kLevel3_1, "0")};
std::vector<webrtc::SdpVideoFormat> supported_formats =
kExplicitlySupportedFormats;
@@ -468,11 +468,11 @@
&supported_formats);
const webrtc::SdpVideoFormat kH264ConstrainedBasedlinePacketization1 =
- webrtc::CreateH264Format(webrtc::H264::kProfileConstrainedBaseline,
- webrtc::H264::kLevel3_1, "1");
+ webrtc::CreateH264Format(webrtc::H264Profile::kProfileConstrainedBaseline,
+ webrtc::H264Level::kLevel3_1, "1");
const webrtc::SdpVideoFormat kH264ConstrainedBasedlinePacketization0 =
- webrtc::CreateH264Format(webrtc::H264::kProfileConstrainedBaseline,
- webrtc::H264::kLevel3_1, "0");
+ webrtc::CreateH264Format(webrtc::H264Profile::kProfileConstrainedBaseline,
+ webrtc::H264Level::kLevel3_1, "0");
EXPECT_EQ(supported_formats[0], kExplicitlySupportedFormats[0]);
EXPECT_EQ(supported_formats[1], kExplicitlySupportedFormats[1]);
@@ -497,14 +497,14 @@
TEST(CodecTest, H264CostrainedBaselineNotAddedIfAlreadySpecified) {
const std::vector<webrtc::SdpVideoFormat> kExplicitlySupportedFormats = {
- webrtc::CreateH264Format(webrtc::H264::kProfileBaseline,
- webrtc::H264::kLevel3_1, "1"),
- webrtc::CreateH264Format(webrtc::H264::kProfileBaseline,
- webrtc::H264::kLevel3_1, "0"),
- webrtc::CreateH264Format(webrtc::H264::kProfileConstrainedBaseline,
- webrtc::H264::kLevel3_1, "1"),
- webrtc::CreateH264Format(webrtc::H264::kProfileConstrainedBaseline,
- webrtc::H264::kLevel3_1, "0")};
+ webrtc::CreateH264Format(webrtc::H264Profile::kProfileBaseline,
+ webrtc::H264Level::kLevel3_1, "1"),
+ webrtc::CreateH264Format(webrtc::H264Profile::kProfileBaseline,
+ webrtc::H264Level::kLevel3_1, "0"),
+ webrtc::CreateH264Format(webrtc::H264Profile::kProfileConstrainedBaseline,
+ webrtc::H264Level::kLevel3_1, "1"),
+ webrtc::CreateH264Format(webrtc::H264Profile::kProfileConstrainedBaseline,
+ webrtc::H264Level::kLevel3_1, "0")};
std::vector<webrtc::SdpVideoFormat> supported_formats =
kExplicitlySupportedFormats;
diff --git a/media/base/h264_profile_level_id.cc b/media/base/h264_profile_level_id.cc
index 32fa02c..6f9fa46 100644
--- a/media/base/h264_profile_level_id.cc
+++ b/media/base/h264_profile_level_id.cc
@@ -10,301 +10,33 @@
#include "media/base/h264_profile_level_id.h"
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-
-#include "rtc_base/arraysize.h"
-#include "rtc_base/checks.h"
+// TODO(crbug.com/1187565): Remove this file once downstream projects stop
+// depend on it.
namespace webrtc {
namespace H264 {
-namespace {
-
-const char kProfileLevelId[] = "profile-level-id";
-const char kLevelAsymmetryAllowed[] = "level-asymmetry-allowed";
-
-// For level_idc=11 and profile_idc=0x42, 0x4D, or 0x58, the constraint set3
-// flag specifies if level 1b or level 1.1 is used.
-const uint8_t kConstraintSet3Flag = 0x10;
-
-// Convert a string of 8 characters into a byte where the positions containing
-// character c will have their bit set. For example, c = 'x', str = "x1xx0000"
-// will return 0b10110000. constexpr is used so that the pattern table in
-// kProfilePatterns is statically initialized.
-constexpr uint8_t ByteMaskString(char c, const char (&str)[9]) {
- return (str[0] == c) << 7 | (str[1] == c) << 6 | (str[2] == c) << 5 |
- (str[3] == c) << 4 | (str[4] == c) << 3 | (str[5] == c) << 2 |
- (str[6] == c) << 1 | (str[7] == c) << 0;
-}
-
-// Class for matching bit patterns such as "x1xx0000" where 'x' is allowed to be
-// either 0 or 1.
-class BitPattern {
- public:
- explicit constexpr BitPattern(const char (&str)[9])
- : mask_(~ByteMaskString('x', str)),
- masked_value_(ByteMaskString('1', str)) {}
-
- bool IsMatch(uint8_t value) const { return masked_value_ == (value & mask_); }
-
- private:
- const uint8_t mask_;
- const uint8_t masked_value_;
-};
-
-// Table for converting between profile_idc/profile_iop to H264::Profile.
-struct ProfilePattern {
- const uint8_t profile_idc;
- const BitPattern profile_iop;
- const Profile profile;
-};
-
-// This is from https://tools.ietf.org/html/rfc6184#section-8.1.
-constexpr ProfilePattern kProfilePatterns[] = {
- {0x42, BitPattern("x1xx0000"), kProfileConstrainedBaseline},
- {0x4D, BitPattern("1xxx0000"), kProfileConstrainedBaseline},
- {0x58, BitPattern("11xx0000"), kProfileConstrainedBaseline},
- {0x42, BitPattern("x0xx0000"), kProfileBaseline},
- {0x58, BitPattern("10xx0000"), kProfileBaseline},
- {0x4D, BitPattern("0x0x0000"), kProfileMain},
- {0x64, BitPattern("00000000"), kProfileHigh},
- {0x64, BitPattern("00001100"), kProfileConstrainedHigh}};
-
-// Compare H264 levels and handle the level 1b case.
-bool IsLess(Level a, Level b) {
- if (a == kLevel1_b)
- return b != kLevel1 && b != kLevel1_b;
- if (b == kLevel1_b)
- return a == kLevel1;
- return a < b;
-}
-
-Level Min(Level a, Level b) {
- return IsLess(a, b) ? a : b;
-}
-
-bool IsLevelAsymmetryAllowed(const CodecParameterMap& params) {
- const auto it = params.find(kLevelAsymmetryAllowed);
- return it != params.end() && strcmp(it->second.c_str(), "1") == 0;
-}
-
-struct LevelConstraint {
- const int max_macroblocks_per_second;
- const int max_macroblock_frame_size;
- const webrtc::H264::Level level;
-};
-
-// This is from ITU-T H.264 (02/2016) Table A-1 – Level limits.
-static constexpr LevelConstraint kLevelConstraints[] = {
- {1485, 99, webrtc::H264::kLevel1},
- {1485, 99, webrtc::H264::kLevel1_b},
- {3000, 396, webrtc::H264::kLevel1_1},
- {6000, 396, webrtc::H264::kLevel1_2},
- {11880, 396, webrtc::H264::kLevel1_3},
- {11880, 396, webrtc::H264::kLevel2},
- {19800, 792, webrtc::H264::kLevel2_1},
- {20250, 1620, webrtc::H264::kLevel2_2},
- {40500, 1620, webrtc::H264::kLevel3},
- {108000, 3600, webrtc::H264::kLevel3_1},
- {216000, 5120, webrtc::H264::kLevel3_2},
- {245760, 8192, webrtc::H264::kLevel4},
- {245760, 8192, webrtc::H264::kLevel4_1},
- {522240, 8704, webrtc::H264::kLevel4_2},
- {589824, 22080, webrtc::H264::kLevel5},
- {983040, 36864, webrtc::H264::kLevel5_1},
- {2073600, 36864, webrtc::H264::kLevel5_2},
-};
-
-} // anonymous namespace
-
absl::optional<ProfileLevelId> ParseProfileLevelId(const char* str) {
- // The string should consist of 3 bytes in hexadecimal format.
- if (strlen(str) != 6u)
- return absl::nullopt;
- const uint32_t profile_level_id_numeric = strtol(str, nullptr, 16);
- if (profile_level_id_numeric == 0)
- return absl::nullopt;
-
- // Separate into three bytes.
- const uint8_t level_idc =
- static_cast<uint8_t>(profile_level_id_numeric & 0xFF);
- const uint8_t profile_iop =
- static_cast<uint8_t>((profile_level_id_numeric >> 8) & 0xFF);
- const uint8_t profile_idc =
- static_cast<uint8_t>((profile_level_id_numeric >> 16) & 0xFF);
-
- // Parse level based on level_idc and constraint set 3 flag.
- Level level;
- switch (level_idc) {
- case kLevel1_1:
- level = (profile_iop & kConstraintSet3Flag) != 0 ? kLevel1_b : kLevel1_1;
- break;
- case kLevel1:
- case kLevel1_2:
- case kLevel1_3:
- case kLevel2:
- case kLevel2_1:
- case kLevel2_2:
- case kLevel3:
- case kLevel3_1:
- case kLevel3_2:
- case kLevel4:
- case kLevel4_1:
- case kLevel4_2:
- case kLevel5:
- case kLevel5_1:
- case kLevel5_2:
- level = static_cast<Level>(level_idc);
- break;
- default:
- // Unrecognized level_idc.
- return absl::nullopt;
- }
-
- // Parse profile_idc/profile_iop into a Profile enum.
- for (const ProfilePattern& pattern : kProfilePatterns) {
- if (profile_idc == pattern.profile_idc &&
- pattern.profile_iop.IsMatch(profile_iop)) {
- return ProfileLevelId(pattern.profile, level);
- }
- }
-
- // Unrecognized profile_idc/profile_iop combination.
- return absl::nullopt;
-}
-
-absl::optional<Level> SupportedLevel(int max_frame_pixel_count, float max_fps) {
- static const int kPixelsPerMacroblock = 16 * 16;
-
- for (int i = arraysize(kLevelConstraints) - 1; i >= 0; --i) {
- const LevelConstraint& level_constraint = kLevelConstraints[i];
- if (level_constraint.max_macroblock_frame_size * kPixelsPerMacroblock <=
- max_frame_pixel_count &&
- level_constraint.max_macroblocks_per_second <=
- max_fps * level_constraint.max_macroblock_frame_size) {
- return level_constraint.level;
- }
- }
-
- // No level supported.
- return absl::nullopt;
+ return webrtc::ParseH264ProfileLevelId(str);
}
absl::optional<ProfileLevelId> ParseSdpProfileLevelId(
- const CodecParameterMap& params) {
- // TODO(magjed): The default should really be kProfileBaseline and kLevel1
- // according to the spec: https://tools.ietf.org/html/rfc6184#section-8.1. In
- // order to not break backwards compatibility with older versions of WebRTC
- // where external codecs don't have any parameters, use
- // kProfileConstrainedBaseline kLevel3_1 instead. This workaround will only be
- // done in an interim period to allow external clients to update their code.
- // http://crbug/webrtc/6337.
- static const ProfileLevelId kDefaultProfileLevelId(
- kProfileConstrainedBaseline, kLevel3_1);
+ const SdpVideoFormat::Parameters& params) {
+ return webrtc::ParseSdpForH264ProfileLevelId(params);
+}
- const auto profile_level_id_it = params.find(kProfileLevelId);
- return (profile_level_id_it == params.end())
- ? kDefaultProfileLevelId
- : ParseProfileLevelId(profile_level_id_it->second.c_str());
+absl::optional<Level> SupportedLevel(int max_frame_pixel_count, float max_fps) {
+ return webrtc::H264SupportedLevel(max_frame_pixel_count, max_fps);
}
absl::optional<std::string> ProfileLevelIdToString(
const ProfileLevelId& profile_level_id) {
- // Handle special case level == 1b.
- if (profile_level_id.level == kLevel1_b) {
- switch (profile_level_id.profile) {
- case kProfileConstrainedBaseline:
- return {"42f00b"};
- case kProfileBaseline:
- return {"42100b"};
- case kProfileMain:
- return {"4d100b"};
- // Level 1b is not allowed for other profiles.
- default:
- return absl::nullopt;
- }
- }
-
- const char* profile_idc_iop_string;
- switch (profile_level_id.profile) {
- case kProfileConstrainedBaseline:
- profile_idc_iop_string = "42e0";
- break;
- case kProfileBaseline:
- profile_idc_iop_string = "4200";
- break;
- case kProfileMain:
- profile_idc_iop_string = "4d00";
- break;
- case kProfileConstrainedHigh:
- profile_idc_iop_string = "640c";
- break;
- case kProfileHigh:
- profile_idc_iop_string = "6400";
- break;
- // Unrecognized profile.
- default:
- return absl::nullopt;
- }
-
- char str[7];
- snprintf(str, 7u, "%s%02x", profile_idc_iop_string, profile_level_id.level);
- return {str};
+ return webrtc::H264ProfileLevelIdToString(profile_level_id);
}
-// Set level according to https://tools.ietf.org/html/rfc6184#section-8.2.2.
-void GenerateProfileLevelIdForAnswer(
- const CodecParameterMap& local_supported_params,
- const CodecParameterMap& remote_offered_params,
- CodecParameterMap* answer_params) {
- // If both local and remote haven't set profile-level-id, they are both using
- // the default profile. In this case, don't set profile-level-id in answer
- // either.
- if (!local_supported_params.count(kProfileLevelId) &&
- !remote_offered_params.count(kProfileLevelId)) {
- return;
- }
-
- // Parse profile-level-ids.
- const absl::optional<ProfileLevelId> local_profile_level_id =
- ParseSdpProfileLevelId(local_supported_params);
- const absl::optional<ProfileLevelId> remote_profile_level_id =
- ParseSdpProfileLevelId(remote_offered_params);
- // The local and remote codec must have valid and equal H264 Profiles.
- RTC_DCHECK(local_profile_level_id);
- RTC_DCHECK(remote_profile_level_id);
- RTC_DCHECK_EQ(local_profile_level_id->profile,
- remote_profile_level_id->profile);
-
- // Parse level information.
- const bool level_asymmetry_allowed =
- IsLevelAsymmetryAllowed(local_supported_params) &&
- IsLevelAsymmetryAllowed(remote_offered_params);
- const Level local_level = local_profile_level_id->level;
- const Level remote_level = remote_profile_level_id->level;
- const Level min_level = Min(local_level, remote_level);
-
- // Determine answer level. When level asymmetry is not allowed, level upgrade
- // is not allowed, i.e., the level in the answer must be equal to or lower
- // than the level in the offer.
- const Level answer_level = level_asymmetry_allowed ? local_level : min_level;
-
- // Set the resulting profile-level-id in the answer parameters.
- (*answer_params)[kProfileLevelId] = *ProfileLevelIdToString(
- ProfileLevelId(local_profile_level_id->profile, answer_level));
-}
-
-bool IsSameH264Profile(const CodecParameterMap& params1,
- const CodecParameterMap& params2) {
- const absl::optional<webrtc::H264::ProfileLevelId> profile_level_id =
- webrtc::H264::ParseSdpProfileLevelId(params1);
- const absl::optional<webrtc::H264::ProfileLevelId> other_profile_level_id =
- webrtc::H264::ParseSdpProfileLevelId(params2);
- // Compare H264 profiles, but not levels.
- return profile_level_id && other_profile_level_id &&
- profile_level_id->profile == other_profile_level_id->profile;
+bool IsSameH264Profile(const SdpVideoFormat::Parameters& params1,
+ const SdpVideoFormat::Parameters& params2) {
+ return webrtc::H264IsSameProfile(params1, params2);
}
} // namespace H264
diff --git a/media/base/h264_profile_level_id.h b/media/base/h264_profile_level_id.h
index f0f7928..c85709f 100644
--- a/media/base/h264_profile_level_id.h
+++ b/media/base/h264_profile_level_id.h
@@ -11,54 +11,45 @@
#ifndef MEDIA_BASE_H264_PROFILE_LEVEL_ID_H_
#define MEDIA_BASE_H264_PROFILE_LEVEL_ID_H_
-#include <map>
#include <string>
-#include "absl/types/optional.h"
-#include "rtc_base/system/rtc_export.h"
+#include "api/video_codecs/h264_profile_level_id.h"
+
+// TODO(crbug.com/1187565): Remove this file once downstream projects stop
+// depend on it.
namespace webrtc {
namespace H264 {
-enum Profile {
- kProfileConstrainedBaseline,
- kProfileBaseline,
- kProfileMain,
- kProfileConstrainedHigh,
- kProfileHigh,
-};
+typedef H264Profile Profile;
+typedef H264Level Level;
+typedef H264ProfileLevelId ProfileLevelId;
-// Map containting SDP codec parameters.
-typedef std::map<std::string, std::string> CodecParameterMap;
+constexpr H264Profile kProfileConstrainedBaseline =
+ H264Profile::kProfileConstrainedBaseline;
+constexpr H264Profile kProfileBaseline = H264Profile::kProfileBaseline;
+constexpr H264Profile kProfileMain = H264Profile::kProfileMain;
+constexpr H264Profile kProfileConstrainedHigh =
+ H264Profile::kProfileConstrainedHigh;
+constexpr H264Profile kProfileHigh = H264Profile::kProfileHigh;
-// All values are equal to ten times the level number, except level 1b which is
-// special.
-enum Level {
- kLevel1_b = 0,
- kLevel1 = 10,
- kLevel1_1 = 11,
- kLevel1_2 = 12,
- kLevel1_3 = 13,
- kLevel2 = 20,
- kLevel2_1 = 21,
- kLevel2_2 = 22,
- kLevel3 = 30,
- kLevel3_1 = 31,
- kLevel3_2 = 32,
- kLevel4 = 40,
- kLevel4_1 = 41,
- kLevel4_2 = 42,
- kLevel5 = 50,
- kLevel5_1 = 51,
- kLevel5_2 = 52
-};
-
-struct ProfileLevelId {
- constexpr ProfileLevelId(Profile profile, Level level)
- : profile(profile), level(level) {}
- Profile profile;
- Level level;
-};
+constexpr H264Level kLevel1_b = H264Level::kLevel1_b;
+constexpr H264Level kLevel1 = H264Level::kLevel1;
+constexpr H264Level kLevel1_1 = H264Level::kLevel1_1;
+constexpr H264Level kLevel1_2 = H264Level::kLevel1_2;
+constexpr H264Level kLevel1_3 = H264Level::kLevel1_3;
+constexpr H264Level kLevel2 = H264Level::kLevel2;
+constexpr H264Level kLevel2_1 = H264Level::kLevel2_1;
+constexpr H264Level kLevel2_2 = H264Level::kLevel2_2;
+constexpr H264Level kLevel3 = H264Level::kLevel3;
+constexpr H264Level kLevel3_1 = H264Level::kLevel3_1;
+constexpr H264Level kLevel3_2 = H264Level::kLevel3_2;
+constexpr H264Level kLevel4 = H264Level::kLevel4;
+constexpr H264Level kLevel4_1 = H264Level::kLevel4_1;
+constexpr H264Level kLevel4_2 = H264Level::kLevel4_2;
+constexpr H264Level kLevel5 = H264Level::kLevel5;
+constexpr H264Level kLevel5_1 = H264Level::kLevel5_1;
+constexpr H264Level kLevel5_2 = H264Level::kLevel5_2;
// Parse profile level id that is represented as a string of 3 hex bytes.
// Nothing will be returned if the string is not a recognized H264
@@ -70,7 +61,7 @@
// returned if the profile-level-id key is missing. Nothing will be returned if
// the key is present but the string is invalid.
RTC_EXPORT absl::optional<ProfileLevelId> ParseSdpProfileLevelId(
- const CodecParameterMap& params);
+ const SdpVideoFormat::Parameters& params);
// Given that a decoder supports up to a given frame size (in pixels) at up to a
// given number of frames per second, return the highest H.264 level where it
@@ -84,33 +75,11 @@
RTC_EXPORT absl::optional<std::string> ProfileLevelIdToString(
const ProfileLevelId& profile_level_id);
-// Generate codec parameters that will be used as answer in an SDP negotiation
-// based on local supported parameters and remote offered parameters. Both
-// |local_supported_params|, |remote_offered_params|, and |answer_params|
-// represent sendrecv media descriptions, i.e they are a mix of both encode and
-// decode capabilities. In theory, when the profile in |local_supported_params|
-// represent a strict superset of the profile in |remote_offered_params|, we
-// could limit the profile in |answer_params| to the profile in
-// |remote_offered_params|. However, to simplify the code, each supported H264
-// profile should be listed explicitly in the list of local supported codecs,
-// even if they are redundant. Then each local codec in the list should be
-// tested one at a time against the remote codec, and only when the profiles are
-// equal should this function be called. Therefore, this function does not need
-// to handle profile intersection, and the profile of |local_supported_params|
-// and |remote_offered_params| must be equal before calling this function. The
-// parameters that are used when negotiating are the level part of
-// profile-level-id and level-asymmetry-allowed.
-void GenerateProfileLevelIdForAnswer(
- const CodecParameterMap& local_supported_params,
- const CodecParameterMap& remote_offered_params,
- CodecParameterMap* answer_params);
-
// Returns true if the parameters have the same H264 profile, i.e. the same
// H264::Profile (Baseline, High, etc).
-bool IsSameH264Profile(const CodecParameterMap& params1,
- const CodecParameterMap& params2);
+RTC_EXPORT bool IsSameH264Profile(const SdpVideoFormat::Parameters& params1,
+ const SdpVideoFormat::Parameters& params2);
} // namespace H264
} // namespace webrtc
-
#endif // MEDIA_BASE_H264_PROFILE_LEVEL_ID_H_
diff --git a/media/base/sdp_fmtp_utils.cc b/media/base/sdp_fmtp_utils.cc
deleted file mode 100644
index 4ffc3b9..0000000
--- a/media/base/sdp_fmtp_utils.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2019 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 "media/base/sdp_fmtp_utils.h"
-
-#include <map>
-#include <utility>
-
-#include "rtc_base/string_to_number.h"
-
-namespace webrtc {
-namespace {
-// Max frame rate for VP8 and VP9 video.
-const char kVPxFmtpMaxFrameRate[] = "max-fr";
-// Max frame size for VP8 and VP9 video.
-const char kVPxFmtpMaxFrameSize[] = "max-fs";
-const int kVPxFmtpFrameSizeSubBlockPixels = 256;
-
-absl::optional<int> ParsePositiveNumberFromParams(
- const SdpVideoFormat::Parameters& params,
- const char* parameter_name) {
- const auto max_frame_rate_it = params.find(parameter_name);
- if (max_frame_rate_it == params.end())
- return absl::nullopt;
-
- const absl::optional<int> i =
- rtc::StringToNumber<int>(max_frame_rate_it->second);
- if (!i.has_value() || i.value() <= 0)
- return absl::nullopt;
- return i;
-}
-
-} // namespace
-
-absl::optional<int> ParseSdpForVPxMaxFrameRate(
- const SdpVideoFormat::Parameters& params) {
- return ParsePositiveNumberFromParams(params, kVPxFmtpMaxFrameRate);
-}
-
-absl::optional<int> ParseSdpForVPxMaxFrameSize(
- const SdpVideoFormat::Parameters& params) {
- const absl::optional<int> i =
- ParsePositiveNumberFromParams(params, kVPxFmtpMaxFrameSize);
- return i ? absl::make_optional(i.value() * kVPxFmtpFrameSizeSubBlockPixels)
- : absl::nullopt;
-}
-
-} // namespace webrtc
diff --git a/media/base/sdp_fmtp_utils.h b/media/base/sdp_fmtp_utils.h
deleted file mode 100644
index 04e9183..0000000
--- a/media/base/sdp_fmtp_utils.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2019 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 MEDIA_BASE_SDP_FMTP_UTILS_H_
-#define MEDIA_BASE_SDP_FMTP_UTILS_H_
-
-#include "absl/types/optional.h"
-#include "api/video_codecs/sdp_video_format.h"
-
-namespace webrtc {
-
-// Parse max frame rate from SDP FMTP line. absl::nullopt is returned if the
-// field is missing or not a number.
-absl::optional<int> ParseSdpForVPxMaxFrameRate(
- const SdpVideoFormat::Parameters& params);
-
-// Parse max frame size from SDP FMTP line. absl::nullopt is returned if the
-// field is missing or not a number. Please note that the value is stored in sub
-// blocks but the returned value is in total number of pixels.
-absl::optional<int> ParseSdpForVPxMaxFrameSize(
- const SdpVideoFormat::Parameters& params);
-
-} // namespace webrtc
-
-#endif // MEDIA_BASE_SDP_FMTP_UTILS_H__
diff --git a/media/base/sdp_fmtp_utils_unittest.cc b/media/base/sdp_fmtp_utils_unittest.cc
deleted file mode 100644
index 0ff12ff..0000000
--- a/media/base/sdp_fmtp_utils_unittest.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2019 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 "media/base/sdp_fmtp_utils.h"
-
-#include <string.h>
-#include <map>
-#include <utility>
-
-#include "rtc_base/string_to_number.h"
-#include "test/gtest.h"
-
-namespace webrtc {
-namespace {
-// Max frame rate for VP8 and VP9 video.
-const char kVPxFmtpMaxFrameRate[] = "max-fr";
-// Max frame size for VP8 and VP9 video.
-const char kVPxFmtpMaxFrameSize[] = "max-fs";
-} // namespace
-
-TEST(SdpFmtpUtilsTest, MaxFrameRateIsMissingOrInvalid) {
- SdpVideoFormat::Parameters params;
- absl::optional<int> empty = ParseSdpForVPxMaxFrameRate(params);
- EXPECT_FALSE(empty);
- params[kVPxFmtpMaxFrameRate] = "-1";
- EXPECT_FALSE(ParseSdpForVPxMaxFrameRate(params));
- params[kVPxFmtpMaxFrameRate] = "0";
- EXPECT_FALSE(ParseSdpForVPxMaxFrameRate(params));
- params[kVPxFmtpMaxFrameRate] = "abcde";
- EXPECT_FALSE(ParseSdpForVPxMaxFrameRate(params));
-}
-
-TEST(SdpFmtpUtilsTest, MaxFrameRateIsSpecified) {
- SdpVideoFormat::Parameters params;
- params[kVPxFmtpMaxFrameRate] = "30";
- EXPECT_EQ(ParseSdpForVPxMaxFrameRate(params), 30);
- params[kVPxFmtpMaxFrameRate] = "60";
- EXPECT_EQ(ParseSdpForVPxMaxFrameRate(params), 60);
-}
-
-TEST(SdpFmtpUtilsTest, MaxFrameSizeIsMissingOrInvalid) {
- SdpVideoFormat::Parameters params;
- absl::optional<int> empty = ParseSdpForVPxMaxFrameSize(params);
- EXPECT_FALSE(empty);
- params[kVPxFmtpMaxFrameSize] = "-1";
- EXPECT_FALSE(ParseSdpForVPxMaxFrameSize(params));
- params[kVPxFmtpMaxFrameSize] = "0";
- EXPECT_FALSE(ParseSdpForVPxMaxFrameSize(params));
- params[kVPxFmtpMaxFrameSize] = "abcde";
- EXPECT_FALSE(ParseSdpForVPxMaxFrameSize(params));
-}
-
-TEST(SdpFmtpUtilsTest, MaxFrameSizeIsSpecified) {
- SdpVideoFormat::Parameters params;
- params[kVPxFmtpMaxFrameSize] = "8100"; // 1920 x 1080 / (16^2)
- EXPECT_EQ(ParseSdpForVPxMaxFrameSize(params), 1920 * 1080);
- params[kVPxFmtpMaxFrameSize] = "32400"; // 3840 x 2160 / (16^2)
- EXPECT_EQ(ParseSdpForVPxMaxFrameSize(params), 3840 * 2160);
-}
-
-} // namespace webrtc
diff --git a/media/base/sdp_video_format_utils.cc b/media/base/sdp_video_format_utils.cc
new file mode 100644
index 0000000..a156afd
--- /dev/null
+++ b/media/base/sdp_video_format_utils.cc
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2019 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 "media/base/sdp_video_format_utils.h"
+
+#include <cstring>
+#include <map>
+#include <utility>
+
+#include "api/video_codecs/h264_profile_level_id.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/string_to_number.h"
+
+namespace webrtc {
+namespace {
+const char kProfileLevelId[] = "profile-level-id";
+const char kH264LevelAsymmetryAllowed[] = "level-asymmetry-allowed";
+// Max frame rate for VP8 and VP9 video.
+const char kVPxFmtpMaxFrameRate[] = "max-fr";
+// Max frame size for VP8 and VP9 video.
+const char kVPxFmtpMaxFrameSize[] = "max-fs";
+const int kVPxFmtpFrameSizeSubBlockPixels = 256;
+
+bool IsH264LevelAsymmetryAllowed(const SdpVideoFormat::Parameters& params) {
+ const auto it = params.find(kH264LevelAsymmetryAllowed);
+ return it != params.end() && strcmp(it->second.c_str(), "1") == 0;
+}
+
+// Compare H264 levels and handle the level 1b case.
+bool H264LevelIsLess(H264Level a, H264Level b) {
+ if (a == H264Level::kLevel1_b)
+ return b != H264Level::kLevel1 && b != H264Level::kLevel1_b;
+ if (b == H264Level::kLevel1_b)
+ return a == H264Level::kLevel1;
+ return a < b;
+}
+
+H264Level H264LevelMin(H264Level a, H264Level b) {
+ return H264LevelIsLess(a, b) ? a : b;
+}
+
+absl::optional<int> ParsePositiveNumberFromParams(
+ const SdpVideoFormat::Parameters& params,
+ const char* parameter_name) {
+ const auto max_frame_rate_it = params.find(parameter_name);
+ if (max_frame_rate_it == params.end())
+ return absl::nullopt;
+
+ const absl::optional<int> i =
+ rtc::StringToNumber<int>(max_frame_rate_it->second);
+ if (!i.has_value() || i.value() <= 0)
+ return absl::nullopt;
+ return i;
+}
+
+} // namespace
+
+// Set level according to https://tools.ietf.org/html/rfc6184#section-8.2.2.
+void H264GenerateProfileLevelIdForAnswer(
+ const SdpVideoFormat::Parameters& local_supported_params,
+ const SdpVideoFormat::Parameters& remote_offered_params,
+ SdpVideoFormat::Parameters* answer_params) {
+ // If both local and remote haven't set profile-level-id, they are both using
+ // the default profile. In this case, don't set profile-level-id in answer
+ // either.
+ if (!local_supported_params.count(kProfileLevelId) &&
+ !remote_offered_params.count(kProfileLevelId)) {
+ return;
+ }
+
+ // Parse profile-level-ids.
+ const absl::optional<H264ProfileLevelId> local_profile_level_id =
+ ParseSdpForH264ProfileLevelId(local_supported_params);
+ const absl::optional<H264ProfileLevelId> remote_profile_level_id =
+ ParseSdpForH264ProfileLevelId(remote_offered_params);
+ // The local and remote codec must have valid and equal H264 Profiles.
+ RTC_DCHECK(local_profile_level_id);
+ RTC_DCHECK(remote_profile_level_id);
+ RTC_DCHECK_EQ(local_profile_level_id->profile,
+ remote_profile_level_id->profile);
+
+ // Parse level information.
+ const bool level_asymmetry_allowed =
+ IsH264LevelAsymmetryAllowed(local_supported_params) &&
+ IsH264LevelAsymmetryAllowed(remote_offered_params);
+ const H264Level local_level = local_profile_level_id->level;
+ const H264Level remote_level = remote_profile_level_id->level;
+ const H264Level min_level = H264LevelMin(local_level, remote_level);
+
+ // Determine answer level. When level asymmetry is not allowed, level upgrade
+ // is not allowed, i.e., the level in the answer must be equal to or lower
+ // than the level in the offer.
+ const H264Level answer_level =
+ level_asymmetry_allowed ? local_level : min_level;
+
+ // Set the resulting profile-level-id in the answer parameters.
+ (*answer_params)[kProfileLevelId] = *H264ProfileLevelIdToString(
+ H264ProfileLevelId(local_profile_level_id->profile, answer_level));
+}
+
+absl::optional<int> ParseSdpForVPxMaxFrameRate(
+ const SdpVideoFormat::Parameters& params) {
+ return ParsePositiveNumberFromParams(params, kVPxFmtpMaxFrameRate);
+}
+
+absl::optional<int> ParseSdpForVPxMaxFrameSize(
+ const SdpVideoFormat::Parameters& params) {
+ const absl::optional<int> i =
+ ParsePositiveNumberFromParams(params, kVPxFmtpMaxFrameSize);
+ return i ? absl::make_optional(i.value() * kVPxFmtpFrameSizeSubBlockPixels)
+ : absl::nullopt;
+}
+
+} // namespace webrtc
diff --git a/media/base/sdp_video_format_utils.h b/media/base/sdp_video_format_utils.h
new file mode 100644
index 0000000..6671c18
--- /dev/null
+++ b/media/base/sdp_video_format_utils.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2019 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 MEDIA_BASE_SDP_VIDEO_FORMAT_UTILS_H_
+#define MEDIA_BASE_SDP_VIDEO_FORMAT_UTILS_H_
+
+#include "absl/types/optional.h"
+#include "api/video_codecs/sdp_video_format.h"
+
+namespace webrtc {
+// Generate codec parameters that will be used as answer in an SDP negotiation
+// based on local supported parameters and remote offered parameters. Both
+// |local_supported_params|, |remote_offered_params|, and |answer_params|
+// represent sendrecv media descriptions, i.e they are a mix of both encode and
+// decode capabilities. In theory, when the profile in |local_supported_params|
+// represent a strict superset of the profile in |remote_offered_params|, we
+// could limit the profile in |answer_params| to the profile in
+// |remote_offered_params|. However, to simplify the code, each supported H264
+// profile should be listed explicitly in the list of local supported codecs,
+// even if they are redundant. Then each local codec in the list should be
+// tested one at a time against the remote codec, and only when the profiles are
+// equal should this function be called. Therefore, this function does not need
+// to handle profile intersection, and the profile of |local_supported_params|
+// and |remote_offered_params| must be equal before calling this function. The
+// parameters that are used when negotiating are the level part of
+// profile-level-id and level-asymmetry-allowed.
+void H264GenerateProfileLevelIdForAnswer(
+ const SdpVideoFormat::Parameters& local_supported_params,
+ const SdpVideoFormat::Parameters& remote_offered_params,
+ SdpVideoFormat::Parameters* answer_params);
+
+// Parse max frame rate from SDP FMTP line. absl::nullopt is returned if the
+// field is missing or not a number.
+absl::optional<int> ParseSdpForVPxMaxFrameRate(
+ const SdpVideoFormat::Parameters& params);
+
+// Parse max frame size from SDP FMTP line. absl::nullopt is returned if the
+// field is missing or not a number. Please note that the value is stored in sub
+// blocks but the returned value is in total number of pixels.
+absl::optional<int> ParseSdpForVPxMaxFrameSize(
+ const SdpVideoFormat::Parameters& params);
+
+} // namespace webrtc
+
+#endif // MEDIA_BASE_SDP_VIDEO_FORMAT_UTILS_H_
diff --git a/media/base/sdp_video_format_utils_unittest.cc b/media/base/sdp_video_format_utils_unittest.cc
new file mode 100644
index 0000000..d8ef9ab
--- /dev/null
+++ b/media/base/sdp_video_format_utils_unittest.cc
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2019 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 "media/base/sdp_video_format_utils.h"
+
+#include <string.h>
+
+#include <map>
+#include <utility>
+
+#include "rtc_base/string_to_number.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace {
+// Max frame rate for VP8 and VP9 video.
+const char kVPxFmtpMaxFrameRate[] = "max-fr";
+// Max frame size for VP8 and VP9 video.
+const char kVPxFmtpMaxFrameSize[] = "max-fs";
+} // namespace
+
+TEST(SdpVideoFormatUtilsTest, TestH264GenerateProfileLevelIdForAnswerEmpty) {
+ SdpVideoFormat::Parameters answer_params;
+ H264GenerateProfileLevelIdForAnswer(SdpVideoFormat::Parameters(),
+ SdpVideoFormat::Parameters(),
+ &answer_params);
+ EXPECT_TRUE(answer_params.empty());
+}
+
+TEST(SdpVideoFormatUtilsTest,
+ TestH264GenerateProfileLevelIdForAnswerLevelSymmetryCapped) {
+ SdpVideoFormat::Parameters low_level;
+ low_level["profile-level-id"] = "42e015";
+ SdpVideoFormat::Parameters high_level;
+ high_level["profile-level-id"] = "42e01f";
+
+ // Level asymmetry is not allowed; test that answer level is the lower of the
+ // local and remote levels.
+ SdpVideoFormat::Parameters answer_params;
+ H264GenerateProfileLevelIdForAnswer(low_level /* local_supported */,
+ high_level /* remote_offered */,
+ &answer_params);
+ EXPECT_EQ("42e015", answer_params["profile-level-id"]);
+
+ SdpVideoFormat::Parameters answer_params2;
+ H264GenerateProfileLevelIdForAnswer(high_level /* local_supported */,
+ low_level /* remote_offered */,
+ &answer_params2);
+ EXPECT_EQ("42e015", answer_params2["profile-level-id"]);
+}
+
+TEST(SdpVideoFormatUtilsTest,
+ TestH264GenerateProfileLevelIdForAnswerConstrainedBaselineLevelAsymmetry) {
+ SdpVideoFormat::Parameters local_params;
+ local_params["profile-level-id"] = "42e01f";
+ local_params["level-asymmetry-allowed"] = "1";
+ SdpVideoFormat::Parameters remote_params;
+ remote_params["profile-level-id"] = "42e015";
+ remote_params["level-asymmetry-allowed"] = "1";
+ SdpVideoFormat::Parameters answer_params;
+ H264GenerateProfileLevelIdForAnswer(local_params, remote_params,
+ &answer_params);
+ // When level asymmetry is allowed, we can answer a higher level than what was
+ // offered.
+ EXPECT_EQ("42e01f", answer_params["profile-level-id"]);
+}
+
+TEST(SdpVideoFormatUtilsTest, MaxFrameRateIsMissingOrInvalid) {
+ SdpVideoFormat::Parameters params;
+ absl::optional<int> empty = ParseSdpForVPxMaxFrameRate(params);
+ EXPECT_FALSE(empty);
+ params[kVPxFmtpMaxFrameRate] = "-1";
+ EXPECT_FALSE(ParseSdpForVPxMaxFrameRate(params));
+ params[kVPxFmtpMaxFrameRate] = "0";
+ EXPECT_FALSE(ParseSdpForVPxMaxFrameRate(params));
+ params[kVPxFmtpMaxFrameRate] = "abcde";
+ EXPECT_FALSE(ParseSdpForVPxMaxFrameRate(params));
+}
+
+TEST(SdpVideoFormatUtilsTest, MaxFrameRateIsSpecified) {
+ SdpVideoFormat::Parameters params;
+ params[kVPxFmtpMaxFrameRate] = "30";
+ EXPECT_EQ(ParseSdpForVPxMaxFrameRate(params), 30);
+ params[kVPxFmtpMaxFrameRate] = "60";
+ EXPECT_EQ(ParseSdpForVPxMaxFrameRate(params), 60);
+}
+
+TEST(SdpVideoFormatUtilsTest, MaxFrameSizeIsMissingOrInvalid) {
+ SdpVideoFormat::Parameters params;
+ absl::optional<int> empty = ParseSdpForVPxMaxFrameSize(params);
+ EXPECT_FALSE(empty);
+ params[kVPxFmtpMaxFrameSize] = "-1";
+ EXPECT_FALSE(ParseSdpForVPxMaxFrameSize(params));
+ params[kVPxFmtpMaxFrameSize] = "0";
+ EXPECT_FALSE(ParseSdpForVPxMaxFrameSize(params));
+ params[kVPxFmtpMaxFrameSize] = "abcde";
+ EXPECT_FALSE(ParseSdpForVPxMaxFrameSize(params));
+}
+
+TEST(SdpVideoFormatUtilsTest, MaxFrameSizeIsSpecified) {
+ SdpVideoFormat::Parameters params;
+ params[kVPxFmtpMaxFrameSize] = "8100"; // 1920 x 1080 / (16^2)
+ EXPECT_EQ(ParseSdpForVPxMaxFrameSize(params), 1920 * 1080);
+ params[kVPxFmtpMaxFrameSize] = "32400"; // 3840 x 2160 / (16^2)
+ EXPECT_EQ(ParseSdpForVPxMaxFrameSize(params), 3840 * 2160);
+}
+
+} // namespace webrtc
diff --git a/media/base/vp9_profile.h b/media/base/vp9_profile.h
index e47204f..d44a799 100644
--- a/media/base/vp9_profile.h
+++ b/media/base/vp9_profile.h
@@ -11,43 +11,9 @@
#ifndef MEDIA_BASE_VP9_PROFILE_H_
#define MEDIA_BASE_VP9_PROFILE_H_
-#include <string>
+#include "api/video_codecs/vp9_profile.h"
-#include "absl/types/optional.h"
-#include "api/video_codecs/sdp_video_format.h"
-#include "rtc_base/system/rtc_export.h"
-
-namespace webrtc {
-
-// Profile information for VP9 video.
-extern RTC_EXPORT const char kVP9FmtpProfileId[];
-
-enum class VP9Profile {
- kProfile0,
- kProfile1,
- kProfile2,
-};
-
-// Helper functions to convert VP9Profile to std::string. Returns "0" by
-// default.
-RTC_EXPORT std::string VP9ProfileToString(VP9Profile profile);
-
-// Helper functions to convert std::string to VP9Profile. Returns null if given
-// an invalid profile string.
-absl::optional<VP9Profile> StringToVP9Profile(const std::string& str);
-
-// Parse profile that is represented as a string of single digit contained in an
-// SDP key-value map. A default profile(kProfile0) will be returned if the
-// profile key is missing. Nothing will be returned if the key is present but
-// the string is invalid.
-RTC_EXPORT absl::optional<VP9Profile> ParseSdpForVP9Profile(
- const SdpVideoFormat::Parameters& params);
-
-// Returns true if the parameters have the same VP9 profile, or neither contains
-// VP9 profile.
-bool IsSameVP9Profile(const SdpVideoFormat::Parameters& params1,
- const SdpVideoFormat::Parameters& params2);
-
-} // namespace webrtc
+// TODO(crbug.com/1187565): Remove this file once downstream projects stop
+// depend on it.
#endif // MEDIA_BASE_VP9_PROFILE_H_
diff --git a/media/engine/internal_decoder_factory_unittest.cc b/media/engine/internal_decoder_factory_unittest.cc
index 61be5e7..a2a6921 100644
--- a/media/engine/internal_decoder_factory_unittest.cc
+++ b/media/engine/internal_decoder_factory_unittest.cc
@@ -12,8 +12,8 @@
#include "api/video_codecs/sdp_video_format.h"
#include "api/video_codecs/video_decoder.h"
+#include "api/video_codecs/vp9_profile.h"
#include "media/base/media_constants.h"
-#include "media/base/vp9_profile.h"
#include "modules/video_coding/codecs/av1/libaom_av1_decoder.h"
#include "test/gmock.h"
#include "test/gtest.h"
diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc
index 2fcebe4..4270e27 100644
--- a/media/engine/webrtc_video_engine_unittest.cc
+++ b/media/engine/webrtc_video_engine_unittest.cc
@@ -35,12 +35,12 @@
#include "api/video/video_bitrate_allocation.h"
#include "api/video_codecs/builtin_video_decoder_factory.h"
#include "api/video_codecs/builtin_video_encoder_factory.h"
+#include "api/video_codecs/h264_profile_level_id.h"
#include "api/video_codecs/sdp_video_format.h"
#include "api/video_codecs/video_decoder_factory.h"
#include "api/video_codecs/video_encoder.h"
#include "api/video_codecs/video_encoder_factory.h"
#include "call/flexfec_receive_stream.h"
-#include "common_video/h264/profile_level_id.h"
#include "media/base/fake_frame_source.h"
#include "media/base/fake_network_interface.h"
#include "media/base/fake_video_renderer.h"
@@ -581,20 +581,21 @@
// TODO(deadbeef): This test should be updated if/when we start
// adding RTX codecs for unrecognized codec names.
TEST_F(WebRtcVideoEngineTest, RtxCodecAddedForH264Codec) {
- using webrtc::H264::kLevel1;
- using webrtc::H264::ProfileLevelId;
- using webrtc::H264::ProfileLevelIdToString;
+ using webrtc::H264Level;
+ using webrtc::H264Profile;
+ using webrtc::H264ProfileLevelId;
+ using webrtc::H264ProfileLevelIdToString;
webrtc::SdpVideoFormat h264_constrained_baseline("H264");
h264_constrained_baseline.parameters[kH264FmtpProfileLevelId] =
- *ProfileLevelIdToString(
- ProfileLevelId(webrtc::H264::kProfileConstrainedBaseline, kLevel1));
+ *H264ProfileLevelIdToString(H264ProfileLevelId(
+ H264Profile::kProfileConstrainedBaseline, H264Level::kLevel1));
webrtc::SdpVideoFormat h264_constrained_high("H264");
h264_constrained_high.parameters[kH264FmtpProfileLevelId] =
- *ProfileLevelIdToString(
- ProfileLevelId(webrtc::H264::kProfileConstrainedHigh, kLevel1));
+ *H264ProfileLevelIdToString(H264ProfileLevelId(
+ H264Profile::kProfileConstrainedHigh, H264Level::kLevel1));
webrtc::SdpVideoFormat h264_high("H264");
- h264_high.parameters[kH264FmtpProfileLevelId] = *ProfileLevelIdToString(
- ProfileLevelId(webrtc::H264::kProfileHigh, kLevel1));
+ h264_high.parameters[kH264FmtpProfileLevelId] = *H264ProfileLevelIdToString(
+ H264ProfileLevelId(H264Profile::kProfileHigh, H264Level::kLevel1));
encoder_factory_->AddSupportedVideoCodec(h264_constrained_baseline);
encoder_factory_->AddSupportedVideoCodec(h264_constrained_high);
@@ -721,10 +722,10 @@
// The tests only use H264 Constrained Baseline. Make sure we don't return
// an internal H264 codec from the engine with a different H264 profile.
if (absl::EqualsIgnoreCase(name.c_str(), kH264CodecName)) {
- const absl::optional<webrtc::H264::ProfileLevelId> profile_level_id =
- webrtc::H264::ParseSdpProfileLevelId(engine_codec.params);
+ const absl::optional<webrtc::H264ProfileLevelId> profile_level_id =
+ webrtc::ParseSdpForH264ProfileLevelId(engine_codec.params);
if (profile_level_id->profile !=
- webrtc::H264::kProfileConstrainedBaseline) {
+ webrtc::H264Profile::kProfileConstrainedBaseline) {
continue;
}
}
diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn
index fd03ffe..153a4b5 100644
--- a/modules/video_coding/BUILD.gn
+++ b/modules/video_coding/BUILD.gn
@@ -592,7 +592,6 @@
"../../api/video_codecs:video_codecs_api",
"../../common_video",
"../../media:rtc_media_base",
- "../../media:rtc_vp9_profile",
"../../rtc_base",
"../../rtc_base:checks",
"../../rtc_base/experiments:encoder_info_settings",
@@ -814,7 +813,6 @@
"../../call:video_stream_api",
"../../common_video",
"../../media:rtc_audio_video",
- "../../media:rtc_h264_profile_id",
"../../media:rtc_internal_video_codecs",
"../../media:rtc_media_base",
"../../rtc_base:checks",
@@ -904,11 +902,9 @@
"../../api/video_codecs:video_codecs_api",
"../../common_video",
"../../common_video/test:utilities",
- "../../media:rtc_h264_profile_id",
"../../media:rtc_internal_video_codecs",
"../../media:rtc_media_base",
"../../media:rtc_simulcast_encoder_adapter",
- "../../media:rtc_vp9_profile",
"../../rtc_base",
"../../test:explicit_key_value_config",
"../../test:field_trial",
diff --git a/modules/video_coding/codecs/h264/h264.cc b/modules/video_coding/codecs/h264/h264.cc
index be5b031..016d0aa 100644
--- a/modules/video_coding/codecs/h264/h264.cc
+++ b/modules/video_coding/codecs/h264/h264.cc
@@ -45,11 +45,11 @@
} // namespace
-SdpVideoFormat CreateH264Format(H264::Profile profile,
- H264::Level level,
+SdpVideoFormat CreateH264Format(H264Profile profile,
+ H264Level level,
const std::string& packetization_mode) {
const absl::optional<std::string> profile_string =
- H264::ProfileLevelIdToString(H264::ProfileLevelId(profile, level));
+ H264ProfileLevelIdToString(H264ProfileLevelId(profile, level));
RTC_CHECK(profile_string);
return SdpVideoFormat(
cricket::kH264CodecName,
@@ -76,12 +76,14 @@
//
// We support both packetization modes 0 (mandatory) and 1 (optional,
// preferred).
- return {
- CreateH264Format(H264::kProfileBaseline, H264::kLevel3_1, "1"),
- CreateH264Format(H264::kProfileBaseline, H264::kLevel3_1, "0"),
- CreateH264Format(H264::kProfileConstrainedBaseline, H264::kLevel3_1, "1"),
- CreateH264Format(H264::kProfileConstrainedBaseline, H264::kLevel3_1,
- "0")};
+ return {CreateH264Format(H264Profile::kProfileBaseline, H264Level::kLevel3_1,
+ "1"),
+ CreateH264Format(H264Profile::kProfileBaseline, H264Level::kLevel3_1,
+ "0"),
+ CreateH264Format(H264Profile::kProfileConstrainedBaseline,
+ H264Level::kLevel3_1, "1"),
+ CreateH264Format(H264Profile::kProfileConstrainedBaseline,
+ H264Level::kLevel3_1, "0")};
}
std::unique_ptr<H264Encoder> H264Encoder::Create(
diff --git a/modules/video_coding/codecs/h264/include/h264.h b/modules/video_coding/codecs/h264/include/h264.h
index 70ca817..1f8f796 100644
--- a/modules/video_coding/codecs/h264/include/h264.h
+++ b/modules/video_coding/codecs/h264/include/h264.h
@@ -27,8 +27,8 @@
// Creates an H264 SdpVideoFormat entry with specified paramters.
RTC_EXPORT SdpVideoFormat
-CreateH264Format(H264::Profile profile,
- H264::Level level,
+CreateH264Format(H264Profile profile,
+ H264Level level,
const std::string& packetization_mode);
// Set to disable the H.264 encoder/decoder implementations that are provided if
diff --git a/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc b/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc
index 1031530..4c11f6a 100644
--- a/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc
+++ b/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc
@@ -25,12 +25,12 @@
#include "api/array_view.h"
#include "api/transport/field_trial_based_config.h"
#include "api/video/video_bitrate_allocation.h"
+#include "api/video_codecs/h264_profile_level_id.h"
#include "api/video_codecs/sdp_video_format.h"
#include "api/video_codecs/video_codec.h"
#include "api/video_codecs/video_decoder.h"
#include "api/video_codecs/video_encoder_config.h"
#include "common_video/h264/h264_common.h"
-#include "media/base/h264_profile_level_id.h"
#include "media/base/media_constants.h"
#include "media/engine/internal_decoder_factory.h"
#include "media/engine/internal_encoder_factory.h"
@@ -302,11 +302,11 @@
name = CodecTypeToPayloadString(codec_settings.codecType);
}
if (codec_settings.codecType == kVideoCodecH264) {
- if (h264_codec_settings.profile == H264::kProfileConstrainedHigh) {
+ if (h264_codec_settings.profile == H264Profile::kProfileConstrainedHigh) {
return name + "-CHP";
} else {
RTC_DCHECK_EQ(h264_codec_settings.profile,
- H264::kProfileConstrainedBaseline);
+ H264Profile::kProfileConstrainedBaseline);
return name + "-CBP";
}
}
@@ -613,8 +613,8 @@
? "1"
: "0";
params = {{cricket::kH264FmtpProfileLevelId,
- *H264::ProfileLevelIdToString(H264::ProfileLevelId(
- config_.h264_codec_settings.profile, H264::kLevel3_1))},
+ *H264ProfileLevelIdToString(H264ProfileLevelId(
+ config_.h264_codec_settings.profile, H264Level::kLevel3_1))},
{cricket::kH264FmtpPacketizationMode, packetization_mode}};
} else {
params = {};
diff --git a/modules/video_coding/codecs/test/videocodec_test_mediacodec.cc b/modules/video_coding/codecs/test/videocodec_test_mediacodec.cc
index 9f88716..978fd88 100644
--- a/modules/video_coding/codecs/test/videocodec_test_mediacodec.cc
+++ b/modules/video_coding/codecs/test/videocodec_test_mediacodec.cc
@@ -95,7 +95,7 @@
const auto frame_checker =
std::make_unique<VideoCodecTestFixtureImpl::H264KeyframeChecker>();
- config.h264_codec_settings.profile = H264::kProfileConstrainedHigh;
+ config.h264_codec_settings.profile = H264Profile::kProfileConstrainedHigh;
config.encoded_frame_checker = frame_checker.get();
config.SetCodecSettings(cricket::kH264CodecName, 1, 1, 1, false, false, false,
352, 288);
diff --git a/modules/video_coding/codecs/test/videocodec_test_videotoolbox.cc b/modules/video_coding/codecs/test/videocodec_test_videotoolbox.cc
index 0f02080..6df9743 100644
--- a/modules/video_coding/codecs/test/videocodec_test_videotoolbox.cc
+++ b/modules/video_coding/codecs/test/videocodec_test_videotoolbox.cc
@@ -71,7 +71,7 @@
const auto frame_checker =
std::make_unique<VideoCodecTestFixtureImpl::H264KeyframeChecker>();
auto config = CreateConfig();
- config.h264_codec_settings.profile = H264::kProfileConstrainedHigh;
+ config.h264_codec_settings.profile = H264Profile::kProfileConstrainedHigh;
config.SetCodecSettings(cricket::kH264CodecName, 1, 1, 1, false, false, false,
352, 288);
config.encoded_frame_checker = frame_checker.get();
diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h
index cf328b2..954c044 100644
--- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h
+++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h
@@ -21,8 +21,8 @@
#include "api/fec_controller_override.h"
#include "api/transport/webrtc_key_value_config.h"
#include "api/video_codecs/video_encoder.h"
+#include "api/video_codecs/vp9_profile.h"
#include "common_video/include/video_frame_buffer_pool.h"
-#include "media/base/vp9_profile.h"
#include "modules/video_coding/codecs/interface/libvpx_interface.h"
#include "modules/video_coding/codecs/vp9/include/vp9.h"
#include "modules/video_coding/codecs/vp9/vp9_frame_buffer_pool.h"
diff --git a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
index 853d2df..e965384 100644
--- a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
+++ b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
@@ -15,8 +15,8 @@
#include "api/video/color_space.h"
#include "api/video/i420_buffer.h"
#include "api/video_codecs/video_encoder.h"
+#include "api/video_codecs/vp9_profile.h"
#include "common_video/libyuv/include/webrtc_libyuv.h"
-#include "media/base/vp9_profile.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/video_coding/codecs/interface/libvpx_interface.h"
#include "modules/video_coding/codecs/interface/mock_libvpx_interface.h"
diff --git a/modules/video_coding/codecs/vp9/vp9.cc b/modules/video_coding/codecs/vp9/vp9.cc
index 1efb1b4..d9caf0f 100644
--- a/modules/video_coding/codecs/vp9/vp9.cc
+++ b/modules/video_coding/codecs/vp9/vp9.cc
@@ -14,7 +14,7 @@
#include "api/transport/field_trial_based_config.h"
#include "api/video_codecs/sdp_video_format.h"
-#include "media/base/vp9_profile.h"
+#include "api/video_codecs/vp9_profile.h"
#include "modules/video_coding/codecs/vp9/libvpx_vp9_decoder.h"
#include "modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h"
#include "rtc_base/checks.h"
diff --git a/pc/BUILD.gn b/pc/BUILD.gn
index 18a81b9..2a18414 100644
--- a/pc/BUILD.gn
+++ b/pc/BUILD.gn
@@ -102,6 +102,7 @@
"../api/video:video_bitrate_allocator_factory",
"../api/video:video_frame",
"../api/video:video_rtp_headers",
+ "../api/video_codecs:video_codecs_api",
"../call:call_interfaces",
"../call:rtp_interfaces",
"../call:rtp_receiver",
@@ -109,9 +110,9 @@
"../common_video:common_video",
"../logging:ice_log",
"../media:rtc_data_sctp_transport_internal",
- "../media:rtc_h264_profile_id",
"../media:rtc_media_base",
"../media:rtc_media_config",
+ "../media:rtc_sdp_video_format_utils",
"../modules/rtp_rtcp:rtp_rtcp",
"../modules/rtp_rtcp:rtp_rtcp_format",
"../p2p:rtc_p2p",
diff --git a/pc/media_session.cc b/pc/media_session.cc
index f67d8ea..2e779bd 100644
--- a/pc/media_session.cc
+++ b/pc/media_session.cc
@@ -24,9 +24,10 @@
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "api/crypto_params.h"
+#include "api/video_codecs/h264_profile_level_id.h"
#include "media/base/codec.h"
-#include "media/base/h264_profile_level_id.h"
#include "media/base/media_constants.h"
+#include "media/base/sdp_video_format_utils.h"
#include "media/sctp/sctp_transport_internal.h"
#include "p2p/base/p2p_constants.h"
#include "pc/channel_manager.h"
@@ -801,8 +802,8 @@
}
}
if (absl::EqualsIgnoreCase(ours.name, kH264CodecName)) {
- webrtc::H264::GenerateProfileLevelIdForAnswer(
- ours.params, theirs.params, &negotiated.params);
+ webrtc::H264GenerateProfileLevelIdForAnswer(ours.params, theirs.params,
+ &negotiated.params);
}
negotiated.id = theirs.id;
negotiated.name = theirs.name;
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index 942202e..e01ab97 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -1655,6 +1655,7 @@
":video_toolbox_cc",
":videocodec_objc",
":videoframebuffer_objc",
+ "../api/video_codecs:video_codecs_api",
"../common_video",
"../modules/video_coding:video_codec_interface",
"../rtc_base:checks",
diff --git a/sdk/android/src/jni/h264_utils.cc b/sdk/android/src/jni/h264_utils.cc
index 02e3ae1..882df95 100644
--- a/sdk/android/src/jni/h264_utils.cc
+++ b/sdk/android/src/jni/h264_utils.cc
@@ -8,10 +8,9 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#include "sdk/android/src/jni/video_codec_info.h"
-
-#include "common_video/h264/profile_level_id.h"
+#include "api/video_codecs/h264_profile_level_id.h"
#include "sdk/android/generated_video_jni/H264Utils_jni.h"
+#include "sdk/android/src/jni/video_codec_info.h"
namespace webrtc {
namespace jni {
@@ -20,8 +19,8 @@
JNIEnv* env,
const JavaParamRef<jobject>& params1,
const JavaParamRef<jobject>& params2) {
- return H264::IsSameH264Profile(JavaToNativeStringMap(env, params1),
- JavaToNativeStringMap(env, params2));
+ return H264IsSameProfile(JavaToNativeStringMap(env, params1),
+ JavaToNativeStringMap(env, params2));
}
} // namespace jni
diff --git a/sdk/objc/components/video_codec/RTCH264ProfileLevelId.mm b/sdk/objc/components/video_codec/RTCH264ProfileLevelId.mm
index b985d9d..f0ef3ec 100644
--- a/sdk/objc/components/video_codec/RTCH264ProfileLevelId.mm
+++ b/sdk/objc/components/video_codec/RTCH264ProfileLevelId.mm
@@ -16,7 +16,7 @@
#import "UIDevice+H264Profile.h"
#endif
-#include "media/base/h264_profile_level_id.h"
+#include "api/video_codecs/h264_profile_level_id.h"
#include "media/base/media_constants.h"
namespace {
@@ -38,13 +38,12 @@
#if defined(WEBRTC_IOS)
-using namespace webrtc::H264;
-
-NSString *MaxSupportedLevelForProfile(Profile profile) {
- const absl::optional<ProfileLevelId> profileLevelId = [UIDevice maxSupportedH264Profile];
+NSString *MaxSupportedLevelForProfile(webrtc::H264Profile profile) {
+ const absl::optional<webrtc::H264ProfileLevelId> profileLevelId =
+ [UIDevice maxSupportedH264Profile];
if (profileLevelId && profileLevelId->profile >= profile) {
const absl::optional<std::string> profileString =
- ProfileLevelIdToString(ProfileLevelId(profile, profileLevelId->level));
+ H264ProfileLevelIdToString(webrtc::H264ProfileLevelId(profile, profileLevelId->level));
if (profileString) {
return [NSString stringForStdString:*profileString];
}
@@ -55,7 +54,7 @@
NSString *MaxSupportedProfileLevelConstrainedBaseline() {
#if defined(WEBRTC_IOS)
- NSString *profile = MaxSupportedLevelForProfile(webrtc::H264::kProfileConstrainedBaseline);
+ NSString *profile = MaxSupportedLevelForProfile(webrtc::H264Profile::kProfileConstrainedBaseline);
if (profile != nil) {
return profile;
}
@@ -65,7 +64,7 @@
NSString *MaxSupportedProfileLevelConstrainedHigh() {
#if defined(WEBRTC_IOS)
- NSString *profile = MaxSupportedLevelForProfile(webrtc::H264::kProfileConstrainedHigh);
+ NSString *profile = MaxSupportedLevelForProfile(webrtc::H264Profile::kProfileConstrainedHigh);
if (profile != nil) {
return profile;
}
@@ -94,8 +93,8 @@
if (self = [super init]) {
self.hexString = hexString;
- absl::optional<webrtc::H264::ProfileLevelId> profile_level_id =
- webrtc::H264::ParseProfileLevelId([hexString cStringUsingEncoding:NSUTF8StringEncoding]);
+ absl::optional<webrtc::H264ProfileLevelId> profile_level_id =
+ webrtc::ParseH264ProfileLevelId([hexString cStringUsingEncoding:NSUTF8StringEncoding]);
if (profile_level_id.has_value()) {
self.profile = static_cast<RTCH264Profile>(profile_level_id->profile);
self.level = static_cast<RTCH264Level>(profile_level_id->level);
@@ -110,8 +109,8 @@
self.level = level;
absl::optional<std::string> hex_string =
- webrtc::H264::ProfileLevelIdToString(webrtc::H264::ProfileLevelId(
- static_cast<webrtc::H264::Profile>(profile), static_cast<webrtc::H264::Level>(level)));
+ webrtc::H264ProfileLevelIdToString(webrtc::H264ProfileLevelId(
+ static_cast<webrtc::H264Profile>(profile), static_cast<webrtc::H264Level>(level)));
self.hexString =
[NSString stringWithCString:hex_string.value_or("").c_str() encoding:NSUTF8StringEncoding];
}
diff --git a/sdk/objc/components/video_codec/RTCVideoEncoderH264.mm b/sdk/objc/components/video_codec/RTCVideoEncoderH264.mm
index 01d48c1..e64f619 100644
--- a/sdk/objc/components/video_codec/RTCVideoEncoderH264.mm
+++ b/sdk/objc/components/video_codec/RTCVideoEncoderH264.mm
@@ -28,8 +28,8 @@
#import "components/video_frame_buffer/RTCCVPixelBuffer.h"
#import "helpers.h"
+#include "api/video_codecs/h264_profile_level_id.h"
#include "common_video/h264/h264_bitstream_parser.h"
-#include "common_video/h264/profile_level_id.h"
#include "common_video/include/bitrate_adjuster.h"
#include "modules/video_coding/include/video_error_codes.h"
#include "rtc_base/buffer.h"
@@ -173,100 +173,100 @@
// no specific VideoToolbox profile for the specified level, AutoLevel will be
// returned. The user must initialize the encoder with a resolution and
// framerate conforming to the selected H264 level regardless.
-CFStringRef ExtractProfile(const webrtc::H264::ProfileLevelId &profile_level_id) {
+CFStringRef ExtractProfile(const webrtc::H264ProfileLevelId &profile_level_id) {
switch (profile_level_id.profile) {
- case webrtc::H264::kProfileConstrainedBaseline:
- case webrtc::H264::kProfileBaseline:
+ case webrtc::H264Profile::kProfileConstrainedBaseline:
+ case webrtc::H264Profile::kProfileBaseline:
switch (profile_level_id.level) {
- case webrtc::H264::kLevel3:
+ case webrtc::H264Level::kLevel3:
return kVTProfileLevel_H264_Baseline_3_0;
- case webrtc::H264::kLevel3_1:
+ case webrtc::H264Level::kLevel3_1:
return kVTProfileLevel_H264_Baseline_3_1;
- case webrtc::H264::kLevel3_2:
+ case webrtc::H264Level::kLevel3_2:
return kVTProfileLevel_H264_Baseline_3_2;
- case webrtc::H264::kLevel4:
+ case webrtc::H264Level::kLevel4:
return kVTProfileLevel_H264_Baseline_4_0;
- case webrtc::H264::kLevel4_1:
+ case webrtc::H264Level::kLevel4_1:
return kVTProfileLevel_H264_Baseline_4_1;
- case webrtc::H264::kLevel4_2:
+ case webrtc::H264Level::kLevel4_2:
return kVTProfileLevel_H264_Baseline_4_2;
- case webrtc::H264::kLevel5:
+ case webrtc::H264Level::kLevel5:
return kVTProfileLevel_H264_Baseline_5_0;
- case webrtc::H264::kLevel5_1:
+ case webrtc::H264Level::kLevel5_1:
return kVTProfileLevel_H264_Baseline_5_1;
- case webrtc::H264::kLevel5_2:
+ case webrtc::H264Level::kLevel5_2:
return kVTProfileLevel_H264_Baseline_5_2;
- case webrtc::H264::kLevel1:
- case webrtc::H264::kLevel1_b:
- case webrtc::H264::kLevel1_1:
- case webrtc::H264::kLevel1_2:
- case webrtc::H264::kLevel1_3:
- case webrtc::H264::kLevel2:
- case webrtc::H264::kLevel2_1:
- case webrtc::H264::kLevel2_2:
+ case webrtc::H264Level::kLevel1:
+ case webrtc::H264Level::kLevel1_b:
+ case webrtc::H264Level::kLevel1_1:
+ case webrtc::H264Level::kLevel1_2:
+ case webrtc::H264Level::kLevel1_3:
+ case webrtc::H264Level::kLevel2:
+ case webrtc::H264Level::kLevel2_1:
+ case webrtc::H264Level::kLevel2_2:
return kVTProfileLevel_H264_Baseline_AutoLevel;
}
- case webrtc::H264::kProfileMain:
+ case webrtc::H264Profile::kProfileMain:
switch (profile_level_id.level) {
- case webrtc::H264::kLevel3:
+ case webrtc::H264Level::kLevel3:
return kVTProfileLevel_H264_Main_3_0;
- case webrtc::H264::kLevel3_1:
+ case webrtc::H264Level::kLevel3_1:
return kVTProfileLevel_H264_Main_3_1;
- case webrtc::H264::kLevel3_2:
+ case webrtc::H264Level::kLevel3_2:
return kVTProfileLevel_H264_Main_3_2;
- case webrtc::H264::kLevel4:
+ case webrtc::H264Level::kLevel4:
return kVTProfileLevel_H264_Main_4_0;
- case webrtc::H264::kLevel4_1:
+ case webrtc::H264Level::kLevel4_1:
return kVTProfileLevel_H264_Main_4_1;
- case webrtc::H264::kLevel4_2:
+ case webrtc::H264Level::kLevel4_2:
return kVTProfileLevel_H264_Main_4_2;
- case webrtc::H264::kLevel5:
+ case webrtc::H264Level::kLevel5:
return kVTProfileLevel_H264_Main_5_0;
- case webrtc::H264::kLevel5_1:
+ case webrtc::H264Level::kLevel5_1:
return kVTProfileLevel_H264_Main_5_1;
- case webrtc::H264::kLevel5_2:
+ case webrtc::H264Level::kLevel5_2:
return kVTProfileLevel_H264_Main_5_2;
- case webrtc::H264::kLevel1:
- case webrtc::H264::kLevel1_b:
- case webrtc::H264::kLevel1_1:
- case webrtc::H264::kLevel1_2:
- case webrtc::H264::kLevel1_3:
- case webrtc::H264::kLevel2:
- case webrtc::H264::kLevel2_1:
- case webrtc::H264::kLevel2_2:
+ case webrtc::H264Level::kLevel1:
+ case webrtc::H264Level::kLevel1_b:
+ case webrtc::H264Level::kLevel1_1:
+ case webrtc::H264Level::kLevel1_2:
+ case webrtc::H264Level::kLevel1_3:
+ case webrtc::H264Level::kLevel2:
+ case webrtc::H264Level::kLevel2_1:
+ case webrtc::H264Level::kLevel2_2:
return kVTProfileLevel_H264_Main_AutoLevel;
}
- case webrtc::H264::kProfileConstrainedHigh:
- case webrtc::H264::kProfileHigh:
+ case webrtc::H264Profile::kProfileConstrainedHigh:
+ case webrtc::H264Profile::kProfileHigh:
switch (profile_level_id.level) {
- case webrtc::H264::kLevel3:
+ case webrtc::H264Level::kLevel3:
return kVTProfileLevel_H264_High_3_0;
- case webrtc::H264::kLevel3_1:
+ case webrtc::H264Level::kLevel3_1:
return kVTProfileLevel_H264_High_3_1;
- case webrtc::H264::kLevel3_2:
+ case webrtc::H264Level::kLevel3_2:
return kVTProfileLevel_H264_High_3_2;
- case webrtc::H264::kLevel4:
+ case webrtc::H264Level::kLevel4:
return kVTProfileLevel_H264_High_4_0;
- case webrtc::H264::kLevel4_1:
+ case webrtc::H264Level::kLevel4_1:
return kVTProfileLevel_H264_High_4_1;
- case webrtc::H264::kLevel4_2:
+ case webrtc::H264Level::kLevel4_2:
return kVTProfileLevel_H264_High_4_2;
- case webrtc::H264::kLevel5:
+ case webrtc::H264Level::kLevel5:
return kVTProfileLevel_H264_High_5_0;
- case webrtc::H264::kLevel5_1:
+ case webrtc::H264Level::kLevel5_1:
return kVTProfileLevel_H264_High_5_1;
- case webrtc::H264::kLevel5_2:
+ case webrtc::H264Level::kLevel5_2:
return kVTProfileLevel_H264_High_5_2;
- case webrtc::H264::kLevel1:
- case webrtc::H264::kLevel1_b:
- case webrtc::H264::kLevel1_1:
- case webrtc::H264::kLevel1_2:
- case webrtc::H264::kLevel1_3:
- case webrtc::H264::kLevel2:
- case webrtc::H264::kLevel2_1:
- case webrtc::H264::kLevel2_2:
+ case webrtc::H264Level::kLevel1:
+ case webrtc::H264Level::kLevel1_b:
+ case webrtc::H264Level::kLevel1_1:
+ case webrtc::H264Level::kLevel1_2:
+ case webrtc::H264Level::kLevel1_3:
+ case webrtc::H264Level::kLevel2:
+ case webrtc::H264Level::kLevel2_1:
+ case webrtc::H264Level::kLevel2_2:
return kVTProfileLevel_H264_High_AutoLevel;
}
}
@@ -276,33 +276,33 @@
// can be processed by given encoder with |profile_level_id|.
// See https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-H.264-201610-S!!PDF-E&type=items
// for details.
-NSUInteger GetMaxSampleRate(const webrtc::H264::ProfileLevelId &profile_level_id) {
+NSUInteger GetMaxSampleRate(const webrtc::H264ProfileLevelId &profile_level_id) {
switch (profile_level_id.level) {
- case webrtc::H264::kLevel3:
+ case webrtc::H264Level::kLevel3:
return 10368000;
- case webrtc::H264::kLevel3_1:
+ case webrtc::H264Level::kLevel3_1:
return 27648000;
- case webrtc::H264::kLevel3_2:
+ case webrtc::H264Level::kLevel3_2:
return 55296000;
- case webrtc::H264::kLevel4:
- case webrtc::H264::kLevel4_1:
+ case webrtc::H264Level::kLevel4:
+ case webrtc::H264Level::kLevel4_1:
return 62914560;
- case webrtc::H264::kLevel4_2:
+ case webrtc::H264Level::kLevel4_2:
return 133693440;
- case webrtc::H264::kLevel5:
+ case webrtc::H264Level::kLevel5:
return 150994944;
- case webrtc::H264::kLevel5_1:
+ case webrtc::H264Level::kLevel5_1:
return 251658240;
- case webrtc::H264::kLevel5_2:
+ case webrtc::H264Level::kLevel5_2:
return 530841600;
- case webrtc::H264::kLevel1:
- case webrtc::H264::kLevel1_b:
- case webrtc::H264::kLevel1_1:
- case webrtc::H264::kLevel1_2:
- case webrtc::H264::kLevel1_3:
- case webrtc::H264::kLevel2:
- case webrtc::H264::kLevel2_1:
- case webrtc::H264::kLevel2_2:
+ case webrtc::H264Level::kLevel1:
+ case webrtc::H264Level::kLevel1_b:
+ case webrtc::H264Level::kLevel1_1:
+ case webrtc::H264Level::kLevel1_2:
+ case webrtc::H264Level::kLevel1_3:
+ case webrtc::H264Level::kLevel2:
+ case webrtc::H264Level::kLevel2_1:
+ case webrtc::H264Level::kLevel2_2:
// Zero means auto rate setting.
return 0;
}
@@ -317,7 +317,7 @@
uint32_t _encoderFrameRate;
uint32_t _maxAllowedFrameRate;
RTCH264PacketizationMode _packetizationMode;
- absl::optional<webrtc::H264::ProfileLevelId> _profile_level_id;
+ absl::optional<webrtc::H264ProfileLevelId> _profile_level_id;
RTCVideoEncoderCallback _callback;
int32_t _width;
int32_t _height;
@@ -342,7 +342,7 @@
_bitrateAdjuster.reset(new webrtc::BitrateAdjuster(.5, .95));
_packetizationMode = RTCH264PacketizationModeNonInterleaved;
_profile_level_id =
- webrtc::H264::ParseSdpProfileLevelId([codecInfo nativeSdpVideoFormat].parameters);
+ webrtc::ParseSdpForH264ProfileLevelId([codecInfo nativeSdpVideoFormat].parameters);
RTC_DCHECK(_profile_level_id);
RTC_LOG(LS_INFO) << "Using profile " << CFStringToString(ExtractProfile(*_profile_level_id));
RTC_CHECK([codecInfo.name isEqualToString:kRTCVideoCodecH264Name]);
diff --git a/sdk/objc/components/video_codec/UIDevice+H264Profile.h b/sdk/objc/components/video_codec/UIDevice+H264Profile.h
index bb6f6ce..a51debb 100644
--- a/sdk/objc/components/video_codec/UIDevice+H264Profile.h
+++ b/sdk/objc/components/video_codec/UIDevice+H264Profile.h
@@ -10,10 +10,10 @@
#import <UIKit/UIKit.h>
-#include "media/base/h264_profile_level_id.h"
+#include "api/video_codecs/h264_profile_level_id.h"
@interface UIDevice (H264Profile)
-+ (absl::optional<webrtc::H264::ProfileLevelId>)maxSupportedH264Profile;
++ (absl::optional<webrtc::H264ProfileLevelId>)maxSupportedH264Profile;
@end
diff --git a/sdk/objc/components/video_codec/UIDevice+H264Profile.mm b/sdk/objc/components/video_codec/UIDevice+H264Profile.mm
index bfbdfa0..42ebadf 100644
--- a/sdk/objc/components/video_codec/UIDevice+H264Profile.mm
+++ b/sdk/objc/components/video_codec/UIDevice+H264Profile.mm
@@ -15,99 +15,156 @@
namespace {
-using namespace webrtc::H264;
+using namespace webrtc;
struct SupportedH264Profile {
const RTCDeviceType deviceType;
- const ProfileLevelId profile;
+ const H264ProfileLevelId profile;
};
constexpr SupportedH264Profile kH264MaxSupportedProfiles[] = {
// iPhones with at least iOS 9
- {RTCDeviceTypeIPhone12ProMax, {kProfileHigh, kLevel5_2}}, // https://support.apple.com/kb/SP832
- {RTCDeviceTypeIPhone12Pro, {kProfileHigh, kLevel5_2}}, // https://support.apple.com/kb/SP831
- {RTCDeviceTypeIPhone12, {kProfileHigh, kLevel5_2}}, // https://support.apple.com/kb/SP830
- {RTCDeviceTypeIPhone12Mini, {kProfileHigh, kLevel5_2}}, // https://support.apple.com/kb/SP829
- {RTCDeviceTypeIPhone11ProMax, {kProfileHigh, kLevel5_2}}, // https://support.apple.com/kb/SP806
- {RTCDeviceTypeIPhone11Pro, {kProfileHigh, kLevel5_2}}, // https://support.apple.com/kb/SP805
- {RTCDeviceTypeIPhone11, {kProfileHigh, kLevel5_2}}, // https://support.apple.com/kb/SP804
- {RTCDeviceTypeIPhoneXS, {kProfileHigh, kLevel5_2}}, // https://support.apple.com/kb/SP779
- {RTCDeviceTypeIPhoneXSMax, {kProfileHigh, kLevel5_2}}, // https://support.apple.com/kb/SP780
- {RTCDeviceTypeIPhoneXR, {kProfileHigh, kLevel5_2}}, // https://support.apple.com/kb/SP781
- {RTCDeviceTypeIPhoneX, {kProfileHigh, kLevel5_2}}, // https://support.apple.com/kb/SP770
- {RTCDeviceTypeIPhone8, {kProfileHigh, kLevel5_2}}, // https://support.apple.com/kb/SP767
- {RTCDeviceTypeIPhone8Plus, {kProfileHigh, kLevel5_2}}, // https://support.apple.com/kb/SP768
- {RTCDeviceTypeIPhone7, {kProfileHigh, kLevel5_1}}, // https://support.apple.com/kb/SP743
- {RTCDeviceTypeIPhone7Plus, {kProfileHigh, kLevel5_1}}, // https://support.apple.com/kb/SP744
- {RTCDeviceTypeIPhoneSE, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP738
- {RTCDeviceTypeIPhone6S, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP726
- {RTCDeviceTypeIPhone6SPlus, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP727
- {RTCDeviceTypeIPhone6, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP705
- {RTCDeviceTypeIPhone6Plus, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP706
- {RTCDeviceTypeIPhone5SGSM, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP685
+ {RTCDeviceTypeIPhone12ProMax,
+ {H264Profile::kProfileHigh, H264Level::kLevel5_2}}, // https://support.apple.com/kb/SP832
+ {RTCDeviceTypeIPhone12Pro,
+ {H264Profile::kProfileHigh, H264Level::kLevel5_2}}, // https://support.apple.com/kb/SP831
+ {RTCDeviceTypeIPhone12,
+ {H264Profile::kProfileHigh, H264Level::kLevel5_2}}, // https://support.apple.com/kb/SP830
+ {RTCDeviceTypeIPhone12Mini,
+ {H264Profile::kProfileHigh, H264Level::kLevel5_2}}, // https://support.apple.com/kb/SP829
+ {RTCDeviceTypeIPhone11ProMax,
+ {H264Profile::kProfileHigh, H264Level::kLevel5_2}}, // https://support.apple.com/kb/SP806
+ {RTCDeviceTypeIPhone11Pro,
+ {H264Profile::kProfileHigh, H264Level::kLevel5_2}}, // https://support.apple.com/kb/SP805
+ {RTCDeviceTypeIPhone11,
+ {H264Profile::kProfileHigh, H264Level::kLevel5_2}}, // https://support.apple.com/kb/SP804
+ {RTCDeviceTypeIPhoneXS,
+ {H264Profile::kProfileHigh, H264Level::kLevel5_2}}, // https://support.apple.com/kb/SP779
+ {RTCDeviceTypeIPhoneXSMax,
+ {H264Profile::kProfileHigh, H264Level::kLevel5_2}}, // https://support.apple.com/kb/SP780
+ {RTCDeviceTypeIPhoneXR,
+ {H264Profile::kProfileHigh, H264Level::kLevel5_2}}, // https://support.apple.com/kb/SP781
+ {RTCDeviceTypeIPhoneX,
+ {H264Profile::kProfileHigh, H264Level::kLevel5_2}}, // https://support.apple.com/kb/SP770
+ {RTCDeviceTypeIPhone8,
+ {H264Profile::kProfileHigh, H264Level::kLevel5_2}}, // https://support.apple.com/kb/SP767
+ {RTCDeviceTypeIPhone8Plus,
+ {H264Profile::kProfileHigh, H264Level::kLevel5_2}}, // https://support.apple.com/kb/SP768
+ {RTCDeviceTypeIPhone7,
+ {H264Profile::kProfileHigh, H264Level::kLevel5_1}}, // https://support.apple.com/kb/SP743
+ {RTCDeviceTypeIPhone7Plus,
+ {H264Profile::kProfileHigh, H264Level::kLevel5_1}}, // https://support.apple.com/kb/SP744
+ {RTCDeviceTypeIPhoneSE,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_2}}, // https://support.apple.com/kb/SP738
+ {RTCDeviceTypeIPhone6S,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_2}}, // https://support.apple.com/kb/SP726
+ {RTCDeviceTypeIPhone6SPlus,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_2}}, // https://support.apple.com/kb/SP727
+ {RTCDeviceTypeIPhone6,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_2}}, // https://support.apple.com/kb/SP705
+ {RTCDeviceTypeIPhone6Plus,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_2}}, // https://support.apple.com/kb/SP706
+ {RTCDeviceTypeIPhone5SGSM,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_2}}, // https://support.apple.com/kb/SP685
{RTCDeviceTypeIPhone5SGSM_CDMA,
- {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP685
- {RTCDeviceTypeIPhone5GSM, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP655
+ {H264Profile::kProfileHigh, H264Level::kLevel4_2}}, // https://support.apple.com/kb/SP685
+ {RTCDeviceTypeIPhone5GSM,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP655
{RTCDeviceTypeIPhone5GSM_CDMA,
- {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP655
- {RTCDeviceTypeIPhone5CGSM, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP684
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP655
+ {RTCDeviceTypeIPhone5CGSM,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP684
{RTCDeviceTypeIPhone5CGSM_CDMA,
- {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP684
- {RTCDeviceTypeIPhone4S, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP643
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP684
+ {RTCDeviceTypeIPhone4S,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP643
// iPods with at least iOS 9
- {RTCDeviceTypeIPodTouch7G, {kProfileMain, kLevel4_1}}, // https://support.apple.com/kb/SP796
- {RTCDeviceTypeIPodTouch6G, {kProfileMain, kLevel4_1}}, // https://support.apple.com/kb/SP720
- {RTCDeviceTypeIPodTouch5G, {kProfileMain, kLevel3_1}}, // https://support.apple.com/kb/SP657
+ {RTCDeviceTypeIPodTouch7G,
+ {H264Profile::kProfileMain, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP796
+ {RTCDeviceTypeIPodTouch6G,
+ {H264Profile::kProfileMain, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP720
+ {RTCDeviceTypeIPodTouch5G,
+ {H264Profile::kProfileMain, H264Level::kLevel3_1}}, // https://support.apple.com/kb/SP657
// iPads with at least iOS 9
- {RTCDeviceTypeIPadAir4Gen, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP828
- {RTCDeviceTypeIPad8, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP822
- {RTCDeviceTypeIPadPro4Gen12Inch, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP815
- {RTCDeviceTypeIPadPro4Gen11Inch, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP814
- {RTCDeviceTypeIPadAir3Gen, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP787
- {RTCDeviceTypeIPadMini5Gen, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP788
+ {RTCDeviceTypeIPadAir4Gen,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP828
+ {RTCDeviceTypeIPad8,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP822
+ {RTCDeviceTypeIPadPro4Gen12Inch,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP815
+ {RTCDeviceTypeIPadPro4Gen11Inch,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP814
+ {RTCDeviceTypeIPadAir3Gen,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP787
+ {RTCDeviceTypeIPadMini5Gen,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP788
{RTCDeviceTypeIPadPro3Gen12Inch,
- {kProfileHigh, kLevel5_2}}, // https://support.apple.com/kb/SP785
+ {H264Profile::kProfileHigh, H264Level::kLevel5_2}}, // https://support.apple.com/kb/SP785
{RTCDeviceTypeIPadPro3Gen11Inch,
- {kProfileHigh, kLevel5_2}}, // https://support.apple.com/kb/SP784
- {RTCDeviceTypeIPad7Gen10Inch, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP807
- {RTCDeviceTypeIPad2Wifi, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP622
- {RTCDeviceTypeIPad2GSM, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP622
- {RTCDeviceTypeIPad2CDMA, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP622
- {RTCDeviceTypeIPad2Wifi2, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP622
- {RTCDeviceTypeIPadMiniWifi, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP661
- {RTCDeviceTypeIPadMiniGSM, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP661
+ {H264Profile::kProfileHigh, H264Level::kLevel5_2}}, // https://support.apple.com/kb/SP784
+ {RTCDeviceTypeIPad7Gen10Inch,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP807
+ {RTCDeviceTypeIPad2Wifi,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP622
+ {RTCDeviceTypeIPad2GSM,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP622
+ {RTCDeviceTypeIPad2CDMA,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP622
+ {RTCDeviceTypeIPad2Wifi2,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP622
+ {RTCDeviceTypeIPadMiniWifi,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP661
+ {RTCDeviceTypeIPadMiniGSM,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP661
{RTCDeviceTypeIPadMiniGSM_CDMA,
- {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP661
- {RTCDeviceTypeIPad3Wifi, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP647
- {RTCDeviceTypeIPad3GSM_CDMA, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP647
- {RTCDeviceTypeIPad3GSM, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP647
- {RTCDeviceTypeIPad4Wifi, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP662
- {RTCDeviceTypeIPad4GSM, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP662
- {RTCDeviceTypeIPad4GSM_CDMA, {kProfileHigh, kLevel4_1}}, // https://support.apple.com/kb/SP662
- {RTCDeviceTypeIPad5, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP751
- {RTCDeviceTypeIPad6, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP774
- {RTCDeviceTypeIPadAirWifi, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP692
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP661
+ {RTCDeviceTypeIPad3Wifi,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP647
+ {RTCDeviceTypeIPad3GSM_CDMA,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP647
+ {RTCDeviceTypeIPad3GSM,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP647
+ {RTCDeviceTypeIPad4Wifi,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP662
+ {RTCDeviceTypeIPad4GSM,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP662
+ {RTCDeviceTypeIPad4GSM_CDMA,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_1}}, // https://support.apple.com/kb/SP662
+ {RTCDeviceTypeIPad5,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_2}}, // https://support.apple.com/kb/SP751
+ {RTCDeviceTypeIPad6,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_2}}, // https://support.apple.com/kb/SP774
+ {RTCDeviceTypeIPadAirWifi,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_2}}, // https://support.apple.com/kb/SP692
{RTCDeviceTypeIPadAirCellular,
- {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP692
+ {H264Profile::kProfileHigh, H264Level::kLevel4_2}}, // https://support.apple.com/kb/SP692
{RTCDeviceTypeIPadAirWifiCellular,
- {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP692
- {RTCDeviceTypeIPadAir2, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP708
- {RTCDeviceTypeIPadMini2GWifi, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP693
+ {H264Profile::kProfileHigh, H264Level::kLevel4_2}}, // https://support.apple.com/kb/SP692
+ {RTCDeviceTypeIPadAir2,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_2}}, // https://support.apple.com/kb/SP708
+ {RTCDeviceTypeIPadMini2GWifi,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_2}}, // https://support.apple.com/kb/SP693
{RTCDeviceTypeIPadMini2GCellular,
- {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP693
+ {H264Profile::kProfileHigh, H264Level::kLevel4_2}}, // https://support.apple.com/kb/SP693
{RTCDeviceTypeIPadMini2GWifiCellular,
- {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP693
- {RTCDeviceTypeIPadMini3, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP709
- {RTCDeviceTypeIPadMini4, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP725
- {RTCDeviceTypeIPadPro9Inch, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP739
- {RTCDeviceTypeIPadPro12Inch, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/sp723
- {RTCDeviceTypeIPadPro12Inch2, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP761
- {RTCDeviceTypeIPadPro10Inch, {kProfileHigh, kLevel4_2}}, // https://support.apple.com/kb/SP762
+ {H264Profile::kProfileHigh, H264Level::kLevel4_2}}, // https://support.apple.com/kb/SP693
+ {RTCDeviceTypeIPadMini3,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_2}}, // https://support.apple.com/kb/SP709
+ {RTCDeviceTypeIPadMini4,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_2}}, // https://support.apple.com/kb/SP725
+ {RTCDeviceTypeIPadPro9Inch,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_2}}, // https://support.apple.com/kb/SP739
+ {RTCDeviceTypeIPadPro12Inch,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_2}}, // https://support.apple.com/kb/sp723
+ {RTCDeviceTypeIPadPro12Inch2,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_2}}, // https://support.apple.com/kb/SP761
+ {RTCDeviceTypeIPadPro10Inch,
+ {H264Profile::kProfileHigh, H264Level::kLevel4_2}}, // https://support.apple.com/kb/SP762
};
-absl::optional<ProfileLevelId> FindMaxSupportedProfileForDevice(RTCDeviceType deviceType) {
+absl::optional<H264ProfileLevelId> FindMaxSupportedProfileForDevice(RTCDeviceType deviceType) {
const auto* result = std::find_if(std::begin(kH264MaxSupportedProfiles),
std::end(kH264MaxSupportedProfiles),
[deviceType](const SupportedH264Profile& supportedProfile) {
@@ -123,7 +180,7 @@
@implementation UIDevice (H264Profile)
-+ (absl::optional<webrtc::H264::ProfileLevelId>)maxSupportedH264Profile {
++ (absl::optional<webrtc::H264ProfileLevelId>)maxSupportedH264Profile {
return FindMaxSupportedProfileForDevice([self deviceType]);
}
diff --git a/video/BUILD.gn b/video/BUILD.gn
index 35ad044..c524212 100644
--- a/video/BUILD.gn
+++ b/video/BUILD.gn
@@ -84,7 +84,6 @@
"../call:rtp_sender",
"../call:video_stream_api",
"../common_video",
- "../media:rtc_h264_profile_id",
"../modules:module_api",
"../modules:module_api_public",
"../modules/pacing",
@@ -175,7 +174,6 @@
"../call:rtp_receiver", # For RtxReceiveStream.
"../call:video_stream_api",
"../common_video",
- "../media:rtc_h264_profile_id",
"../modules:module_api",
"../modules/pacing",
"../modules/remote_bitrate_estimator",
@@ -431,7 +429,6 @@
"../api:test_dependency_factory",
"../api:video_quality_test_fixture_api",
"../api/video_codecs:video_codecs_api",
- "../media:rtc_vp9_profile",
"../modules/pacing",
"../modules/video_coding:webrtc_vp9",
"../rtc_base/experiments:alr_experiment",
@@ -463,8 +460,8 @@
"../api:peer_connection_quality_test_fixture_api",
"../api:simulated_network_api",
"../api:time_controller",
+ "../api/video_codecs:video_codecs_api",
"../call:simulated_network",
- "../media:rtc_vp9_profile",
"../modules/video_coding:webrtc_vp9",
"../system_wrappers:field_trial",
"../test:field_trial",
diff --git a/video/full_stack_tests.cc b/video/full_stack_tests.cc
index ece756b..3831fdf 100644
--- a/video/full_stack_tests.cc
+++ b/video/full_stack_tests.cc
@@ -21,7 +21,7 @@
#include "api/video_codecs/sdp_video_format.h"
#include "api/video_codecs/video_codec.h"
#include "api/video_codecs/video_encoder_config.h"
-#include "media/base/vp9_profile.h"
+#include "api/video_codecs/vp9_profile.h"
#include "modules/video_coding/codecs/vp9/include/vp9.h"
#include "system_wrappers/include/field_trial.h"
#include "test/field_trial.h"
diff --git a/video/pc_full_stack_tests.cc b/video/pc_full_stack_tests.cc
index cca3353..5cebf41 100644
--- a/video/pc_full_stack_tests.cc
+++ b/video/pc_full_stack_tests.cc
@@ -21,8 +21,8 @@
#include "api/test/peerconnection_quality_test_fixture.h"
#include "api/test/simulated_network.h"
#include "api/test/time_controller.h"
+#include "api/video_codecs/vp9_profile.h"
#include "call/simulated_network.h"
-#include "media/base/vp9_profile.h"
#include "modules/video_coding/codecs/vp9/include/vp9.h"
#include "system_wrappers/include/field_trial.h"
#include "test/field_trial.h"
diff --git a/video/video_receive_stream.cc b/video/video_receive_stream.cc
index 12cb01d..8f51a8a 100644
--- a/video/video_receive_stream.cc
+++ b/video/video_receive_stream.cc
@@ -24,6 +24,7 @@
#include "api/array_view.h"
#include "api/crypto/frame_decryptor_interface.h"
#include "api/video/encoded_image.h"
+#include "api/video_codecs/h264_profile_level_id.h"
#include "api/video_codecs/sdp_video_format.h"
#include "api/video_codecs/video_codec.h"
#include "api/video_codecs/video_decoder_factory.h"
@@ -31,7 +32,6 @@
#include "call/rtp_stream_receiver_controller_interface.h"
#include "call/rtx_receive_stream.h"
#include "common_video/include/incoming_video_stream.h"
-#include "media/base/h264_profile_level_id.h"
#include "modules/utility/include/process_thread.h"
#include "modules/video_coding/include/video_codec_interface.h"
#include "modules/video_coding/include/video_coding_defines.h"
diff --git a/video/video_receive_stream2.cc b/video/video_receive_stream2.cc
index 4821f3c..2c7461a 100644
--- a/video/video_receive_stream2.cc
+++ b/video/video_receive_stream2.cc
@@ -24,6 +24,7 @@
#include "api/array_view.h"
#include "api/crypto/frame_decryptor_interface.h"
#include "api/video/encoded_image.h"
+#include "api/video_codecs/h264_profile_level_id.h"
#include "api/video_codecs/sdp_video_format.h"
#include "api/video_codecs/video_codec.h"
#include "api/video_codecs/video_decoder_factory.h"
@@ -31,7 +32,6 @@
#include "call/rtp_stream_receiver_controller_interface.h"
#include "call/rtx_receive_stream.h"
#include "common_video/include/incoming_video_stream.h"
-#include "media/base/h264_profile_level_id.h"
#include "modules/video_coding/include/video_codec_interface.h"
#include "modules/video_coding/include/video_coding_defines.h"
#include "modules/video_coding/include/video_error_codes.h"