1 /*
2  *  Copyright 2017 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 "sdk/android/src/jni/pc/rtp_parameters.h"
12 
13 #include "sdk/android/generated_peerconnection_jni/RtpParameters_jni.h"
14 #include "sdk/android/native_api/jni/java_types.h"
15 #include "sdk/android/src/jni/jni_helpers.h"
16 #include "sdk/android/src/jni/pc/media_stream_track.h"
17 
18 namespace webrtc {
19 namespace jni {
20 
21 namespace {
22 
JavaToNativeDegradationPreference(JNIEnv * jni,const JavaRef<jobject> & j_degradation_preference)23 webrtc::DegradationPreference JavaToNativeDegradationPreference(
24     JNIEnv* jni,
25     const JavaRef<jobject>& j_degradation_preference) {
26   std::string enum_name = GetJavaEnumName(jni, j_degradation_preference);
27 
28   if (enum_name == "DISABLED")
29     return webrtc::DegradationPreference::DISABLED;
30 
31   if (enum_name == "MAINTAIN_FRAMERATE")
32     return webrtc::DegradationPreference::MAINTAIN_FRAMERATE;
33 
34   if (enum_name == "MAINTAIN_RESOLUTION")
35     return webrtc::DegradationPreference::MAINTAIN_RESOLUTION;
36 
37   if (enum_name == "BALANCED")
38     return webrtc::DegradationPreference::BALANCED;
39 
40   RTC_CHECK(false) << "Unexpected DegradationPreference enum_name "
41                    << enum_name;
42   return webrtc::DegradationPreference::DISABLED;
43 }
44 
NativeToJavaRtpEncodingParameter(JNIEnv * env,const RtpEncodingParameters & encoding)45 ScopedJavaLocalRef<jobject> NativeToJavaRtpEncodingParameter(
46     JNIEnv* env,
47     const RtpEncodingParameters& encoding) {
48   return Java_Encoding_Constructor(
49       env, NativeToJavaString(env, encoding.rid), encoding.active,
50       encoding.bitrate_priority, static_cast<int>(encoding.network_priority),
51       NativeToJavaInteger(env, encoding.max_bitrate_bps),
52       NativeToJavaInteger(env, encoding.min_bitrate_bps),
53       NativeToJavaInteger(env, encoding.max_framerate),
54       NativeToJavaInteger(env, encoding.num_temporal_layers),
55       NativeToJavaDouble(env, encoding.scale_resolution_down_by),
56       encoding.ssrc ? NativeToJavaLong(env, *encoding.ssrc) : nullptr);
57 }
58 
NativeToJavaRtpCodecParameter(JNIEnv * env,const RtpCodecParameters & codec)59 ScopedJavaLocalRef<jobject> NativeToJavaRtpCodecParameter(
60     JNIEnv* env,
61     const RtpCodecParameters& codec) {
62   return Java_Codec_Constructor(env, codec.payload_type,
63                                 NativeToJavaString(env, codec.name),
64                                 NativeToJavaMediaType(env, codec.kind),
65                                 NativeToJavaInteger(env, codec.clock_rate),
66                                 NativeToJavaInteger(env, codec.num_channels),
67                                 NativeToJavaStringMap(env, codec.parameters));
68 }
69 
NativeToJavaRtpRtcpParameters(JNIEnv * env,const RtcpParameters & rtcp)70 ScopedJavaLocalRef<jobject> NativeToJavaRtpRtcpParameters(
71     JNIEnv* env,
72     const RtcpParameters& rtcp) {
73   return Java_Rtcp_Constructor(env, NativeToJavaString(env, rtcp.cname),
74                                rtcp.reduced_size);
75 }
76 
NativeToJavaRtpHeaderExtensionParameter(JNIEnv * env,const RtpExtension & extension)77 ScopedJavaLocalRef<jobject> NativeToJavaRtpHeaderExtensionParameter(
78     JNIEnv* env,
79     const RtpExtension& extension) {
80   return Java_HeaderExtension_Constructor(
81       env, NativeToJavaString(env, extension.uri), extension.id,
82       extension.encrypt);
83 }
84 
85 }  // namespace
86 
JavaToNativeRtpEncodingParameters(JNIEnv * jni,const JavaRef<jobject> & j_encoding_parameters)87 RtpEncodingParameters JavaToNativeRtpEncodingParameters(
88     JNIEnv* jni,
89     const JavaRef<jobject>& j_encoding_parameters) {
90   RtpEncodingParameters encoding;
91   ScopedJavaLocalRef<jstring> j_rid =
92       Java_Encoding_getRid(jni, j_encoding_parameters);
93   if (!IsNull(jni, j_rid)) {
94     encoding.rid = JavaToNativeString(jni, j_rid);
95   }
96   encoding.active = Java_Encoding_getActive(jni, j_encoding_parameters);
97   ScopedJavaLocalRef<jobject> j_max_bitrate =
98       Java_Encoding_getMaxBitrateBps(jni, j_encoding_parameters);
99   encoding.bitrate_priority =
100       Java_Encoding_getBitratePriority(jni, j_encoding_parameters);
101   encoding.network_priority = static_cast<webrtc::Priority>(
102       Java_Encoding_getNetworkPriority(jni, j_encoding_parameters));
103   encoding.max_bitrate_bps = JavaToNativeOptionalInt(jni, j_max_bitrate);
104   ScopedJavaLocalRef<jobject> j_min_bitrate =
105       Java_Encoding_getMinBitrateBps(jni, j_encoding_parameters);
106   encoding.min_bitrate_bps = JavaToNativeOptionalInt(jni, j_min_bitrate);
107   ScopedJavaLocalRef<jobject> j_max_framerate =
108       Java_Encoding_getMaxFramerate(jni, j_encoding_parameters);
109   encoding.max_framerate = JavaToNativeOptionalInt(jni, j_max_framerate);
110   ScopedJavaLocalRef<jobject> j_num_temporal_layers =
111       Java_Encoding_getNumTemporalLayers(jni, j_encoding_parameters);
112   encoding.num_temporal_layers =
113       JavaToNativeOptionalInt(jni, j_num_temporal_layers);
114   ScopedJavaLocalRef<jobject> j_scale_resolution_down_by =
115       Java_Encoding_getScaleResolutionDownBy(jni, j_encoding_parameters);
116   encoding.scale_resolution_down_by =
117       JavaToNativeOptionalDouble(jni, j_scale_resolution_down_by);
118   ScopedJavaLocalRef<jobject> j_ssrc =
119       Java_Encoding_getSsrc(jni, j_encoding_parameters);
120   if (!IsNull(jni, j_ssrc))
121     encoding.ssrc = JavaToNativeLong(jni, j_ssrc);
122   return encoding;
123 }
124 
JavaToNativeRtpParameters(JNIEnv * jni,const JavaRef<jobject> & j_parameters)125 RtpParameters JavaToNativeRtpParameters(JNIEnv* jni,
126                                         const JavaRef<jobject>& j_parameters) {
127   RtpParameters parameters;
128 
129   ScopedJavaLocalRef<jstring> j_transaction_id =
130       Java_RtpParameters_getTransactionId(jni, j_parameters);
131   parameters.transaction_id = JavaToNativeString(jni, j_transaction_id);
132 
133   ScopedJavaLocalRef<jobject> j_degradation_preference =
134       Java_RtpParameters_getDegradationPreference(jni, j_parameters);
135   if (!IsNull(jni, j_degradation_preference)) {
136     parameters.degradation_preference =
137         JavaToNativeDegradationPreference(jni, j_degradation_preference);
138   }
139 
140   ScopedJavaLocalRef<jobject> j_rtcp =
141       Java_RtpParameters_getRtcp(jni, j_parameters);
142   ScopedJavaLocalRef<jstring> j_rtcp_cname = Java_Rtcp_getCname(jni, j_rtcp);
143   jboolean j_rtcp_reduced_size = Java_Rtcp_getReducedSize(jni, j_rtcp);
144   parameters.rtcp.cname = JavaToNativeString(jni, j_rtcp_cname);
145   parameters.rtcp.reduced_size = j_rtcp_reduced_size;
146 
147   ScopedJavaLocalRef<jobject> j_header_extensions =
148       Java_RtpParameters_getHeaderExtensions(jni, j_parameters);
149   for (const JavaRef<jobject>& j_header_extension :
150        Iterable(jni, j_header_extensions)) {
151     RtpExtension header_extension;
152     header_extension.uri = JavaToStdString(
153         jni, Java_HeaderExtension_getUri(jni, j_header_extension));
154     header_extension.id = Java_HeaderExtension_getId(jni, j_header_extension);
155     header_extension.encrypt =
156         Java_HeaderExtension_getEncrypted(jni, j_header_extension);
157     parameters.header_extensions.push_back(header_extension);
158   }
159 
160   // Convert encodings.
161   ScopedJavaLocalRef<jobject> j_encodings =
162       Java_RtpParameters_getEncodings(jni, j_parameters);
163   for (const JavaRef<jobject>& j_encoding_parameters :
164        Iterable(jni, j_encodings)) {
165     RtpEncodingParameters encoding =
166         JavaToNativeRtpEncodingParameters(jni, j_encoding_parameters);
167     parameters.encodings.push_back(encoding);
168   }
169 
170   // Convert codecs.
171   ScopedJavaLocalRef<jobject> j_codecs =
172       Java_RtpParameters_getCodecs(jni, j_parameters);
173   for (const JavaRef<jobject>& j_codec : Iterable(jni, j_codecs)) {
174     RtpCodecParameters codec;
175     codec.payload_type = Java_Codec_getPayloadType(jni, j_codec);
176     codec.name = JavaToStdString(jni, Java_Codec_getName(jni, j_codec));
177     codec.kind = JavaToNativeMediaType(jni, Java_Codec_getKind(jni, j_codec));
178     codec.clock_rate =
179         JavaToNativeOptionalInt(jni, Java_Codec_getClockRate(jni, j_codec));
180     codec.num_channels =
181         JavaToNativeOptionalInt(jni, Java_Codec_getNumChannels(jni, j_codec));
182     auto parameters_map =
183         JavaToNativeStringMap(jni, Java_Codec_getParameters(jni, j_codec));
184     codec.parameters.insert(parameters_map.begin(), parameters_map.end());
185     parameters.codecs.push_back(codec);
186   }
187   return parameters;
188 }
189 
NativeToJavaRtpParameters(JNIEnv * env,const RtpParameters & parameters)190 ScopedJavaLocalRef<jobject> NativeToJavaRtpParameters(
191     JNIEnv* env,
192     const RtpParameters& parameters) {
193   return Java_RtpParameters_Constructor(
194       env, NativeToJavaString(env, parameters.transaction_id),
195       parameters.degradation_preference.has_value()
196           ? Java_DegradationPreference_fromNativeIndex(
197                 env, static_cast<int>(*parameters.degradation_preference))
198           : nullptr,
199       NativeToJavaRtpRtcpParameters(env, parameters.rtcp),
200       NativeToJavaList(env, parameters.header_extensions,
201                        &NativeToJavaRtpHeaderExtensionParameter),
202       NativeToJavaList(env, parameters.encodings,
203                        &NativeToJavaRtpEncodingParameter),
204       NativeToJavaList(env, parameters.codecs, &NativeToJavaRtpCodecParameter));
205 }
206 
207 }  // namespace jni
208 }  // namespace webrtc
209