Adding C++ versions of currently spec'd "RtpParameters" structs.
These structs will be used for ORTC objects (and their WebRTC
equivalents).
This CL also introduces some minor changes to the existing implemented
structs:
- max_bitrate_bps uses rtc::Optional instead of "-1 means unset"
- "mime_type" turned into "name"/"kind" (which can be used to form the
MIME type string, if needed).
- clock_rate and channels changed to rtc::Optional, since they will
need to be for RtpSender.send().
- Renamed "channels" to "num_channels" (the ORTC name, which I prefer).
BUG=webrtc:7013, webrtc:7112
Review-Url: https://codereview.webrtc.org/2651883010
Cr-Commit-Position: refs/heads/master@{#16437}
diff --git a/webrtc/api/rtpparameters.h b/webrtc/api/rtpparameters.h
index 13704dc..f506c40 100644
--- a/webrtc/api/rtpparameters.h
+++ b/webrtc/api/rtpparameters.h
@@ -12,22 +12,297 @@
#define WEBRTC_API_RTPPARAMETERS_H_
#include <string>
+#include <unordered_map>
#include <vector>
+#include "webrtc/api/mediatypes.h"
#include "webrtc/base/optional.h"
namespace webrtc {
-// These structures are defined as part of the RtpSender interface.
-// See http://w3c.github.io/webrtc-pc/#rtcrtpsender-interface for details.
-struct RtpEncodingParameters {
+// These structures are intended to mirror those defined by:
+// http://draft.ortc.org/#rtcrtpdictionaries*
+// Contains everything specified as of 2017 Jan 24.
+//
+// They are used when retrieving or modifying the parameters of an
+// RtpSender/RtpReceiver, or retrieving capabilities.
+//
+// Note on conventions: Where ORTC may use "octet", "short" and "unsigned"
+// types, we typically use "int", in keeping with our style guidelines. The
+// parameter's actual valid range will be enforced when the parameters are set,
+// rather than when the parameters struct is built. An exception is made for
+// SSRCs, since they use the full unsigned 32-bit range, and aren't expected to
+// be used for any numeric comparisons/operations.
+//
+// Additionally, where ORTC uses strings, we may use enums for things that have
+// a fixed number of supported values. However, for things that can be extended
+// (such as codecs, by providing an external encoder factory), a string
+// identifier is used.
+
+enum class FecMechanism {
+ RED,
+ RED_AND_ULPFEC,
+ FLEXFEC,
+};
+
+// Used in RtcpFeedback struct.
+enum class RtcpFeedbackType {
+ ACK,
+ CCM,
+ NACK,
+ REMB, // "goog-remb"
+ TRANSPORT_CC,
+};
+
+// Used in RtcpFeedback struct when type is ACK, NACK or CCM.
+enum class RtcpFeedbackMessageType {
+ // Equivalent to {type: "nack", parameter: undefined} in ORTC.
+ GENERIC_NACK,
+ PLI, // Usable with NACK.
+ FIR, // Usable with CCM.
+};
+
+enum class DtxStatus {
+ DISABLED,
+ ENABLED,
+};
+
+enum class DegradationPreference {
+ MAINTAIN_FRAMERATE,
+ MAINTAIN_RESOLUTION,
+ BALANCED,
+};
+
+enum class PriorityType { VERY_LOW, LOW, MEDIUM, HIGH };
+
+struct RtcpFeedback {
+ RtcpFeedbackType type = RtcpFeedbackType::ACK;
+
+ // Equivalent to ORTC "parameter" field with slight differences:
+ // 1. It's an enum instead of a string.
+ // 2. Generic NACK feedback is represented by a GENERIC_NACK message type,
+ // rather than an unset "parameter" value.
+ rtc::Optional<RtcpFeedbackMessageType> message_type;
+
+ bool operator==(const RtcpFeedback& o) const {
+ return type == o.type && message_type == o.message_type;
+ }
+ bool operator!=(const RtcpFeedback& o) const { return !(*this == o); }
+};
+
+// RtpCodecCapability is to RtpCodecParameters as RtpCapabilities is to
+// RtpParameters. This represents the static capabilities of an endpoint's
+// implementation of a codec.
+struct RtpCodecCapability {
+ // Build MIME "type/subtype" string from |name| and |kind|.
+ std::string mime_type() const { return MediaTypeToString(kind) + "/" + name; }
+
+ // Used to identify the codec. Equivalent to MIME subtype.
+ std::string name;
+
+ // The media type of this codec. Equivalent to MIME top-level type.
+ cricket::MediaType kind = cricket::MEDIA_TYPE_AUDIO;
+
+ // Clock rate in Hertz. If unset, the codec is applicable to any clock rate.
+ rtc::Optional<int> clock_rate;
+
+ // Default payload type for this codec. Mainly needed for codecs that use
+ // that have statically assigned payload types.
+ rtc::Optional<int> preferred_payload_type;
+
+ // Maximum packetization time supported by an RtpReceiver for this codec.
+ // TODO(deadbeef): Not implemented.
+ rtc::Optional<int> max_ptime;
+
+ // Preferred packetization time for an RtpReceiver or RtpSender of this
+ // codec.
+ // TODO(deadbeef): Not implemented.
+ rtc::Optional<int> ptime;
+
+ // The number of audio channels supported. Unused for video codecs.
+ rtc::Optional<int> num_channels;
+
+ // Feedback mechanisms supported for this codec.
+ std::vector<RtcpFeedback> rtcp_feedback;
+
+ // Codec-specific parameters that must be signaled to the remote party.
+ // Corresponds to "a=fmtp" parameters in SDP.
+ std::unordered_map<std::string, std::string> parameters;
+
+ // Codec-specific parameters that may optionally be signaled to the remote
+ // party.
+ // TODO(deadbeef): Not implemented.
+ std::unordered_map<std::string, std::string> options;
+
+ // Maximum number of temporal layer extensions supported by this codec.
+ // For example, a value of 1 indicates that 2 total layers are supported.
+ // TODO(deadbeef): Not implemented.
+ int max_temporal_layer_extensions = 0;
+
+ // Maximum number of spatial layer extensions supported by this codec.
+ // For example, a value of 1 indicates that 2 total layers are supported.
+ // TODO(deadbeef): Not implemented.
+ int max_spatial_layer_extensions = 0;
+
+ // Whether the implementation can send/receive SVC layers with distinct
+ // SSRCs. Always false for audio codecs. True for video codecs that support
+ // scalable video coding with MRST.
+ // TODO(deadbeef): Not implemented.
+ bool svc_multi_stream_support = false;
+
+ bool operator==(const RtpCodecCapability& o) const {
+ return name == o.name && kind == o.kind && clock_rate == o.clock_rate &&
+ preferred_payload_type == o.preferred_payload_type &&
+ max_ptime == o.max_ptime && ptime == o.ptime &&
+ num_channels == o.num_channels && rtcp_feedback == o.rtcp_feedback &&
+ parameters == o.parameters && options == o.options &&
+ max_temporal_layer_extensions == o.max_temporal_layer_extensions &&
+ max_spatial_layer_extensions == o.max_spatial_layer_extensions &&
+ svc_multi_stream_support == o.svc_multi_stream_support;
+ }
+ bool operator!=(const RtpCodecCapability& o) const { return !(*this == o); }
+};
+
+// Used in RtpCapabilities; represents the capabilities/preferences of an
+// implementation for a header extension.
+//
+// Just called "RtpHeaderExtension" in ORTC, but the "Capability" suffix was
+// added here for consistency and to avoid confusion with
+// RtpHeaderExtensionParameters.
+//
+// Note that ORTC includes a "kind" field, but we omit this because it's
+// redundant; if you call "RtpReceiver::GetCapabilities(MEDIA_TYPE_AUDIO)",
+// you know you're getting audio capabilities.
+struct RtpHeaderExtensionCapability {
+ // URI of this extension, as defined in RFC5285.
+ std::string uri;
+
+ // Preferred value of ID that goes in the packet.
+ rtc::Optional<int> preferred_id;
+
+ // If true, it's preferred that the value in the header is encrypted.
+ // TODO(deadbeef): Not implemented.
+ bool preferred_encrypt = false;
+
+ bool operator==(const RtpHeaderExtensionCapability& o) const {
+ return uri == o.uri && preferred_id == o.preferred_id &&
+ preferred_encrypt == o.preferred_encrypt;
+ }
+ bool operator!=(const RtpHeaderExtensionCapability& o) const {
+ return !(*this == o);
+ }
+};
+
+// Used in RtpParameters; represents a specific configuration of a header
+// extension.
+struct RtpHeaderExtensionParameters {
+ // URI of this extension, as defined in RFC5285.
+ std::string uri;
+
+ // ID value that goes in the packet.
+ int id = 0;
+
+ // If true, the value in the header is encrypted.
+ // TODO(deadbeef): Not implemented.
+ bool encrypt = false;
+
+ bool operator==(const RtpHeaderExtensionParameters& o) const {
+ return uri == o.uri && id == o.id && encrypt == o.encrypt;
+ }
+ bool operator!=(const RtpHeaderExtensionParameters& o) const {
+ return !(*this == o);
+ }
+};
+
+struct RtpFecParameters {
+ // If unset, a value is chosen by the implementation.
rtc::Optional<uint32_t> ssrc;
+
+ FecMechanism mechanism = FecMechanism::RED;
+
+ bool operator==(const RtpFecParameters& o) const {
+ return ssrc == o.ssrc && mechanism == o.mechanism;
+ }
+ bool operator!=(const RtpFecParameters& o) const { return !(*this == o); }
+};
+
+struct RtpRtxParameters {
+ // If unset, a value is chosen by the implementation.
+ rtc::Optional<uint32_t> ssrc;
+
+ bool operator==(const RtpRtxParameters& o) const { return ssrc == o.ssrc; }
+ bool operator!=(const RtpRtxParameters& o) const { return !(*this == o); }
+};
+
+struct RtpEncodingParameters {
+ // If unset, a value is chosen by the implementation.
+ rtc::Optional<uint32_t> ssrc;
+
+ // Can be used to reference a codec in the |codecs| member of the
+ // RtpParameters that contains this RtpEncodingParameters. If unset, the
+ // implementation will choose the first possible codec.
+ // TODO(deadbeef): Not implemented.
+ rtc::Optional<int> codec_payload_type;
+
+ // Specifies the FEC mechanism, if set.
+ // TODO(deadbeef): Not implemented.
+ rtc::Optional<RtpFecParameters> fec;
+
+ // Specifies the RTX parameters, if set.
+ // TODO(deadbeef): Not implemented.
+ rtc::Optional<RtpRtxParameters> rtx;
+
+ // Only used for audio. If set, determines whether or not discontinuous
+ // transmission will be used, if an available codec supports it. If not
+ // set, the implementation default setting will be used.
+ rtc::Optional<DtxStatus> dtx;
+
+ // The relative priority of this encoding.
+ // TODO(deadbeef): Not implemented.
+ rtc::Optional<PriorityType> priority;
+
+ // If set, this represents the Transport Independent Application Specific
+ // maximum bandwidth defined in RFC3890. If unset, there is no maximum
+ // bitrate.
+ // Just called "maxBitrate" in ORTC spec.
+ rtc::Optional<int> max_bitrate_bps;
+
+ // TODO(deadbeef): Not implemented.
+ rtc::Optional<int> max_framerate;
+
+ // For video, scale the resolution down by this factor.
+ // TODO(deadbeef): Not implemented.
+ double scale_resolution_down_by = 1.0;
+
+ // Scale the framerate down by this factor.
+ // TODO(deadbeef): Not implemented.
+ double scale_framerate_down_by = 1.0;
+
+ // For an RtpSender, set to true to cause this encoding to be sent, and false
+ // for it not to be sent. For an RtpReceiver, set to true to cause the
+ // encoding to be decoded, and false for it to be ignored.
+ // TODO(deadbeef): RtpReceiver part is not implemented.
bool active = true;
- int max_bitrate_bps = -1;
+
+ // Value to use for RID RTP header extension.
+ // Called "encodingId" in ORTC.
+ // TODO(deadbeef): Not implemented.
+ std::string rid;
+
+ // RIDs of encodings on which this layer depends.
+ // Called "dependencyEncodingIds" in ORTC spec.
+ // TODO(deadbeef): Not implemented.
+ std::vector<std::string> dependency_rids;
bool operator==(const RtpEncodingParameters& o) const {
- return ssrc == o.ssrc && active == o.active &&
- max_bitrate_bps == o.max_bitrate_bps;
+ return ssrc == o.ssrc && codec_payload_type == o.codec_payload_type &&
+ fec == o.fec && rtx == o.rtx && dtx == o.dtx &&
+ priority == o.priority && max_bitrate_bps == o.max_bitrate_bps &&
+ max_framerate == o.max_framerate &&
+ scale_resolution_down_by == o.scale_resolution_down_by &&
+ scale_framerate_down_by == o.scale_framerate_down_by &&
+ active == o.active && rid == o.rid &&
+ dependency_rids == o.dependency_rids;
}
bool operator!=(const RtpEncodingParameters& o) const {
return !(*this == o);
@@ -35,25 +310,107 @@
};
struct RtpCodecParameters {
- int payload_type;
- std::string mime_type;
- int clock_rate;
- int channels = 1;
- // TODO(deadbeef): Add sdpFmtpLine field.
+ // Build MIME "type/subtype" string from |name| and |kind|.
+ std::string mime_type() const { return MediaTypeToString(kind) + "/" + name; }
+
+ // Used to identify the codec. Equivalent to MIME subtype.
+ std::string name;
+
+ // The media type of this codec. Equivalent to MIME top-level type.
+ cricket::MediaType kind = cricket::MEDIA_TYPE_AUDIO;
+
+ // Payload type used to identify this codec in RTP packets.
+ // This MUST always be present, and must be unique across all codecs using
+ // the same transport.
+ int payload_type = 0;
+
+ // If unset, the implementation default is used.
+ rtc::Optional<int> clock_rate;
+
+ // The number of audio channels used. Unset for video codecs. If unset for
+ // audio, the implementation default is used.
+ // TODO(deadbeef): The "implementation default" part is unimplemented.
+ rtc::Optional<int> num_channels;
+
+ // The maximum packetization time to be used by an RtpSender.
+ // If |ptime| is also set, this will be ignored.
+ // TODO(deadbeef): Not implemented.
+ rtc::Optional<int> max_ptime;
+
+ // The packetization time to be used by an RtpSender.
+ // If unset, will use any time up to max_ptime.
+ // TODO(deadbeef): Not implemented.
+ rtc::Optional<int> ptime;
+
+ // Feedback mechanisms to be used for this codec.
+ // TODO(deadbeef): Not implemented.
+ std::vector<RtcpFeedback> rtcp_feedback;
+
+ // Codec-specific parameters that must be signaled to the remote party.
+ // Corresponds to "a=fmtp" parameters in SDP.
+ // TODO(deadbeef): Not implemented.
+ std::unordered_map<std::string, std::string> parameters;
bool operator==(const RtpCodecParameters& o) const {
- return payload_type == o.payload_type && mime_type == o.mime_type &&
- clock_rate == o.clock_rate && channels == o.channels;
+ return name == o.name && kind == o.kind && payload_type == o.payload_type &&
+ clock_rate == o.clock_rate && num_channels == o.num_channels &&
+ max_ptime == o.max_ptime && ptime == o.ptime &&
+ rtcp_feedback == o.rtcp_feedback && parameters == o.parameters;
}
bool operator!=(const RtpCodecParameters& o) const { return !(*this == o); }
};
+// RtpCapabilities is used to represent the static capabilities of an
+// endpoint. An application can use these capabilities to construct an
+// RtpParameters.
+struct RtpCapabilities {
+ // Supported codecs.
+ std::vector<RtpCodecCapability> codecs;
+
+ // Supported RTP header extensions.
+ std::vector<RtpHeaderExtensionCapability> header_extensions;
+
+ // Supported Forward Error Correction (FEC) mechanisms.
+ std::vector<FecMechanism> fec;
+
+ bool operator==(const RtpCapabilities& o) const {
+ return codecs == o.codecs && header_extensions == o.header_extensions &&
+ fec == o.fec;
+ }
+ bool operator!=(const RtpCapabilities& o) const { return !(*this == o); }
+};
+
+// Note that unlike in ORTC, an RtcpParameters is not included in
+// RtpParameters, because our API will include an additional "RtpTransport"
+// abstraction on which RTCP parameters are set.
struct RtpParameters {
- std::vector<RtpEncodingParameters> encodings;
+ // Used when calling getParameters/setParameters with a PeerConnection
+ // RtpSender, to ensure that outdated parameters are not unintentionally
+ // applied successfully.
+ // TODO(deadbeef): Not implemented.
+ std::string transaction_id;
+
+ // Value to use for MID RTP header extension.
+ // Called "muxId" in ORTC.
+ // TODO(deadbeef): Not implemented.
+ std::string mid;
+
std::vector<RtpCodecParameters> codecs;
+ // TODO(deadbeef): Not implemented.
+ std::vector<RtpHeaderExtensionParameters> header_extensions;
+
+ std::vector<RtpEncodingParameters> encodings;
+
+ // TODO(deadbeef): Not implemented.
+ DegradationPreference degradation_preference =
+ DegradationPreference::BALANCED;
+
bool operator==(const RtpParameters& o) const {
- return encodings == o.encodings && codecs == o.codecs;
+ return mid == o.mid && codecs == o.codecs &&
+ header_extensions == o.header_extensions &&
+ encodings == o.encodings &&
+ degradation_preference == o.degradation_preference;
}
bool operator!=(const RtpParameters& o) const { return !(*this == o); }
};
diff --git a/webrtc/media/base/codec.cc b/webrtc/media/base/codec.cc
index 75e5a7b..1e305a6 100644
--- a/webrtc/media/base/codec.cc
+++ b/webrtc/media/base/codec.cc
@@ -149,8 +149,8 @@
webrtc::RtpCodecParameters Codec::ToCodecParameters() const {
webrtc::RtpCodecParameters codec_params;
codec_params.payload_type = id;
- codec_params.mime_type = name;
- codec_params.clock_rate = clockrate;
+ codec_params.name = name;
+ codec_params.clock_rate = rtc::Optional<int>(clockrate);
return codec_params;
}
@@ -190,12 +190,6 @@
((codec.channels < 2 && channels < 2) || channels == codec.channels);
}
-webrtc::RtpCodecParameters AudioCodec::ToCodecParameters() const {
- webrtc::RtpCodecParameters codec_params = Codec::ToCodecParameters();
- codec_params.channels = static_cast<int>(channels);
- return codec_params;
-}
-
std::string AudioCodec::ToString() const {
std::ostringstream os;
os << "AudioCodec[" << id << ":" << name << ":" << clockrate << ":" << bitrate
@@ -203,12 +197,25 @@
return os.str();
}
+webrtc::RtpCodecParameters AudioCodec::ToCodecParameters() const {
+ webrtc::RtpCodecParameters codec_params = Codec::ToCodecParameters();
+ codec_params.num_channels = rtc::Optional<int>(static_cast<int>(channels));
+ codec_params.kind = MEDIA_TYPE_AUDIO;
+ return codec_params;
+}
+
std::string VideoCodec::ToString() const {
std::ostringstream os;
os << "VideoCodec[" << id << ":" << name << "]";
return os.str();
}
+webrtc::RtpCodecParameters VideoCodec::ToCodecParameters() const {
+ webrtc::RtpCodecParameters codec_params = Codec::ToCodecParameters();
+ codec_params.kind = MEDIA_TYPE_VIDEO;
+ return codec_params;
+}
+
VideoCodec::VideoCodec(int id, const std::string& name)
: Codec(id, name, kVideoCodecClockrate) {
SetDefaultParameters();
diff --git a/webrtc/media/base/codec.h b/webrtc/media/base/codec.h
index ac85d1f..7dd8889 100644
--- a/webrtc/media/base/codec.h
+++ b/webrtc/media/base/codec.h
@@ -162,6 +162,8 @@
std::string ToString() const;
+ webrtc::RtpCodecParameters ToCodecParameters() const override;
+
VideoCodec& operator=(const VideoCodec& c);
VideoCodec& operator=(VideoCodec&& c);
diff --git a/webrtc/media/base/codec_unittest.cc b/webrtc/media/base/codec_unittest.cc
index 77c1fd0..5a375fc 100644
--- a/webrtc/media/base/codec_unittest.cc
+++ b/webrtc/media/base/codec_unittest.cc
@@ -311,14 +311,17 @@
const VideoCodec v(96, "V");
webrtc::RtpCodecParameters codec_params_1 = v.ToCodecParameters();
EXPECT_EQ(96, codec_params_1.payload_type);
- EXPECT_EQ("V", codec_params_1.mime_type);
- EXPECT_EQ(cricket::kVideoCodecClockrate, codec_params_1.clock_rate);
- EXPECT_EQ(1, codec_params_1.channels);
+ EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, codec_params_1.kind);
+ EXPECT_EQ("V", codec_params_1.name);
+ EXPECT_EQ(rtc::Optional<int>(cricket::kVideoCodecClockrate),
+ codec_params_1.clock_rate);
+ EXPECT_EQ(rtc::Optional<int>(), codec_params_1.num_channels);
const AudioCodec a(97, "A", 44100, 20000, 2);
webrtc::RtpCodecParameters codec_params_2 = a.ToCodecParameters();
EXPECT_EQ(97, codec_params_2.payload_type);
- EXPECT_EQ("A", codec_params_2.mime_type);
- EXPECT_EQ(44100, codec_params_2.clock_rate);
- EXPECT_EQ(2, codec_params_2.channels);
+ EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, codec_params_2.kind);
+ EXPECT_EQ("A", codec_params_2.name);
+ EXPECT_EQ(rtc::Optional<int>(44100), codec_params_2.clock_rate);
+ EXPECT_EQ(rtc::Optional<int>(2), codec_params_2.num_channels);
}
diff --git a/webrtc/media/engine/webrtcvideoengine2.cc b/webrtc/media/engine/webrtcvideoengine2.cc
index c6c522a..955560a 100644
--- a/webrtc/media/engine/webrtcvideoengine2.cc
+++ b/webrtc/media/engine/webrtcvideoengine2.cc
@@ -1861,9 +1861,12 @@
encoder_config.number_of_streams = 1;
}
- int stream_max_bitrate =
- MinPositive(rtp_parameters_.encodings[0].max_bitrate_bps,
- parameters_.max_bitrate_bps);
+ int stream_max_bitrate = parameters_.max_bitrate_bps;
+ if (rtp_parameters_.encodings[0].max_bitrate_bps) {
+ stream_max_bitrate =
+ MinPositive(*(rtp_parameters_.encodings[0].max_bitrate_bps),
+ parameters_.max_bitrate_bps);
+ }
int codec_max_bitrate_kbps;
if (codec.GetParam(kCodecParamMaxBitrate, &codec_max_bitrate_kbps)) {
diff --git a/webrtc/media/engine/webrtcvideoengine2_unittest.cc b/webrtc/media/engine/webrtcvideoengine2_unittest.cc
index f7bfeb1..4b73faa 100644
--- a/webrtc/media/engine/webrtcvideoengine2_unittest.cc
+++ b/webrtc/media/engine/webrtcvideoengine2_unittest.cc
@@ -1177,12 +1177,13 @@
webrtc::RtpParameters parameters =
channel_->GetRtpSendParameters(last_ssrc_);
EXPECT_EQ(1UL, parameters.encodings.size());
- parameters.encodings[0].max_bitrate_bps = stream_max;
+ parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(stream_max);
EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
// Read back the parameteres and verify they have the correct value
parameters = channel_->GetRtpSendParameters(last_ssrc_);
EXPECT_EQ(1UL, parameters.encodings.size());
- EXPECT_EQ(stream_max, parameters.encodings[0].max_bitrate_bps);
+ EXPECT_EQ(rtc::Optional<int>(stream_max),
+ parameters.encodings[0].max_bitrate_bps);
// Verify that the new value propagated down to the encoder
EXPECT_EQ(expected_encoder_bitrate, GetMaxEncoderBitrate());
}
diff --git a/webrtc/media/engine/webrtcvoiceengine.cc b/webrtc/media/engine/webrtcvoiceengine.cc
index 65a238f..7029e5b 100644
--- a/webrtc/media/engine/webrtcvoiceengine.cc
+++ b/webrtc/media/engine/webrtcvoiceengine.cc
@@ -520,10 +520,16 @@
{kDtmfCodecName, 8000, 1, 126, false, {}}
};
+// |max_send_bitrate_bps| is the bitrate from "b=" in SDP.
+// |rtp_max_bitrate_bps| is the bitrate from RtpSender::SetParameters.
rtc::Optional<int> ComputeSendBitrate(int max_send_bitrate_bps,
- int rtp_max_bitrate_bps,
+ rtc::Optional<int> rtp_max_bitrate_bps,
const webrtc::CodecInst& codec_inst) {
- const int bps = MinPositive(max_send_bitrate_bps, rtp_max_bitrate_bps);
+ // If application-configured bitrate is set, take minimum of that and SDP
+ // bitrate.
+ const int bps = rtp_max_bitrate_bps
+ ? MinPositive(max_send_bitrate_bps, *rtp_max_bitrate_bps)
+ : max_send_bitrate_bps;
const int codec_rate = codec_inst.rate;
if (bps <= 0) {
diff --git a/webrtc/media/engine/webrtcvoiceengine_unittest.cc b/webrtc/media/engine/webrtcvoiceengine_unittest.cc
index 526f7cc..a7ea8c2 100644
--- a/webrtc/media/engine/webrtcvoiceengine_unittest.cc
+++ b/webrtc/media/engine/webrtcvoiceengine_unittest.cc
@@ -289,7 +289,7 @@
webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc);
EXPECT_EQ(1UL, parameters.encodings.size());
- parameters.encodings[0].max_bitrate_bps = bitrate;
+ parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(bitrate);
return channel_->SetRtpSendParameters(ssrc, parameters);
}
diff --git a/webrtc/pc/channel_unittest.cc b/webrtc/pc/channel_unittest.cc
index 57e7afb..a64fc34 100644
--- a/webrtc/pc/channel_unittest.cc
+++ b/webrtc/pc/channel_unittest.cc
@@ -1956,7 +1956,7 @@
return channel1_->SetRemoteContent(&content, CA_OFFER, NULL);
}
- webrtc::RtpParameters BitrateLimitedParameters(int limit) {
+ webrtc::RtpParameters BitrateLimitedParameters(rtc::Optional<int> limit) {
webrtc::RtpParameters parameters;
webrtc::RtpEncodingParameters encoding;
encoding.max_bitrate_bps = limit;
@@ -1965,7 +1965,7 @@
}
void VerifyMaxBitrate(const webrtc::RtpParameters& parameters,
- int expected_bitrate) {
+ rtc::Optional<int> expected_bitrate) {
EXPECT_EQ(1UL, parameters.encodings.size());
EXPECT_EQ(expected_bitrate, parameters.encodings[0].max_bitrate_bps);
}
@@ -1975,7 +1975,8 @@
EXPECT_TRUE(
channel1_->SetLocalContent(&local_media_content1_, CA_OFFER, NULL));
EXPECT_EQ(media_channel1_->max_bps(), -1);
- VerifyMaxBitrate(media_channel1_->GetRtpSendParameters(kSsrc1), -1);
+ VerifyMaxBitrate(media_channel1_->GetRtpSendParameters(kSsrc1),
+ rtc::Optional<int>());
}
void CanChangeMaxBitrate() {
@@ -1984,15 +1985,19 @@
channel1_->SetLocalContent(&local_media_content1_, CA_OFFER, NULL));
EXPECT_TRUE(channel1_->SetRtpSendParameters(
- kSsrc1, BitrateLimitedParameters(1000)));
- VerifyMaxBitrate(channel1_->GetRtpSendParameters(kSsrc1), 1000);
- VerifyMaxBitrate(media_channel1_->GetRtpSendParameters(kSsrc1), 1000);
+ kSsrc1, BitrateLimitedParameters(rtc::Optional<int>(1000))));
+ VerifyMaxBitrate(channel1_->GetRtpSendParameters(kSsrc1),
+ rtc::Optional<int>(1000));
+ VerifyMaxBitrate(media_channel1_->GetRtpSendParameters(kSsrc1),
+ rtc::Optional<int>(1000));
EXPECT_EQ(-1, media_channel1_->max_bps());
- EXPECT_TRUE(
- channel1_->SetRtpSendParameters(kSsrc1, BitrateLimitedParameters(-1)));
- VerifyMaxBitrate(channel1_->GetRtpSendParameters(kSsrc1), -1);
- VerifyMaxBitrate(media_channel1_->GetRtpSendParameters(kSsrc1), -1);
+ EXPECT_TRUE(channel1_->SetRtpSendParameters(
+ kSsrc1, BitrateLimitedParameters(rtc::Optional<int>())));
+ VerifyMaxBitrate(channel1_->GetRtpSendParameters(kSsrc1),
+ rtc::Optional<int>());
+ VerifyMaxBitrate(media_channel1_->GetRtpSendParameters(kSsrc1),
+ rtc::Optional<int>());
EXPECT_EQ(-1, media_channel1_->max_bps());
}
diff --git a/webrtc/pc/rtcstatscollector.cc b/webrtc/pc/rtcstatscollector.cc
index 6344d87..435cf8e 100644
--- a/webrtc/pc/rtcstatscollector.cc
+++ b/webrtc/pc/rtcstatscollector.cc
@@ -170,13 +170,16 @@
const RtpCodecParameters& codec_params) {
RTC_DCHECK_GE(codec_params.payload_type, 0);
RTC_DCHECK_LE(codec_params.payload_type, 127);
+ RTC_DCHECK(codec_params.clock_rate);
uint32_t payload_type = static_cast<uint32_t>(codec_params.payload_type);
std::unique_ptr<RTCCodecStats> codec_stats(new RTCCodecStats(
RTCCodecStatsIDFromDirectionMediaAndPayload(inbound, audio, payload_type),
timestamp_us));
codec_stats->payload_type = payload_type;
- codec_stats->codec = (audio ? "audio/" : "video/") + codec_params.mime_type;
- codec_stats->clock_rate = static_cast<uint32_t>(codec_params.clock_rate);
+ codec_stats->codec = codec_params.mime_type();
+ if (codec_params.clock_rate) {
+ codec_stats->clock_rate = static_cast<uint32_t>(*codec_params.clock_rate);
+ }
return codec_stats;
}
diff --git a/webrtc/pc/rtcstatscollector_unittest.cc b/webrtc/pc/rtcstatscollector_unittest.cc
index 6d1595e..178deee 100644
--- a/webrtc/pc/rtcstatscollector_unittest.cc
+++ b/webrtc/pc/rtcstatscollector_unittest.cc
@@ -765,15 +765,17 @@
RtpCodecParameters inbound_audio_codec;
inbound_audio_codec.payload_type = 1;
- inbound_audio_codec.mime_type = "opus";
- inbound_audio_codec.clock_rate = 1337;
+ inbound_audio_codec.kind = cricket::MEDIA_TYPE_AUDIO;
+ inbound_audio_codec.name = "opus";
+ inbound_audio_codec.clock_rate = rtc::Optional<int>(1337);
voice_media_info.receive_codecs.insert(
std::make_pair(inbound_audio_codec.payload_type, inbound_audio_codec));
RtpCodecParameters outbound_audio_codec;
outbound_audio_codec.payload_type = 2;
- outbound_audio_codec.mime_type = "isac";
- outbound_audio_codec.clock_rate = 1338;
+ outbound_audio_codec.kind = cricket::MEDIA_TYPE_AUDIO;
+ outbound_audio_codec.name = "isac";
+ outbound_audio_codec.clock_rate = rtc::Optional<int>(1338);
voice_media_info.send_codecs.insert(
std::make_pair(outbound_audio_codec.payload_type, outbound_audio_codec));
@@ -785,15 +787,17 @@
RtpCodecParameters inbound_video_codec;
inbound_video_codec.payload_type = 3;
- inbound_video_codec.mime_type = "H264";
- inbound_video_codec.clock_rate = 1339;
+ inbound_video_codec.kind = cricket::MEDIA_TYPE_VIDEO;
+ inbound_video_codec.name = "H264";
+ inbound_video_codec.clock_rate = rtc::Optional<int>(1339);
video_media_info.receive_codecs.insert(
std::make_pair(inbound_video_codec.payload_type, inbound_video_codec));
RtpCodecParameters outbound_video_codec;
outbound_video_codec.payload_type = 4;
- outbound_video_codec.mime_type = "VP8";
- outbound_video_codec.clock_rate = 1340;
+ outbound_video_codec.kind = cricket::MEDIA_TYPE_VIDEO;
+ outbound_video_codec.name = "VP8";
+ outbound_video_codec.clock_rate = rtc::Optional<int>(1340);
video_media_info.send_codecs.insert(
std::make_pair(outbound_video_codec.payload_type, outbound_video_codec));
@@ -1687,8 +1691,9 @@
RtpCodecParameters codec_parameters;
codec_parameters.payload_type = 42;
- codec_parameters.mime_type = "dummy";
- codec_parameters.clock_rate = 0;
+ codec_parameters.kind = cricket::MEDIA_TYPE_AUDIO;
+ codec_parameters.name = "dummy";
+ codec_parameters.clock_rate = rtc::Optional<int>(0);
voice_media_info.receive_codecs.insert(
std::make_pair(codec_parameters.payload_type, codec_parameters));
@@ -1769,8 +1774,9 @@
RtpCodecParameters codec_parameters;
codec_parameters.payload_type = 42;
- codec_parameters.mime_type = "dummy";
- codec_parameters.clock_rate = 0;
+ codec_parameters.kind = cricket::MEDIA_TYPE_AUDIO;
+ codec_parameters.name = "dummy";
+ codec_parameters.clock_rate = rtc::Optional<int>(0);
video_media_info.receive_codecs.insert(
std::make_pair(codec_parameters.payload_type, codec_parameters));
@@ -1848,8 +1854,9 @@
RtpCodecParameters codec_parameters;
codec_parameters.payload_type = 42;
- codec_parameters.mime_type = "dummy";
- codec_parameters.clock_rate = 0;
+ codec_parameters.kind = cricket::MEDIA_TYPE_AUDIO;
+ codec_parameters.name = "dummy";
+ codec_parameters.clock_rate = rtc::Optional<int>(0);
voice_media_info.send_codecs.insert(
std::make_pair(codec_parameters.payload_type, codec_parameters));
@@ -1927,8 +1934,9 @@
RtpCodecParameters codec_parameters;
codec_parameters.payload_type = 42;
- codec_parameters.mime_type = "dummy";
- codec_parameters.clock_rate = 0;
+ codec_parameters.kind = cricket::MEDIA_TYPE_AUDIO;
+ codec_parameters.name = "dummy";
+ codec_parameters.clock_rate = rtc::Optional<int>(0);
video_media_info.send_codecs.insert(
std::make_pair(codec_parameters.payload_type, codec_parameters));
diff --git a/webrtc/pc/rtpsenderreceiver_unittest.cc b/webrtc/pc/rtpsenderreceiver_unittest.cc
index 508a417..c02da58 100644
--- a/webrtc/pc/rtpsenderreceiver_unittest.cc
+++ b/webrtc/pc/rtpsenderreceiver_unittest.cc
@@ -575,19 +575,19 @@
EXPECT_EQ(-1, voice_media_channel_->max_bps());
webrtc::RtpParameters params = audio_rtp_sender_->GetParameters();
EXPECT_EQ(1, params.encodings.size());
- EXPECT_EQ(-1, params.encodings[0].max_bitrate_bps);
- params.encodings[0].max_bitrate_bps = 1000;
+ EXPECT_FALSE(params.encodings[0].max_bitrate_bps);
+ params.encodings[0].max_bitrate_bps = rtc::Optional<int>(1000);
EXPECT_TRUE(audio_rtp_sender_->SetParameters(params));
// Read back the parameters and verify they have been changed.
params = audio_rtp_sender_->GetParameters();
EXPECT_EQ(1, params.encodings.size());
- EXPECT_EQ(1000, params.encodings[0].max_bitrate_bps);
+ EXPECT_EQ(rtc::Optional<int>(1000), params.encodings[0].max_bitrate_bps);
// Verify that the audio channel received the new parameters.
params = voice_media_channel_->GetRtpSendParameters(kAudioSsrc);
EXPECT_EQ(1, params.encodings.size());
- EXPECT_EQ(1000, params.encodings[0].max_bitrate_bps);
+ EXPECT_EQ(rtc::Optional<int>(1000), params.encodings[0].max_bitrate_bps);
// Verify that the global bitrate limit has not been changed.
EXPECT_EQ(-1, voice_media_channel_->max_bps());
@@ -611,19 +611,19 @@
EXPECT_EQ(-1, video_media_channel_->max_bps());
webrtc::RtpParameters params = video_rtp_sender_->GetParameters();
EXPECT_EQ(1, params.encodings.size());
- EXPECT_EQ(-1, params.encodings[0].max_bitrate_bps);
- params.encodings[0].max_bitrate_bps = 1000;
+ EXPECT_FALSE(params.encodings[0].max_bitrate_bps);
+ params.encodings[0].max_bitrate_bps = rtc::Optional<int>(1000);
EXPECT_TRUE(video_rtp_sender_->SetParameters(params));
// Read back the parameters and verify they have been changed.
params = video_rtp_sender_->GetParameters();
EXPECT_EQ(1, params.encodings.size());
- EXPECT_EQ(1000, params.encodings[0].max_bitrate_bps);
+ EXPECT_EQ(rtc::Optional<int>(1000), params.encodings[0].max_bitrate_bps);
// Verify that the video channel received the new parameters.
params = video_media_channel_->GetRtpSendParameters(kVideoSsrc);
EXPECT_EQ(1, params.encodings.size());
- EXPECT_EQ(1000, params.encodings[0].max_bitrate_bps);
+ EXPECT_EQ(rtc::Optional<int>(1000), params.encodings[0].max_bitrate_bps);
// Verify that the global bitrate limit has not been changed.
EXPECT_EQ(-1, video_media_channel_->max_bps());
diff --git a/webrtc/sdk/android/api/org/webrtc/RtpParameters.java b/webrtc/sdk/android/api/org/webrtc/RtpParameters.java
index a50cf55..fde2b35 100644
--- a/webrtc/sdk/android/api/org/webrtc/RtpParameters.java
+++ b/webrtc/sdk/android/api/org/webrtc/RtpParameters.java
@@ -15,23 +15,43 @@
/**
* The parameters for an {@code RtpSender}, as defined in
* http://w3c.github.io/webrtc-pc/#rtcrtpsender-interface.
+ *
+ * Note: These structures use nullable Integer/etc. types because in the
+ * future, they may be used to construct ORTC RtpSender/RtpReceivers, in
+ * which case "null" will be used to represent "choose the implementation
+ * default value".
*/
public class RtpParameters {
public static class Encoding {
+ // Set to true to cause this encoding to be sent, and false for it not to
+ // be sent.
public boolean active = true;
- // A null value means "no maximum bitrate".
+ // If non-null, this represents the Transport Independent Application
+ // Specific maximum bandwidth defined in RFC3890. If null, there is no
+ // maximum bitrate.
public Integer maxBitrateBps;
+ // SSRC to be used by this encoding.
+ // Can't be changed between getParameters/setParameters.
public Long ssrc;
}
public static class Codec {
- int payloadType;
- String mimeType;
- int clockRate;
- int channels = 1;
+ // Payload type used to identify this codec in RTP packets.
+ public int payloadType;
+ // Name used to identify the codec. Equivalent to MIME subtype.
+ public String name;
+ // The media type of this codec. Equivalent to MIME top-level type.
+ MediaStreamTrack.MediaType kind;
+ // Clock rate in Hertz.
+ public Integer clockRate;
+ // The number of audio channels used. Set to null for video codecs.
+ public Integer numChannels;
}
public final LinkedList<Encoding> encodings;
+ // Codec parameters can't currently be changed between getParameters and
+ // setParameters. Though in the future it will be possible to reorder them or
+ // remove them.
public final LinkedList<Codec> codecs;
public RtpParameters() {
diff --git a/webrtc/sdk/android/src/jni/peerconnection_jni.cc b/webrtc/sdk/android/src/jni/peerconnection_jni.cc
index 6a6ba25..d3f2344 100644
--- a/webrtc/sdk/android/src/jni/peerconnection_jni.cc
+++ b/webrtc/sdk/android/src/jni/peerconnection_jni.cc
@@ -158,6 +158,47 @@
return init;
}
+static cricket::MediaType JavaMediaTypeToJsepMediaType(JNIEnv* jni,
+ jobject j_media_type) {
+ jclass j_media_type_class =
+ FindClass(jni, "org/webrtc/MediaStreamTrack$MediaType");
+ jmethodID j_name_id =
+ GetMethodID(jni, j_media_type_class, "name", "()Ljava/lang/String;");
+ jstring j_type_string =
+ (jstring)jni->CallObjectMethod(j_media_type, j_name_id);
+ CHECK_EXCEPTION(jni) << "error during CallObjectMethod";
+ std::string type_string = JavaToStdString(jni, j_type_string);
+
+ RTC_DCHECK(type_string == "MEDIA_TYPE_AUDIO" ||
+ type_string == "MEDIA_TYPE_VIDEO")
+ << "Media type: " << type_string;
+ return type_string == "MEDIA_TYPE_AUDIO" ? cricket::MEDIA_TYPE_AUDIO
+ : cricket::MEDIA_TYPE_VIDEO;
+}
+
+static jobject JsepMediaTypeToJavaMediaType(JNIEnv* jni,
+ cricket::MediaType media_type) {
+ jclass j_media_type_class =
+ FindClass(jni, "org/webrtc/MediaStreamTrack$MediaType");
+
+ const char* media_type_str = nullptr;
+ switch (media_type) {
+ case cricket::MEDIA_TYPE_AUDIO:
+ media_type_str = "MEDIA_TYPE_AUDIO";
+ break;
+ case cricket::MEDIA_TYPE_VIDEO:
+ media_type_str = "MEDIA_TYPE_VIDEO";
+ break;
+ case cricket::MEDIA_TYPE_DATA:
+ RTC_NOTREACHED();
+ break;
+ }
+ jfieldID j_media_type_fid =
+ GetStaticFieldID(jni, j_media_type_class, media_type_str,
+ "Lorg/webrtc/MediaStreamTrack$MediaType;");
+ return GetStaticObjectField(jni, j_media_type_class, j_media_type_fid);
+}
+
class ConstraintsWrapper;
// Adapter between the C++ PeerConnectionObserver interface and the Java
@@ -917,20 +958,7 @@
jni, GetObjectClass(jni, *j_observer_global_), "onFirstPacketReceived",
"(Lorg/webrtc/MediaStreamTrack$MediaType;)V");
// Get the Java version of media type.
- jclass j_media_type_class =
- FindClass(jni, "org/webrtc/MediaStreamTrack$MediaType");
-
- RTC_DCHECK(media_type == cricket::MEDIA_TYPE_AUDIO ||
- media_type == cricket::MEDIA_TYPE_VIDEO)
- << "Media type: " << media_type;
- const char* media_type_str = media_type == cricket::MEDIA_TYPE_AUDIO
- ? "MEDIA_TYPE_AUDIO"
- : "MEDIA_TYPE_VIDEO";
- jfieldID j_media_type_fid =
- GetStaticFieldID(jni, j_media_type_class, media_type_str,
- "Lorg/webrtc/MediaStreamTrack$MediaType;");
- jobject JavaMediaType =
- GetStaticObjectField(jni, j_media_type_class, j_media_type_fid);
+ jobject JavaMediaType = JsepMediaTypeToJavaMediaType(jni, media_type);
// Trigger the callback function.
jni->CallVoidMethod(*j_observer_global_, j_on_first_packet_received_mid,
JavaMediaType);
@@ -2400,7 +2428,6 @@
// Convert encodings.
jobject j_encodings = GetObjectField(jni, j_parameters, encodings_id);
- const int kBitrateUnlimited = -1;
jclass j_encoding_parameters_class =
jni->FindClass("org/webrtc/RtpParameters$Encoding");
jfieldID active_id =
@@ -2422,9 +2449,7 @@
if (!IsNull(jni, j_bitrate)) {
int bitrate_value = jni->CallIntMethod(j_bitrate, int_value_id);
CHECK_EXCEPTION(jni) << "error during CallIntMethod";
- encoding.max_bitrate_bps = bitrate_value;
- } else {
- encoding.max_bitrate_bps = kBitrateUnlimited;
+ encoding.max_bitrate_bps = rtc::Optional<int>(bitrate_value);
}
jobject j_ssrc =
GetNullableObjectField(jni, j_encoding_parameters, ssrc_id);
@@ -2440,18 +2465,33 @@
jobject j_codecs = GetObjectField(jni, j_parameters, codecs_id);
jclass codec_class = jni->FindClass("org/webrtc/RtpParameters$Codec");
jfieldID payload_type_id = GetFieldID(jni, codec_class, "payloadType", "I");
- jfieldID mime_type_id =
- GetFieldID(jni, codec_class, "mimeType", "Ljava/lang/String;");
- jfieldID clock_rate_id = GetFieldID(jni, codec_class, "clockRate", "I");
- jfieldID channels_id = GetFieldID(jni, codec_class, "channels", "I");
+ jfieldID name_id = GetFieldID(jni, codec_class, "name", "Ljava/lang/String;");
+ jfieldID kind_id = GetFieldID(jni, codec_class, "kind",
+ "Lorg/webrtc/MediaStreamTrack$MediaType;");
+ jfieldID clock_rate_id =
+ GetFieldID(jni, codec_class, "clockRate", "Ljava/lang/Integer;");
+ jfieldID num_channels_id =
+ GetFieldID(jni, codec_class, "numChannels", "Ljava/lang/Integer;");
for (jobject j_codec : Iterable(jni, j_codecs)) {
webrtc::RtpCodecParameters codec;
codec.payload_type = GetIntField(jni, j_codec, payload_type_id);
- codec.mime_type =
- JavaToStdString(jni, GetStringField(jni, j_codec, mime_type_id));
- codec.clock_rate = GetIntField(jni, j_codec, clock_rate_id);
- codec.channels = GetIntField(jni, j_codec, channels_id);
+ codec.name = JavaToStdString(jni, GetStringField(jni, j_codec, name_id));
+ codec.kind = JavaMediaTypeToJsepMediaType(
+ jni, GetObjectField(jni, j_codec, kind_id));
+ jobject j_clock_rate = GetNullableObjectField(jni, j_codec, clock_rate_id);
+ if (!IsNull(jni, j_clock_rate)) {
+ int clock_rate_value = jni->CallIntMethod(j_clock_rate, int_value_id);
+ CHECK_EXCEPTION(jni) << "error during CallIntMethod";
+ codec.clock_rate = rtc::Optional<int>(clock_rate_value);
+ }
+ jobject j_num_channels =
+ GetNullableObjectField(jni, j_codec, num_channels_id);
+ if (!IsNull(jni, j_num_channels)) {
+ int num_channels_value = jni->CallIntMethod(j_num_channels, int_value_id);
+ CHECK_EXCEPTION(jni) << "error during CallIntMethod";
+ codec.num_channels = rtc::Optional<int>(num_channels_value);
+ }
parameters->codecs.push_back(codec);
}
}
@@ -2473,8 +2513,7 @@
jobject j_encodings = GetObjectField(jni, j_parameters, encodings_id);
jmethodID encodings_add = GetMethodID(jni, GetObjectClass(jni, j_encodings),
"add", "(Ljava/lang/Object;)Z");
- jfieldID active_id =
- GetFieldID(jni, encoding_class, "active", "Z");
+ jfieldID active_id = GetFieldID(jni, encoding_class, "active", "Z");
jfieldID bitrate_id =
GetFieldID(jni, encoding_class, "maxBitrateBps", "Ljava/lang/Integer;");
jfieldID ssrc_id =
@@ -2491,9 +2530,9 @@
CHECK_EXCEPTION(jni) << "error during NewObject";
jni->SetBooleanField(j_encoding_parameters, active_id, encoding.active);
CHECK_EXCEPTION(jni) << "error during SetBooleanField";
- if (encoding.max_bitrate_bps > 0) {
- jobject j_bitrate_value =
- jni->NewObject(integer_class, integer_ctor, encoding.max_bitrate_bps);
+ if (encoding.max_bitrate_bps) {
+ jobject j_bitrate_value = jni->NewObject(integer_class, integer_ctor,
+ *(encoding.max_bitrate_bps));
CHECK_EXCEPTION(jni) << "error during NewObject";
jni->SetObjectField(j_encoding_parameters, bitrate_id, j_bitrate_value);
CHECK_EXCEPTION(jni) << "error during SetObjectField";
@@ -2517,26 +2556,42 @@
jfieldID codecs_id =
GetFieldID(jni, parameters_class, "codecs", "Ljava/util/LinkedList;");
jobject j_codecs = GetObjectField(jni, j_parameters, codecs_id);
- jmethodID codecs_add = GetMethodID(jni, GetObjectClass(jni, j_codecs),
- "add", "(Ljava/lang/Object;)Z");
+ jmethodID codecs_add = GetMethodID(jni, GetObjectClass(jni, j_codecs), "add",
+ "(Ljava/lang/Object;)Z");
jfieldID payload_type_id = GetFieldID(jni, codec_class, "payloadType", "I");
- jfieldID mime_type_id =
- GetFieldID(jni, codec_class, "mimeType", "Ljava/lang/String;");
- jfieldID clock_rate_id = GetFieldID(jni, codec_class, "clockRate", "I");
- jfieldID channels_id = GetFieldID(jni, codec_class, "channels", "I");
+ jfieldID name_id = GetFieldID(jni, codec_class, "name", "Ljava/lang/String;");
+ jfieldID kind_id = GetFieldID(jni, codec_class, "kind",
+ "Lorg/webrtc/MediaStreamTrack$MediaType;");
+ jfieldID clock_rate_id =
+ GetFieldID(jni, codec_class, "clockRate", "Ljava/lang/Integer;");
+ jfieldID num_channels_id =
+ GetFieldID(jni, codec_class, "numChannels", "Ljava/lang/Integer;");
for (const webrtc::RtpCodecParameters& codec : parameters.codecs) {
jobject j_codec = jni->NewObject(codec_class, codec_ctor);
CHECK_EXCEPTION(jni) << "error during NewObject";
jni->SetIntField(j_codec, payload_type_id, codec.payload_type);
CHECK_EXCEPTION(jni) << "error during SetIntField";
- jni->SetObjectField(j_codec, mime_type_id,
- JavaStringFromStdString(jni, codec.mime_type));
+ jni->SetObjectField(j_codec, name_id,
+ JavaStringFromStdString(jni, codec.name));
CHECK_EXCEPTION(jni) << "error during SetObjectField";
- jni->SetIntField(j_codec, clock_rate_id, codec.clock_rate);
- CHECK_EXCEPTION(jni) << "error during SetIntField";
- jni->SetIntField(j_codec, channels_id, codec.channels);
- CHECK_EXCEPTION(jni) << "error during SetIntField";
+ jni->SetObjectField(j_codec, kind_id,
+ JsepMediaTypeToJavaMediaType(jni, codec.kind));
+ CHECK_EXCEPTION(jni) << "error during SetObjectField";
+ if (codec.clock_rate) {
+ jobject j_clock_rate_value =
+ jni->NewObject(integer_class, integer_ctor, *(codec.clock_rate));
+ CHECK_EXCEPTION(jni) << "error during NewObject";
+ jni->SetObjectField(j_codec, clock_rate_id, j_clock_rate_value);
+ CHECK_EXCEPTION(jni) << "error during SetObjectField";
+ }
+ if (codec.num_channels) {
+ jobject j_num_channels_value =
+ jni->NewObject(integer_class, integer_ctor, *(codec.num_channels));
+ CHECK_EXCEPTION(jni) << "error during NewObject";
+ jni->SetObjectField(j_codec, num_channels_id, j_num_channels_value);
+ CHECK_EXCEPTION(jni) << "error during SetObjectField";
+ }
jboolean added = jni->CallBooleanMethod(j_codecs, codecs_add, j_codec);
CHECK_EXCEPTION(jni) << "error during CallBooleanMethod";
RTC_CHECK(added);
diff --git a/webrtc/sdk/objc/Framework/Classes/RTCRtpCodecParameters.mm b/webrtc/sdk/objc/Framework/Classes/RTCRtpCodecParameters.mm
index 40f4f25..90529c8 100644
--- a/webrtc/sdk/objc/Framework/Classes/RTCRtpCodecParameters.mm
+++ b/webrtc/sdk/objc/Framework/Classes/RTCRtpCodecParameters.mm
@@ -11,33 +11,36 @@
#import "RTCRtpCodecParameters+Private.h"
#import "NSString+StdString.h"
+#import "WebRTC/RTCMediaStreamTrack.h" // For "kind" strings.
+#include "webrtc/base/checks.h"
#include "webrtc/media/base/mediaconstants.h"
-const NSString * const kRTCRtxCodecMimeType = @(cricket::kRtxCodecName);
-const NSString * const kRTCRedCodecMimeType = @(cricket::kRedCodecName);
-const NSString * const kRTCUlpfecCodecMimeType = @(cricket::kUlpfecCodecName);
-const NSString * const kRTCFlexfecCodecMimeType = @(cricket::kFlexfecCodecName);
-const NSString * const kRTCOpusCodecMimeType = @(cricket::kOpusCodecName);
-const NSString * const kRTCIsacCodecMimeType = @(cricket::kIsacCodecName);
-const NSString * const kRTCL16CodecMimeType = @(cricket::kL16CodecName);
-const NSString * const kRTCG722CodecMimeType = @(cricket::kG722CodecName);
-const NSString * const kRTCIlbcCodecMimeType = @(cricket::kIlbcCodecName);
-const NSString * const kRTCPcmuCodecMimeType = @(cricket::kPcmuCodecName);
-const NSString * const kRTCPcmaCodecMimeType = @(cricket::kPcmaCodecName);
-const NSString * const kRTCDtmfCodecMimeType = @(cricket::kDtmfCodecName);
-const NSString * const kRTCComfortNoiseCodecMimeType =
+const NSString * const kRTCRtxCodecName = @(cricket::kRtxCodecName);
+const NSString * const kRTCRedCodecName = @(cricket::kRedCodecName);
+const NSString * const kRTCUlpfecCodecName = @(cricket::kUlpfecCodecName);
+const NSString * const kRTCFlexfecCodecName = @(cricket::kFlexfecCodecName);
+const NSString * const kRTCOpusCodecName = @(cricket::kOpusCodecName);
+const NSString * const kRTCIsacCodecName = @(cricket::kIsacCodecName);
+const NSString * const kRTCL16CodecName = @(cricket::kL16CodecName);
+const NSString * const kRTCG722CodecName = @(cricket::kG722CodecName);
+const NSString * const kRTCIlbcCodecName = @(cricket::kIlbcCodecName);
+const NSString * const kRTCPcmuCodecName = @(cricket::kPcmuCodecName);
+const NSString * const kRTCPcmaCodecName = @(cricket::kPcmaCodecName);
+const NSString * const kRTCDtmfCodecName = @(cricket::kDtmfCodecName);
+const NSString * const kRTCComfortNoiseCodecName =
@(cricket::kComfortNoiseCodecName);
-const NSString * const kVp8CodecMimeType = @(cricket::kVp8CodecName);
-const NSString * const kVp9CodecMimeType = @(cricket::kVp9CodecName);
-const NSString * const kH264CodecMimeType = @(cricket::kH264CodecName);
+const NSString * const kVp8CodecName = @(cricket::kVp8CodecName);
+const NSString * const kVp9CodecName = @(cricket::kVp9CodecName);
+const NSString * const kH264CodecName = @(cricket::kH264CodecName);
@implementation RTCRtpCodecParameters
@synthesize payloadType = _payloadType;
-@synthesize mimeType = _mimeType;
+@synthesize name = _name;
+@synthesize kind = _kind;
@synthesize clockRate = _clockRate;
-@synthesize channels = _channels;
+@synthesize numChannels = _numChannels;
- (instancetype)init {
return [super init];
@@ -47,9 +50,24 @@
(const webrtc::RtpCodecParameters &)nativeParameters {
if (self = [self init]) {
_payloadType = nativeParameters.payload_type;
- _mimeType = [NSString stringForStdString:nativeParameters.mime_type];
- _clockRate = nativeParameters.clock_rate;
- _channels = nativeParameters.channels;
+ _name = [NSString stringForStdString:nativeParameters.name];
+ switch (nativeParameters.kind) {
+ case cricket::MEDIA_TYPE_AUDIO:
+ _kind = kRTCMediaStreamTrackKindAudio;
+ break;
+ case cricket::MEDIA_TYPE_VIDEO:
+ _kind = kRTCMediaStreamTrackKindVideo;
+ break;
+ case cricket::MEDIA_TYPE_DATA:
+ RTC_NOTREACHED();
+ break;
+ }
+ if (nativeParameters.clock_rate) {
+ _clockRate = [NSNumber numberWithInt:*nativeParameters.clock_rate];
+ }
+ if (nativeParameters.num_channels) {
+ _numChannels = [NSNumber numberWithInt:*nativeParameters.num_channels];
+ }
}
return self;
}
@@ -57,9 +75,22 @@
- (webrtc::RtpCodecParameters)nativeParameters {
webrtc::RtpCodecParameters parameters;
parameters.payload_type = _payloadType;
- parameters.mime_type = [NSString stdStringForString:_mimeType];
- parameters.clock_rate = _clockRate;
- parameters.channels = _channels;
+ parameters.name = [NSString stdStringForString:_name];
+ // NSString pointer comparison is safe here since "kind" is readonly and only
+ // populated above.
+ if (_kind == kRTCMediaStreamTrackKindAudio) {
+ parameters.kind = cricket::MEDIA_TYPE_AUDIO;
+ } else if (_kind == kRTCMediaStreamTrackKindVideo) {
+ parameters.kind = cricket::MEDIA_TYPE_VIDEO;
+ } else {
+ RTC_NOTREACHED();
+ }
+ if (_clockRate != nil) {
+ parameters.clock_rate = rtc::Optional<int>(_clockRate.intValue);
+ }
+ if (_numChannels != nil) {
+ parameters.num_channels = rtc::Optional<int>(_numChannels.intValue);
+ }
return parameters;
}
diff --git a/webrtc/sdk/objc/Framework/Classes/RTCRtpEncodingParameters.mm b/webrtc/sdk/objc/Framework/Classes/RTCRtpEncodingParameters.mm
index be47894..8e72d18 100644
--- a/webrtc/sdk/objc/Framework/Classes/RTCRtpEncodingParameters.mm
+++ b/webrtc/sdk/objc/Framework/Classes/RTCRtpEncodingParameters.mm
@@ -16,8 +16,6 @@
@synthesize maxBitrateBps = _maxBitrateBps;
@synthesize ssrc = _ssrc;
-static const int kBitrateUnlimited = -1;
-
- (instancetype)init {
return [super init];
}
@@ -26,10 +24,9 @@
(const webrtc::RtpEncodingParameters &)nativeParameters {
if (self = [self init]) {
_isActive = nativeParameters.active;
- // TODO(skvlad): Replace with rtc::Optional once the C++ code is updated.
- if (nativeParameters.max_bitrate_bps != kBitrateUnlimited) {
+ if (nativeParameters.max_bitrate_bps) {
_maxBitrateBps =
- [NSNumber numberWithInt:nativeParameters.max_bitrate_bps];
+ [NSNumber numberWithInt:*nativeParameters.max_bitrate_bps];
}
if (nativeParameters.ssrc) {
_ssrc = [NSNumber numberWithUnsignedLong:*nativeParameters.ssrc];
@@ -42,7 +39,7 @@
webrtc::RtpEncodingParameters parameters;
parameters.active = _isActive;
if (_maxBitrateBps != nil) {
- parameters.max_bitrate_bps = _maxBitrateBps.intValue;
+ parameters.max_bitrate_bps = rtc::Optional<int>(_maxBitrateBps.intValue);
}
if (_ssrc != nil) {
parameters.ssrc = rtc::Optional<uint32_t>(_ssrc.unsignedLongValue);
diff --git a/webrtc/sdk/objc/Framework/Headers/WebRTC/RTCRtpCodecParameters.h b/webrtc/sdk/objc/Framework/Headers/WebRTC/RTCRtpCodecParameters.h
index a3156bb..c7ca2f5 100644
--- a/webrtc/sdk/objc/Framework/Headers/WebRTC/RTCRtpCodecParameters.h
+++ b/webrtc/sdk/objc/Framework/Headers/WebRTC/RTCRtpCodecParameters.h
@@ -14,22 +14,22 @@
NS_ASSUME_NONNULL_BEGIN
-RTC_EXTERN const NSString * const kRTCRtxCodecMimeType;
-RTC_EXTERN const NSString * const kRTCRedCodecMimeType;
-RTC_EXTERN const NSString * const kRTCUlpfecCodecMimeType;
-RTC_EXTERN const NSString * const kRTCFlexfecCodecMimeType;
-RTC_EXTERN const NSString * const kRTCOpusCodecMimeType;
-RTC_EXTERN const NSString * const kRTCIsacCodecMimeType;
-RTC_EXTERN const NSString * const kRTCL16CodecMimeType;
-RTC_EXTERN const NSString * const kRTCG722CodecMimeType;
-RTC_EXTERN const NSString * const kRTCIlbcCodecMimeType;
-RTC_EXTERN const NSString * const kRTCPcmuCodecMimeType;
-RTC_EXTERN const NSString * const kRTCPcmaCodecMimeType;
-RTC_EXTERN const NSString * const kRTCDtmfCodecMimeType;
-RTC_EXTERN const NSString * const kRTCComfortNoiseCodecMimeType;
-RTC_EXTERN const NSString * const kRTCVp8CodecMimeType;
-RTC_EXTERN const NSString * const kRTCVp9CodecMimeType;
-RTC_EXTERN const NSString * const kRTCH264CodecMimeType;
+RTC_EXTERN const NSString * const kRTCRtxCodecName;
+RTC_EXTERN const NSString * const kRTCRedCodecName;
+RTC_EXTERN const NSString * const kRTCUlpfecCodecName;
+RTC_EXTERN const NSString * const kRTCFlexfecCodecName;
+RTC_EXTERN const NSString * const kRTCOpusCodecName;
+RTC_EXTERN const NSString * const kRTCIsacCodecName;
+RTC_EXTERN const NSString * const kRTCL16CodecName;
+RTC_EXTERN const NSString * const kRTCG722CodecName;
+RTC_EXTERN const NSString * const kRTCIlbcCodecName;
+RTC_EXTERN const NSString * const kRTCPcmuCodecName;
+RTC_EXTERN const NSString * const kRTCPcmaCodecName;
+RTC_EXTERN const NSString * const kRTCDtmfCodecName;
+RTC_EXTERN const NSString * const kRTCComfortNoiseCodecName;
+RTC_EXTERN const NSString * const kRTCVp8CodecName;
+RTC_EXTERN const NSString * const kRTCVp9CodecName;
+RTC_EXTERN const NSString * const kRTCH264CodecName;
/** Defined in http://w3c.github.io/webrtc-pc/#idl-def-RTCRtpCodecParameters */
RTC_EXPORT
@@ -39,18 +39,29 @@
@property(nonatomic, assign) int payloadType;
/**
- * The codec MIME type. Valid types are listed in:
+ * The codec MIME subtype. Valid types are listed in:
* http://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml#rtp-parameters-2
*
* Several supported types are represented by the constants above.
*/
-@property(nonatomic, nonnull) NSString *mimeType;
+@property(nonatomic, readonly, nonnull) NSString *name;
+
+/**
+ * The media type of this codec. Equivalent to MIME top-level type.
+ *
+ * Valid values are kRTCMediaStreamTrackKindAudio and
+ * kRTCMediaStreamTrackKindVideo.
+ */
+@property(nonatomic, readonly, nonnull) NSString *kind;
/** The codec clock rate expressed in Hertz. */
-@property(nonatomic, assign) int clockRate;
+@property(nonatomic, readonly, nullable) NSNumber *clockRate;
-/** The number of channels (mono=1, stereo=2). */
-@property(nonatomic, assign) int channels;
+/**
+ * The number of channels (mono=1, stereo=2).
+ * Set to null for video codecs.
+ **/
+@property(nonatomic, readonly, nullable) NSNumber *numChannels;
- (instancetype)init NS_DESIGNATED_INITIALIZER;