mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 05:40:42 +01:00
Moved Asynchronicity From Java to C++ for AndroidVoip Demo App
Moved asynchronicity from Java to C++. Bug: webrtc:11723 Change-Id: I985693dc7d4312b6072314088716167b9cdd9999 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/180774 Commit-Queue: Tim Na <natim@webrtc.org> Reviewed-by: Tim Na <natim@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31958}
This commit is contained in:
parent
552d3e3d5e
commit
577fc0c395
5 changed files with 438 additions and 286 deletions
|
@ -26,6 +26,7 @@ if (is_android) {
|
|||
":resources",
|
||||
"//modules/audio_device:audio_device_java",
|
||||
"//rtc_base:base_java",
|
||||
"//sdk/android:base_java",
|
||||
"//sdk/android:java_audio_device_module_java",
|
||||
"//sdk/android:video_java",
|
||||
"//third_party/android_deps:androidx_core_core_java",
|
||||
|
|
|
@ -219,10 +219,12 @@ public class MainActivity extends Activity implements OnVoipClientTaskCompleted
|
|||
}
|
||||
|
||||
private void showToast(String message) {
|
||||
toast.cancel();
|
||||
toast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
|
||||
toast.setGravity(Gravity.TOP, 0, 200);
|
||||
toast.show();
|
||||
if (toast != null) {
|
||||
toast.cancel();
|
||||
toast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
|
||||
toast.setGravity(Gravity.TOP, 0, 200);
|
||||
toast.show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -15,26 +15,15 @@ import android.os.Handler;
|
|||
import android.os.HandlerThread;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.webrtc.CalledByNative;
|
||||
|
||||
public class VoipClient {
|
||||
private static final String TAG = "VoipClient";
|
||||
|
||||
private final HandlerThread thread;
|
||||
private final Handler handler;
|
||||
|
||||
private long nativeClient;
|
||||
private OnVoipClientTaskCompleted listener;
|
||||
|
||||
public VoipClient(Context applicationContext, OnVoipClientTaskCompleted listener) {
|
||||
this.listener = listener;
|
||||
thread = new HandlerThread(TAG + "Thread");
|
||||
thread.start();
|
||||
handler = new Handler(thread.getLooper());
|
||||
|
||||
handler.post(() -> {
|
||||
nativeClient = nativeCreateClient(applicationContext);
|
||||
listener.onVoipClientInitializationCompleted(/* isSuccessful */ nativeClient != 0);
|
||||
});
|
||||
nativeClient = nativeCreateClient(applicationContext, this);
|
||||
}
|
||||
|
||||
private boolean isInitialized() {
|
||||
|
@ -42,147 +31,161 @@ public class VoipClient {
|
|||
}
|
||||
|
||||
public void getAndSetUpSupportedCodecs() {
|
||||
handler.post(() -> {
|
||||
if (isInitialized()) {
|
||||
listener.onGetSupportedCodecsCompleted(nativeGetSupportedCodecs(nativeClient));
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
});
|
||||
if (isInitialized()) {
|
||||
nativeGetSupportedCodecs(nativeClient);
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
}
|
||||
|
||||
public void getAndSetUpLocalIPAddress() {
|
||||
handler.post(() -> {
|
||||
if (isInitialized()) {
|
||||
listener.onGetLocalIPAddressCompleted(nativeGetLocalIPAddress(nativeClient));
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
});
|
||||
if (isInitialized()) {
|
||||
nativeGetLocalIPAddress(nativeClient);
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
}
|
||||
|
||||
public void setEncoder(String encoder) {
|
||||
handler.post(() -> {
|
||||
if (isInitialized()) {
|
||||
nativeSetEncoder(nativeClient, encoder);
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
});
|
||||
if (isInitialized()) {
|
||||
nativeSetEncoder(nativeClient, encoder);
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
}
|
||||
|
||||
public void setDecoders(List<String> decoders) {
|
||||
handler.post(() -> {
|
||||
if (isInitialized()) {
|
||||
nativeSetDecoders(nativeClient, decoders);
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
});
|
||||
if (isInitialized()) {
|
||||
nativeSetDecoders(nativeClient, decoders);
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
}
|
||||
|
||||
public void setLocalAddress(String ipAddress, int portNumber) {
|
||||
handler.post(() -> {
|
||||
if (isInitialized()) {
|
||||
nativeSetLocalAddress(nativeClient, ipAddress, portNumber);
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
});
|
||||
if (isInitialized()) {
|
||||
nativeSetLocalAddress(nativeClient, ipAddress, portNumber);
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
}
|
||||
|
||||
public void setRemoteAddress(String ipAddress, int portNumber) {
|
||||
handler.post(() -> {
|
||||
if (isInitialized()) {
|
||||
nativeSetRemoteAddress(nativeClient, ipAddress, portNumber);
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
});
|
||||
if (isInitialized()) {
|
||||
nativeSetRemoteAddress(nativeClient, ipAddress, portNumber);
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
}
|
||||
|
||||
public void startSession() {
|
||||
handler.post(() -> {
|
||||
if (isInitialized()) {
|
||||
listener.onStartSessionCompleted(nativeStartSession(nativeClient));
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
});
|
||||
if (isInitialized()) {
|
||||
nativeStartSession(nativeClient);
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
}
|
||||
|
||||
public void stopSession() {
|
||||
handler.post(() -> {
|
||||
if (isInitialized()) {
|
||||
listener.onStopSessionCompleted(nativeStopSession(nativeClient));
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
});
|
||||
if (isInitialized()) {
|
||||
nativeStopSession(nativeClient);
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
}
|
||||
|
||||
public void startSend() {
|
||||
handler.post(() -> {
|
||||
if (isInitialized()) {
|
||||
listener.onStartSendCompleted(nativeStartSend(nativeClient));
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
});
|
||||
if (isInitialized()) {
|
||||
nativeStartSend(nativeClient);
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
}
|
||||
|
||||
public void stopSend() {
|
||||
handler.post(() -> {
|
||||
if (isInitialized()) {
|
||||
listener.onStopSendCompleted(nativeStopSend(nativeClient));
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
});
|
||||
if (isInitialized()) {
|
||||
nativeStopSend(nativeClient);
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
}
|
||||
|
||||
public void startPlayout() {
|
||||
handler.post(() -> {
|
||||
if (isInitialized()) {
|
||||
listener.onStartPlayoutCompleted(nativeStartPlayout(nativeClient));
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
});
|
||||
if (isInitialized()) {
|
||||
nativeStartPlayout(nativeClient);
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
}
|
||||
|
||||
public void stopPlayout() {
|
||||
handler.post(() -> {
|
||||
if (isInitialized()) {
|
||||
listener.onStopPlayoutCompleted(nativeStopPlayout(nativeClient));
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
});
|
||||
if (isInitialized()) {
|
||||
nativeStopPlayout(nativeClient);
|
||||
} else {
|
||||
listener.onUninitializedVoipClient();
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
handler.post(() -> {
|
||||
nativeDelete(nativeClient);
|
||||
nativeClient = 0;
|
||||
});
|
||||
thread.quitSafely();
|
||||
nativeDelete(nativeClient);
|
||||
nativeClient = 0;
|
||||
}
|
||||
|
||||
private static native long nativeCreateClient(Context applicationContext);
|
||||
private static native List<String> nativeGetSupportedCodecs(long nativeAndroidVoipClient);
|
||||
private static native String nativeGetLocalIPAddress(long nativeAndroidVoipClient);
|
||||
@CalledByNative
|
||||
public void onGetLocalIPAddressCompleted(String localIPAddress) {
|
||||
listener.onGetLocalIPAddressCompleted(localIPAddress);
|
||||
}
|
||||
|
||||
@CalledByNative
|
||||
public void onGetSupportedCodecsCompleted(List<String> supportedCodecs) {
|
||||
listener.onGetSupportedCodecsCompleted(supportedCodecs);
|
||||
}
|
||||
|
||||
@CalledByNative
|
||||
public void onStartSessionCompleted(boolean isSuccessful) {
|
||||
listener.onStartSessionCompleted(isSuccessful);
|
||||
}
|
||||
|
||||
@CalledByNative
|
||||
public void onStopSessionCompleted(boolean isSuccessful) {
|
||||
listener.onStopSessionCompleted(isSuccessful);
|
||||
}
|
||||
|
||||
@CalledByNative
|
||||
public void onStartSendCompleted(boolean isSuccessful) {
|
||||
listener.onStartSendCompleted(isSuccessful);
|
||||
}
|
||||
|
||||
@CalledByNative
|
||||
public void onStopSendCompleted(boolean isSuccessful) {
|
||||
listener.onStopSendCompleted(isSuccessful);
|
||||
}
|
||||
|
||||
@CalledByNative
|
||||
public void onStartPlayoutCompleted(boolean isSuccessful) {
|
||||
listener.onStartPlayoutCompleted(isSuccessful);
|
||||
}
|
||||
|
||||
@CalledByNative
|
||||
public void onStopPlayoutCompleted(boolean isSuccessful) {
|
||||
listener.onStopPlayoutCompleted(isSuccessful);
|
||||
}
|
||||
|
||||
private static native long nativeCreateClient(
|
||||
Context applicationContext, VoipClient javaVoipClient);
|
||||
private static native void nativeGetSupportedCodecs(long nativeAndroidVoipClient);
|
||||
private static native void nativeGetLocalIPAddress(long nativeAndroidVoipClient);
|
||||
private static native void nativeSetEncoder(long nativeAndroidVoipClient, String encoder);
|
||||
private static native void nativeSetDecoders(long nativeAndroidVoipClient, List<String> decoders);
|
||||
private static native void nativeSetLocalAddress(
|
||||
long nativeAndroidVoipClient, String ipAddress, int portNumber);
|
||||
private static native void nativeSetRemoteAddress(
|
||||
long nativeAndroidVoipClient, String ipAddress, int portNumber);
|
||||
private static native boolean nativeStartSession(long nativeAndroidVoipClient);
|
||||
private static native boolean nativeStopSession(long nativeAndroidVoipClient);
|
||||
private static native boolean nativeStartSend(long nativeAndroidVoipClient);
|
||||
private static native boolean nativeStopSend(long nativeAndroidVoipClient);
|
||||
private static native boolean nativeStartPlayout(long nativeAndroidVoipClient);
|
||||
private static native boolean nativeStopPlayout(long nativeAndroidVoipClient);
|
||||
private static native void nativeStartSession(long nativeAndroidVoipClient);
|
||||
private static native void nativeStopSession(long nativeAndroidVoipClient);
|
||||
private static native void nativeStartSend(long nativeAndroidVoipClient);
|
||||
private static native void nativeStopSend(long nativeAndroidVoipClient);
|
||||
private static native void nativeStartPlayout(long nativeAndroidVoipClient);
|
||||
private static native void nativeStopPlayout(long nativeAndroidVoipClient);
|
||||
private static native void nativeDelete(long nativeAndroidVoipClient);
|
||||
}
|
||||
|
|
|
@ -33,9 +33,20 @@
|
|||
#include "rtc_base/socket_server.h"
|
||||
#include "sdk/android/native_api/audio_device_module/audio_device_android.h"
|
||||
#include "sdk/android/native_api/jni/java_types.h"
|
||||
#include "sdk/android/native_api/jni/jvm.h"
|
||||
#include "sdk/android/native_api/jni/scoped_java_ref.h"
|
||||
|
||||
namespace {
|
||||
|
||||
#define RUN_ON_VOIP_THREAD(method, ...) \
|
||||
if (!voip_thread_->IsCurrent()) { \
|
||||
voip_thread_->PostTask( \
|
||||
RTC_FROM_HERE, \
|
||||
std::bind(&AndroidVoipClient::method, this, ##__VA_ARGS__)); \
|
||||
return; \
|
||||
} \
|
||||
RTC_DCHECK_RUN_ON(voip_thread_.get());
|
||||
|
||||
// Connects a UDP socket to a public address and returns the local
|
||||
// address associated with it. Since it binds to the "any" address
|
||||
// internally, it returns the default local address on a multi-homed
|
||||
|
@ -109,12 +120,9 @@ int GetPayloadType(const std::string& codec_name) {
|
|||
|
||||
namespace webrtc_examples {
|
||||
|
||||
AndroidVoipClient::AndroidVoipClient(
|
||||
bool AndroidVoipClient::Init(
|
||||
JNIEnv* env,
|
||||
const webrtc::JavaParamRef<jobject>& application_context) {
|
||||
voip_thread_ = rtc::Thread::CreateWithSocketServer();
|
||||
voip_thread_->Start();
|
||||
|
||||
webrtc::VoipEngineConfig config;
|
||||
config.encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
|
||||
config.decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
|
||||
|
@ -123,137 +131,195 @@ AndroidVoipClient::AndroidVoipClient(
|
|||
webrtc::CreateJavaAudioDeviceModule(env, application_context.obj());
|
||||
config.audio_processing = webrtc::AudioProcessingBuilder().Create();
|
||||
|
||||
supported_codecs_ = config.encoder_factory->GetSupportedEncoders();
|
||||
|
||||
voip_thread_->Start();
|
||||
// Due to consistent thread requirement on
|
||||
// modules/audio_device/android/audio_device_template.h,
|
||||
// code is invoked in the context of voip_thread_.
|
||||
voip_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
|
||||
return voip_thread_->Invoke<bool>(RTC_FROM_HERE, [this, &config] {
|
||||
RTC_DCHECK_RUN_ON(voip_thread_.get());
|
||||
|
||||
supported_codecs_ = config.encoder_factory->GetSupportedEncoders();
|
||||
env_ = webrtc::AttachCurrentThreadIfNeeded();
|
||||
voip_engine_ = webrtc::CreateVoipEngine(std::move(config));
|
||||
if (!voip_engine_) {
|
||||
RTC_LOG(LS_ERROR) << "VoipEngine creation failed";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
AndroidVoipClient::~AndroidVoipClient() {
|
||||
voip_thread_->Invoke<void>(RTC_FROM_HERE, [this] {
|
||||
RTC_DCHECK_RUN_ON(voip_thread_.get());
|
||||
|
||||
JavaVM* jvm = nullptr;
|
||||
env_->GetJavaVM(&jvm);
|
||||
if (!jvm) {
|
||||
RTC_LOG(LS_ERROR) << "Failed to retrieve JVM";
|
||||
return;
|
||||
}
|
||||
jint res = jvm->DetachCurrentThread();
|
||||
if (res != JNI_OK) {
|
||||
RTC_LOG(LS_ERROR) << "DetachCurrentThread failed: " << res;
|
||||
}
|
||||
});
|
||||
|
||||
voip_thread_->Stop();
|
||||
}
|
||||
|
||||
AndroidVoipClient* AndroidVoipClient::Create(
|
||||
JNIEnv* env,
|
||||
const webrtc::JavaParamRef<jobject>& application_context) {
|
||||
const webrtc::JavaParamRef<jobject>& application_context,
|
||||
const webrtc::JavaParamRef<jobject>& j_voip_client) {
|
||||
// Using `new` to access a non-public constructor.
|
||||
auto voip_client =
|
||||
absl::WrapUnique(new AndroidVoipClient(env, application_context));
|
||||
if (!voip_client->voip_engine_) {
|
||||
absl::WrapUnique(new AndroidVoipClient(env, j_voip_client));
|
||||
if (!voip_client->Init(env, application_context)) {
|
||||
return nullptr;
|
||||
}
|
||||
return voip_client.release();
|
||||
}
|
||||
|
||||
webrtc::ScopedJavaLocalRef<jobject> AndroidVoipClient::GetSupportedCodecs(
|
||||
JNIEnv* env) {
|
||||
void AndroidVoipClient::GetSupportedCodecs(JNIEnv* env) {
|
||||
RUN_ON_VOIP_THREAD(GetSupportedCodecs, env);
|
||||
|
||||
std::vector<std::string> names;
|
||||
for (const webrtc::AudioCodecSpec& spec : supported_codecs_) {
|
||||
names.push_back(spec.format.name);
|
||||
}
|
||||
webrtc::ScopedJavaLocalRef<jstring> (*convert_function)(
|
||||
JNIEnv*, const std::string&) = &webrtc::NativeToJavaString;
|
||||
return NativeToJavaList(env, names, convert_function);
|
||||
Java_VoipClient_onGetSupportedCodecsCompleted(
|
||||
env_, j_voip_client_, NativeToJavaList(env_, names, convert_function));
|
||||
}
|
||||
|
||||
webrtc::ScopedJavaLocalRef<jstring> AndroidVoipClient::GetLocalIPAddress(
|
||||
JNIEnv* env) {
|
||||
void AndroidVoipClient::GetLocalIPAddress(JNIEnv* env) {
|
||||
RUN_ON_VOIP_THREAD(GetLocalIPAddress, env);
|
||||
|
||||
std::string local_ip_address;
|
||||
rtc::IPAddress ipv4_address = QueryDefaultLocalAddress(AF_INET);
|
||||
if (!ipv4_address.IsNil()) {
|
||||
return webrtc::NativeToJavaString(env, ipv4_address.ToString());
|
||||
local_ip_address = ipv4_address.ToString();
|
||||
} else {
|
||||
rtc::IPAddress ipv6_address = QueryDefaultLocalAddress(AF_INET6);
|
||||
if (!ipv6_address.IsNil()) {
|
||||
local_ip_address = ipv6_address.ToString();
|
||||
}
|
||||
}
|
||||
rtc::IPAddress ipv6_address = QueryDefaultLocalAddress(AF_INET6);
|
||||
if (!ipv6_address.IsNil()) {
|
||||
return webrtc::NativeToJavaString(env, ipv6_address.ToString());
|
||||
}
|
||||
return webrtc::NativeToJavaString(env, "");
|
||||
Java_VoipClient_onGetLocalIPAddressCompleted(
|
||||
env_, j_voip_client_, webrtc::NativeToJavaString(env_, local_ip_address));
|
||||
}
|
||||
|
||||
void AndroidVoipClient::SetEncoder(
|
||||
JNIEnv* env,
|
||||
const webrtc::JavaRef<jstring>& j_encoder_string) {
|
||||
void AndroidVoipClient::SetEncoder(const std::string& encoder) {
|
||||
RTC_DCHECK_RUN_ON(voip_thread_.get());
|
||||
|
||||
if (!channel_) {
|
||||
RTC_LOG(LS_ERROR) << "Channel has not been created";
|
||||
return;
|
||||
}
|
||||
const std::string& chosen_encoder =
|
||||
webrtc::JavaToNativeString(env, j_encoder_string);
|
||||
for (const webrtc::AudioCodecSpec& encoder : supported_codecs_) {
|
||||
if (encoder.format.name == chosen_encoder) {
|
||||
for (const webrtc::AudioCodecSpec& codec : supported_codecs_) {
|
||||
if (codec.format.name == encoder) {
|
||||
voip_engine_->Codec().SetSendCodec(
|
||||
*channel_, GetPayloadType(encoder.format.name), encoder.format);
|
||||
break;
|
||||
*channel_, GetPayloadType(codec.format.name), codec.format);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidVoipClient::SetDecoders(
|
||||
void AndroidVoipClient::SetEncoder(
|
||||
JNIEnv* env,
|
||||
const webrtc::JavaParamRef<jobject>& j_decoder_strings) {
|
||||
const webrtc::JavaParamRef<jstring>& j_encoder_string) {
|
||||
const std::string& chosen_encoder =
|
||||
webrtc::JavaToNativeString(env, j_encoder_string);
|
||||
voip_thread_->PostTask(
|
||||
RTC_FROM_HERE, [this, chosen_encoder] { SetEncoder(chosen_encoder); });
|
||||
}
|
||||
|
||||
void AndroidVoipClient::SetDecoders(const std::vector<std::string>& decoders) {
|
||||
RTC_DCHECK_RUN_ON(voip_thread_.get());
|
||||
|
||||
if (!channel_) {
|
||||
RTC_LOG(LS_ERROR) << "Channel has not been created";
|
||||
return;
|
||||
}
|
||||
std::vector<std::string> chosen_decoders =
|
||||
webrtc::JavaListToNativeVector<std::string, jstring>(
|
||||
env, j_decoder_strings, &webrtc::JavaToNativeString);
|
||||
std::map<int, webrtc::SdpAudioFormat> decoder_specs;
|
||||
|
||||
for (const webrtc::AudioCodecSpec& decoder : supported_codecs_) {
|
||||
if (std::find(chosen_decoders.begin(), chosen_decoders.end(),
|
||||
decoder.format.name) != chosen_decoders.end()) {
|
||||
decoder_specs.insert(
|
||||
{GetPayloadType(decoder.format.name), decoder.format});
|
||||
for (const webrtc::AudioCodecSpec& codec : supported_codecs_) {
|
||||
if (std::find(decoders.begin(), decoders.end(), codec.format.name) !=
|
||||
decoders.end()) {
|
||||
decoder_specs.insert({GetPayloadType(codec.format.name), codec.format});
|
||||
}
|
||||
}
|
||||
|
||||
voip_engine_->Codec().SetReceiveCodecs(*channel_, decoder_specs);
|
||||
}
|
||||
|
||||
void AndroidVoipClient::SetDecoders(
|
||||
JNIEnv* env,
|
||||
const webrtc::JavaParamRef<jobject>& j_decoder_strings) {
|
||||
const std::vector<std::string>& chosen_decoders =
|
||||
webrtc::JavaListToNativeVector<std::string, jstring>(
|
||||
env, j_decoder_strings, &webrtc::JavaToNativeString);
|
||||
voip_thread_->PostTask(
|
||||
RTC_FROM_HERE, [this, chosen_decoders] { SetDecoders(chosen_decoders); });
|
||||
}
|
||||
|
||||
void AndroidVoipClient::SetLocalAddress(const std::string& ip_address,
|
||||
const int port_number) {
|
||||
RTC_DCHECK_RUN_ON(voip_thread_.get());
|
||||
|
||||
rtp_local_address_ = rtc::SocketAddress(ip_address, port_number);
|
||||
rtcp_local_address_ = rtc::SocketAddress(ip_address, port_number + 1);
|
||||
}
|
||||
|
||||
void AndroidVoipClient::SetLocalAddress(
|
||||
JNIEnv* env,
|
||||
const webrtc::JavaRef<jstring>& j_ip_address_string,
|
||||
const webrtc::JavaParamRef<jstring>& j_ip_address_string,
|
||||
jint j_port_number_int) {
|
||||
const std::string& ip_address =
|
||||
webrtc::JavaToNativeString(env, j_ip_address_string);
|
||||
rtp_local_address_ = rtc::SocketAddress(ip_address, j_port_number_int);
|
||||
rtcp_local_address_ = rtc::SocketAddress(ip_address, j_port_number_int + 1);
|
||||
voip_thread_->PostTask(RTC_FROM_HERE, [this, ip_address, j_port_number_int] {
|
||||
SetLocalAddress(ip_address, j_port_number_int);
|
||||
});
|
||||
}
|
||||
|
||||
void AndroidVoipClient::SetRemoteAddress(const std::string& ip_address,
|
||||
const int port_number) {
|
||||
RTC_DCHECK_RUN_ON(voip_thread_.get());
|
||||
|
||||
rtp_remote_address_ = rtc::SocketAddress(ip_address, port_number);
|
||||
rtcp_remote_address_ = rtc::SocketAddress(ip_address, port_number + 1);
|
||||
}
|
||||
|
||||
void AndroidVoipClient::SetRemoteAddress(
|
||||
JNIEnv* env,
|
||||
const webrtc::JavaRef<jstring>& j_ip_address_string,
|
||||
const webrtc::JavaParamRef<jstring>& j_ip_address_string,
|
||||
jint j_port_number_int) {
|
||||
const std::string& ip_address =
|
||||
webrtc::JavaToNativeString(env, j_ip_address_string);
|
||||
rtp_remote_address_ = rtc::SocketAddress(ip_address, j_port_number_int);
|
||||
rtcp_remote_address_ = rtc::SocketAddress(ip_address, j_port_number_int + 1);
|
||||
voip_thread_->PostTask(RTC_FROM_HERE, [this, ip_address, j_port_number_int] {
|
||||
SetRemoteAddress(ip_address, j_port_number_int);
|
||||
});
|
||||
}
|
||||
|
||||
jboolean AndroidVoipClient::StartSession(JNIEnv* env) {
|
||||
// Due to consistent thread requirement on
|
||||
// modules/utility/source/process_thread_impl.cc,
|
||||
// code is invoked in the context of voip_thread_.
|
||||
channel_ = voip_thread_->Invoke<absl::optional<webrtc::ChannelId>>(
|
||||
RTC_FROM_HERE,
|
||||
[this] { return voip_engine_->Base().CreateChannel(this, 0); });
|
||||
void AndroidVoipClient::StartSession(JNIEnv* env) {
|
||||
RUN_ON_VOIP_THREAD(StartSession, env);
|
||||
|
||||
channel_ = voip_engine_->Base().CreateChannel(this, absl::nullopt);
|
||||
if (!channel_) {
|
||||
RTC_LOG(LS_ERROR) << "Channel creation failed";
|
||||
return false;
|
||||
Java_VoipClient_onStartSessionCompleted(env_, j_voip_client_,
|
||||
/*isSuccessful=*/false);
|
||||
return;
|
||||
}
|
||||
|
||||
rtp_socket_.reset(rtc::AsyncUDPSocket::Create(voip_thread_->socketserver(),
|
||||
rtp_local_address_));
|
||||
if (!rtp_socket_) {
|
||||
RTC_LOG_ERR(LERROR) << "Socket creation failed";
|
||||
return false;
|
||||
Java_VoipClient_onStartSessionCompleted(env_, j_voip_client_,
|
||||
/*isSuccessful=*/false);
|
||||
return;
|
||||
}
|
||||
rtp_socket_->SignalReadPacket.connect(
|
||||
this, &AndroidVoipClient::OnSignalReadRTPPacket);
|
||||
|
@ -262,123 +328,171 @@ jboolean AndroidVoipClient::StartSession(JNIEnv* env) {
|
|||
rtcp_local_address_));
|
||||
if (!rtcp_socket_) {
|
||||
RTC_LOG_ERR(LERROR) << "Socket creation failed";
|
||||
return false;
|
||||
Java_VoipClient_onStartSessionCompleted(env_, j_voip_client_,
|
||||
/*isSuccessful=*/false);
|
||||
return;
|
||||
}
|
||||
rtcp_socket_->SignalReadPacket.connect(
|
||||
this, &AndroidVoipClient::OnSignalReadRTCPPacket);
|
||||
|
||||
return true;
|
||||
Java_VoipClient_onStartSessionCompleted(env_, j_voip_client_,
|
||||
/*isSuccessful=*/true);
|
||||
}
|
||||
|
||||
jboolean AndroidVoipClient::StopSession(JNIEnv* env) {
|
||||
void AndroidVoipClient::StopSession(JNIEnv* env) {
|
||||
RUN_ON_VOIP_THREAD(StopSession, env);
|
||||
|
||||
if (!channel_) {
|
||||
RTC_LOG(LS_ERROR) << "Channel has not been created";
|
||||
return false;
|
||||
Java_VoipClient_onStopSessionCompleted(env_, j_voip_client_,
|
||||
/*isSuccessful=*/false);
|
||||
return;
|
||||
}
|
||||
if (!StopSend(env) || !StopPlayout(env)) {
|
||||
return false;
|
||||
if (!voip_engine_->Base().StopSend(*channel_) ||
|
||||
!voip_engine_->Base().StopPlayout(*channel_)) {
|
||||
Java_VoipClient_onStopSessionCompleted(env_, j_voip_client_,
|
||||
/*isSuccessful=*/false);
|
||||
return;
|
||||
}
|
||||
|
||||
rtp_socket_->Close();
|
||||
rtcp_socket_->Close();
|
||||
// Due to consistent thread requirement on
|
||||
// modules/utility/source/process_thread_impl.cc,
|
||||
// code is invoked in the context of voip_thread_.
|
||||
voip_thread_->Invoke<void>(RTC_FROM_HERE, [this] {
|
||||
voip_engine_->Base().ReleaseChannel(*channel_);
|
||||
});
|
||||
|
||||
voip_engine_->Base().ReleaseChannel(*channel_);
|
||||
channel_ = absl::nullopt;
|
||||
return true;
|
||||
Java_VoipClient_onStopSessionCompleted(env_, j_voip_client_,
|
||||
/*isSuccessful=*/true);
|
||||
}
|
||||
|
||||
jboolean AndroidVoipClient::StartSend(JNIEnv* env) {
|
||||
void AndroidVoipClient::StartSend(JNIEnv* env) {
|
||||
RUN_ON_VOIP_THREAD(StartSend, env);
|
||||
|
||||
if (!channel_) {
|
||||
RTC_LOG(LS_ERROR) << "Channel has not been created";
|
||||
return false;
|
||||
Java_VoipClient_onStartSendCompleted(env_, j_voip_client_,
|
||||
/*isSuccessful=*/false);
|
||||
return;
|
||||
}
|
||||
// Due to consistent thread requirement on
|
||||
// modules/audio_device/android/opensles_recorder.cc,
|
||||
// code is invoked in the context of voip_thread_.
|
||||
return voip_thread_->Invoke<bool>(RTC_FROM_HERE, [this] {
|
||||
return voip_engine_->Base().StartSend(*channel_);
|
||||
});
|
||||
Java_VoipClient_onStartSendCompleted(
|
||||
env_, j_voip_client_, voip_engine_->Base().StartSend(*channel_));
|
||||
}
|
||||
|
||||
jboolean AndroidVoipClient::StopSend(JNIEnv* env) {
|
||||
void AndroidVoipClient::StopSend(JNIEnv* env) {
|
||||
RUN_ON_VOIP_THREAD(StopSend, env);
|
||||
|
||||
if (!channel_) {
|
||||
RTC_LOG(LS_ERROR) << "Channel has not been created";
|
||||
return false;
|
||||
Java_VoipClient_onStopSendCompleted(env_, j_voip_client_,
|
||||
/*isSuccessful=*/false);
|
||||
return;
|
||||
}
|
||||
// Due to consistent thread requirement on
|
||||
// modules/audio_device/android/opensles_recorder.cc,
|
||||
// code is invoked in the context of voip_thread_.
|
||||
return voip_thread_->Invoke<bool>(RTC_FROM_HERE, [this] {
|
||||
return voip_engine_->Base().StopSend(*channel_);
|
||||
});
|
||||
Java_VoipClient_onStopSendCompleted(env_, j_voip_client_,
|
||||
voip_engine_->Base().StopSend(*channel_));
|
||||
}
|
||||
|
||||
jboolean AndroidVoipClient::StartPlayout(JNIEnv* env) {
|
||||
void AndroidVoipClient::StartPlayout(JNIEnv* env) {
|
||||
RUN_ON_VOIP_THREAD(StartPlayout, env);
|
||||
|
||||
if (!channel_) {
|
||||
RTC_LOG(LS_ERROR) << "Channel has not been created";
|
||||
return false;
|
||||
Java_VoipClient_onStartPlayoutCompleted(env_, j_voip_client_,
|
||||
/*isSuccessful=*/false);
|
||||
return;
|
||||
}
|
||||
// Due to consistent thread requirement on
|
||||
// modules/audio_device/android/opensles_player.cc,
|
||||
// code is invoked in the context of voip_thread_.
|
||||
return voip_thread_->Invoke<bool>(RTC_FROM_HERE, [this] {
|
||||
return voip_engine_->Base().StartPlayout(*channel_);
|
||||
});
|
||||
Java_VoipClient_onStartPlayoutCompleted(
|
||||
env_, j_voip_client_, voip_engine_->Base().StartPlayout(*channel_));
|
||||
}
|
||||
|
||||
jboolean AndroidVoipClient::StopPlayout(JNIEnv* env) {
|
||||
void AndroidVoipClient::StopPlayout(JNIEnv* env) {
|
||||
RUN_ON_VOIP_THREAD(StopPlayout, env);
|
||||
|
||||
if (!channel_) {
|
||||
RTC_LOG(LS_ERROR) << "Channel has not been created";
|
||||
return false;
|
||||
Java_VoipClient_onStopPlayoutCompleted(env_, j_voip_client_,
|
||||
/*isSuccessful=*/false);
|
||||
return;
|
||||
}
|
||||
// Due to consistent thread requirement on
|
||||
// modules/audio_device/android/opensles_player.cc,
|
||||
// code is invoked in the context of voip_thread_.
|
||||
return voip_thread_->Invoke<bool>(RTC_FROM_HERE, [this] {
|
||||
return voip_engine_->Base().StopPlayout(*channel_);
|
||||
});
|
||||
Java_VoipClient_onStopPlayoutCompleted(
|
||||
env_, j_voip_client_, voip_engine_->Base().StopPlayout(*channel_));
|
||||
}
|
||||
|
||||
void AndroidVoipClient::Delete(JNIEnv* env) {
|
||||
delete this;
|
||||
}
|
||||
|
||||
void AndroidVoipClient::SendRtpPacket(const std::vector<uint8_t>& packet_copy) {
|
||||
RTC_DCHECK_RUN_ON(voip_thread_.get());
|
||||
|
||||
if (!rtp_socket_->SendTo(packet_copy.data(), packet_copy.size(),
|
||||
rtp_remote_address_, rtc::PacketOptions())) {
|
||||
RTC_LOG(LS_ERROR) << "Failed to send RTP packet";
|
||||
}
|
||||
}
|
||||
|
||||
bool AndroidVoipClient::SendRtp(const uint8_t* packet,
|
||||
size_t length,
|
||||
const webrtc::PacketOptions& options) {
|
||||
if (!rtp_socket_->SendTo(packet, length, rtp_remote_address_,
|
||||
rtc::PacketOptions())) {
|
||||
RTC_LOG(LS_ERROR) << "Failed to send RTP packet";
|
||||
return false;
|
||||
}
|
||||
std::vector<uint8_t> packet_copy(packet, packet + length);
|
||||
voip_thread_->PostTask(RTC_FROM_HERE,
|
||||
[this, packet_copy = std::move(packet_copy)] {
|
||||
SendRtpPacket(packet_copy);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AndroidVoipClient::SendRtcp(const uint8_t* packet, size_t length) {
|
||||
if (!rtcp_socket_->SendTo(packet, length, rtcp_remote_address_,
|
||||
rtc::PacketOptions())) {
|
||||
void AndroidVoipClient::SendRtcpPacket(
|
||||
const std::vector<uint8_t>& packet_copy) {
|
||||
RTC_DCHECK_RUN_ON(voip_thread_.get());
|
||||
|
||||
if (!rtcp_socket_->SendTo(packet_copy.data(), packet_copy.size(),
|
||||
rtcp_remote_address_, rtc::PacketOptions())) {
|
||||
RTC_LOG(LS_ERROR) << "Failed to send RTCP packet";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool AndroidVoipClient::SendRtcp(const uint8_t* packet, size_t length) {
|
||||
std::vector<uint8_t> packet_copy(packet, packet + length);
|
||||
voip_thread_->PostTask(RTC_FROM_HERE,
|
||||
[this, packet_copy = std::move(packet_copy)] {
|
||||
SendRtcpPacket(packet_copy);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
void AndroidVoipClient::ReadRTPPacket(const std::vector<uint8_t>& packet_copy) {
|
||||
RTC_DCHECK_RUN_ON(voip_thread_.get());
|
||||
|
||||
if (!channel_) {
|
||||
RTC_LOG(LS_ERROR) << "Channel has not been created";
|
||||
return;
|
||||
}
|
||||
voip_engine_->Network().ReceivedRTPPacket(
|
||||
*channel_,
|
||||
rtc::ArrayView<const uint8_t>(packet_copy.data(), packet_copy.size()));
|
||||
}
|
||||
|
||||
void AndroidVoipClient::OnSignalReadRTPPacket(rtc::AsyncPacketSocket* socket,
|
||||
const char* rtp_packet,
|
||||
size_t size,
|
||||
const rtc::SocketAddress& addr,
|
||||
const int64_t& timestamp) {
|
||||
std::vector<uint8_t> packet_copy(rtp_packet, rtp_packet + size);
|
||||
voip_thread_->PostTask(RTC_FROM_HERE,
|
||||
[this, packet_copy = std::move(packet_copy)] {
|
||||
ReadRTPPacket(packet_copy);
|
||||
});
|
||||
}
|
||||
|
||||
void AndroidVoipClient::ReadRTCPPacket(
|
||||
const std::vector<uint8_t>& packet_copy) {
|
||||
RTC_DCHECK_RUN_ON(voip_thread_.get());
|
||||
|
||||
if (!channel_) {
|
||||
RTC_LOG(LS_ERROR) << "Channel has not been created";
|
||||
return;
|
||||
}
|
||||
voip_engine_->Network().ReceivedRTPPacket(
|
||||
*channel_, rtc::ArrayView<const uint8_t>(
|
||||
reinterpret_cast<const uint8_t*>(rtp_packet), size));
|
||||
voip_engine_->Network().ReceivedRTCPPacket(
|
||||
*channel_,
|
||||
rtc::ArrayView<const uint8_t>(packet_copy.data(), packet_copy.size()));
|
||||
}
|
||||
|
||||
void AndroidVoipClient::OnSignalReadRTCPPacket(rtc::AsyncPacketSocket* socket,
|
||||
|
@ -386,20 +500,19 @@ void AndroidVoipClient::OnSignalReadRTCPPacket(rtc::AsyncPacketSocket* socket,
|
|||
size_t size,
|
||||
const rtc::SocketAddress& addr,
|
||||
const int64_t& timestamp) {
|
||||
if (!channel_) {
|
||||
RTC_LOG(LS_ERROR) << "Channel has not been created";
|
||||
return;
|
||||
}
|
||||
voip_engine_->Network().ReceivedRTCPPacket(
|
||||
*channel_, rtc::ArrayView<const uint8_t>(
|
||||
reinterpret_cast<const uint8_t*>(rtcp_packet), size));
|
||||
std::vector<uint8_t> packet_copy(rtcp_packet, rtcp_packet + size);
|
||||
voip_thread_->PostTask(RTC_FROM_HERE,
|
||||
[this, packet_copy = std::move(packet_copy)] {
|
||||
ReadRTCPPacket(packet_copy);
|
||||
});
|
||||
}
|
||||
|
||||
static jlong JNI_VoipClient_CreateClient(
|
||||
JNIEnv* env,
|
||||
const webrtc::JavaParamRef<jobject>& application_context) {
|
||||
const webrtc::JavaParamRef<jobject>& application_context,
|
||||
const webrtc::JavaParamRef<jobject>& j_voip_client) {
|
||||
return webrtc::NativeToJavaPointer(
|
||||
AndroidVoipClient::Create(env, application_context));
|
||||
AndroidVoipClient::Create(env, application_context, j_voip_client));
|
||||
}
|
||||
|
||||
} // namespace webrtc_examples
|
||||
|
|
|
@ -36,10 +36,10 @@ namespace webrtc_examples {
|
|||
// webrtc::Transport to send RTP/RTCP packets to the remote endpoint.
|
||||
// It also creates methods (slots) for sockets to connect to in
|
||||
// order to receive RTP/RTCP packets. AndroidVoipClient does all
|
||||
// VoipBase related operations with rtc::Thread (voip_thread_), this
|
||||
// is to comply with consistent thread usage requirement with
|
||||
// ProcessThread used within VoipEngine. AndroidVoipClient is meant
|
||||
// to be used by Java through JNI.
|
||||
// operations with rtc::Thread (voip_thread_), this is to comply
|
||||
// with consistent thread usage requirement with ProcessThread used
|
||||
// within VoipEngine, as well as providing asynchronicity to the
|
||||
// caller. AndroidVoipClient is meant to be used by Java through JNI.
|
||||
class AndroidVoipClient : public webrtc::Transport,
|
||||
public sigslot::has_slots<> {
|
||||
public:
|
||||
|
@ -50,22 +50,24 @@ class AndroidVoipClient : public webrtc::Transport,
|
|||
// they are done with it (this class provides a Delete() method).
|
||||
static AndroidVoipClient* Create(
|
||||
JNIEnv* env,
|
||||
const webrtc::JavaParamRef<jobject>& application_context);
|
||||
const webrtc::JavaParamRef<jobject>& application_context,
|
||||
const webrtc::JavaParamRef<jobject>& j_voip_client);
|
||||
|
||||
~AndroidVoipClient() override;
|
||||
|
||||
// Returns a Java List of Strings containing names of the built-in
|
||||
// supported codecs.
|
||||
webrtc::ScopedJavaLocalRef<jobject> GetSupportedCodecs(JNIEnv* env);
|
||||
// Provides client with a Java List of Strings containing names of
|
||||
// the built-in supported codecs through callback.
|
||||
void GetSupportedCodecs(JNIEnv* env);
|
||||
|
||||
// Returns a Java String of the default local IPv4 address. If IPv4
|
||||
// address is not found, returns the default local IPv6 address. If
|
||||
// IPv6 address is not found, returns an empty string.
|
||||
webrtc::ScopedJavaLocalRef<jstring> GetLocalIPAddress(JNIEnv* env);
|
||||
// Provides client with a Java String of the default local IPv4 address
|
||||
// through callback. If IPv4 address is not found, provide the default
|
||||
// local IPv6 address. If IPv6 address is not found, provide an empty
|
||||
// string.
|
||||
void GetLocalIPAddress(JNIEnv* env);
|
||||
|
||||
// Sets the encoder used by the VoIP API.
|
||||
void SetEncoder(JNIEnv* env,
|
||||
const webrtc::JavaRef<jstring>& j_encoder_string);
|
||||
const webrtc::JavaParamRef<jstring>& j_encoder_string);
|
||||
|
||||
// Sets the decoders used by the VoIP API.
|
||||
void SetDecoders(JNIEnv* env,
|
||||
|
@ -76,36 +78,41 @@ class AndroidVoipClient : public webrtc::Transport,
|
|||
// and port number j_port_number_int, the RTCP address will have IP address
|
||||
// j_ip_address_string and port number j_port_number_int+1.
|
||||
void SetLocalAddress(JNIEnv* env,
|
||||
const webrtc::JavaRef<jstring>& j_ip_address_string,
|
||||
const webrtc::JavaParamRef<jstring>& j_ip_address_string,
|
||||
jint j_port_number_int);
|
||||
void SetRemoteAddress(JNIEnv* env,
|
||||
const webrtc::JavaRef<jstring>& j_ip_address_string,
|
||||
jint j_port_number_int);
|
||||
void SetRemoteAddress(
|
||||
JNIEnv* env,
|
||||
const webrtc::JavaParamRef<jstring>& j_ip_address_string,
|
||||
jint j_port_number_int);
|
||||
|
||||
// Starts a VoIP session. The VoIP operations below can only be
|
||||
// used after a session has already started. Returns true if session
|
||||
// started successfully and false otherwise.
|
||||
jboolean StartSession(JNIEnv* env);
|
||||
// Starts a VoIP session, then calls a callback method with a boolean
|
||||
// value indicating if the session has started successfully. The VoIP
|
||||
// operations below can only be used after a session has already started.
|
||||
void StartSession(JNIEnv* env);
|
||||
|
||||
// Stops the current session. Returns true if session stopped
|
||||
// successfully and false otherwise.
|
||||
jboolean StopSession(JNIEnv* env);
|
||||
// Stops the current session, then calls a callback method with a
|
||||
// boolean value indicating if the session has stopped successfully.
|
||||
void StopSession(JNIEnv* env);
|
||||
|
||||
// Starts sending RTP/RTCP packets to the remote endpoint. Returns
|
||||
// the return value of StartSend in api/voip/voip_base.h.
|
||||
jboolean StartSend(JNIEnv* env);
|
||||
// Starts sending RTP/RTCP packets to the remote endpoint, then calls
|
||||
// a callback method with a boolean value indicating if sending
|
||||
// has started successfully.
|
||||
void StartSend(JNIEnv* env);
|
||||
|
||||
// Stops sending RTP/RTCP packets to the remote endpoint. Returns
|
||||
// the return value of StopSend in api/voip/voip_base.h.
|
||||
jboolean StopSend(JNIEnv* env);
|
||||
// Stops sending RTP/RTCP packets to the remote endpoint, then calls
|
||||
// a callback method with a boolean value indicating if sending
|
||||
// has stopped successfully.
|
||||
void StopSend(JNIEnv* env);
|
||||
|
||||
// Starts playing out the voice data received from the remote endpoint.
|
||||
// Returns the return value of StartPlayout in api/voip/voip_base.h.
|
||||
jboolean StartPlayout(JNIEnv* env);
|
||||
// Starts playing out the voice data received from the remote endpoint,
|
||||
// then calls a callback method with a boolean value indicating if
|
||||
// playout has started successfully.
|
||||
void StartPlayout(JNIEnv* env);
|
||||
|
||||
// Stops playing out the voice data received from the remote endpoint.
|
||||
// Returns the return value of StopPlayout in api/voip/voip_base.h.
|
||||
jboolean StopPlayout(JNIEnv* env);
|
||||
// Stops playing out the voice data received from the remote endpoint,
|
||||
// then calls a callback method with a boolean value indicating if
|
||||
// playout has stopped successfully.
|
||||
void StopPlayout(JNIEnv* env);
|
||||
|
||||
// Deletes this object. Used by client when they are done.
|
||||
void Delete(JNIEnv* env);
|
||||
|
@ -130,25 +137,51 @@ class AndroidVoipClient : public webrtc::Transport,
|
|||
|
||||
private:
|
||||
AndroidVoipClient(JNIEnv* env,
|
||||
const webrtc::JavaParamRef<jobject>& application_context);
|
||||
const webrtc::JavaParamRef<jobject>& j_voip_client)
|
||||
: voip_thread_(rtc::Thread::CreateWithSocketServer()),
|
||||
j_voip_client_(env, j_voip_client) {}
|
||||
|
||||
// Used to invoke VoipBase operations and send/receive
|
||||
// RTP/RTCP packets.
|
||||
bool Init(JNIEnv* env,
|
||||
const webrtc::JavaParamRef<jobject>& application_context);
|
||||
|
||||
// Overloaded methods having native C++ variables as arguments.
|
||||
void SetEncoder(const std::string& encoder);
|
||||
void SetDecoders(const std::vector<std::string>& decoders);
|
||||
void SetLocalAddress(const std::string& ip_address, const int port_number);
|
||||
void SetRemoteAddress(const std::string& ip_address, const int port_number);
|
||||
|
||||
// Methods to send and receive RTP/RTCP packets. Takes in a
|
||||
// copy of a packet as a vector to prolong the lifetime of
|
||||
// the packet as these methods will be called asynchronously.
|
||||
void SendRtpPacket(const std::vector<uint8_t>& packet_copy);
|
||||
void SendRtcpPacket(const std::vector<uint8_t>& packet_copy);
|
||||
void ReadRTPPacket(const std::vector<uint8_t>& packet_copy);
|
||||
void ReadRTCPPacket(const std::vector<uint8_t>& packet_copy);
|
||||
|
||||
// Used to invoke operations and send/receive RTP/RTCP packets.
|
||||
std::unique_ptr<rtc::Thread> voip_thread_;
|
||||
// Reference to the VoipClient java instance used to
|
||||
// invoke callbacks when operations are finished.
|
||||
webrtc::ScopedJavaGlobalRef<jobject> j_voip_client_
|
||||
RTC_GUARDED_BY(voip_thread_);
|
||||
// A list of AudioCodecSpec supported by the built-in
|
||||
// encoder/decoder factories.
|
||||
std::vector<webrtc::AudioCodecSpec> supported_codecs_;
|
||||
std::vector<webrtc::AudioCodecSpec> supported_codecs_
|
||||
RTC_GUARDED_BY(voip_thread_);
|
||||
// A JNI context used by the voip_thread_.
|
||||
JNIEnv* env_ RTC_GUARDED_BY(voip_thread_);
|
||||
// The entry point to all VoIP APIs.
|
||||
std::unique_ptr<webrtc::VoipEngine> voip_engine_;
|
||||
std::unique_ptr<webrtc::VoipEngine> voip_engine_ RTC_GUARDED_BY(voip_thread_);
|
||||
// Used by the VoIP API to facilitate a VoIP session.
|
||||
absl::optional<webrtc::ChannelId> channel_;
|
||||
absl::optional<webrtc::ChannelId> channel_ RTC_GUARDED_BY(voip_thread_);
|
||||
// Members below are used for network related operations.
|
||||
std::unique_ptr<rtc::AsyncUDPSocket> rtp_socket_;
|
||||
std::unique_ptr<rtc::AsyncUDPSocket> rtcp_socket_;
|
||||
rtc::SocketAddress rtp_local_address_;
|
||||
rtc::SocketAddress rtcp_local_address_;
|
||||
rtc::SocketAddress rtp_remote_address_;
|
||||
rtc::SocketAddress rtcp_remote_address_;
|
||||
std::unique_ptr<rtc::AsyncUDPSocket> rtp_socket_ RTC_GUARDED_BY(voip_thread_);
|
||||
std::unique_ptr<rtc::AsyncUDPSocket> rtcp_socket_
|
||||
RTC_GUARDED_BY(voip_thread_);
|
||||
rtc::SocketAddress rtp_local_address_ RTC_GUARDED_BY(voip_thread_);
|
||||
rtc::SocketAddress rtcp_local_address_ RTC_GUARDED_BY(voip_thread_);
|
||||
rtc::SocketAddress rtp_remote_address_ RTC_GUARDED_BY(voip_thread_);
|
||||
rtc::SocketAddress rtcp_remote_address_ RTC_GUARDED_BY(voip_thread_);
|
||||
};
|
||||
|
||||
} // namespace webrtc_examples
|
||||
|
|
Loading…
Reference in a new issue