mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 05:40:42 +01:00

This reverts commit 63d03f586b
.
Reason for revert: Breaks downstream project (not backwards compatible API change)
Original change's description:
> Unify access to SDP codec parameters
>
> which come from the a=fmtp:<pt> lines in the SDP and were used as either
> std::map<std::string, std:string>
> with three aliases,
> cricket::CodecParameterMap
> SdpAudioFormat::Parameters
> SdpVideoFormat::Parameters
>
> Use webrtc::CodecParameterMap in all places.
>
> BUG=None
>
> Change-Id: If47692bde7347834c349c6539b43309d8770e67b
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/330420
> Reviewed-by: Florent Castelli <orphis@webrtc.org>
> Reviewed-by: Harald Alvestrand <hta@webrtc.org>
> Commit-Queue: Philipp Hancke <phancke@microsoft.com>
> Cr-Commit-Position: refs/heads/main@{#41375}
Bug: None
Change-Id: I841735d98533d3b66850b9cfcf7ee0a99ddde078
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/331400
Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org>
Auto-Submit: Mirko Bonadei <mbonadei@webrtc.org>
Owners-Override: Mirko Bonadei <mbonadei@webrtc.org>
Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/heads/main@{#41377}
248 lines
7.1 KiB
C++
248 lines
7.1 KiB
C++
/*
|
|
* Copyright (c) 2023 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/h265_profile_tier_level.h"
|
|
|
|
#include <string>
|
|
|
|
#include "rtc_base/string_to_number.h"
|
|
|
|
namespace webrtc {
|
|
|
|
namespace {
|
|
|
|
const char kH265FmtpProfile[] = "profile-id";
|
|
const char kH265FmtpTier[] = "tier-flag";
|
|
const char kH265FmtpLevel[] = "level-id";
|
|
|
|
} // anonymous namespace
|
|
|
|
// Annex A of https://www.itu.int/rec/T-REC-H.265 (08/21), section A.3.
|
|
absl::optional<H265Profile> StringToH265Profile(const std::string& profile) {
|
|
absl::optional<int> i = rtc::StringToNumber<int>(profile);
|
|
if (!i.has_value()) {
|
|
return absl::nullopt;
|
|
}
|
|
|
|
switch (i.value()) {
|
|
case 1:
|
|
return H265Profile::kProfileMain;
|
|
case 2:
|
|
return H265Profile::kProfileMain10;
|
|
case 3:
|
|
return H265Profile::kProfileMainStill;
|
|
case 4:
|
|
return H265Profile::kProfileRangeExtensions;
|
|
case 5:
|
|
return H265Profile::kProfileHighThroughput;
|
|
case 6:
|
|
return H265Profile::kProfileMultiviewMain;
|
|
case 7:
|
|
return H265Profile::kProfileScalableMain;
|
|
case 8:
|
|
return H265Profile::kProfile3dMain;
|
|
case 9:
|
|
return H265Profile::kProfileScreenContentCoding;
|
|
case 10:
|
|
return H265Profile::kProfileScalableRangeExtensions;
|
|
case 11:
|
|
return H265Profile::kProfileHighThroughputScreenContentCoding;
|
|
default:
|
|
return absl::nullopt;
|
|
}
|
|
}
|
|
|
|
// Annex A of https://www.itu.int/rec/T-REC-H.265 (08/21), section A.4,
|
|
// tiers and levels.
|
|
absl::optional<H265Tier> StringToH265Tier(const std::string& tier) {
|
|
absl::optional<int> i = rtc::StringToNumber<int>(tier);
|
|
if (!i.has_value()) {
|
|
return absl::nullopt;
|
|
}
|
|
|
|
switch (i.value()) {
|
|
case 0:
|
|
return H265Tier::kTier0;
|
|
case 1:
|
|
return H265Tier::kTier1;
|
|
default:
|
|
return absl::nullopt;
|
|
}
|
|
}
|
|
|
|
absl::optional<H265Level> StringToH265Level(const std::string& level) {
|
|
const absl::optional<int> i = rtc::StringToNumber<int>(level);
|
|
if (!i.has_value())
|
|
return absl::nullopt;
|
|
|
|
switch (i.value()) {
|
|
case 30:
|
|
return H265Level::kLevel1;
|
|
case 60:
|
|
return H265Level::kLevel2;
|
|
case 63:
|
|
return H265Level::kLevel2_1;
|
|
case 90:
|
|
return H265Level::kLevel3;
|
|
case 93:
|
|
return H265Level::kLevel3_1;
|
|
case 120:
|
|
return H265Level::kLevel4;
|
|
case 123:
|
|
return H265Level::kLevel4_1;
|
|
case 150:
|
|
return H265Level::kLevel5;
|
|
case 153:
|
|
return H265Level::kLevel5_1;
|
|
case 156:
|
|
return H265Level::kLevel5_2;
|
|
case 180:
|
|
return H265Level::kLevel6;
|
|
case 183:
|
|
return H265Level::kLevel6_1;
|
|
case 186:
|
|
return H265Level::kLevel6_2;
|
|
default:
|
|
return absl::nullopt;
|
|
}
|
|
}
|
|
|
|
std::string H265ProfileToString(H265Profile profile) {
|
|
switch (profile) {
|
|
case H265Profile::kProfileMain:
|
|
return "1";
|
|
case H265Profile::kProfileMain10:
|
|
return "2";
|
|
case H265Profile::kProfileMainStill:
|
|
return "3";
|
|
case H265Profile::kProfileRangeExtensions:
|
|
return "4";
|
|
case H265Profile::kProfileHighThroughput:
|
|
return "5";
|
|
case H265Profile::kProfileMultiviewMain:
|
|
return "6";
|
|
case H265Profile::kProfileScalableMain:
|
|
return "7";
|
|
case H265Profile::kProfile3dMain:
|
|
return "8";
|
|
case H265Profile::kProfileScreenContentCoding:
|
|
return "9";
|
|
case H265Profile::kProfileScalableRangeExtensions:
|
|
return "10";
|
|
case H265Profile::kProfileHighThroughputScreenContentCoding:
|
|
return "11";
|
|
}
|
|
}
|
|
|
|
std::string H265TierToString(H265Tier tier) {
|
|
switch (tier) {
|
|
case H265Tier::kTier0:
|
|
return "0";
|
|
case H265Tier::kTier1:
|
|
return "1";
|
|
}
|
|
}
|
|
|
|
std::string H265LevelToString(H265Level level) {
|
|
switch (level) {
|
|
case H265Level::kLevel1:
|
|
return "30";
|
|
case H265Level::kLevel2:
|
|
return "60";
|
|
case H265Level::kLevel2_1:
|
|
return "63";
|
|
case H265Level::kLevel3:
|
|
return "90";
|
|
case H265Level::kLevel3_1:
|
|
return "93";
|
|
case H265Level::kLevel4:
|
|
return "120";
|
|
case H265Level::kLevel4_1:
|
|
return "123";
|
|
case H265Level::kLevel5:
|
|
return "150";
|
|
case H265Level::kLevel5_1:
|
|
return "153";
|
|
case H265Level::kLevel5_2:
|
|
return "156";
|
|
case H265Level::kLevel6:
|
|
return "180";
|
|
case H265Level::kLevel6_1:
|
|
return "183";
|
|
case H265Level::kLevel6_2:
|
|
return "186";
|
|
}
|
|
}
|
|
|
|
absl::optional<H265ProfileTierLevel> ParseSdpForH265ProfileTierLevel(
|
|
const SdpVideoFormat::Parameters& params) {
|
|
static const H265ProfileTierLevel kDefaultProfileTierLevel(
|
|
H265Profile::kProfileMain, H265Tier::kTier0, H265Level::kLevel3_1);
|
|
bool profile_tier_level_specified = false;
|
|
|
|
absl::optional<H265Profile> profile;
|
|
const auto profile_it = params.find(kH265FmtpProfile);
|
|
if (profile_it != params.end()) {
|
|
profile_tier_level_specified = true;
|
|
const std::string& profile_str = profile_it->second;
|
|
profile = StringToH265Profile(profile_str);
|
|
if (!profile) {
|
|
return absl::nullopt;
|
|
}
|
|
} else {
|
|
profile = H265Profile::kProfileMain;
|
|
}
|
|
absl::optional<H265Tier> tier;
|
|
const auto tier_it = params.find(kH265FmtpTier);
|
|
if (tier_it != params.end()) {
|
|
profile_tier_level_specified = true;
|
|
const std::string& tier_str = tier_it->second;
|
|
tier = StringToH265Tier(tier_str);
|
|
if (!tier) {
|
|
return absl::nullopt;
|
|
}
|
|
} else {
|
|
tier = H265Tier::kTier0;
|
|
}
|
|
absl::optional<H265Level> level;
|
|
const auto level_it = params.find(kH265FmtpLevel);
|
|
if (level_it != params.end()) {
|
|
profile_tier_level_specified = true;
|
|
const std::string& level_str = level_it->second;
|
|
level = StringToH265Level(level_str);
|
|
if (!level) {
|
|
return absl::nullopt;
|
|
}
|
|
} else {
|
|
level = H265Level::kLevel3_1;
|
|
}
|
|
|
|
// Spec Table A.9, level 1 to level 3.1 does not allow high tiers.
|
|
if (level <= H265Level::kLevel3_1 && tier == H265Tier::kTier1) {
|
|
return absl::nullopt;
|
|
}
|
|
|
|
return !profile_tier_level_specified
|
|
? kDefaultProfileTierLevel
|
|
: H265ProfileTierLevel(profile.value(), tier.value(),
|
|
level.value());
|
|
}
|
|
|
|
bool H265IsSameProfileTierLevel(const SdpVideoFormat::Parameters& params1,
|
|
const SdpVideoFormat::Parameters& params2) {
|
|
const absl::optional<H265ProfileTierLevel> ptl1 =
|
|
ParseSdpForH265ProfileTierLevel(params1);
|
|
const absl::optional<H265ProfileTierLevel> ptl2 =
|
|
ParseSdpForH265ProfileTierLevel(params2);
|
|
return ptl1 && ptl2 && ptl1->profile == ptl2->profile &&
|
|
ptl1->tier == ptl2->tier && ptl1->level == ptl2->level;
|
|
}
|
|
|
|
} // namespace webrtc
|