OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2017 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2017 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/sdk/android/src/jni/pc/peerconnectionobserver_jni.h" | 11 #include "webrtc/sdk/android/src/jni/pc/peerconnectionobserver_jni.h" |
12 | 12 |
13 #include <webrtc/pc/mediastreamobserver.h> | |
13 #include <string> | 14 #include <string> |
14 | 15 |
15 #include "webrtc/sdk/android/src/jni/classreferenceholder.h" | 16 #include "webrtc/sdk/android/src/jni/classreferenceholder.h" |
16 #include "webrtc/sdk/android/src/jni/pc/java_native_conversion.h" | 17 #include "webrtc/sdk/android/src/jni/pc/java_native_conversion.h" |
17 | 18 |
18 namespace webrtc_jni { | 19 namespace webrtc_jni { |
19 | 20 |
20 // Convenience, used since callbacks occur on the signaling thread, which may | 21 // Convenience, used since callbacks occur on the signaling thread, which may |
21 // be a non-Java thread. | 22 // be a non-Java thread. |
22 static JNIEnv* jni() { | 23 static JNIEnv* jni() { |
23 return AttachCurrentThreadIfNeeded(); | 24 return AttachCurrentThreadIfNeeded(); |
24 } | 25 } |
25 | 26 |
26 PeerConnectionObserverJni::PeerConnectionObserverJni(JNIEnv* jni, | 27 PeerConnectionObserverJni::PeerConnectionObserverJni(JNIEnv* jni, |
27 jobject j_observer) | 28 jobject j_observer) |
28 : j_observer_global_(jni, j_observer), | 29 : j_observer_global_(jni, j_observer), |
29 j_observer_class_(jni, GetObjectClass(jni, *j_observer_global_)), | 30 j_observer_class_(jni, GetObjectClass(jni, *j_observer_global_)), |
30 j_media_stream_class_(jni, FindClass(jni, "org/webrtc/MediaStream")), | 31 j_media_stream_class_(jni, FindClass(jni, "org/webrtc/MediaStream")), |
31 j_media_stream_ctor_( | 32 j_media_stream_ctor_( |
32 GetMethodID(jni, *j_media_stream_class_, "<init>", "(J)V")), | 33 GetMethodID(jni, *j_media_stream_class_, "<init>", "(J)V")), |
33 j_audio_track_class_(jni, FindClass(jni, "org/webrtc/AudioTrack")), | 34 j_audio_track_class_(jni, FindClass(jni, "org/webrtc/AudioTrack")), |
34 j_audio_track_ctor_( | 35 j_audio_track_ctor_( |
35 GetMethodID(jni, *j_audio_track_class_, "<init>", "(J)V")), | 36 GetMethodID(jni, *j_audio_track_class_, "<init>", "(J)V")), |
36 j_video_track_class_(jni, FindClass(jni, "org/webrtc/VideoTrack")), | 37 j_video_track_class_(jni, FindClass(jni, "org/webrtc/VideoTrack")), |
37 j_video_track_ctor_( | 38 j_video_track_ctor_( |
38 GetMethodID(jni, *j_video_track_class_, "<init>", "(J)V")), | 39 GetMethodID(jni, *j_video_track_class_, "<init>", "(J)V")), |
39 j_data_channel_class_(jni, FindClass(jni, "org/webrtc/DataChannel")), | 40 j_data_channel_class_(jni, FindClass(jni, "org/webrtc/DataChannel")), |
40 j_data_channel_ctor_( | 41 j_data_channel_ctor_( |
41 GetMethodID(jni, *j_data_channel_class_, "<init>", "(J)V")), | 42 GetMethodID(jni, *j_data_channel_class_, "<init>", "(J)V")) {} |
42 j_rtp_receiver_class_(jni, FindClass(jni, "org/webrtc/RtpReceiver")), | |
43 j_rtp_receiver_ctor_( | |
44 GetMethodID(jni, *j_rtp_receiver_class_, "<init>", "(J)V")) {} | |
45 | 43 |
46 PeerConnectionObserverJni::~PeerConnectionObserverJni() { | 44 PeerConnectionObserverJni::~PeerConnectionObserverJni() { |
47 ScopedLocalRefFrame local_ref_frame(jni()); | 45 ScopedLocalRefFrame local_ref_frame(jni()); |
46 stream_observers_.clear(); | |
47 while (!remote_tracks_.empty()) { | |
48 NativeToJavaMediaTrackMap::iterator it = remote_tracks_.begin(); | |
49 DeleteGlobalRef(jni(), it->second); | |
50 remote_tracks_.erase(it); | |
51 } | |
48 while (!remote_streams_.empty()) | 52 while (!remote_streams_.empty()) |
49 DisposeRemoteStream(remote_streams_.begin()); | 53 DisposeRemoteStream(remote_streams_.begin()); |
50 while (!rtp_receivers_.empty()) | |
51 DisposeRtpReceiver(rtp_receivers_.begin()); | |
52 } | 54 } |
53 | 55 |
54 void PeerConnectionObserverJni::OnIceCandidate( | 56 void PeerConnectionObserverJni::OnIceCandidate( |
55 const webrtc::IceCandidateInterface* candidate) { | 57 const webrtc::IceCandidateInterface* candidate) { |
56 ScopedLocalRefFrame local_ref_frame(jni()); | 58 ScopedLocalRefFrame local_ref_frame(jni()); |
57 std::string sdp; | 59 std::string sdp; |
58 RTC_CHECK(candidate->ToString(&sdp)) << "got so far: " << sdp; | 60 RTC_CHECK(candidate->ToString(&sdp)) << "got so far: " << sdp; |
59 jclass candidate_class = FindClass(jni(), "org/webrtc/IceCandidate"); | 61 jclass candidate_class = FindClass(jni(), "org/webrtc/IceCandidate"); |
60 jmethodID ctor = | 62 jmethodID ctor = |
61 GetMethodID(jni(), candidate_class, "<init>", | 63 GetMethodID(jni(), candidate_class, "<init>", |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
125 } | 127 } |
126 | 128 |
127 void PeerConnectionObserverJni::OnAddStream( | 129 void PeerConnectionObserverJni::OnAddStream( |
128 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) { | 130 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) { |
129 ScopedLocalRefFrame local_ref_frame(jni()); | 131 ScopedLocalRefFrame local_ref_frame(jni()); |
130 // The stream could be added into the remote_streams_ map when calling | 132 // The stream could be added into the remote_streams_ map when calling |
131 // OnAddTrack. | 133 // OnAddTrack. |
132 jobject j_stream = GetOrCreateJavaStream(stream); | 134 jobject j_stream = GetOrCreateJavaStream(stream); |
133 | 135 |
134 for (const auto& track : stream->GetAudioTracks()) { | 136 for (const auto& track : stream->GetAudioTracks()) { |
135 jstring id = JavaStringFromStdString(jni(), track->id()); | 137 OnAudioTrackAdded(track, stream); |
136 // Java AudioTrack holds one reference. Corresponding Release() is in | |
137 // MediaStreamTrack_free, triggered by AudioTrack.dispose(). | |
138 track->AddRef(); | |
139 jobject j_track = | |
140 jni()->NewObject(*j_audio_track_class_, j_audio_track_ctor_, | |
141 reinterpret_cast<jlong>(track.get()), id); | |
142 CHECK_EXCEPTION(jni()) << "error during NewObject"; | |
143 jfieldID audio_tracks_id = GetFieldID( | |
144 jni(), *j_media_stream_class_, "audioTracks", "Ljava/util/LinkedList;"); | |
145 jobject audio_tracks = GetObjectField(jni(), j_stream, audio_tracks_id); | |
146 jmethodID add = GetMethodID(jni(), GetObjectClass(jni(), audio_tracks), | |
147 "add", "(Ljava/lang/Object;)Z"); | |
148 jboolean added = jni()->CallBooleanMethod(audio_tracks, add, j_track); | |
149 CHECK_EXCEPTION(jni()) << "error during CallBooleanMethod"; | |
150 RTC_CHECK(added); | |
151 } | 138 } |
152 | 139 |
153 for (const auto& track : stream->GetVideoTracks()) { | 140 for (const auto& track : stream->GetVideoTracks()) { |
154 jstring id = JavaStringFromStdString(jni(), track->id()); | 141 OnVideoTrackAdded(track, stream); |
155 // Java VideoTrack holds one reference. Corresponding Release() is in | |
156 // MediaStreamTrack_free, triggered by VideoTrack.dispose(). | |
157 track->AddRef(); | |
158 jobject j_track = | |
159 jni()->NewObject(*j_video_track_class_, j_video_track_ctor_, | |
160 reinterpret_cast<jlong>(track.get()), id); | |
161 CHECK_EXCEPTION(jni()) << "error during NewObject"; | |
162 jfieldID video_tracks_id = GetFieldID( | |
163 jni(), *j_media_stream_class_, "videoTracks", "Ljava/util/LinkedList;"); | |
164 jobject video_tracks = GetObjectField(jni(), j_stream, video_tracks_id); | |
165 jmethodID add = GetMethodID(jni(), GetObjectClass(jni(), video_tracks), | |
166 "add", "(Ljava/lang/Object;)Z"); | |
167 jboolean added = jni()->CallBooleanMethod(video_tracks, add, j_track); | |
168 CHECK_EXCEPTION(jni()) << "error during CallBooleanMethod"; | |
169 RTC_CHECK(added); | |
170 } | 142 } |
171 | 143 |
172 jmethodID m = GetMethodID(jni(), *j_observer_class_, "onAddStream", | 144 jmethodID m = GetMethodID(jni(), *j_observer_class_, "onAddStream", |
173 "(Lorg/webrtc/MediaStream;)V"); | 145 "(Lorg/webrtc/MediaStream;)V"); |
174 jni()->CallVoidMethod(*j_observer_global_, m, j_stream); | 146 jni()->CallVoidMethod(*j_observer_global_, m, j_stream); |
175 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; | 147 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; |
148 | |
149 webrtc::MediaStreamObserver* observer = | |
150 new webrtc::MediaStreamObserver(stream); | |
151 observer->SignalVideoTrackAdded.connect( | |
152 this, &PeerConnectionObserverJni::OnVideoTrackAdded); | |
153 observer->SignalAudioTrackAdded.connect( | |
154 this, &PeerConnectionObserverJni::OnAudioTrackAdded); | |
155 observer->SignalAudioTrackRemoved.connect( | |
156 this, &PeerConnectionObserverJni::OnAudioTrackRemoved); | |
157 observer->SignalVideoTrackRemoved.connect( | |
158 this, &PeerConnectionObserverJni::OnVideoTrackRemoved); | |
159 stream_observers_.push_back( | |
160 std::unique_ptr<webrtc::MediaStreamObserver>(observer)); | |
161 } | |
162 | |
163 void PeerConnectionObserverJni::OnAudioTrackAdded( | |
164 webrtc::AudioTrackInterface* track, | |
165 webrtc::MediaStreamInterface* stream) { | |
166 ScopedLocalRefFrame local_ref_frame(jni()); | |
167 jstring id = JavaStringFromStdString(jni(), track->id()); | |
168 jobject j_stream = GetOrCreateJavaStream(stream); | |
169 // Java AudioTrack holds one reference. Corresponding Release() is in | |
170 // MediaStreamTrack_free, triggered by AudioTrack.dispose(). | |
171 track->AddRef(); | |
172 jobject j_track = jni()->NewObject(*j_audio_track_class_, j_audio_track_ctor_, | |
173 reinterpret_cast<jlong>(track), id); | |
174 CHECK_EXCEPTION(jni()) << "error during NewObject"; | |
175 remote_tracks_[track] = NewGlobalRef(jni(), j_track); | |
176 jfieldID audio_tracks_id = GetFieldID( | |
177 jni(), *j_media_stream_class_, "audioTracks", "Ljava/util/LinkedList;"); | |
178 jobject audio_tracks = GetObjectField(jni(), j_stream, audio_tracks_id); | |
179 jmethodID add = GetMethodID(jni(), GetObjectClass(jni(), audio_tracks), "add", | |
180 "(Ljava/lang/Object;)Z"); | |
181 jboolean added = jni()->CallBooleanMethod(audio_tracks, add, j_track); | |
182 CHECK_EXCEPTION(jni()) << "error during CallBooleanMethod"; | |
183 RTC_CHECK(added); | |
184 | |
185 std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>> streams; | |
186 streams.push_back(rtc::scoped_refptr<webrtc::MediaStreamInterface>(stream)); | |
187 jobjectArray j_stream_array = NativeToJavaMediaStreamArray(jni(), streams); | |
188 jmethodID m = | |
189 GetMethodID(jni(), *j_observer_class_, "onAddTrack", | |
190 "(Lorg/webrtc/MediaStreamTrack;[Lorg/webrtc/MediaStream;)V"); | |
191 jni()->CallVoidMethod(*j_observer_global_, m, j_track, j_stream_array); | |
192 CHECK_EXCEPTION(jni()) << "Error during CallVoidMethod"; | |
193 } | |
194 | |
195 void PeerConnectionObserverJni::OnVideoTrackAdded( | |
196 webrtc::VideoTrackInterface* track, | |
197 webrtc::MediaStreamInterface* stream) { | |
198 ScopedLocalRefFrame local_ref_frame(jni()); | |
199 jobject j_stream = GetOrCreateJavaStream(stream); | |
200 | |
201 jstring id = JavaStringFromStdString(jni(), track->id()); | |
202 // Java VideoTrack holds one reference. Corresponding Release() is in | |
203 // MediaStreamTrack_free, triggered by VideoTrack.dispose(). | |
204 track->AddRef(); | |
205 jobject j_track = jni()->NewObject(*j_video_track_class_, j_video_track_ctor_, | |
206 reinterpret_cast<jlong>(track), id); | |
207 CHECK_EXCEPTION(jni()) << "error during NewObject"; | |
208 remote_tracks_[track] = NewGlobalRef(jni(), j_track); | |
209 jfieldID video_tracks_id = GetFieldID( | |
210 jni(), *j_media_stream_class_, "videoTracks", "Ljava/util/LinkedList;"); | |
211 jobject video_tracks = GetObjectField(jni(), j_stream, video_tracks_id); | |
212 jmethodID add = GetMethodID(jni(), GetObjectClass(jni(), video_tracks), "add", | |
213 "(Ljava/lang/Object;)Z"); | |
214 jboolean added = jni()->CallBooleanMethod(video_tracks, add, j_track); | |
215 CHECK_EXCEPTION(jni()) << "error during CallBooleanMethod"; | |
216 RTC_CHECK(added); | |
217 | |
218 std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>> streams; | |
219 streams.push_back(rtc::scoped_refptr<webrtc::MediaStreamInterface>(stream)); | |
220 jobjectArray j_stream_array = NativeToJavaMediaStreamArray(jni(), streams); | |
221 jmethodID m = | |
222 GetMethodID(jni(), *j_observer_class_, "onAddTrack", | |
223 "(Lorg/webrtc/MediaStreamTrack;[Lorg/webrtc/MediaStream;)V"); | |
224 jni()->CallVoidMethod(*j_observer_global_, m, j_track, j_stream_array); | |
225 CHECK_EXCEPTION(jni()) << "Error during CallVoidMethod"; | |
226 } | |
227 | |
228 void PeerConnectionObserverJni::OnAudioTrackRemoved( | |
229 webrtc::AudioTrackInterface* track, | |
230 webrtc::MediaStreamInterface* stream) { | |
231 ScopedLocalRefFrame local_ref_frame(jni()); | |
232 jobject j_stream = GetOrCreateJavaStream(stream); | |
233 NativeToJavaMediaTrackMap::iterator track_it = remote_tracks_.find(track); | |
234 RTC_CHECK(track_it != remote_tracks_.end()); | |
235 jobject j_track = track_it->second; | |
236 | |
237 jfieldID audio_tracks_id = GetFieldID( | |
238 jni(), *j_media_stream_class_, "audioTracks", "Ljava/util/LinkedList;"); | |
239 jobject video_tracks = GetObjectField(jni(), j_stream, audio_tracks_id); | |
240 jmethodID remove = GetMethodID(jni(), GetObjectClass(jni(), video_tracks), | |
241 "remove", "(Ljava/lang/Object;)Z"); | |
242 jboolean removed = jni()->CallBooleanMethod(video_tracks, remove, j_track); | |
243 CHECK_EXCEPTION(jni()) << "error during CallBooleanMethod"; | |
244 RTC_CHECK(removed); | |
245 | |
246 std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>> streams; | |
247 streams.push_back(rtc::scoped_refptr<webrtc::MediaStreamInterface>(stream)); | |
248 jobjectArray j_stream_array = NativeToJavaMediaStreamArray(jni(), streams); | |
249 jmethodID m = | |
250 GetMethodID(jni(), *j_observer_class_, "onRemoveTrack", | |
251 "(Lorg/webrtc/MediaStreamTrack;[Lorg/webrtc/MediaStream;)V"); | |
252 jni()->CallVoidMethod(*j_observer_global_, m, j_track, j_stream_array); | |
253 CHECK_EXCEPTION(jni()) << "Error during CallVoidMethod"; | |
254 | |
255 DisposeRemoteTrack(track_it); | |
256 } | |
257 | |
258 void PeerConnectionObserverJni::OnVideoTrackRemoved( | |
259 webrtc::VideoTrackInterface* track, | |
260 webrtc::MediaStreamInterface* stream) { | |
261 ScopedLocalRefFrame local_ref_frame(jni()); | |
262 jobject j_stream = GetOrCreateJavaStream(stream); | |
263 NativeToJavaMediaTrackMap::iterator track_it = remote_tracks_.find(track); | |
264 RTC_CHECK(track_it != remote_tracks_.end()); | |
265 jobject j_track = track_it->second; | |
266 | |
267 jfieldID video_tracks_id = GetFieldID( | |
268 jni(), *j_media_stream_class_, "videoTracks", "Ljava/util/LinkedList;"); | |
269 jobject video_tracks = GetObjectField(jni(), j_stream, video_tracks_id); | |
270 jmethodID remove = GetMethodID(jni(), GetObjectClass(jni(), video_tracks), | |
271 "remove", "(Ljava/lang/Object;)Z"); | |
272 jboolean removed = jni()->CallBooleanMethod(video_tracks, remove, j_track); | |
273 CHECK_EXCEPTION(jni()) << "error during CallBooleanMethod"; | |
274 RTC_CHECK(removed); | |
275 | |
276 std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>> streams; | |
277 streams.push_back(rtc::scoped_refptr<webrtc::MediaStreamInterface>(stream)); | |
278 jobjectArray j_stream_array = NativeToJavaMediaStreamArray(jni(), streams); | |
279 jmethodID m = | |
280 GetMethodID(jni(), *j_observer_class_, "onRemoveTrack", | |
281 "(Lorg/webrtc/MediaStreamTrack;[Lorg/webrtc/MediaStream;)V"); | |
282 jni()->CallVoidMethod(*j_observer_global_, m, j_track, j_stream_array); | |
283 CHECK_EXCEPTION(jni()) << "Error during CallVoidMethod"; | |
284 | |
285 DisposeRemoteTrack(track_it); | |
176 } | 286 } |
177 | 287 |
178 void PeerConnectionObserverJni::OnRemoveStream( | 288 void PeerConnectionObserverJni::OnRemoveStream( |
179 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) { | 289 rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) { |
180 ScopedLocalRefFrame local_ref_frame(jni()); | 290 ScopedLocalRefFrame local_ref_frame(jni()); |
181 NativeToJavaStreamsMap::iterator it = remote_streams_.find(stream); | 291 NativeToJavaStreamsMap::iterator it = remote_streams_.find(stream); |
182 RTC_CHECK(it != remote_streams_.end()) | 292 RTC_CHECK(it != remote_streams_.end()) |
183 << "unexpected stream: " << std::hex << stream; | 293 << "unexpected stream: " << std::hex << stream; |
184 jobject j_stream = it->second; | 294 jobject j_stream = it->second; |
185 jmethodID m = GetMethodID(jni(), *j_observer_class_, "onRemoveStream", | 295 jmethodID m = GetMethodID(jni(), *j_observer_class_, "onRemoveStream", |
186 "(Lorg/webrtc/MediaStream;)V"); | 296 "(Lorg/webrtc/MediaStream;)V"); |
187 jni()->CallVoidMethod(*j_observer_global_, m, j_stream); | 297 jni()->CallVoidMethod(*j_observer_global_, m, j_stream); |
188 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; | 298 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; |
299 | |
300 stream_observers_.erase( | |
301 std::remove_if( | |
302 stream_observers_.begin(), stream_observers_.end(), | |
303 [stream]( | |
304 const std::unique_ptr<webrtc::MediaStreamObserver>& observer) { | |
305 return observer->stream() == stream; | |
306 }), | |
307 stream_observers_.end()); | |
308 | |
189 // Release the refptr reference so that DisposeRemoteStream can assert | 309 // Release the refptr reference so that DisposeRemoteStream can assert |
190 // it removes the final reference. | 310 // it removes the final reference. |
191 stream = nullptr; | 311 stream = nullptr; |
192 DisposeRemoteStream(it); | 312 DisposeRemoteStream(it); |
193 } | 313 } |
194 | 314 |
195 void PeerConnectionObserverJni::OnDataChannel( | 315 void PeerConnectionObserverJni::OnDataChannel( |
196 rtc::scoped_refptr<webrtc::DataChannelInterface> channel) { | 316 rtc::scoped_refptr<webrtc::DataChannelInterface> channel) { |
197 ScopedLocalRefFrame local_ref_frame(jni()); | 317 ScopedLocalRefFrame local_ref_frame(jni()); |
198 jobject j_channel = | 318 jobject j_channel = |
(...skipping 20 matching lines...) Expand all Loading... | |
219 jmethodID m = | 339 jmethodID m = |
220 GetMethodID(jni(), *j_observer_class_, "onRenegotiationNeeded", "()V"); | 340 GetMethodID(jni(), *j_observer_class_, "onRenegotiationNeeded", "()V"); |
221 jni()->CallVoidMethod(*j_observer_global_, m); | 341 jni()->CallVoidMethod(*j_observer_global_, m); |
222 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; | 342 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; |
223 } | 343 } |
224 | 344 |
225 void PeerConnectionObserverJni::OnAddTrack( | 345 void PeerConnectionObserverJni::OnAddTrack( |
226 rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver, | 346 rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver, |
227 const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>& | 347 const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>& |
228 streams) { | 348 streams) { |
229 ScopedLocalRefFrame local_ref_frame(jni()); | 349 // PCO::onAddTrack is broken and called only one time when the MediaStream |
230 jobject j_rtp_receiver = | 350 // is added to PC. Android sdk observes MediaStream's tracks modification |
231 jni()->NewObject(*j_rtp_receiver_class_, j_rtp_receiver_ctor_, | 351 // with MediaStreamObserver - see PeerConnectionObserverJni::OnAddStream |
Taylor Brandstetter
2017/08/29 19:48:09
Can you explain the issue more? Can this be fixed,
korniltsev
2017/08/30 21:47:47
It was not actually broken, I was wrong when I wro
| |
232 jlongFromPointer(receiver.get())); | |
233 CHECK_EXCEPTION(jni()) << "error during NewObject"; | |
234 receiver->AddRef(); | |
235 rtp_receivers_[receiver] = NewGlobalRef(jni(), j_rtp_receiver); | |
236 | |
237 jobjectArray j_stream_array = NativeToJavaMediaStreamArray(jni(), streams); | |
238 jmethodID m = | |
239 GetMethodID(jni(), *j_observer_class_, "onAddTrack", | |
240 "(Lorg/webrtc/RtpReceiver;[Lorg/webrtc/MediaStream;)V"); | |
241 jni()->CallVoidMethod(*j_observer_global_, m, j_rtp_receiver, j_stream_array); | |
242 CHECK_EXCEPTION(jni()) << "Error during CallVoidMethod"; | |
243 } | 352 } |
244 | 353 |
245 void PeerConnectionObserverJni::SetConstraints( | 354 void PeerConnectionObserverJni::SetConstraints( |
246 MediaConstraintsJni* constraints) { | 355 MediaConstraintsJni* constraints) { |
247 RTC_CHECK(!constraints_.get()) << "constraints already set!"; | 356 RTC_CHECK(!constraints_.get()) << "constraints already set!"; |
248 constraints_.reset(constraints); | 357 constraints_.reset(constraints); |
249 } | 358 } |
250 | 359 |
251 void PeerConnectionObserverJni::DisposeRemoteStream( | 360 void PeerConnectionObserverJni::DisposeRemoteStream( |
252 const NativeToJavaStreamsMap::iterator& it) { | 361 const NativeToJavaStreamsMap::iterator& it) { |
253 jobject j_stream = it->second; | 362 jobject j_stream = it->second; |
254 remote_streams_.erase(it); | 363 remote_streams_.erase(it); |
255 jni()->CallVoidMethod( | 364 jni()->CallVoidMethod( |
256 j_stream, GetMethodID(jni(), *j_media_stream_class_, "dispose", "()V")); | 365 j_stream, GetMethodID(jni(), *j_media_stream_class_, "dispose", "()V")); |
257 CHECK_EXCEPTION(jni()) << "error during MediaStream.dispose()"; | 366 CHECK_EXCEPTION(jni()) << "error during MediaStream.dispose()"; |
258 DeleteGlobalRef(jni(), j_stream); | 367 DeleteGlobalRef(jni(), j_stream); |
259 } | 368 } |
260 | 369 |
261 void PeerConnectionObserverJni::DisposeRtpReceiver( | 370 void PeerConnectionObserverJni::DisposeRemoteTrack( |
262 const NativeToJavaRtpReceiverMap::iterator& it) { | 371 const NativeToJavaMediaTrackMap::iterator& it) { |
263 jobject j_rtp_receiver = it->second; | 372 RTC_CHECK(it != remote_tracks_.end()); |
264 rtp_receivers_.erase(it); | 373 webrtc::MediaStreamTrackInterface* track = it->first; |
265 jni()->CallVoidMethod( | 374 jobject j_track = it->second; |
266 j_rtp_receiver, | 375 remote_tracks_.erase(it); |
267 GetMethodID(jni(), *j_rtp_receiver_class_, "dispose", "()V")); | 376 jmethodID dispose; |
268 CHECK_EXCEPTION(jni()) << "error during RtpReceiver.dispose()"; | 377 if (track->kind() == webrtc::MediaStreamTrackInterface::kVideoKind) { |
269 DeleteGlobalRef(jni(), j_rtp_receiver); | 378 dispose = GetMethodID(jni(), *j_video_track_class_, "dispose", "()V"); |
379 } else { | |
380 dispose = GetMethodID(jni(), *j_audio_track_class_, "dispose", "()V"); | |
381 } | |
382 jni()->CallVoidMethod(j_track, dispose); | |
383 CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; | |
384 DeleteGlobalRef(jni(), j_track); | |
270 } | 385 } |
271 | 386 |
272 // If the NativeToJavaStreamsMap contains the stream, return it. | 387 // If the NativeToJavaStreamsMap contains the stream, return it. |
273 // Otherwise, create a new Java MediaStream. | 388 // Otherwise, create a new Java MediaStream. |
274 jobject PeerConnectionObserverJni::GetOrCreateJavaStream( | 389 jobject PeerConnectionObserverJni::GetOrCreateJavaStream( |
275 const rtc::scoped_refptr<webrtc::MediaStreamInterface>& stream) { | 390 const rtc::scoped_refptr<webrtc::MediaStreamInterface>& stream) { |
276 NativeToJavaStreamsMap::iterator it = remote_streams_.find(stream); | 391 NativeToJavaStreamsMap::iterator it = remote_streams_.find(stream); |
277 if (it != remote_streams_.end()) { | 392 if (it != remote_streams_.end()) { |
278 return it->second; | 393 return it->second; |
279 } | 394 } |
280 | |
281 // Java MediaStream holds one reference. Corresponding Release() is in | 395 // Java MediaStream holds one reference. Corresponding Release() is in |
282 // MediaStream_free, triggered by MediaStream.dispose(). | 396 // MediaStream_free, triggered by MediaStream.dispose(). |
283 stream->AddRef(); | 397 stream->AddRef(); |
284 jobject j_stream = | 398 jobject j_stream = |
285 jni()->NewObject(*j_media_stream_class_, j_media_stream_ctor_, | 399 jni()->NewObject(*j_media_stream_class_, j_media_stream_ctor_, |
286 reinterpret_cast<jlong>(stream.get())); | 400 reinterpret_cast<jlong>(stream.get())); |
287 CHECK_EXCEPTION(jni()) << "error during NewObject"; | 401 CHECK_EXCEPTION(jni()) << "error during NewObject"; |
288 | 402 |
289 remote_streams_[stream] = NewGlobalRef(jni(), j_stream); | 403 remote_streams_[stream] = NewGlobalRef(jni(), j_stream); |
290 return j_stream; | 404 return j_stream; |
291 } | 405 } |
292 | 406 |
293 jobjectArray PeerConnectionObserverJni::NativeToJavaMediaStreamArray( | 407 jobjectArray PeerConnectionObserverJni::NativeToJavaMediaStreamArray( |
294 JNIEnv* jni, | 408 JNIEnv* jni, |
295 const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>& | 409 const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>& |
296 streams) { | 410 streams) { |
297 jobjectArray java_streams = | 411 jobjectArray java_streams = |
298 jni->NewObjectArray(streams.size(), *j_media_stream_class_, nullptr); | 412 jni->NewObjectArray(streams.size(), *j_media_stream_class_, nullptr); |
299 CHECK_EXCEPTION(jni) << "error during NewObjectArray"; | 413 CHECK_EXCEPTION(jni) << "error during NewObjectArray"; |
300 for (size_t i = 0; i < streams.size(); ++i) { | 414 for (size_t i = 0; i < streams.size(); ++i) { |
301 jobject j_stream = GetOrCreateJavaStream(streams[i]); | 415 jobject j_stream = GetOrCreateJavaStream(streams[i]); |
302 jni->SetObjectArrayElement(java_streams, i, j_stream); | 416 jni->SetObjectArrayElement(java_streams, i, j_stream); |
303 } | 417 } |
304 return java_streams; | 418 return java_streams; |
305 } | 419 } |
306 | 420 |
307 } // namespace webrtc_jni | 421 } // namespace webrtc_jni |
OLD | NEW |