Skip to content

Commit 180037f

Browse files
committed
feat: Expose setCodecPreferences/getCapabilities for android. (#61)
* feat: Expose setCodecPreferences/getCapabilities. * chore: update license. * fix bugs.
1 parent 73b4375 commit 180037f

File tree

8 files changed

+338
-0
lines changed

8 files changed

+338
-0
lines changed

sdk/android/BUILD.gn

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ if (is_android) {
291291
"api/org/webrtc/RTCStatsCollectorCallback.java",
292292
"api/org/webrtc/RTCStatsReport.java",
293293
"api/org/webrtc/RtcCertificatePem.java",
294+
"api/org/webrtc/RtpCapabilities.java",
294295
"api/org/webrtc/RtpParameters.java",
295296
"api/org/webrtc/RtpReceiver.java",
296297
"api/org/webrtc/RtpSender.java",
@@ -744,6 +745,8 @@ if (current_os == "linux" || is_android) {
744745
"src/jni/pc/rtc_certificate.h",
745746
"src/jni/pc/rtc_stats_collector_callback_wrapper.cc",
746747
"src/jni/pc/rtc_stats_collector_callback_wrapper.h",
748+
"src/jni/pc/rtp_capabilities.cc",
749+
"src/jni/pc/rtp_capabilities.h",
747750
"src/jni/pc/rtp_parameters.cc",
748751
"src/jni/pc/rtp_parameters.h",
749752
"src/jni/pc/rtp_receiver.cc",
@@ -1421,6 +1424,7 @@ if (current_os == "linux" || is_android) {
14211424
"api/org/webrtc/RTCStatsCollectorCallback.java",
14221425
"api/org/webrtc/RTCStatsReport.java",
14231426
"api/org/webrtc/RtcCertificatePem.java",
1427+
"api/org/webrtc/RtpCapabilities.java",
14241428
"api/org/webrtc/RtpParameters.java",
14251429
"api/org/webrtc/RtpReceiver.java",
14261430
"api/org/webrtc/RtpSender.java",

sdk/android/api/org/webrtc/PeerConnectionFactory.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.webrtc.PeerConnection;
1919
import org.webrtc.audio.AudioDeviceModule;
2020
import org.webrtc.audio.JavaAudioDeviceModule;
21+
import org.webrtc.RtpCapabilities;
2122

2223
/**
2324
* Java wrapper for a C++ PeerConnectionFactoryInterface. Main entry point to
@@ -471,6 +472,16 @@ public AudioTrack createAudioTrack(String id, AudioSource source) {
471472
return new AudioTrack(nativeCreateAudioTrack(nativeFactory, id, source.getNativeAudioSource()));
472473
}
473474

475+
public RtpCapabilities getRtpReceiverCapabilities(MediaStreamTrack.MediaType mediaType) {
476+
checkPeerConnectionFactoryExists();
477+
return nativeGetRtpReceiverCapabilities(nativeFactory, mediaType);
478+
}
479+
480+
public RtpCapabilities getRtpSenderCapabilities(MediaStreamTrack.MediaType mediaType) {
481+
checkPeerConnectionFactoryExists();
482+
return nativeGetRtpSenderCapabilities(nativeFactory, mediaType);
483+
}
484+
474485
// Starts recording an AEC dump. Ownership of the file is transfered to the
475486
// native code. If an AEC dump is already in progress, it will be stopped and
476487
// a new one will start using the provided file.
@@ -615,4 +626,6 @@ private static native boolean nativeStartAecDump(
615626
private static native void nativeInjectLoggable(JNILogging jniLogging, int severity);
616627
private static native void nativeDeleteLoggable();
617628
private static native void nativePrintStackTrace(int tid);
629+
private static native RtpCapabilities nativeGetRtpSenderCapabilities(long factory, MediaStreamTrack.MediaType mediaType);
630+
private static native RtpCapabilities nativeGetRtpReceiverCapabilities(long factory, MediaStreamTrack.MediaType mediaType);
618631
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/*
2+
* Copyright 2023 LiveKit
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.webrtc;
18+
19+
import androidx.annotation.Nullable;
20+
import java.util.List;
21+
import java.util.Map;
22+
import org.webrtc.MediaStreamTrack;
23+
24+
public class RtpCapabilities {
25+
public static class CodecCapability {
26+
public int preferredPayloadType;
27+
// Name used to identify the codec. Equivalent to MIME subtype.
28+
public String name;
29+
// The media type of this codec. Equivalent to MIME top-level type.
30+
public MediaStreamTrack.MediaType kind;
31+
// Clock rate in Hertz.
32+
public Integer clockRate;
33+
// The number of audio channels used. Set to null for video codecs.
34+
public Integer numChannels;
35+
// The "format specific parameters" field from the "a=fmtp" line in the SDP
36+
public Map<String, String> parameters;
37+
// The MIME type of the codec. This is a convenience field.
38+
public String mimeType;
39+
40+
public CodecCapability() {}
41+
42+
@CalledByNative("CodecCapability")
43+
CodecCapability(int preferredPayloadType, String name, MediaStreamTrack.MediaType kind,
44+
Integer clockRate, Integer numChannels, String mimeType, Map<String, String> parameters) {
45+
this.preferredPayloadType = preferredPayloadType;
46+
this.name = name;
47+
this.kind = kind;
48+
this.clockRate = clockRate;
49+
this.numChannels = numChannels;
50+
this.parameters = parameters;
51+
this.mimeType = mimeType;
52+
}
53+
54+
@CalledByNative("CodecCapability")
55+
int getPreferredPayloadType() {
56+
return preferredPayloadType;
57+
}
58+
59+
@CalledByNative("CodecCapability")
60+
String getName() {
61+
return name;
62+
}
63+
64+
@CalledByNative("CodecCapability")
65+
MediaStreamTrack.MediaType getKind() {
66+
return kind;
67+
}
68+
69+
@CalledByNative("CodecCapability")
70+
Integer getClockRate() {
71+
return clockRate;
72+
}
73+
74+
@CalledByNative("CodecCapability")
75+
Integer getNumChannels() {
76+
return numChannels;
77+
}
78+
79+
@CalledByNative("CodecCapability")
80+
Map getParameters() {
81+
return parameters;
82+
}
83+
}
84+
85+
public static class HeaderExtensionCapability {
86+
private final String uri;
87+
private final int preferredId;
88+
private final boolean preferredEncrypted;
89+
90+
@CalledByNative("HeaderExtensionCapability")
91+
HeaderExtensionCapability(String uri, int preferredId, boolean preferredEncrypted) {
92+
this.uri = uri;
93+
this.preferredId = preferredId;
94+
this.preferredEncrypted = preferredEncrypted;
95+
}
96+
97+
@CalledByNative("HeaderExtensionCapability")
98+
public String getUri() {
99+
return uri;
100+
}
101+
102+
@CalledByNative("HeaderExtensionCapability")
103+
public int getPreferredId() {
104+
return preferredId;
105+
}
106+
107+
@CalledByNative("HeaderExtensionCapability")
108+
public boolean getPreferredEncrypted() {
109+
return preferredEncrypted;
110+
}
111+
}
112+
113+
public List<CodecCapability> codecs;
114+
public List<HeaderExtensionCapability> headerExtensions;
115+
116+
@CalledByNative
117+
RtpCapabilities(List<CodecCapability> codecs, List<HeaderExtensionCapability> headerExtensions) {
118+
this.headerExtensions = headerExtensions;
119+
this.codecs = codecs;
120+
}
121+
122+
@CalledByNative
123+
public List<HeaderExtensionCapability> getHeaderExtensions() {
124+
return headerExtensions;
125+
}
126+
127+
@CalledByNative
128+
List<CodecCapability> getCodecs() {
129+
return codecs;
130+
}
131+
}

sdk/android/api/org/webrtc/RtpTransceiver.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,11 @@ public void stop() {
215215
nativeStopInternal(nativeRtpTransceiver);
216216
}
217217

218+
public void setCodecPreferences(List<RtpCapabilities.CodecCapability> codecs) {
219+
checkRtpTransceiverExists();
220+
nativeSetCodecPreferences(nativeRtpTransceiver, codecs);
221+
}
222+
218223
/**
219224
* The StopInternal method stops the RtpTransceiver, like Stop, but goes
220225
* immediately to Stopped state.
@@ -263,4 +268,5 @@ private void checkRtpTransceiverExists() {
263268
private static native void nativeStopStandard(long rtpTransceiver);
264269
private static native boolean nativeSetDirection(
265270
long rtpTransceiver, RtpTransceiverDirection rtpTransceiverDirection);
271+
private static native void nativeSetCodecPreferences(long rtpTransceiver, List<RtpCapabilities.CodecCapability> codecs);
266272
}

sdk/android/src/jni/pc/peer_connection_factory.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@
3939
#include "sdk/android/src/jni/logging/log_sink.h"
4040
#include "sdk/android/src/jni/pc/android_network_monitor.h"
4141
#include "sdk/android/src/jni/pc/audio.h"
42+
#include "sdk/android/src/jni/pc/rtp_capabilities.h"
4243
#include "sdk/android/src/jni/pc/ice_candidate.h"
44+
#include "sdk/android/src/jni/pc/media_stream_track.h"
4345
#include "sdk/android/src/jni/pc/owned_factory_and_threads.h"
4446
#include "sdk/android/src/jni/pc/peer_connection.h"
4547
#include "sdk/android/src/jni/pc/ssl_certificate_verifier_wrapper.h"
@@ -393,6 +395,22 @@ jlong JNI_PeerConnectionFactory_CreateAudioTrack(
393395
return jlongFromPointer(track.release());
394396
}
395397

398+
ScopedJavaLocalRef<jobject> JNI_PeerConnectionFactory_GetRtpSenderCapabilities(
399+
JNIEnv* jni,
400+
jlong native_factory,
401+
const JavaParamRef<jobject>& media_type) {
402+
auto factory = PeerConnectionFactoryFromJava(native_factory);
403+
return NativeToJavaRtpCapabilities(jni, factory->GetRtpSenderCapabilities(JavaToNativeMediaType(jni, media_type)));
404+
}
405+
406+
ScopedJavaLocalRef<jobject> JNI_PeerConnectionFactory_GetRtpReceiverCapabilities(
407+
JNIEnv* jni,
408+
jlong native_factory,
409+
const JavaParamRef<jobject>& media_type) {
410+
auto factory = PeerConnectionFactoryFromJava(native_factory);
411+
return NativeToJavaRtpCapabilities(jni, factory->GetRtpReceiverCapabilities(JavaToNativeMediaType(jni, media_type)));
412+
}
413+
396414
static jboolean JNI_PeerConnectionFactory_StartAecDump(
397415
JNIEnv* jni,
398416
jlong native_factory,
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Copyright 2023 LiveKit
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "sdk/android/src/jni/pc/rtp_capabilities.h"
18+
19+
#include "sdk/android/generated_peerconnection_jni/RtpCapabilities_jni.h"
20+
#include "sdk/android/native_api/jni/java_types.h"
21+
#include "sdk/android/src/jni/jni_helpers.h"
22+
#include "sdk/android/src/jni/pc/media_stream_track.h"
23+
24+
namespace webrtc {
25+
namespace jni {
26+
27+
namespace {
28+
29+
ScopedJavaLocalRef<jobject> NativeToJavaRtpCodecParameter(
30+
JNIEnv* env,
31+
const RtpCodecCapability& codec) {
32+
return Java_CodecCapability_Constructor(env, codec.preferred_payload_type.value(),
33+
NativeToJavaString(env, codec.name),
34+
NativeToJavaMediaType(env, codec.kind),
35+
NativeToJavaInteger(env, codec.clock_rate),
36+
NativeToJavaInteger(env, codec.num_channels),
37+
NativeToJavaString(env, codec.mime_type()),
38+
NativeToJavaStringMap(env, codec.parameters));
39+
}
40+
41+
ScopedJavaLocalRef<jobject> NativeToJavaRtpHeaderExtensionParameter(
42+
JNIEnv* env,
43+
const RtpHeaderExtensionCapability& extension) {
44+
return Java_HeaderExtensionCapability_Constructor(
45+
env, NativeToJavaString(env, extension.uri), extension.preferred_id.value(),
46+
extension.preferred_encrypt);
47+
}
48+
} // namespace
49+
50+
RtpCapabilities JavaToNativeRtpCapabilities(JNIEnv* jni,
51+
const JavaRef<jobject>& j_capabilities) {
52+
RtpCapabilities capabilities;
53+
54+
ScopedJavaLocalRef<jobject> j_header_extensions =
55+
Java_RtpCapabilities_getHeaderExtensions(jni, j_capabilities);
56+
for (const JavaRef<jobject>& j_header_extension :
57+
Iterable(jni, j_header_extensions)) {
58+
RtpHeaderExtensionCapability header_extension;
59+
header_extension.uri = JavaToStdString(
60+
jni, Java_HeaderExtensionCapability_getUri(jni, j_header_extension));
61+
header_extension.preferred_id = Java_HeaderExtensionCapability_getPreferredId(jni, j_header_extension);
62+
header_extension.preferred_encrypt =
63+
Java_HeaderExtensionCapability_getPreferredEncrypted(jni, j_header_extension);
64+
capabilities.header_extensions.push_back(header_extension);
65+
}
66+
67+
// Convert codecs.
68+
ScopedJavaLocalRef<jobject> j_codecs =
69+
Java_RtpCapabilities_getCodecs(jni, j_capabilities);
70+
for (const JavaRef<jobject>& j_codec : Iterable(jni, j_codecs)) {
71+
RtpCodecCapability codec;
72+
codec.preferred_payload_type = Java_CodecCapability_getPreferredPayloadType(jni, j_codec);
73+
codec.name = JavaToStdString(jni, Java_CodecCapability_getName(jni, j_codec));
74+
codec.kind = JavaToNativeMediaType(jni, Java_CodecCapability_getKind(jni, j_codec));
75+
codec.clock_rate =
76+
JavaToNativeOptionalInt(jni, Java_CodecCapability_getClockRate(jni, j_codec));
77+
codec.num_channels =
78+
JavaToNativeOptionalInt(jni, Java_CodecCapability_getNumChannels(jni, j_codec));
79+
auto parameters_map =
80+
JavaToNativeStringMap(jni, Java_CodecCapability_getParameters(jni, j_codec));
81+
codec.parameters.insert(parameters_map.begin(), parameters_map.end());
82+
capabilities.codecs.push_back(codec);
83+
}
84+
return capabilities;
85+
}
86+
87+
ScopedJavaLocalRef<jobject> NativeToJavaRtpCapabilities(
88+
JNIEnv* env,
89+
const RtpCapabilities& capabilities) {
90+
return Java_RtpCapabilities_Constructor(
91+
env, NativeToJavaList(env, capabilities.codecs, &NativeToJavaRtpCodecParameter),
92+
NativeToJavaList(env, capabilities.header_extensions,
93+
&NativeToJavaRtpHeaderExtensionParameter)
94+
);
95+
}
96+
97+
RtpCodecCapability JavaToNativeRtpCodecCapability(JNIEnv* jni,
98+
const JavaRef<jobject>& j_codec) {
99+
RtpCodecCapability codec;
100+
codec.preferred_payload_type = Java_CodecCapability_getPreferredPayloadType(jni, j_codec);
101+
codec.name = JavaToStdString(jni, Java_CodecCapability_getName(jni, j_codec));
102+
codec.kind = JavaToNativeMediaType(jni, Java_CodecCapability_getKind(jni, j_codec));
103+
codec.clock_rate =
104+
JavaToNativeOptionalInt(jni, Java_CodecCapability_getClockRate(jni, j_codec));
105+
codec.num_channels =
106+
JavaToNativeOptionalInt(jni, Java_CodecCapability_getNumChannels(jni, j_codec));
107+
auto parameters_map =
108+
JavaToNativeStringMap(jni, Java_CodecCapability_getParameters(jni, j_codec));
109+
codec.parameters.insert(parameters_map.begin(), parameters_map.end());
110+
return codec;
111+
}
112+
113+
} // namespace jni
114+
} // namespace webrtc
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright 2023 LiveKit
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef SDK_ANDROID_SRC_JNI_PC_RTP_CAPABLILITES_H_
18+
#define SDK_ANDROID_SRC_JNI_PC_RTP_CAPABLILITES_H_
19+
20+
#include <jni.h>
21+
22+
#include "api/rtp_parameters.h"
23+
#include "sdk/android/native_api/jni/scoped_java_ref.h"
24+
25+
namespace webrtc {
26+
namespace jni {
27+
28+
RtpCapabilities JavaToNativeRtpCapabilities(JNIEnv* jni,
29+
const JavaRef<jobject>& j_capabilities);
30+
31+
ScopedJavaLocalRef<jobject> NativeToJavaRtpCapabilities(
32+
JNIEnv* jni,
33+
const RtpCapabilities& capabilities);
34+
35+
RtpCodecCapability JavaToNativeRtpCodecCapability(JNIEnv* jni,
36+
const JavaRef<jobject>& j_codec_capability);
37+
38+
} // namespace jni
39+
} // namespace webrtc
40+
41+
#endif // SDK_ANDROID_SRC_JNI_PC_RTP_CAPABLILITES_H_

0 commit comments

Comments
 (0)