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/rtp_receiver.h"
12 
13 #include "sdk/android/generated_peerconnection_jni/RtpReceiver_jni.h"
14 #include "sdk/android/native_api/jni/java_types.h"
15 #include "sdk/android/src/jni/jni_helpers.h"
16 #include "sdk/android/src/jni/pc/media_stream_track.h"
17 #include "sdk/android/src/jni/pc/rtp_parameters.h"
18 
19 namespace webrtc {
20 namespace jni {
21 
22 namespace {
23 
24 // Adapter between the C++ RtpReceiverObserverInterface and the Java
25 // RtpReceiver.Observer interface. Wraps an instance of the Java interface and
26 // dispatches C++ callbacks to Java.
27 class RtpReceiverObserverJni : public RtpReceiverObserverInterface {
28  public:
RtpReceiverObserverJni(JNIEnv * env,const JavaRef<jobject> & j_observer)29   RtpReceiverObserverJni(JNIEnv* env, const JavaRef<jobject>& j_observer)
30       : j_observer_global_(env, j_observer) {}
31 
32   ~RtpReceiverObserverJni() override = default;
33 
OnFirstPacketReceived(cricket::MediaType media_type)34   void OnFirstPacketReceived(cricket::MediaType media_type) override {
35     JNIEnv* const env = AttachCurrentThreadIfNeeded();
36     Java_Observer_onFirstPacketReceived(env, j_observer_global_,
37                                         NativeToJavaMediaType(env, media_type));
38   }
39 
40  private:
41   const ScopedJavaGlobalRef<jobject> j_observer_global_;
42 };
43 
44 }  // namespace
45 
NativeToJavaRtpReceiver(JNIEnv * env,rtc::scoped_refptr<RtpReceiverInterface> receiver)46 ScopedJavaLocalRef<jobject> NativeToJavaRtpReceiver(
47     JNIEnv* env,
48     rtc::scoped_refptr<RtpReceiverInterface> receiver) {
49   // Receiver is now owned by Java object, and will be freed from there.
50   return Java_RtpReceiver_Constructor(env,
51                                       jlongFromPointer(receiver.release()));
52 }
53 
JavaRtpReceiverGlobalOwner(JNIEnv * env,const JavaRef<jobject> & j_receiver)54 JavaRtpReceiverGlobalOwner::JavaRtpReceiverGlobalOwner(
55     JNIEnv* env,
56     const JavaRef<jobject>& j_receiver)
57     : j_receiver_(env, j_receiver) {}
58 
59 JavaRtpReceiverGlobalOwner::JavaRtpReceiverGlobalOwner(
60     JavaRtpReceiverGlobalOwner&& other) = default;
61 
~JavaRtpReceiverGlobalOwner()62 JavaRtpReceiverGlobalOwner::~JavaRtpReceiverGlobalOwner() {
63   if (j_receiver_.obj())
64     Java_RtpReceiver_dispose(AttachCurrentThreadIfNeeded(), j_receiver_);
65 }
66 
JNI_RtpReceiver_GetTrack(JNIEnv * jni,jlong j_rtp_receiver_pointer)67 static jlong JNI_RtpReceiver_GetTrack(JNIEnv* jni,
68                                       jlong j_rtp_receiver_pointer) {
69   // MediaStreamTrack will have shared ownership by the MediaStreamTrack Java
70   // object.
71   return jlongFromPointer(
72       reinterpret_cast<RtpReceiverInterface*>(j_rtp_receiver_pointer)
73           ->track()
74           .release());
75 }
76 
JNI_RtpReceiver_GetParameters(JNIEnv * jni,jlong j_rtp_receiver_pointer)77 static ScopedJavaLocalRef<jobject> JNI_RtpReceiver_GetParameters(
78     JNIEnv* jni,
79     jlong j_rtp_receiver_pointer) {
80   RtpParameters parameters =
81       reinterpret_cast<RtpReceiverInterface*>(j_rtp_receiver_pointer)
82           ->GetParameters();
83   return NativeToJavaRtpParameters(jni, parameters);
84 }
85 
JNI_RtpReceiver_GetId(JNIEnv * jni,jlong j_rtp_receiver_pointer)86 static ScopedJavaLocalRef<jstring> JNI_RtpReceiver_GetId(
87     JNIEnv* jni,
88     jlong j_rtp_receiver_pointer) {
89   return NativeToJavaString(
90       jni,
91       reinterpret_cast<RtpReceiverInterface*>(j_rtp_receiver_pointer)->id());
92 }
93 
JNI_RtpReceiver_SetObserver(JNIEnv * jni,jlong j_rtp_receiver_pointer,const JavaParamRef<jobject> & j_observer)94 static jlong JNI_RtpReceiver_SetObserver(
95     JNIEnv* jni,
96     jlong j_rtp_receiver_pointer,
97     const JavaParamRef<jobject>& j_observer) {
98   RtpReceiverObserverJni* rtpReceiverObserver =
99       new RtpReceiverObserverJni(jni, j_observer);
100   reinterpret_cast<RtpReceiverInterface*>(j_rtp_receiver_pointer)
101       ->SetObserver(rtpReceiverObserver);
102   return jlongFromPointer(rtpReceiverObserver);
103 }
104 
JNI_RtpReceiver_UnsetObserver(JNIEnv * jni,jlong j_rtp_receiver_pointer,jlong j_observer_pointer)105 static void JNI_RtpReceiver_UnsetObserver(JNIEnv* jni,
106                                           jlong j_rtp_receiver_pointer,
107                                           jlong j_observer_pointer) {
108   reinterpret_cast<RtpReceiverInterface*>(j_rtp_receiver_pointer)
109       ->SetObserver(nullptr);
110   RtpReceiverObserverJni* observer =
111       reinterpret_cast<RtpReceiverObserverJni*>(j_observer_pointer);
112   if (observer) {
113     delete observer;
114   }
115 }
116 
JNI_RtpReceiver_SetFrameDecryptor(JNIEnv * jni,jlong j_rtp_sender_pointer,jlong j_frame_decryptor_pointer)117 static void JNI_RtpReceiver_SetFrameDecryptor(JNIEnv* jni,
118                                               jlong j_rtp_sender_pointer,
119                                               jlong j_frame_decryptor_pointer) {
120   reinterpret_cast<RtpReceiverInterface*>(j_rtp_sender_pointer)
121       ->SetFrameDecryptor(reinterpret_cast<FrameDecryptorInterface*>(
122           j_frame_decryptor_pointer));
123 }
124 
125 }  // namespace jni
126 }  // namespace webrtc
127