Android: Generate JNI code for MediaStream

Bug: webrtc:8278
Change-Id: I48d0615f3db3f22e7179a2d7c59b970a33678ada
Reviewed-on: https://webrtc-review.googlesource.com/25962
Commit-Queue: Magnus Jedvert <magjed@webrtc.org>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20891}
This commit is contained in:
Magnus Jedvert
2017-11-27 11:23:42 +01:00
committed by Commit Bot
parent b8ff8f7d40
commit 6a0345b3b0
6 changed files with 77 additions and 126 deletions

View File

@ -59,7 +59,6 @@ ClassReferenceHolder::ClassReferenceHolder(JNIEnv* jni) {
LoadClass(jni, "java/nio/ByteBuffer");
LoadClass(jni, "java/util/ArrayList");
LoadClass(jni, "java/util/LinkedHashMap");
LoadClass(jni, "org/webrtc/AudioTrack");
LoadClass(jni, "org/webrtc/Camera1Enumerator");
LoadClass(jni, "org/webrtc/Camera2Enumerator");
LoadClass(jni, "org/webrtc/CameraEnumerationAndroid");
@ -76,7 +75,6 @@ ClassReferenceHolder::ClassReferenceHolder(JNIEnv* jni) {
LoadClass(jni, "org/webrtc/MediaCodecVideoEncoder$OutputBufferInfo");
LoadClass(jni, "org/webrtc/MediaCodecVideoEncoder$VideoCodecType");
LoadClass(jni, "org/webrtc/MediaSource$State");
LoadClass(jni, "org/webrtc/MediaStream");
LoadClass(jni, "org/webrtc/MediaStreamTrack");
LoadClass(jni, "org/webrtc/MediaStreamTrack$MediaType");
LoadClass(jni, "org/webrtc/MediaStreamTrack$State");
@ -114,7 +112,6 @@ ClassReferenceHolder::ClassReferenceHolder(JNIEnv* jni) {
LoadClass(jni, "org/webrtc/VideoFrame$TextureBuffer");
LoadClass(jni, "org/webrtc/VideoRenderer$I420Frame");
LoadClass(jni, "org/webrtc/VideoSink");
LoadClass(jni, "org/webrtc/VideoTrack");
LoadClass(jni, "org/webrtc/WrappedNativeI420Buffer");
}

View File

@ -15,7 +15,7 @@ namespace webrtc {
namespace jni {
JNI_FUNCTION_DECLARATION(jboolean,
MediaStream_nativeAddAudioTrack,
MediaStream_addAudioTrackToNativeStream,
JNIEnv* jni,
jclass,
jlong pointer,
@ -25,7 +25,7 @@ JNI_FUNCTION_DECLARATION(jboolean,
}
JNI_FUNCTION_DECLARATION(jboolean,
MediaStream_nativeAddVideoTrack,
MediaStream_addVideoTrackToNativeStream,
JNIEnv* jni,
jclass,
jlong pointer,
@ -35,7 +35,7 @@ JNI_FUNCTION_DECLARATION(jboolean,
}
JNI_FUNCTION_DECLARATION(jboolean,
MediaStream_nativeRemoveAudioTrack,
MediaStream_removeNativeAudioTrack,
JNIEnv* jni,
jclass,
jlong pointer,
@ -45,7 +45,7 @@ JNI_FUNCTION_DECLARATION(jboolean,
}
JNI_FUNCTION_DECLARATION(jboolean,
MediaStream_nativeRemoveVideoTrack,
MediaStream_removeNativeVideoTrack,
JNIEnv* jni,
jclass,
jlong pointer,
@ -55,7 +55,7 @@ JNI_FUNCTION_DECLARATION(jboolean,
}
JNI_FUNCTION_DECLARATION(jstring,
MediaStream_nativeLabel,
MediaStream_getNativeLabel,
JNIEnv* jni,
jclass,
jlong j_p) {

View File

@ -14,6 +14,7 @@
#include <string>
#include "rtc_base/ptr_util.h"
#include "sdk/android/generated_peerconnection_jni/jni/MediaStream_jni.h"
#include "sdk/android/src/jni/classreferenceholder.h"
#include "sdk/android/src/jni/pc/datachannel.h"
#include "sdk/android/src/jni/pc/java_native_conversion.h"
@ -31,22 +32,6 @@ PeerConnectionObserverJni::PeerConnectionObserverJni(JNIEnv* jni,
jobject j_observer)
: j_observer_global_(jni, j_observer),
j_observer_class_(jni, GetObjectClass(jni, *j_observer_global_)),
j_media_stream_class_(jni, FindClass(jni, "org/webrtc/MediaStream")),
j_media_stream_ctor_(
GetMethodID(jni, *j_media_stream_class_, "<init>", "(J)V")),
j_media_stream_track_class_(
jni,
FindClass(jni, "org/webrtc/MediaStreamTrack")),
j_track_dispose_id_(
GetMethodID(jni, *j_media_stream_track_class_, "dispose", "()V")),
j_native_track_id_(
GetFieldID(jni, *j_media_stream_track_class_, "nativeTrack", "J")),
j_audio_track_class_(jni, FindClass(jni, "org/webrtc/AudioTrack")),
j_audio_track_ctor_(
GetMethodID(jni, *j_audio_track_class_, "<init>", "(J)V")),
j_video_track_class_(jni, FindClass(jni, "org/webrtc/VideoTrack")),
j_video_track_ctor_(
GetMethodID(jni, *j_video_track_class_, "<init>", "(J)V")),
j_rtp_receiver_class_(jni, FindClass(jni, "org/webrtc/RtpReceiver")),
j_rtp_receiver_ctor_(
GetMethodID(jni, *j_rtp_receiver_class_, "<init>", "(J)V")) {}
@ -159,66 +144,17 @@ void PeerConnectionObserverJni::OnAddStream(
void PeerConnectionObserverJni::AddNativeAudioTrackToJavaStream(
rtc::scoped_refptr<AudioTrackInterface> track,
jobject j_stream) {
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";
// Now add to the audioTracks linked list.
jfieldID audio_tracks_id = GetFieldID(jni(), *j_media_stream_class_,
"audioTracks", "Ljava/util/List;");
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);
JNIEnv* env = AttachCurrentThreadIfNeeded();
Java_MediaStream_addNativeAudioTrack(env, j_stream,
jlongFromPointer(track.release()));
}
void PeerConnectionObserverJni::AddNativeVideoTrackToJavaStream(
rtc::scoped_refptr<VideoTrackInterface> track,
jobject j_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.get()), id);
CHECK_EXCEPTION(jni()) << "error during NewObject";
// Now add to the videoTracks linked list.
jfieldID video_tracks_id = GetFieldID(jni(), *j_media_stream_class_,
"videoTracks", "Ljava/util/List;");
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::RemoveAndDisposeNativeTrackFromJavaTrackList(
MediaStreamTrackInterface* track,
jobject j_tracks) {
Iterable iterable_tracks(jni(), j_tracks);
for (auto it = iterable_tracks.begin(); it != iterable_tracks.end(); ++it) {
MediaStreamTrackInterface* native_track =
reinterpret_cast<MediaStreamTrackInterface*>(
jni()->GetLongField(*it, j_native_track_id_));
CHECK_EXCEPTION(jni()) << "error during GetLongField";
if (native_track == track) {
jni()->CallVoidMethod(*it, j_track_dispose_id_);
it.Remove();
return;
}
}
// If we reached this point, we didn't find the track, which means we're
// getting a "track removed" callback but the Java stream doesn't have a
// corresponding track, which indicates a bug somewhere.
RTC_NOTREACHED();
JNIEnv* env = AttachCurrentThreadIfNeeded();
Java_MediaStream_addNativeVideoTrack(env, j_stream,
jlongFromPointer(track.release()));
}
void PeerConnectionObserverJni::OnAudioTrackAddedToStream(
@ -240,23 +176,19 @@ void PeerConnectionObserverJni::OnVideoTrackAddedToStream(
void PeerConnectionObserverJni::OnAudioTrackRemovedFromStream(
AudioTrackInterface* track,
MediaStreamInterface* stream) {
ScopedLocalRefFrame local_ref_frame(jni());
JNIEnv* env = AttachCurrentThreadIfNeeded();
ScopedLocalRefFrame local_ref_frame(env);
jobject j_stream = GetOrCreateJavaStream(stream);
jfieldID audio_tracks_id = GetFieldID(jni(), *j_media_stream_class_,
"audioTracks", "Ljava/util/List;");
jobject audio_tracks = GetObjectField(jni(), j_stream, audio_tracks_id);
RemoveAndDisposeNativeTrackFromJavaTrackList(track, audio_tracks);
Java_MediaStream_removeAudioTrack(env, j_stream, jlongFromPointer(track));
}
void PeerConnectionObserverJni::OnVideoTrackRemovedFromStream(
VideoTrackInterface* track,
MediaStreamInterface* stream) {
ScopedLocalRefFrame local_ref_frame(jni());
JNIEnv* env = AttachCurrentThreadIfNeeded();
ScopedLocalRefFrame local_ref_frame(env);
jobject j_stream = GetOrCreateJavaStream(stream);
jfieldID video_tracks_id = GetFieldID(jni(), *j_media_stream_class_,
"videoTracks", "Ljava/util/List;");
jobject video_tracks = GetObjectField(jni(), j_stream, video_tracks_id);
RemoveAndDisposeNativeTrackFromJavaTrackList(track, video_tracks);
Java_MediaStream_removeVideoTrack(env, j_stream, jlongFromPointer(track));
}
void PeerConnectionObserverJni::OnRemoveStream(
@ -336,10 +268,9 @@ void PeerConnectionObserverJni::DisposeRemoteStream(
stream_observers_.end());
remote_streams_.erase(it);
jni()->CallVoidMethod(
j_stream, GetMethodID(jni(), *j_media_stream_class_, "dispose", "()V"));
CHECK_EXCEPTION(jni()) << "error during MediaStream.dispose()";
DeleteGlobalRef(jni(), j_stream);
JNIEnv* env = AttachCurrentThreadIfNeeded();
Java_MediaStream_dispose(env, j_stream);
DeleteGlobalRef(env, j_stream);
}
void PeerConnectionObserverJni::DisposeRtpReceiver(
@ -365,9 +296,7 @@ jobject PeerConnectionObserverJni::GetOrCreateJavaStream(
// MediaStream_free, triggered by MediaStream.dispose().
stream->AddRef();
jobject j_stream =
jni()->NewObject(*j_media_stream_class_, j_media_stream_ctor_,
reinterpret_cast<jlong>(stream.get()));
CHECK_EXCEPTION(jni()) << "error during NewObject";
Java_MediaStream_Constructor(jni(), jlongFromPointer(stream.get()));
remote_streams_[stream] = NewGlobalRef(jni(), j_stream);
return j_stream;
@ -376,8 +305,8 @@ jobject PeerConnectionObserverJni::GetOrCreateJavaStream(
jobjectArray PeerConnectionObserverJni::NativeToJavaMediaStreamArray(
JNIEnv* jni,
const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
jobjectArray java_streams =
jni->NewObjectArray(streams.size(), *j_media_stream_class_, nullptr);
jobjectArray java_streams = jni->NewObjectArray(
streams.size(), org_webrtc_MediaStream_clazz(jni), nullptr);
CHECK_EXCEPTION(jni) << "error during NewObjectArray";
for (size_t i = 0; i < streams.size(); ++i) {
jobject j_stream = GetOrCreateJavaStream(streams[i]);

View File

@ -87,14 +87,6 @@ class PeerConnectionObserverJni : public PeerConnectionObserver,
void AddNativeVideoTrackToJavaStream(
rtc::scoped_refptr<VideoTrackInterface> track,
jobject j_stream);
// Remove and dispose the Java MediaStreamTrack object that wraps |track|,
// given |j_tracks| which is a linked list of tracks (either the videoTracks
// or audioTracks member of MediaStream).
//
// DCHECKs if the track isn't found.
void RemoveAndDisposeNativeTrackFromJavaTrackList(
MediaStreamTrackInterface* track,
jobject j_tracks);
// Callbacks invoked when a native stream changes, and the Java stream needs
// to be updated; MediaStreamObserver is used to make this simpler.
@ -109,15 +101,6 @@ class PeerConnectionObserverJni : public PeerConnectionObserver,
const ScopedGlobalRef<jobject> j_observer_global_;
const ScopedGlobalRef<jclass> j_observer_class_;
const ScopedGlobalRef<jclass> j_media_stream_class_;
const jmethodID j_media_stream_ctor_;
const ScopedGlobalRef<jclass> j_media_stream_track_class_;
const jmethodID j_track_dispose_id_;
const jfieldID j_native_track_id_;
const ScopedGlobalRef<jclass> j_audio_track_class_;
const jmethodID j_audio_track_ctor_;
const ScopedGlobalRef<jclass> j_video_track_class_;
const jmethodID j_video_track_ctor_;
const ScopedGlobalRef<jclass> j_rtp_receiver_class_;
const jmethodID j_rtp_receiver_ctor_;