sdp_video_format_utils_unittest.cc (6123B)
1 /* 2 * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "media/base/sdp_video_format_utils.h" 12 13 #include <map> 14 #include <optional> 15 16 #include "api/rtp_parameters.h" 17 #include "test/gtest.h" 18 19 namespace webrtc { 20 namespace { 21 // Max frame rate for VP8 and VP9 video. 22 constexpr char kVPxFmtpMaxFrameRate[] = "max-fr"; 23 // Max frame size for VP8 and VP9 video. 24 constexpr char kVPxFmtpMaxFrameSize[] = "max-fs"; 25 // Nonstandard per-layer PLI for video. 26 constexpr char kCodecParamPerLayerPictureLossIndication[] = 27 "x-google-per-layer-pli"; 28 } // namespace 29 30 TEST(SdpVideoFormatUtilsTest, TestH264GenerateProfileLevelIdForAnswerEmpty) { 31 CodecParameterMap answer_params; 32 H264GenerateProfileLevelIdForAnswer(CodecParameterMap(), CodecParameterMap(), 33 &answer_params); 34 EXPECT_TRUE(answer_params.empty()); 35 } 36 37 TEST(SdpVideoFormatUtilsTest, 38 TestH264GenerateProfileLevelIdForAnswerLevelSymmetryCapped) { 39 CodecParameterMap low_level; 40 low_level["profile-level-id"] = "42e015"; 41 CodecParameterMap high_level; 42 high_level["profile-level-id"] = "42e01f"; 43 44 // Level asymmetry is not allowed; test that answer level is the lower of the 45 // local and remote levels. 46 CodecParameterMap answer_params; 47 H264GenerateProfileLevelIdForAnswer(low_level /* local_supported */, 48 high_level /* remote_offered */, 49 &answer_params); 50 EXPECT_EQ("42e015", answer_params["profile-level-id"]); 51 52 CodecParameterMap answer_params2; 53 H264GenerateProfileLevelIdForAnswer(high_level /* local_supported */, 54 low_level /* remote_offered */, 55 &answer_params2); 56 EXPECT_EQ("42e015", answer_params2["profile-level-id"]); 57 } 58 59 TEST(SdpVideoFormatUtilsTest, 60 TestH264GenerateProfileLevelIdForAnswerConstrainedBaselineLevelAsymmetry) { 61 CodecParameterMap local_params; 62 local_params["profile-level-id"] = "42e01f"; 63 local_params["level-asymmetry-allowed"] = "1"; 64 CodecParameterMap remote_params; 65 remote_params["profile-level-id"] = "42e015"; 66 remote_params["level-asymmetry-allowed"] = "1"; 67 CodecParameterMap answer_params; 68 H264GenerateProfileLevelIdForAnswer(local_params, remote_params, 69 &answer_params); 70 // When level asymmetry is allowed, we can answer a higher level than what was 71 // offered. 72 EXPECT_EQ("42e01f", answer_params["profile-level-id"]); 73 } 74 75 #ifdef RTC_ENABLE_H265 76 // Answer should not include explicit PTL info if neither local nor remote set 77 // any of them. 78 TEST(SdpVideoFormatUtilsTest, H265GenerateProfileTierLevelEmpty) { 79 CodecParameterMap answer_params; 80 H265GenerateProfileTierLevelForAnswer(CodecParameterMap(), 81 CodecParameterMap(), &answer_params); 82 EXPECT_TRUE(answer_params.empty()); 83 } 84 85 // Answer must use the minimum level as supported by both local and remote. 86 TEST(SdpVideoFormatUtilsTest, H265GenerateProfileTierLevelNoEmpty) { 87 constexpr char kLocallySupportedLevelId[] = "93"; 88 constexpr char kRemoteOfferedLevelId[] = "120"; 89 90 CodecParameterMap local_params; 91 local_params["profile-id"] = "1"; 92 local_params["tier-flag"] = "0"; 93 local_params["level-id"] = kLocallySupportedLevelId; 94 CodecParameterMap remote_params; 95 remote_params["profile-id"] = "1"; 96 remote_params["tier-flag"] = "0"; 97 remote_params["level-id"] = kRemoteOfferedLevelId; 98 CodecParameterMap answer_params; 99 H265GenerateProfileTierLevelForAnswer(local_params, remote_params, 100 &answer_params); 101 EXPECT_EQ(kLocallySupportedLevelId, answer_params["level-id"]); 102 } 103 #endif 104 105 TEST(SdpVideoFormatUtilsTest, MaxFrameRateIsMissingOrInvalid) { 106 CodecParameterMap params; 107 std::optional<int> empty = ParseSdpForVPxMaxFrameRate(params); 108 EXPECT_FALSE(empty); 109 params[kVPxFmtpMaxFrameRate] = "-1"; 110 EXPECT_FALSE(ParseSdpForVPxMaxFrameRate(params)); 111 params[kVPxFmtpMaxFrameRate] = "0"; 112 EXPECT_FALSE(ParseSdpForVPxMaxFrameRate(params)); 113 params[kVPxFmtpMaxFrameRate] = "abcde"; 114 EXPECT_FALSE(ParseSdpForVPxMaxFrameRate(params)); 115 } 116 117 TEST(SdpVideoFormatUtilsTest, MaxFrameRateIsSpecified) { 118 CodecParameterMap params; 119 params[kVPxFmtpMaxFrameRate] = "30"; 120 EXPECT_EQ(ParseSdpForVPxMaxFrameRate(params), 30); 121 params[kVPxFmtpMaxFrameRate] = "60"; 122 EXPECT_EQ(ParseSdpForVPxMaxFrameRate(params), 60); 123 } 124 125 TEST(SdpVideoFormatUtilsTest, MaxFrameSizeIsMissingOrInvalid) { 126 CodecParameterMap params; 127 std::optional<int> empty = ParseSdpForVPxMaxFrameSize(params); 128 EXPECT_FALSE(empty); 129 params[kVPxFmtpMaxFrameSize] = "-1"; 130 EXPECT_FALSE(ParseSdpForVPxMaxFrameSize(params)); 131 params[kVPxFmtpMaxFrameSize] = "0"; 132 EXPECT_FALSE(ParseSdpForVPxMaxFrameSize(params)); 133 params[kVPxFmtpMaxFrameSize] = "abcde"; 134 EXPECT_FALSE(ParseSdpForVPxMaxFrameSize(params)); 135 } 136 137 TEST(SdpVideoFormatUtilsTest, MaxFrameSizeIsSpecified) { 138 CodecParameterMap params; 139 params[kVPxFmtpMaxFrameSize] = "8100"; // 1920 x 1080 / (16^2) 140 EXPECT_EQ(ParseSdpForVPxMaxFrameSize(params), 1920 * 1080); 141 params[kVPxFmtpMaxFrameSize] = "32400"; // 3840 x 2160 / (16^2) 142 EXPECT_EQ(ParseSdpForVPxMaxFrameSize(params), 3840 * 2160); 143 } 144 145 TEST(SdpVideoFormatUtilsTest, PerLayerPictureLossIndication) { 146 CodecParameterMap params; 147 EXPECT_FALSE(SupportsPerLayerPictureLossIndication(params)); 148 params[kCodecParamPerLayerPictureLossIndication] = "wrong"; 149 EXPECT_FALSE(SupportsPerLayerPictureLossIndication(params)); 150 params[kCodecParamPerLayerPictureLossIndication] = "0"; 151 EXPECT_FALSE(SupportsPerLayerPictureLossIndication(params)); 152 params[kCodecParamPerLayerPictureLossIndication] = "1"; 153 EXPECT_TRUE(SupportsPerLayerPictureLossIndication(params)); 154 } 155 156 } // namespace webrtc