blob: 67c89135d0a6c2d5820cd8266ebcde678c8cc4a3 [file] [log] [blame]
Niels Möllerbe682d42018-03-27 08:31:45 +02001/*
2 * Copyright (c) 2018 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 "api/video_codecs/sdp_video_format.h"
Jonas Olssona4d87372019-07-05 19:08:33 +020012
Johannes Kron20ee02c2021-04-20 15:53:52 +020013#include "absl/strings/match.h"
Joe Downing87bcc1c2022-06-09 15:56:08 -070014#include "api/video_codecs/av1_profile.h"
Johannes Kron20ee02c2021-04-20 15:53:52 +020015#include "api/video_codecs/h264_profile_level_id.h"
16#include "api/video_codecs/video_codec.h"
17#include "api/video_codecs/vp9_profile.h"
18#include "rtc_base/checks.h"
philipele8ed8302019-07-03 11:53:48 +020019#include "rtc_base/strings/string_builder.h"
Niels Möllerbe682d42018-03-27 08:31:45 +020020
21namespace webrtc {
22
Johannes Kron20ee02c2021-04-20 15:53:52 +020023namespace {
24
25std::string H264GetPacketizationModeOrDefault(
26 const SdpVideoFormat::Parameters& params) {
27 constexpr char kH264FmtpPacketizationMode[] = "packetization-mode";
28 const auto it = params.find(kH264FmtpPacketizationMode);
29 if (it != params.end()) {
30 return it->second;
31 }
32 // If packetization-mode is not present, default to "0".
33 // https://tools.ietf.org/html/rfc6184#section-6.2
34 return "0";
35}
36
37bool H264IsSamePacketizationMode(const SdpVideoFormat::Parameters& left,
38 const SdpVideoFormat::Parameters& right) {
39 return H264GetPacketizationModeOrDefault(left) ==
40 H264GetPacketizationModeOrDefault(right);
41}
42
43// Some (video) codecs are actually families of codecs and rely on parameters
44// to distinguish different incompatible family members.
45bool IsSameCodecSpecific(const SdpVideoFormat& format1,
46 const SdpVideoFormat& format2) {
47 // The assumption when calling this function is that the two formats have the
48 // same name.
49 RTC_DCHECK(absl::EqualsIgnoreCase(format1.name, format2.name));
50
51 VideoCodecType codec_type = PayloadStringToCodecType(format1.name);
52 switch (codec_type) {
53 case kVideoCodecH264:
54 return H264IsSameProfile(format1.parameters, format2.parameters) &&
55 H264IsSamePacketizationMode(format1.parameters,
56 format2.parameters);
57 case kVideoCodecVP9:
58 return VP9IsSameProfile(format1.parameters, format2.parameters);
Joe Downing87bcc1c2022-06-09 15:56:08 -070059 case kVideoCodecAV1:
60 return AV1IsSameProfile(format1.parameters, format2.parameters);
Johannes Kron20ee02c2021-04-20 15:53:52 +020061 default:
62 return true;
63 }
64}
65} // namespace
66
Niels Möllerbe682d42018-03-27 08:31:45 +020067SdpVideoFormat::SdpVideoFormat(const std::string& name) : name(name) {}
68
69SdpVideoFormat::SdpVideoFormat(const std::string& name,
70 const Parameters& parameters)
71 : name(name), parameters(parameters) {}
72
73SdpVideoFormat::SdpVideoFormat(const SdpVideoFormat&) = default;
74SdpVideoFormat::SdpVideoFormat(SdpVideoFormat&&) = default;
Niels Möllerc5d44612018-03-28 09:02:09 +020075SdpVideoFormat& SdpVideoFormat::operator=(const SdpVideoFormat&) = default;
76SdpVideoFormat& SdpVideoFormat::operator=(SdpVideoFormat&&) = default;
Niels Möllerbe682d42018-03-27 08:31:45 +020077
78SdpVideoFormat::~SdpVideoFormat() = default;
79
philipele8ed8302019-07-03 11:53:48 +020080std::string SdpVideoFormat::ToString() const {
81 rtc::StringBuilder builder;
82 builder << "Codec name: " << name << ", parameters: {";
83 for (const auto& kv : parameters)
84 builder << " " << kv.first << "=" << kv.second;
85 builder << " }";
86
87 return builder.str();
88}
89
Johannes Kron20ee02c2021-04-20 15:53:52 +020090bool SdpVideoFormat::IsSameCodec(const SdpVideoFormat& other) const {
91 // Two codecs are considered the same if the name matches (case insensitive)
92 // and certain codec-specific parameters match.
93 return absl::EqualsIgnoreCase(name, other.name) &&
94 IsSameCodecSpecific(*this, other);
95}
96
97bool SdpVideoFormat::IsCodecInList(
98 rtc::ArrayView<const webrtc::SdpVideoFormat> formats) const {
99 for (const auto& format : formats) {
100 if (IsSameCodec(format)) {
101 return true;
102 }
103 }
104 return false;
105}
106
Niels Möllerbe682d42018-03-27 08:31:45 +0200107bool operator==(const SdpVideoFormat& a, const SdpVideoFormat& b) {
108 return a.name == b.name && a.parameters == b.parameters;
109}
110
111} // namespace webrtc