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/media_stream.h"
12
13 #include <memory>
14
15 #include "sdk/android/generated_peerconnection_jni/MediaStream_jni.h"
16 #include "sdk/android/native_api/jni/java_types.h"
17 #include "sdk/android/src/jni/jni_helpers.h"
18
19 namespace webrtc {
20 namespace jni {
21
JavaMediaStream(JNIEnv * env,rtc::scoped_refptr<MediaStreamInterface> media_stream)22 JavaMediaStream::JavaMediaStream(
23 JNIEnv* env,
24 rtc::scoped_refptr<MediaStreamInterface> media_stream)
25 : j_media_stream_(
26 env,
27 Java_MediaStream_Constructor(env,
28 jlongFromPointer(media_stream.get()))),
29 observer_(std::make_unique<MediaStreamObserver>(media_stream)) {
30 for (rtc::scoped_refptr<AudioTrackInterface> track :
31 media_stream->GetAudioTracks()) {
32 Java_MediaStream_addNativeAudioTrack(env, j_media_stream_,
33 jlongFromPointer(track.release()));
34 }
35 for (rtc::scoped_refptr<VideoTrackInterface> track :
36 media_stream->GetVideoTracks()) {
37 Java_MediaStream_addNativeVideoTrack(env, j_media_stream_,
38 jlongFromPointer(track.release()));
39 }
40
41 // Create an observer to update the Java stream when the native stream's set
42 // of tracks changes.
43 observer_->SignalAudioTrackRemoved.connect(
44 this, &JavaMediaStream::OnAudioTrackRemovedFromStream);
45 observer_->SignalVideoTrackRemoved.connect(
46 this, &JavaMediaStream::OnVideoTrackRemovedFromStream);
47 observer_->SignalAudioTrackAdded.connect(
48 this, &JavaMediaStream::OnAudioTrackAddedToStream);
49 observer_->SignalVideoTrackAdded.connect(
50 this, &JavaMediaStream::OnVideoTrackAddedToStream);
51
52 // |j_media_stream| holds one reference. Corresponding Release() is in
53 // MediaStream_free, triggered by MediaStream.dispose().
54 media_stream.release();
55 }
56
~JavaMediaStream()57 JavaMediaStream::~JavaMediaStream() {
58 JNIEnv* env = AttachCurrentThreadIfNeeded();
59 // Remove the observer first, so it doesn't react to events during deletion.
60 observer_ = nullptr;
61 Java_MediaStream_dispose(env, j_media_stream_);
62 }
63
OnAudioTrackAddedToStream(AudioTrackInterface * track,MediaStreamInterface * stream)64 void JavaMediaStream::OnAudioTrackAddedToStream(AudioTrackInterface* track,
65 MediaStreamInterface* stream) {
66 JNIEnv* env = AttachCurrentThreadIfNeeded();
67 ScopedLocalRefFrame local_ref_frame(env);
68 track->AddRef();
69 Java_MediaStream_addNativeAudioTrack(env, j_media_stream_,
70 jlongFromPointer(track));
71 }
72
OnVideoTrackAddedToStream(VideoTrackInterface * track,MediaStreamInterface * stream)73 void JavaMediaStream::OnVideoTrackAddedToStream(VideoTrackInterface* track,
74 MediaStreamInterface* stream) {
75 JNIEnv* env = AttachCurrentThreadIfNeeded();
76 ScopedLocalRefFrame local_ref_frame(env);
77 track->AddRef();
78 Java_MediaStream_addNativeVideoTrack(env, j_media_stream_,
79 jlongFromPointer(track));
80 }
81
OnAudioTrackRemovedFromStream(AudioTrackInterface * track,MediaStreamInterface * stream)82 void JavaMediaStream::OnAudioTrackRemovedFromStream(
83 AudioTrackInterface* track,
84 MediaStreamInterface* stream) {
85 JNIEnv* env = AttachCurrentThreadIfNeeded();
86 ScopedLocalRefFrame local_ref_frame(env);
87 Java_MediaStream_removeAudioTrack(env, j_media_stream_,
88 jlongFromPointer(track));
89 }
90
OnVideoTrackRemovedFromStream(VideoTrackInterface * track,MediaStreamInterface * stream)91 void JavaMediaStream::OnVideoTrackRemovedFromStream(
92 VideoTrackInterface* track,
93 MediaStreamInterface* stream) {
94 JNIEnv* env = AttachCurrentThreadIfNeeded();
95 ScopedLocalRefFrame local_ref_frame(env);
96 Java_MediaStream_removeVideoTrack(env, j_media_stream_,
97 jlongFromPointer(track));
98 }
99
GetMediaStreamClass(JNIEnv * env)100 jclass GetMediaStreamClass(JNIEnv* env) {
101 return org_webrtc_MediaStream_clazz(env);
102 }
103
JNI_MediaStream_AddAudioTrackToNativeStream(JNIEnv * jni,jlong pointer,jlong j_audio_track_pointer)104 static jboolean JNI_MediaStream_AddAudioTrackToNativeStream(
105 JNIEnv* jni,
106 jlong pointer,
107 jlong j_audio_track_pointer) {
108 return reinterpret_cast<MediaStreamInterface*>(pointer)->AddTrack(
109 reinterpret_cast<AudioTrackInterface*>(j_audio_track_pointer));
110 }
111
JNI_MediaStream_AddVideoTrackToNativeStream(JNIEnv * jni,jlong pointer,jlong j_video_track_pointer)112 static jboolean JNI_MediaStream_AddVideoTrackToNativeStream(
113 JNIEnv* jni,
114 jlong pointer,
115 jlong j_video_track_pointer) {
116 return reinterpret_cast<MediaStreamInterface*>(pointer)->AddTrack(
117 reinterpret_cast<VideoTrackInterface*>(j_video_track_pointer));
118 }
119
JNI_MediaStream_RemoveAudioTrack(JNIEnv * jni,jlong pointer,jlong j_audio_track_pointer)120 static jboolean JNI_MediaStream_RemoveAudioTrack(JNIEnv* jni,
121 jlong pointer,
122 jlong j_audio_track_pointer) {
123 return reinterpret_cast<MediaStreamInterface*>(pointer)->RemoveTrack(
124 reinterpret_cast<AudioTrackInterface*>(j_audio_track_pointer));
125 }
126
JNI_MediaStream_RemoveVideoTrack(JNIEnv * jni,jlong pointer,jlong j_video_track_pointer)127 static jboolean JNI_MediaStream_RemoveVideoTrack(JNIEnv* jni,
128 jlong pointer,
129 jlong j_video_track_pointer) {
130 return reinterpret_cast<MediaStreamInterface*>(pointer)->RemoveTrack(
131 reinterpret_cast<VideoTrackInterface*>(j_video_track_pointer));
132 }
133
JNI_MediaStream_GetId(JNIEnv * jni,jlong j_p)134 static ScopedJavaLocalRef<jstring> JNI_MediaStream_GetId(JNIEnv* jni,
135 jlong j_p) {
136 return NativeToJavaString(jni,
137 reinterpret_cast<MediaStreamInterface*>(j_p)->id());
138 }
139
140 } // namespace jni
141 } // namespace webrtc
142