blob: 9f505c19d7510ab591982a9fc6462fe020f0f0c3 [file] [log] [blame]
Johannes Kronc3fcee72021-04-19 07:09:261/*
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 <string.h>
14
15#include <map>
16#include <utility>
17
18#include "rtc_base/string_to_number.h"
19#include "test/gtest.h"
20
21namespace webrtc {
22namespace {
23// Max frame rate for VP8 and VP9 video.
24const char kVPxFmtpMaxFrameRate[] = "max-fr";
25// Max frame size for VP8 and VP9 video.
26const char kVPxFmtpMaxFrameSize[] = "max-fs";
27} // namespace
28
29TEST(SdpVideoFormatUtilsTest, TestH264GenerateProfileLevelIdForAnswerEmpty) {
Philipp Hanckede172522023-12-14 08:45:3930 CodecParameterMap answer_params;
31 H264GenerateProfileLevelIdForAnswer(CodecParameterMap(), CodecParameterMap(),
Johannes Kronc3fcee72021-04-19 07:09:2632 &answer_params);
33 EXPECT_TRUE(answer_params.empty());
34}
35
36TEST(SdpVideoFormatUtilsTest,
37 TestH264GenerateProfileLevelIdForAnswerLevelSymmetryCapped) {
Philipp Hanckede172522023-12-14 08:45:3938 CodecParameterMap low_level;
Johannes Kronc3fcee72021-04-19 07:09:2639 low_level["profile-level-id"] = "42e015";
Philipp Hanckede172522023-12-14 08:45:3940 CodecParameterMap high_level;
Johannes Kronc3fcee72021-04-19 07:09:2641 high_level["profile-level-id"] = "42e01f";
42
43 // Level asymmetry is not allowed; test that answer level is the lower of the
44 // local and remote levels.
Philipp Hanckede172522023-12-14 08:45:3945 CodecParameterMap answer_params;
Johannes Kronc3fcee72021-04-19 07:09:2646 H264GenerateProfileLevelIdForAnswer(low_level /* local_supported */,
47 high_level /* remote_offered */,
48 &answer_params);
49 EXPECT_EQ("42e015", answer_params["profile-level-id"]);
50
Philipp Hanckede172522023-12-14 08:45:3951 CodecParameterMap answer_params2;
Johannes Kronc3fcee72021-04-19 07:09:2652 H264GenerateProfileLevelIdForAnswer(high_level /* local_supported */,
53 low_level /* remote_offered */,
54 &answer_params2);
55 EXPECT_EQ("42e015", answer_params2["profile-level-id"]);
56}
57
58TEST(SdpVideoFormatUtilsTest,
59 TestH264GenerateProfileLevelIdForAnswerConstrainedBaselineLevelAsymmetry) {
Philipp Hanckede172522023-12-14 08:45:3960 CodecParameterMap local_params;
Johannes Kronc3fcee72021-04-19 07:09:2661 local_params["profile-level-id"] = "42e01f";
62 local_params["level-asymmetry-allowed"] = "1";
Philipp Hanckede172522023-12-14 08:45:3963 CodecParameterMap remote_params;
Johannes Kronc3fcee72021-04-19 07:09:2664 remote_params["profile-level-id"] = "42e015";
65 remote_params["level-asymmetry-allowed"] = "1";
Philipp Hanckede172522023-12-14 08:45:3966 CodecParameterMap answer_params;
Johannes Kronc3fcee72021-04-19 07:09:2667 H264GenerateProfileLevelIdForAnswer(local_params, remote_params,
68 &answer_params);
69 // When level asymmetry is allowed, we can answer a higher level than what was
70 // offered.
71 EXPECT_EQ("42e01f", answer_params["profile-level-id"]);
72}
73
Qiu Jianlinb3488d02023-12-07 00:12:1274#ifdef RTC_ENABLE_H265
75// Answer should not include explicit PTL info if neither local nor remote set
76// any of them.
77TEST(SdpVideoFormatUtilsTest, H265GenerateProfileTierLevelEmpty) {
Philipp Hanckede172522023-12-14 08:45:3978 CodecParameterMap answer_params;
79 H265GenerateProfileTierLevelForAnswer(CodecParameterMap(),
80 CodecParameterMap(), &answer_params);
Qiu Jianlinb3488d02023-12-07 00:12:1281 EXPECT_TRUE(answer_params.empty());
82}
83
84// Answer must use the minimum level as supported by both local and remote.
85TEST(SdpVideoFormatUtilsTest, H265GenerateProfileTierLevelNoEmpty) {
86 constexpr char kLocallySupportedLevelId[] = "93";
87 constexpr char kRemoteOfferedLevelId[] = "120";
88
Philipp Hanckede172522023-12-14 08:45:3989 CodecParameterMap local_params;
Qiu Jianlinb3488d02023-12-07 00:12:1290 local_params["profile-id"] = "1";
91 local_params["tier-flag"] = "0";
92 local_params["level-id"] = kLocallySupportedLevelId;
Philipp Hanckede172522023-12-14 08:45:3993 CodecParameterMap remote_params;
Qiu Jianlinb3488d02023-12-07 00:12:1294 remote_params["profile-id"] = "1";
95 remote_params["tier-flag"] = "0";
96 remote_params["level-id"] = kRemoteOfferedLevelId;
Philipp Hanckede172522023-12-14 08:45:3997 CodecParameterMap answer_params;
Qiu Jianlinb3488d02023-12-07 00:12:1298 H265GenerateProfileTierLevelForAnswer(local_params, remote_params,
99 &answer_params);
100 EXPECT_EQ(kLocallySupportedLevelId, answer_params["level-id"]);
101}
102#endif
103
Johannes Kronc3fcee72021-04-19 07:09:26104TEST(SdpVideoFormatUtilsTest, MaxFrameRateIsMissingOrInvalid) {
Philipp Hanckede172522023-12-14 08:45:39105 CodecParameterMap params;
Johannes Kronc3fcee72021-04-19 07:09:26106 absl::optional<int> empty = ParseSdpForVPxMaxFrameRate(params);
107 EXPECT_FALSE(empty);
108 params[kVPxFmtpMaxFrameRate] = "-1";
109 EXPECT_FALSE(ParseSdpForVPxMaxFrameRate(params));
110 params[kVPxFmtpMaxFrameRate] = "0";
111 EXPECT_FALSE(ParseSdpForVPxMaxFrameRate(params));
112 params[kVPxFmtpMaxFrameRate] = "abcde";
113 EXPECT_FALSE(ParseSdpForVPxMaxFrameRate(params));
114}
115
116TEST(SdpVideoFormatUtilsTest, MaxFrameRateIsSpecified) {
Philipp Hanckede172522023-12-14 08:45:39117 CodecParameterMap params;
Johannes Kronc3fcee72021-04-19 07:09:26118 params[kVPxFmtpMaxFrameRate] = "30";
119 EXPECT_EQ(ParseSdpForVPxMaxFrameRate(params), 30);
120 params[kVPxFmtpMaxFrameRate] = "60";
121 EXPECT_EQ(ParseSdpForVPxMaxFrameRate(params), 60);
122}
123
124TEST(SdpVideoFormatUtilsTest, MaxFrameSizeIsMissingOrInvalid) {
Philipp Hanckede172522023-12-14 08:45:39125 CodecParameterMap params;
Johannes Kronc3fcee72021-04-19 07:09:26126 absl::optional<int> empty = ParseSdpForVPxMaxFrameSize(params);
127 EXPECT_FALSE(empty);
128 params[kVPxFmtpMaxFrameSize] = "-1";
129 EXPECT_FALSE(ParseSdpForVPxMaxFrameSize(params));
130 params[kVPxFmtpMaxFrameSize] = "0";
131 EXPECT_FALSE(ParseSdpForVPxMaxFrameSize(params));
132 params[kVPxFmtpMaxFrameSize] = "abcde";
133 EXPECT_FALSE(ParseSdpForVPxMaxFrameSize(params));
134}
135
136TEST(SdpVideoFormatUtilsTest, MaxFrameSizeIsSpecified) {
Philipp Hanckede172522023-12-14 08:45:39137 CodecParameterMap params;
Johannes Kronc3fcee72021-04-19 07:09:26138 params[kVPxFmtpMaxFrameSize] = "8100"; // 1920 x 1080 / (16^2)
139 EXPECT_EQ(ParseSdpForVPxMaxFrameSize(params), 1920 * 1080);
140 params[kVPxFmtpMaxFrameSize] = "32400"; // 3840 x 2160 / (16^2)
141 EXPECT_EQ(ParseSdpForVPxMaxFrameSize(params), 3840 * 2160);
142}
143
144} // namespace webrtc