Expose peer connection's getStats by RtpSender/Receiver in Android SDK

Currently if you want to obtain the stats for a specific sender/receiver
in Android, you need to call peerConnection.getStats() and filter
manually the result by sender.

pc.getStats(receiver/sender) exists in c++ and ios but was not exposed
in Android

Bug: webrtc:14547
Change-Id: I9954434880f0f93821fcd2e2de24a875e8d136ae
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/275880
Reviewed-by: Xavier Lepaul‎ <xalep@webrtc.org>
Commit-Queue: Sergey Silkin <ssilkin@webrtc.org>
Reviewed-by: Sergey Silkin <ssilkin@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#38428}
This commit is contained in:
Roberto Perez 2022-10-07 10:50:46 +02:00 committed by WebRTC LUCI CQ
parent 048f5c7516
commit 4dc6e05ac9
5 changed files with 68 additions and 0 deletions

View file

@ -141,6 +141,7 @@ CoSMo Software Consulting, Pte Ltd <*@cosmosoftware.io>
Facebook Inc. <*@fb.com> Facebook Inc. <*@fb.com>
Google Inc. <*@google.com> Google Inc. <*@google.com>
Highfive, Inc. <*@highfive.com> Highfive, Inc. <*@highfive.com>
Hopin Ltd. <*@hopin.to>
HyperConnect Inc. <*@hpcnt.com> HyperConnect Inc. <*@hpcnt.com>
Intel Corporation <*@intel.com> Intel Corporation <*@intel.com>
LG Electronics, Inc. <*@lge.com> LG Electronics, Inc. <*@lge.com>

View file

@ -1176,6 +1176,22 @@ public class PeerConnection {
nativeNewGetStats(callback); nativeNewGetStats(callback);
} }
/**
* Gets stats using the new stats collection API, see webrtc/api/stats/. These
* will replace old stats collection API when the new API has matured enough.
*/
public void getStats(RtpSender sender, RTCStatsCollectorCallback callback) {
nativeNewGetStatsSender(sender.getNativeRtpSender(), callback);
}
/**
* Gets stats using the new stats collection API, see webrtc/api/stats/. These
* will replace old stats collection API when the new API has matured enough.
*/
public void getStats(RtpReceiver receiver, RTCStatsCollectorCallback callback) {
nativeNewGetStatsReceiver(receiver.getNativeRtpReceiver(), callback);
}
/** /**
* Limits the bandwidth allocated for all RTP streams sent by this * Limits the bandwidth allocated for all RTP streams sent by this
* PeerConnection. Pass null to leave a value unchanged. * PeerConnection. Pass null to leave a value unchanged.
@ -1310,6 +1326,8 @@ public class PeerConnection {
private native void nativeRemoveLocalStream(long stream); private native void nativeRemoveLocalStream(long stream);
private native boolean nativeOldGetStats(StatsObserver observer, long nativeTrack); private native boolean nativeOldGetStats(StatsObserver observer, long nativeTrack);
private native void nativeNewGetStats(RTCStatsCollectorCallback callback); private native void nativeNewGetStats(RTCStatsCollectorCallback callback);
private native void nativeNewGetStatsSender(long sender, RTCStatsCollectorCallback callback);
private native void nativeNewGetStatsReceiver(long receiver, RTCStatsCollectorCallback callback);
private native RtpSender nativeCreateSender(String kind, String stream_id); private native RtpSender nativeCreateSender(String kind, String stream_id);
private native List<RtpSender> nativeGetSenders(); private native List<RtpSender> nativeGetSenders();
private native List<RtpReceiver> nativeGetReceivers(); private native List<RtpReceiver> nativeGetReceivers();

View file

@ -49,6 +49,12 @@ public class RtpReceiver {
return nativeGetId(nativeRtpReceiver); return nativeGetId(nativeRtpReceiver);
} }
/** Returns a pointer to webrtc::RtpReceiverInterface. */
long getNativeRtpReceiver() {
checkRtpReceiverExists();
return nativeRtpReceiver;
}
@CalledByNative @CalledByNative
public void dispose() { public void dispose() {
checkRtpReceiverExists(); checkRtpReceiverExists();

View file

@ -931,6 +931,23 @@ public class PeerConnectionEndToEndTest {
assertTrue(offeringPC.setBitrate(100000, 5000000, 500000000)); assertTrue(offeringPC.setBitrate(100000, 5000000, 500000000));
assertFalse(offeringPC.setBitrate(3, 2, 1)); assertFalse(offeringPC.setBitrate(3, 2, 1));
// Test getStats by Sender interface
offeringExpectations.expectNewStatsCallback();
offeringPC.getStats(videoSender, offeringExpectations);
assertTrue(offeringExpectations.waitForAllExpectationsToBeSatisfied(DEFAULT_TIMEOUT_SECONDS));
// Test getStats by Receiver interface
RtpReceiver videoReceiver = null;
for (RtpReceiver receiver : answeringPC.getReceivers()) {
if (receiver.track().kind().equals("video")) {
videoReceiver = receiver;
}
}
assertNotNull(videoReceiver);
answeringExpectations.expectNewStatsCallback();
answeringPC.getStats(videoReceiver, answeringExpectations);
assertTrue(answeringExpectations.waitForAllExpectationsToBeSatisfied(DEFAULT_TIMEOUT_SECONDS));
// Free the Java-land objects and collect them. // Free the Java-land objects and collect them.
shutdownPC(offeringPC, offeringExpectations); shutdownPC(offeringPC, offeringExpectations);
offeringPC = null; offeringPC = null;

View file

@ -842,6 +842,32 @@ static void JNI_PeerConnection_NewGetStats(
ExtractNativePC(jni, j_pc)->GetStats(callback.get()); ExtractNativePC(jni, j_pc)->GetStats(callback.get());
} }
static void JNI_PeerConnection_NewGetStatsSender(
JNIEnv* jni,
const JavaParamRef<jobject>& j_pc,
jlong native_sender,
const JavaParamRef<jobject>& j_callback) {
auto callback =
rtc::make_ref_counted<RTCStatsCollectorCallbackWrapper>(jni, j_callback);
ExtractNativePC(jni, j_pc)->GetStats(
rtc::scoped_refptr<RtpSenderInterface>(
reinterpret_cast<RtpSenderInterface*>(native_sender)),
rtc::scoped_refptr<RTCStatsCollectorCallbackWrapper>(callback.get()));
}
static void JNI_PeerConnection_NewGetStatsReceiver(
JNIEnv* jni,
const JavaParamRef<jobject>& j_pc,
jlong native_receiver,
const JavaParamRef<jobject>& j_callback) {
auto callback =
rtc::make_ref_counted<RTCStatsCollectorCallbackWrapper>(jni, j_callback);
ExtractNativePC(jni, j_pc)->GetStats(
rtc::scoped_refptr<RtpReceiverInterface>(
reinterpret_cast<RtpReceiverInterface*>(native_receiver)),
rtc::scoped_refptr<RTCStatsCollectorCallbackWrapper>(callback.get()));
}
static jboolean JNI_PeerConnection_SetBitrate( static jboolean JNI_PeerConnection_SetBitrate(
JNIEnv* jni, JNIEnv* jni,
const JavaParamRef<jobject>& j_pc, const JavaParamRef<jobject>& j_pc,