Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(28)

Unified Diff: webrtc/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc

Issue 3007543002: Add PeerConnectionObserver#onRemoveTrack to android sdk
Patch Set: review fixes Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/sdk/android/src/jni/pc/peerconnectionobserver_jni.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc
diff --git a/webrtc/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc b/webrtc/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc
index 18767925933ffb6006845d83b1fd2d3edb0954f5..8182abb42fc9f0722ce610bff187cee55e80fac5 100644
--- a/webrtc/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc
+++ b/webrtc/sdk/android/src/jni/pc/peerconnectionobserver_jni.cc
@@ -10,6 +10,7 @@
#include "webrtc/sdk/android/src/jni/pc/peerconnectionobserver_jni.h"
+#include <webrtc/pc/mediastreamobserver.h>
#include <string>
#include "webrtc/sdk/android/src/jni/classreferenceholder.h"
@@ -45,6 +46,12 @@ PeerConnectionObserverJni::PeerConnectionObserverJni(JNIEnv* jni,
PeerConnectionObserverJni::~PeerConnectionObserverJni() {
ScopedLocalRefFrame local_ref_frame(jni());
+ stream_observers_.clear();
+ while (!remote_tracks_.empty()) {
+ NativeToJavaMediaTrackMap::iterator it = remote_tracks_.begin();
+ DeleteGlobalRef(jni(), it->second);
+ remote_tracks_.erase(it);
+ }
while (!remote_streams_.empty())
DisposeRemoteStream(remote_streams_.begin());
while (!rtp_receivers_.empty())
@@ -131,48 +138,144 @@ void PeerConnectionObserverJni::OnAddStream(
// OnAddTrack.
jobject j_stream = GetOrCreateJavaStream(stream);
- for (const auto& track : stream->GetAudioTracks()) {
- jstring id = JavaStringFromStdString(jni(), track->id());
- // Java AudioTrack holds one reference. Corresponding Release() is in
- // MediaStreamTrack_free, triggered by AudioTrack.dispose().
- track->AddRef();
- jobject j_track =
- jni()->NewObject(*j_audio_track_class_, j_audio_track_ctor_,
- reinterpret_cast<jlong>(track.get()), id);
- CHECK_EXCEPTION(jni()) << "error during NewObject";
- jfieldID audio_tracks_id = GetFieldID(
- jni(), *j_media_stream_class_, "audioTracks", "Ljava/util/LinkedList;");
- jobject audio_tracks = GetObjectField(jni(), j_stream, audio_tracks_id);
- jmethodID add = GetMethodID(jni(), GetObjectClass(jni(), audio_tracks),
- "add", "(Ljava/lang/Object;)Z");
- jboolean added = jni()->CallBooleanMethod(audio_tracks, add, j_track);
- CHECK_EXCEPTION(jni()) << "error during CallBooleanMethod";
- RTC_CHECK(added);
- }
-
- for (const auto& track : stream->GetVideoTracks()) {
- jstring id = JavaStringFromStdString(jni(), track->id());
- // Java VideoTrack holds one reference. Corresponding Release() is in
- // MediaStreamTrack_free, triggered by VideoTrack.dispose().
- track->AddRef();
- jobject j_track =
- jni()->NewObject(*j_video_track_class_, j_video_track_ctor_,
- reinterpret_cast<jlong>(track.get()), id);
- CHECK_EXCEPTION(jni()) << "error during NewObject";
- jfieldID video_tracks_id = GetFieldID(
- jni(), *j_media_stream_class_, "videoTracks", "Ljava/util/LinkedList;");
- jobject video_tracks = GetObjectField(jni(), j_stream, video_tracks_id);
- jmethodID add = GetMethodID(jni(), GetObjectClass(jni(), video_tracks),
- "add", "(Ljava/lang/Object;)Z");
- jboolean added = jni()->CallBooleanMethod(video_tracks, add, j_track);
- CHECK_EXCEPTION(jni()) << "error during CallBooleanMethod";
- RTC_CHECK(added);
- }
-
jmethodID m = GetMethodID(jni(), *j_observer_class_, "onAddStream",
"(Lorg/webrtc/MediaStream;)V");
jni()->CallVoidMethod(*j_observer_global_, m, j_stream);
CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";
+
+ webrtc::MediaStreamObserver* observer =
+ new webrtc::MediaStreamObserver(stream);
+ observer->SignalAudioTrackRemoved.connect(
+ this, &PeerConnectionObserverJni::OnAudioTrackRemoved);
+ observer->SignalVideoTrackRemoved.connect(
+ this, &PeerConnectionObserverJni::OnVideoTrackRemoved);
+ stream_observers_.push_back(
+ std::unique_ptr<webrtc::MediaStreamObserver>(observer));
+}
+
+void PeerConnectionObserverJni::OnAudioTrackAdded(
+ webrtc::AudioTrackInterface* track,
+ webrtc::MediaStreamInterface* stream) {
+ ScopedLocalRefFrame local_ref_frame(jni());
+ jstring id = JavaStringFromStdString(jni(), track->id());
+ jobject j_stream = GetOrCreateJavaStream(stream);
+ // Java AudioTrack holds one reference. Corresponding Release() is in
+ // MediaStreamTrack_free, triggered by AudioTrack.dispose().
+ track->AddRef();
+ jobject j_track = jni()->NewObject(*j_audio_track_class_, j_audio_track_ctor_,
+ reinterpret_cast<jlong>(track), id);
+ CHECK_EXCEPTION(jni()) << "error during NewObject";
+ remote_tracks_[track] = NewGlobalRef(jni(), j_track);
+ jfieldID audio_tracks_id = GetFieldID(
+ jni(), *j_media_stream_class_, "audioTracks", "Ljava/util/LinkedList;");
+ jobject audio_tracks = GetObjectField(jni(), j_stream, audio_tracks_id);
+ jmethodID add = GetMethodID(jni(), GetObjectClass(jni(), audio_tracks), "add",
+ "(Ljava/lang/Object;)Z");
+ jboolean added = jni()->CallBooleanMethod(audio_tracks, add, j_track);
+ CHECK_EXCEPTION(jni()) << "error during CallBooleanMethod";
+ RTC_CHECK(added);
+}
+
+void PeerConnectionObserverJni::OnVideoTrackAdded(
+ webrtc::VideoTrackInterface* track,
+ webrtc::MediaStreamInterface* stream) {
+ ScopedLocalRefFrame local_ref_frame(jni());
+ jobject j_stream = GetOrCreateJavaStream(stream);
+
+ jstring id = JavaStringFromStdString(jni(), track->id());
+ // Java VideoTrack holds one reference. Corresponding Release() is in
+ // MediaStreamTrack_free, triggered by VideoTrack.dispose().
+ track->AddRef();
+ jobject j_track = jni()->NewObject(*j_video_track_class_, j_video_track_ctor_,
+ reinterpret_cast<jlong>(track), id);
+ CHECK_EXCEPTION(jni()) << "error during NewObject";
+ remote_tracks_[track] = NewGlobalRef(jni(), j_track);
+ jfieldID video_tracks_id = GetFieldID(
+ jni(), *j_media_stream_class_, "videoTracks", "Ljava/util/LinkedList;");
+ jobject video_tracks = GetObjectField(jni(), j_stream, video_tracks_id);
+ jmethodID add = GetMethodID(jni(), GetObjectClass(jni(), video_tracks), "add",
+ "(Ljava/lang/Object;)Z");
+ jboolean added = jni()->CallBooleanMethod(video_tracks, add, j_track);
+ CHECK_EXCEPTION(jni()) << "error during CallBooleanMethod";
+ RTC_CHECK(added);
+}
+
+void PeerConnectionObserverJni::OnAudioTrackRemoved(
+ webrtc::AudioTrackInterface* track,
+ webrtc::MediaStreamInterface* stream) {
+ ScopedLocalRefFrame local_ref_frame(jni());
+ jobject j_stream = GetOrCreateJavaStream(stream);
+ NativeToJavaMediaTrackMap::iterator track_it = remote_tracks_.find(track);
+ RTC_CHECK(track_it != remote_tracks_.end());
+ NativeMediaStreamTrackToNativeRtpReceiver::iterator receiver_it =
+ track_to_receiver_.find(track);
+ RTC_CHECK(receiver_it != track_to_receiver_.end());
+ NativeToJavaRtpReceiverMap::iterator j_receiver_it =
+ rtp_receivers_.find(receiver_it->second);
+ RTC_CHECK(j_receiver_it != rtp_receivers_.end());
+
+ jobject j_track = track_it->second;
+ jobject j_receiver = j_receiver_it->second;
+
+ jfieldID audio_tracks_id = GetFieldID(
+ jni(), *j_media_stream_class_, "audioTracks", "Ljava/util/LinkedList;");
+ jobject video_tracks = GetObjectField(jni(), j_stream, audio_tracks_id);
+ jmethodID remove = GetMethodID(jni(), GetObjectClass(jni(), video_tracks),
+ "remove", "(Ljava/lang/Object;)Z");
+ jboolean removed = jni()->CallBooleanMethod(video_tracks, remove, j_track);
+ CHECK_EXCEPTION(jni()) << "error during CallBooleanMethod";
+ RTC_CHECK(removed);
+
+ std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>> streams;
+ streams.push_back(rtc::scoped_refptr<webrtc::MediaStreamInterface>(stream));
+ jobjectArray j_stream_array = NativeToJavaMediaStreamArray(jni(), streams);
+ jmethodID m =
+ GetMethodID(jni(), *j_observer_class_, "onRemoveTrack",
+ "(Lorg/webrtc/RtpReceiver;[Lorg/webrtc/MediaStream;)V");
+ jni()->CallVoidMethod(*j_observer_global_, m, j_receiver, j_stream_array);
+ CHECK_EXCEPTION(jni()) << "Error during CallVoidMethod";
+
+ DisposeRemoteTrack(track_it);
+ DisposeRtpReceiver(j_receiver_it);
+}
+
+void PeerConnectionObserverJni::OnVideoTrackRemoved(
+ webrtc::VideoTrackInterface* track,
+ webrtc::MediaStreamInterface* stream) {
+ ScopedLocalRefFrame local_ref_frame(jni());
+ jobject j_stream = GetOrCreateJavaStream(stream);
+ NativeToJavaMediaTrackMap::iterator track_it = remote_tracks_.find(track);
+ RTC_CHECK(track_it != remote_tracks_.end());
+ NativeMediaStreamTrackToNativeRtpReceiver::iterator receiver_it =
+ track_to_receiver_.find(track);
+ RTC_CHECK(receiver_it != track_to_receiver_.end());
+ NativeToJavaRtpReceiverMap::iterator j_receiver_it =
+ rtp_receivers_.find(receiver_it->second);
+ RTC_CHECK(j_receiver_it != rtp_receivers_.end());
+
+ jobject j_track = track_it->second;
+ jobject j_receiver = j_receiver_it->second;
+
+ jfieldID video_tracks_id = GetFieldID(
+ jni(), *j_media_stream_class_, "videoTracks", "Ljava/util/LinkedList;");
+ jobject video_tracks = GetObjectField(jni(), j_stream, video_tracks_id);
+ jmethodID remove = GetMethodID(jni(), GetObjectClass(jni(), video_tracks),
+ "remove", "(Ljava/lang/Object;)Z");
+ jboolean removed = jni()->CallBooleanMethod(video_tracks, remove, j_track);
+ CHECK_EXCEPTION(jni()) << "error during CallBooleanMethod";
+ RTC_CHECK(removed);
+
+ std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>> streams;
+ streams.push_back(rtc::scoped_refptr<webrtc::MediaStreamInterface>(stream));
+ jobjectArray j_stream_array = NativeToJavaMediaStreamArray(jni(), streams);
+ jmethodID m =
+ GetMethodID(jni(), *j_observer_class_, "onRemoveTrack",
+ "(Lorg/webrtc/RtpReceiver;[Lorg/webrtc/MediaStream;)V");
+ jni()->CallVoidMethod(*j_observer_global_, m, j_receiver, j_stream_array);
+ CHECK_EXCEPTION(jni()) << "Error during CallVoidMethod";
+
+ DisposeRemoteTrack(track_it);
+ DisposeRtpReceiver(j_receiver_it);
}
void PeerConnectionObserverJni::OnRemoveStream(
@@ -186,6 +289,16 @@ void PeerConnectionObserverJni::OnRemoveStream(
"(Lorg/webrtc/MediaStream;)V");
jni()->CallVoidMethod(*j_observer_global_, m, j_stream);
CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";
+
+ stream_observers_.erase(
+ std::remove_if(
+ stream_observers_.begin(), stream_observers_.end(),
+ [stream](
+ const std::unique_ptr<webrtc::MediaStreamObserver>& observer) {
+ return observer->stream() == stream;
+ }),
+ stream_observers_.end());
+
// Release the refptr reference so that DisposeRemoteStream can assert
// it removes the final reference.
stream = nullptr;
@@ -233,6 +346,22 @@ void PeerConnectionObserverJni::OnAddTrack(
CHECK_EXCEPTION(jni()) << "error during NewObject";
receiver->AddRef();
rtp_receivers_[receiver] = NewGlobalRef(jni(), j_rtp_receiver);
+ track_to_receiver_[receiver->track()] = receiver;
+ for (auto stream : streams) {
+ if (receiver->media_type() == cricket::MediaType::MEDIA_TYPE_AUDIO) {
+ webrtc::AudioTrackInterface* track =
+ reinterpret_cast<webrtc::AudioTrackInterface*>(
+ receiver->track().get());
+ OnAudioTrackAdded(track, stream);
+ } else if (receiver->media_type() == cricket::MediaType::MEDIA_TYPE_VIDEO) {
+ webrtc::VideoTrackInterface* track =
+ reinterpret_cast<webrtc::VideoTrackInterface*>(
+ receiver->track().get());
+ OnVideoTrackAdded(track, stream);
+ } else {
+ RTC_NOTREACHED();
+ }
+ }
jobjectArray j_stream_array = NativeToJavaMediaStreamArray(jni(), streams);
jmethodID m =
@@ -269,6 +398,23 @@ void PeerConnectionObserverJni::DisposeRtpReceiver(
DeleteGlobalRef(jni(), j_rtp_receiver);
}
+void PeerConnectionObserverJni::DisposeRemoteTrack(
+ const NativeToJavaMediaTrackMap::iterator& it) {
+ RTC_CHECK(it != remote_tracks_.end());
+ webrtc::MediaStreamTrackInterface* track = it->first;
+ jobject j_track = it->second;
+ remote_tracks_.erase(it);
+ jmethodID dispose;
+ if (track->kind() == webrtc::MediaStreamTrackInterface::kVideoKind) {
+ dispose = GetMethodID(jni(), *j_video_track_class_, "dispose", "()V");
+ } else {
+ dispose = GetMethodID(jni(), *j_audio_track_class_, "dispose", "()V");
+ }
+ jni()->CallVoidMethod(j_track, dispose);
+ CHECK_EXCEPTION(jni()) << "error during CallVoidMethod";
+ DeleteGlobalRef(jni(), j_track);
+}
+
// If the NativeToJavaStreamsMap contains the stream, return it.
// Otherwise, create a new Java MediaStream.
jobject PeerConnectionObserverJni::GetOrCreateJavaStream(
@@ -277,7 +423,6 @@ jobject PeerConnectionObserverJni::GetOrCreateJavaStream(
if (it != remote_streams_.end()) {
return it->second;
}
-
// Java MediaStream holds one reference. Corresponding Release() is in
// MediaStream_free, triggered by MediaStream.dispose().
stream->AddRef();
« no previous file with comments | « webrtc/sdk/android/src/jni/pc/peerconnectionobserver_jni.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698