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