diff options
Diffstat (limited to 'third_party/libwebrtc/media/base/sdp_video_format_utils.cc')
-rw-r--r-- | third_party/libwebrtc/media/base/sdp_video_format_utils.cc | 73 |
1 files changed, 66 insertions, 7 deletions
diff --git a/third_party/libwebrtc/media/base/sdp_video_format_utils.cc b/third_party/libwebrtc/media/base/sdp_video_format_utils.cc index a156afdc02..2b756ba734 100644 --- a/third_party/libwebrtc/media/base/sdp_video_format_utils.cc +++ b/third_party/libwebrtc/media/base/sdp_video_format_utils.cc @@ -15,6 +15,9 @@ #include <utility> #include "api/video_codecs/h264_profile_level_id.h" +#ifdef RTC_ENABLE_H265 +#include "api/video_codecs/h265_profile_tier_level.h" +#endif #include "rtc_base/checks.h" #include "rtc_base/string_to_number.h" @@ -27,8 +30,13 @@ const char kVPxFmtpMaxFrameRate[] = "max-fr"; // Max frame size for VP8 and VP9 video. const char kVPxFmtpMaxFrameSize[] = "max-fs"; const int kVPxFmtpFrameSizeSubBlockPixels = 256; +#ifdef RTC_ENABLE_H265 +constexpr char kH265ProfileId[] = "profile-id"; +constexpr char kH265TierFlag[] = "tier-flag"; +constexpr char kH265LevelId[] = "level-id"; +#endif -bool IsH264LevelAsymmetryAllowed(const SdpVideoFormat::Parameters& params) { +bool IsH264LevelAsymmetryAllowed(const CodecParameterMap& params) { const auto it = params.find(kH264LevelAsymmetryAllowed); return it != params.end() && strcmp(it->second.c_str(), "1") == 0; } @@ -47,7 +55,7 @@ H264Level H264LevelMin(H264Level a, H264Level b) { } absl::optional<int> ParsePositiveNumberFromParams( - const SdpVideoFormat::Parameters& params, + const CodecParameterMap& params, const char* parameter_name) { const auto max_frame_rate_it = params.find(parameter_name); if (max_frame_rate_it == params.end()) @@ -60,13 +68,64 @@ absl::optional<int> ParsePositiveNumberFromParams( return i; } +#ifdef RTC_ENABLE_H265 +// Compares two H265Level and return the smaller. +H265Level H265LevelMin(H265Level a, H265Level b) { + return a <= b ? a : b; +} + +// Returns true if none of profile-id/tier-flag/level-id is specified +// explicitly in the param. +bool IsDefaultH265PTL(const CodecParameterMap& params) { + return !params.count(kH265ProfileId) && !params.count(kH265TierFlag) && + !params.count(kH265LevelId); +} +#endif + } // namespace +#ifdef RTC_ENABLE_H265 +// Set level according to https://tools.ietf.org/html/rfc7798#section-7.1 +void H265GenerateProfileTierLevelForAnswer( + const CodecParameterMap& local_supported_params, + const CodecParameterMap& remote_offered_params, + CodecParameterMap* answer_params) { + // If local and remote haven't set profile-id/tier-flag/level-id, they + // are both using the default PTL In this case, don't set PTL in answer + // either. + if (IsDefaultH265PTL(local_supported_params) && + IsDefaultH265PTL(remote_offered_params)) { + return; + } + + // Parse profile-tier-level. + const absl::optional<H265ProfileTierLevel> local_profile_tier_level = + ParseSdpForH265ProfileTierLevel(local_supported_params); + const absl::optional<H265ProfileTierLevel> remote_profile_tier_level = + ParseSdpForH265ProfileTierLevel(remote_offered_params); + // Profile and tier for local and remote codec must be valid and equal. + RTC_DCHECK(local_profile_tier_level); + RTC_DCHECK(remote_profile_tier_level); + RTC_DCHECK_EQ(local_profile_tier_level->profile, + remote_profile_tier_level->profile); + RTC_DCHECK_EQ(local_profile_tier_level->tier, + remote_profile_tier_level->tier); + + const H265Level answer_level = H265LevelMin(local_profile_tier_level->level, + remote_profile_tier_level->level); + + // Level-id in answer is changable as long as the highest level indicated by + // the answer is not higher than that indicated by the offer. See + // https://tools.ietf.org/html/rfc7798#section-7.2.2, sub-clause 2. + (*answer_params)[kH265LevelId] = H265LevelToString(answer_level); +} +#endif + // 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) { + 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. @@ -106,12 +165,12 @@ void H264GenerateProfileLevelIdForAnswer( } absl::optional<int> ParseSdpForVPxMaxFrameRate( - const SdpVideoFormat::Parameters& params) { + const CodecParameterMap& params) { return ParsePositiveNumberFromParams(params, kVPxFmtpMaxFrameRate); } absl::optional<int> ParseSdpForVPxMaxFrameSize( - const SdpVideoFormat::Parameters& params) { + const CodecParameterMap& params) { const absl::optional<int> i = ParsePositiveNumberFromParams(params, kVPxFmtpMaxFrameSize); return i ? absl::make_optional(i.value() * kVPxFmtpFrameSizeSubBlockPixels) |