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:
committed by
Commit Bot
parent
b8ff8f7d40
commit
6a0345b3b0
@ -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");
|
||||
}
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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]);
|
||||
|
||||
@ -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_;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user