Add Oboe audio device backend for Android (#2707)

This commit is contained in:
Nanang Izzuddin 2022-02-08 12:58:29 +07:00 committed by GitHub
parent 119623b633
commit 639e7dc7e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 1585 additions and 97 deletions

View File

@ -693,6 +693,8 @@ ac_android_cflags
ac_pjmedia_video_has_android
ac_pjmedia_video
ac_pjmedia_audiodev_objs
ac_oboe_ldflags
ac_oboe_cflags
ac_pa_cflags
ac_external_pa
ac_pjmedia_snd
@ -808,6 +810,7 @@ with_external_webrtc_aec3
enable_resample
enable_sound
with_external_pa
with_oboe
enable_video
enable_ext_sound
enable_small_filter
@ -1570,6 +1573,7 @@ Optional Packages:
option is set, make sure that PortAudio is
accessible to use (hint: use CFLAGS and LDFLAGS env
var to set the include/lib paths)
--with-oboe Enable Android Oboe audio device backend.
--with-sdl=DIR Specify alternate libSDL prefix
--with-ffmpeg=DIR Specify alternate FFMPEG prefix
--with-openh264=DIR Specify alternate OpenH264 prefix
@ -6502,15 +6506,100 @@ else
ac_pa_cflags="$ac_pa_cflags -DPA_LITTLE_ENDIAN"
fi
# Check whether --with-oboe was given.
if test "${with_oboe+set}" = set; then :
withval=$with_oboe;
if test "x$with_oboe" != "xno" -a "x$with_oboe" != "x"; then
OBOE_PREFIX=$with_oboe
OBOE_CFLAGS="-I$OBOE_PREFIX/prefab/modules/oboe/include"
OBOE_LDFLAGS="-L$OBOE_PREFIX/prefab/modules/oboe/libs/android.$TARGET_ABI"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Using Oboe prefix... $with_oboe" >&5
$as_echo "Using Oboe prefix... $with_oboe" >&6; }
else
OBOE_CFLAGS=""
OBOE_LDFLAGS=""
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Oboe usability" >&5
$as_echo_n "checking Oboe usability... " >&6; }
OBOE_LIBS="-loboe -lOpenSLES -llog"
SAVED_LIBS="$LIBS"
SAVED_LDFLAGS="$LDFLAGS"
SAVED_CXXFLAGS="$CXXFLAGS"
LIBS="$OBOE_LIBS $LIBS"
LDFLAGS="$OBOE_LDFLAGS $LDFLAGS"
CXXFLAGS="$OBOE_CFLAGS $CXXFLAGS"
ac_ext=cpp
ac_cpp='$CXXCPP $CPPFLAGS'
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <oboe/Oboe.h>
int
main ()
{
oboe::AudioStreamBuilder sb; sb.setDeviceId(0);
;
return 0;
}
_ACEOF
if ac_fn_cxx_try_link "$LINENO"; then :
ac_oboe_cflags="-DPJMEDIA_AUDIO_DEV_HAS_OBOE=1 $OBOE_CFLAGS"
ac_oboe_ldflags="$OBOE_LDFLAGS $OBOE_LIBS"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
# Put back original CXXFLAGS as app won't needed it.
#LIBS="$SAVED_LIBS"
#LDFLAGS="$SAVED_LDFLAGS"
CXXFLAGS="$SAVED_CFLAGS"
fi
if test "$enable_sound" = "no"; then
true;
else
case $target in
*android*)
LIBS="$LIBS -lOpenSLES"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Checking sound device backend... OpenSL ES" >&5
$as_echo "Checking sound device backend... OpenSL ES" >&6; }
if test "x$ac_oboe_cflags" != "x"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Checking sound device backend... Oboe" >&5
$as_echo "Checking sound device backend... Oboe" >&6; }
else
LIBS="$LIBS -lOpenSLES"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Checking sound device backend... Android" >&5
$as_echo "Checking sound device backend... Android" >&6; }
fi
;;
*-apple-darwin_ios*)
LIBS="$LIBS -framework CoreAudio -framework CoreFoundation -framework AudioToolbox -framework CFNetwork -framework UIKit -framework AVFoundation"

View File

@ -756,14 +756,69 @@ else
ac_pa_cflags="$ac_pa_cflags -DPA_LITTLE_ENDIAN"
fi
dnl # Enable Android Oboe audio device
AC_SUBST(ac_oboe_cflags)
AC_SUBST(ac_oboe_ldflags)
AC_ARG_WITH(oboe,
AS_HELP_STRING([--with-oboe],
[Enable Android Oboe audio device backend.]),
[
if test "x$with_oboe" != "xno" -a "x$with_oboe" != "x"; then
OBOE_PREFIX=$with_oboe
OBOE_CFLAGS="-I$OBOE_PREFIX/prefab/modules/oboe/include"
OBOE_LDFLAGS="-L$OBOE_PREFIX/prefab/modules/oboe/libs/android.$TARGET_ABI"
AC_MSG_RESULT([Using Oboe prefix... $with_oboe])
else
OBOE_CFLAGS=""
OBOE_LDFLAGS=""
fi
AC_MSG_CHECKING([Oboe usability])
OBOE_LIBS="-loboe -lOpenSLES -llog"
SAVED_LIBS="$LIBS"
SAVED_LDFLAGS="$LDFLAGS"
SAVED_CXXFLAGS="$CXXFLAGS"
LIBS="$OBOE_LIBS $LIBS"
LDFLAGS="$OBOE_LDFLAGS $LDFLAGS"
CXXFLAGS="$OBOE_CFLAGS $CXXFLAGS"
AC_LANG_PUSH([C++])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <oboe/Oboe.h>]],
[oboe::AudioStreamBuilder sb; sb.setDeviceId(0);]
)],
[ ac_oboe_cflags="-DPJMEDIA_AUDIO_DEV_HAS_OBOE=1 $OBOE_CFLAGS"
ac_oboe_ldflags="$OBOE_LDFLAGS $OBOE_LIBS"
AC_MSG_RESULT(yes)
],
[
LIBS="$SAVED_LIBS"
LDFLAGS="$SAVED_LDFLAGS"
AC_MSG_RESULT(no)
])
AC_LANG_POP([C++])
# Put back original CXXFLAGS as app won't needed it.
CXXFLAGS="$SAVED_CFLAGS"
]
)
if test "$enable_sound" = "no"; then
true;
else
AC_SUBST(ac_pjmedia_audiodev_objs)
case $target in
*android*)
LIBS="$LIBS -lOpenSLES"
AC_MSG_RESULT([Checking sound device backend... OpenSL ES])
if test "x$ac_oboe_cflags" != "x"; then
AC_MSG_RESULT([Checking sound device backend... Oboe])
else
LIBS="$LIBS -lOpenSLES"
AC_MSG_RESULT([Checking sound device backend... Android])
fi
;;
*-apple-darwin_ios*)
LIBS="$LIBS -framework CoreAudio -framework CoreFoundation -framework AudioToolbox -framework CFNetwork -framework UIKit -framework AVFoundation"

View File

@ -216,6 +216,7 @@ endif
# Android
ANDROID_CFLAGS = @ac_android_cflags@
OBOE_CFLAGS = @ac_oboe_cflags@
# PJMEDIA features exclusion
PJ_VIDEO_CFLAGS += $(SDL_CFLAGS) $(FFMPEG_CFLAGS) $(V4L2_CFLAGS) $(DSHOW_CFLAGS) $(QT_CFLAGS) \

View File

@ -246,6 +246,9 @@ PJ_DECL(int) pj_thread_get_prio(pj_thread_t *thread);
* value range, which can be retrieved with #pj_thread_get_prio_min() and
* #pj_thread_get_prio_max() functions.
*
* For Android, this function will only set the priority of the calling thread
* (the thread param must be set to NULL or the calling thread handle).
*
* @param thread Thread handle.
* @param prio New priority to be set to the thread.
*

View File

@ -69,8 +69,10 @@ JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved)
return JNI_VERSION_1_4;
}
#endif
struct pj_thread_t
{
char obj_name[PJ_MAX_OBJ_NAME];
@ -303,6 +305,95 @@ PJ_DEF(pj_bool_t) pj_thread_is_registered(void)
}
/* Thread priority utils for Android (via JNI as NDK does not provide it).
* Set priority is probably not enough because it does not change the thread
* group in scheduler.
* Temporary solution is to call the Java API to set the thread priority.
* A cool solution would be to port (if possible) the code from the
* android os regarding set_sched groups.
*/
#if PJ_ANDROID
#include <jni.h>
#include <sys/resource.h>
#include <sys/system_properties.h>
PJ_DEF(pj_bool_t) pj_jni_attach_jvm(JNIEnv **jni_env)
{
if ((*pj_jni_jvm)->GetEnv(pj_jni_jvm, (void **)jni_env,
JNI_VERSION_1_4) < 0)
{
if ((*pj_jni_jvm)->AttachCurrentThread(pj_jni_jvm, jni_env, NULL) < 0)
{
jni_env = NULL;
return PJ_FALSE;
}
return PJ_TRUE;
}
return PJ_FALSE;
}
PJ_DEF(void) pj_jni_dettach_jvm(pj_bool_t attached)
{
if (attached)
(*pj_jni_jvm)->DetachCurrentThread(pj_jni_jvm);
}
static pj_status_t set_android_thread_priority(int priority)
{
jclass process_class;
jmethodID set_prio_method;
jthrowable exc;
pj_status_t result = PJ_SUCCESS;
JNIEnv *jni_env = 0;
pj_bool_t attached = pj_jni_attach_jvm(&jni_env);
PJ_ASSERT_RETURN(jni_env, PJ_FALSE);
/* Get pointer to the java class */
process_class = (jclass)(*jni_env)->NewGlobalRef(jni_env,
(*jni_env)->FindClass(jni_env, "android/os/Process"));
if (process_class == 0) {
PJ_LOG(5, (THIS_FILE, "Unable to find class android.os.Process"));
result = PJ_EIGNORED;
goto on_return;
}
/* Get the id of set thread priority function */
set_prio_method = (*jni_env)->GetStaticMethodID(jni_env, process_class,
"setThreadPriority",
"(I)V");
if (set_prio_method == 0) {
PJ_LOG(5, (THIS_FILE, "Unable to find setThreadPriority() method"));
result = PJ_EIGNORED;
goto on_return;
}
/* Set the thread priority */
(*jni_env)->CallStaticVoidMethod(jni_env, process_class, set_prio_method,
priority);
exc = (*jni_env)->ExceptionOccurred(jni_env);
if (exc) {
(*jni_env)->ExceptionDescribe(jni_env);
(*jni_env)->ExceptionClear(jni_env);
PJ_LOG(4, (THIS_FILE, "Failure in setting thread priority using "
"Java API, fallback to setpriority()"));
setpriority(PRIO_PROCESS, 0, priority);
} else {
PJ_LOG(5, (THIS_FILE, "Setting thread priority to %d successful",
priority));
}
on_return:
pj_jni_dettach_jvm(attached);
return result;
}
#endif
/*
* Get thread priority value for the thread.
*/
@ -331,6 +422,12 @@ PJ_DEF(int) pj_thread_get_prio(pj_thread_t *thread)
PJ_DEF(pj_status_t) pj_thread_set_prio(pj_thread_t *thread, int prio)
{
#if PJ_HAS_THREADS
# if PJ_ANDROID
PJ_ASSERT_RETURN(thread==NULL || thread==pj_thread_this(), PJ_EINVAL);
return set_android_thread_priority(prio);
# else
struct sched_param param;
int policy;
int rc;
@ -346,6 +443,9 @@ PJ_DEF(pj_status_t) pj_thread_set_prio(pj_thread_t *thread, int prio)
return PJ_RETURN_OS_ERROR(rc);
return PJ_SUCCESS;
# endif /* PJ_ANDROID */
#else
PJ_UNUSED_ARG(thread);
PJ_UNUSED_ARG(prio);

View File

@ -92,7 +92,7 @@ export PJMEDIA_AUDIODEV_SRCDIR = ../src/pjmedia-audiodev
export PJMEDIA_AUDIODEV_OBJS += audiodev.o audiotest.o errno.o \
legacy_dev.o null_dev.o pa_dev.o wmme_dev.o \
alsa_dev.o bb10_dev.o bdimad_dev.o \
android_jni_dev.o opensl_dev.o
android_jni_dev.o opensl_dev.o oboe_dev.o
export PJMEDIA_AUDIODEV_CFLAGS += $(_CFLAGS)
export PJMEDIA_AUDIODEV_CXXFLAGS += $(_CXXFLAGS)
export PJMEDIA_AUDIODEV_LDFLAGS += $(PJMEDIA_LDLIB) \

View File

@ -31,6 +31,8 @@ DARWIN_CFLAGS = @ac_darwin_cflags@
# Android
ANDROID_CFLAGS = @ac_android_cflags@
OBOE_CFLAGS = @ac_oboe_cflags@
OBOE_LDFLAGS = @ac_oboe_ldflags@
# openh264
OPENH264_CFLAGS = @ac_openh264_cflags@
@ -45,9 +47,9 @@ VPX_LDFLAGS = @ac_vpx_ldflags@
export CFLAGS += @ac_no_small_filter@ @ac_no_large_filter@ @ac_no_speex_aec@ \
$(SDL_CFLAGS) $(FFMPEG_CFLAGS) $(V4L2_CFLAGS) $(DSHOW_CFLAGS) $(QT_CFLAGS) \
$(DARWIN_CFLAGS) $(ANDROID_CFLAGS) \
$(OPENH264_CFLAGS) $(VPX_CFLAGS)
$(OPENH264_CFLAGS) $(VPX_CFLAGS) $(OBOE_CFLAGS)
export LDFLAGS += $(SDL_LDFLAGS) $(FFMPEG_LDFLAGS) $(V4L2_LDFLAGS) $(DSHOW_LDFLAGS) \
$(OPENH264_LDFLAGS) $(VPX_LDFLAGS)
$(OPENH264_LDFLAGS) $(VPX_LDFLAGS) $(OBOE_LDFLAGS)
# Define the desired sound device backend
# Valid values are:

View File

@ -81,6 +81,14 @@ PJ_BEGIN_DECL
# define PJMEDIA_AUDIO_DEV_HAS_ANDROID_JNI PJ_ANDROID
#endif
/**
* This setting controls whether Android Oboe audio support should be
* included.
*/
#ifndef PJMEDIA_AUDIO_DEV_HAS_OBOE
# define PJMEDIA_AUDIO_DEV_HAS_OBOE 0
#endif
/**
* This setting controls whether BlackBerry 10 (BB10) audio support
* should be included.

View File

@ -0,0 +1,167 @@
/*
* Copyright (C) 2021 Teluu Inc. (http://www.teluu.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.pjsip;
import android.content.Context;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.os.Build;
import android.util.Log;
import android.util.SparseArray;
import java.util.Arrays;
public class PjAudioDevInfo {
/* API */
public int id;
public String name;
public int direction;
public int[] supportedClockRates;
public int[] supportedChannelCounts;
public static int GetCount()
{
return devices.size();
}
public static PjAudioDevInfo GetInfo(int idx)
{
return devices.valueAt(idx);
}
public static void RefreshDevices(Context context)
{
devices = new SparseArray<>();
/* Default device */
PjAudioDevInfo pj_adi = new PjAudioDevInfo();
pj_adi.id = 0;
pj_adi.name = "Default";
pj_adi.direction = 3;
devices.put(0, pj_adi);
/* Enumerate devices (for API level 23 or later) */
if (android.os.Build.VERSION.SDK_INT < 23)
return;
AudioManager am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
AudioDeviceInfo[] devs = am.getDevices(AudioManager.GET_DEVICES_ALL);
Log.i("Oboe", "Enumerating AudioManager devices..");
for (AudioDeviceInfo adi: devs) {
LogDevInfo(adi);
pj_adi = new PjAudioDevInfo();
pj_adi.id = adi.getId();
pj_adi.name = DevTypeStr(adi.getType()) + " - " + adi.getProductName().toString();
pj_adi.direction = 0;
if (adi.isSource()) pj_adi.direction |= 1;
if (adi.isSink()) pj_adi.direction |= 2;
pj_adi.supportedChannelCounts = adi.getChannelCounts();
pj_adi.supportedClockRates = adi.getSampleRates();
devices.put(adi.getId(), pj_adi);
}
}
/* Private members */
private static SparseArray<PjAudioDevInfo> devices;
private static String DevTypeStr(int type) {
if (android.os.Build.VERSION.SDK_INT < 23)
return "Unknown";
/*
if (android.os.Build.VERSION.SDK_INT > 30) {
if (type == AudioDeviceInfo.TYPE_BLE_HEADSET)
return "BLE Headset";
if (type == AudioDeviceInfo.TYPE_BLE_SPEAKER)
return "BLE Speaker";
}
*/
switch (type) {
case AudioDeviceInfo.TYPE_BUILTIN_EARPIECE:
return "Builtin Earpiece";
case AudioDeviceInfo.TYPE_BUILTIN_SPEAKER:
return "Builtin Speaker";
case AudioDeviceInfo.TYPE_WIRED_HEADSET:
return "Wired Headset";
case AudioDeviceInfo.TYPE_WIRED_HEADPHONES:
return "Wired Headphones";
case AudioDeviceInfo.TYPE_LINE_ANALOG:
return "Line Analog";
case AudioDeviceInfo.TYPE_LINE_DIGITAL:
return "Line Digital";
case AudioDeviceInfo.TYPE_BLUETOOTH_SCO:
return "Bluetooth SCO";
case AudioDeviceInfo.TYPE_BLUETOOTH_A2DP:
return "Bluetooth A2DP";
case AudioDeviceInfo.TYPE_HDMI:
return "HDMI";
case AudioDeviceInfo.TYPE_HDMI_ARC:
return "HDMI ARC";
case AudioDeviceInfo.TYPE_USB_DEVICE:
return "USB Device";
case AudioDeviceInfo.TYPE_USB_ACCESSORY:
return "USB Accessory";
case AudioDeviceInfo.TYPE_DOCK:
return "Dock";
case AudioDeviceInfo.TYPE_FM:
return "FM";
case AudioDeviceInfo.TYPE_BUILTIN_MIC:
return "Builtin Mic";
case AudioDeviceInfo.TYPE_FM_TUNER:
return "FM Tuner";
case AudioDeviceInfo.TYPE_TV_TUNER:
return "TV Tuner";
case AudioDeviceInfo.TYPE_TELEPHONY:
return "Telephony";
case AudioDeviceInfo.TYPE_AUX_LINE:
return "AUX Line";
case AudioDeviceInfo.TYPE_IP:
return "IP";
case AudioDeviceInfo.TYPE_BUS:
return "Bus";
case AudioDeviceInfo.TYPE_USB_HEADSET:
return "USB Headset";
default:
return "Unknown ("+ type +")";
}
}
private static void LogDevInfo(AudioDeviceInfo adi) {
if (Build.VERSION.SDK_INT < 23)
return;
StringBuilder info = new StringBuilder();
info.append("id=").append(adi.getId());
info.append(",");
if (adi.isSource()) info.append(" in");
if (adi.isSink()) info.append(" out");
info.append(", ").append(DevTypeStr(adi.getType()));
if (adi.getChannelCounts().length > 0) {
info.append(", channels=").append(Arrays.toString(adi.getChannelCounts()));
}
if (adi.getSampleRates().length > 0) {
info.append(", clock rates=").append(Arrays.toString(adi.getSampleRates()));
}
Log.i("Oboe", info.toString());
}
}

View File

@ -141,81 +141,12 @@ static pjmedia_aud_stream_op android_strm_op =
&strm_destroy
};
extern JavaVM *pj_jni_jvm;
static pj_bool_t attach_jvm(JNIEnv **jni_env)
{
if ((*pj_jni_jvm)->GetEnv(pj_jni_jvm, (void **)jni_env,
JNI_VERSION_1_4) < 0)
{
if ((*pj_jni_jvm)->AttachCurrentThread(pj_jni_jvm, jni_env, NULL) < 0)
{
jni_env = NULL;
return PJ_FALSE;
}
return PJ_TRUE;
}
return PJ_FALSE;
}
#define detach_jvm(attached) \
if (attached) \
(*pj_jni_jvm)->DetachCurrentThread(pj_jni_jvm);
/* Thread priority utils */
/* TODO : port it to pj_thread functions */
#define THREAD_PRIORITY_AUDIO -16
#define THREAD_PRIORITY_URGENT_AUDIO -19
pj_status_t set_android_thread_priority(int priority)
{
jclass process_class;
jmethodID set_prio_method;
jthrowable exc;
pj_status_t result = PJ_SUCCESS;
JNIEnv *jni_env = 0;
pj_bool_t attached = attach_jvm(&jni_env);
PJ_ASSERT_RETURN(jni_env, PJ_FALSE);
/* Get pointer to the java class */
process_class = (jclass)(*jni_env)->NewGlobalRef(jni_env,
(*jni_env)->FindClass(jni_env, "android/os/Process"));
if (process_class == 0) {
PJ_LOG(4, (THIS_FILE, "Unable to find os process class"));
result = PJ_EIGNORED;
goto on_return;
}
/* Get the id of set thread priority function */
set_prio_method = (*jni_env)->GetStaticMethodID(jni_env, process_class,
"setThreadPriority",
"(I)V");
if (set_prio_method == 0) {
PJ_LOG(4, (THIS_FILE, "Unable to find setThreadPriority() method"));
result = PJ_EIGNORED;
goto on_return;
}
/* Set the thread priority */
(*jni_env)->CallStaticVoidMethod(jni_env, process_class, set_prio_method,
priority);
exc = (*jni_env)->ExceptionOccurred(jni_env);
if (exc) {
(*jni_env)->ExceptionDescribe(jni_env);
(*jni_env)->ExceptionClear(jni_env);
PJ_LOG(4, (THIS_FILE, "Failure in setting thread priority using "
"Java API, fallback to setpriority()"));
setpriority(PRIO_PROCESS, 0, priority);
} else {
PJ_LOG(4, (THIS_FILE, "Setting thread priority successful"));
}
on_return:
detach_jvm(attached);
return result;
}
PJ_DECL(pj_bool_t) pj_jni_attach_jvm(JNIEnv **jni_env);
PJ_DECL(void) pj_jni_dettach_jvm(pj_bool_t attached);
#define attach_jvm(jni_env) pj_jni_attach_jvm(jni_env)
#define detach_jvm(attached) pj_jni_dettach_jvm(attached)
#define THREAD_PRIORITY_AUDIO -16
#define THREAD_PRIORITY_URGENT_AUDIO -19
static int AndroidRecorderCallback(void *userData)
@ -255,15 +186,8 @@ static int AndroidRecorderCallback(void *userData)
goto on_return;
}
/* Start recording
* setpriority(PRIO_PROCESS, 0, -19); //ANDROID_PRIORITY_AUDIO
* set priority is probably not enough because it does not change the thread
* group in scheduler
* Temporary solution is to call the java api to set the thread priority.
* A cool solution would be to port (if possible) the code from the
* android os regarding set_sched groups
*/
set_android_thread_priority(THREAD_PRIORITY_URGENT_AUDIO);
/* Start recording */
pj_thread_set_prio(NULL, THREAD_PRIORITY_URGENT_AUDIO);
(*jni_env)->CallVoidMethod(jni_env, stream->record, record_method);
while (!stream->quit_flag) {
@ -356,7 +280,7 @@ static int AndroidTrackCallback(void *userData)
buf = (*jni_env)->GetByteArrayElements(jni_env, outputBuffer, 0);
/* Start playing */
set_android_thread_priority(THREAD_PRIORITY_URGENT_AUDIO);
pj_thread_set_prio(NULL, THREAD_PRIORITY_URGENT_AUDIO);
(*jni_env)->CallVoidMethod(jni_env, stream->track, play_method);
while (!stream->quit_flag) {

View File

@ -44,6 +44,10 @@ pjmedia_aud_dev_factory* pjmedia_opensl_factory(pj_pool_factory *pf);
pjmedia_aud_dev_factory* pjmedia_android_factory(pj_pool_factory *pf);
#endif
#if PJMEDIA_AUDIO_DEV_HAS_OBOE
pjmedia_aud_dev_factory* pjmedia_android_oboe_factory(pj_pool_factory *pf);
#endif
#if PJMEDIA_AUDIO_DEV_HAS_BB10
pjmedia_aud_dev_factory* pjmedia_bb10_factory(pj_pool_factory *pf);
#endif
@ -103,6 +107,9 @@ PJ_DEF(pj_status_t) pjmedia_aud_subsys_init(pj_pool_factory *pf)
aud_subsys->dev_cnt = 0;
/* Register creation functions */
#if PJMEDIA_AUDIO_DEV_HAS_OBOE
aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_android_oboe_factory;
#endif
#if PJMEDIA_AUDIO_DEV_HAS_OPENSL
aud_subsys->drv[aud_subsys->drv_cnt++].create = &pjmedia_opensl_factory;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -190,13 +190,18 @@ $(OUT_DIR)/pjsua2_wrap.cpp: ../pjsua2.i ../symbols.i $(SRCS)
clean distclean realclean:
rm -rf $(LIBPJSUA2_SO) $(OUT_DIR)/* \
$(MY_PACKAGE_PATH)/*.java $(MY_PACKAGE_PATH)/*.class
$(MY_PACKAGE_PATH)/*.java $(MY_PACKAGE_PATH)/*.class \
$(MY_PACKAGE_PATH)/../*.java $(MY_PACKAGE_PATH)/../*.class
java: $(MY_PACKAGE_PATH)/Error.class $(MY_PACKAGE_PATH)/test.class $(MY_PACKAGE_PATH)/sample.class
ifneq (,$(findstring PJMEDIA_VIDEO_DEV_HAS_ANDROID=1,$(ANDROID_CFLAGS)))
@echo "Copying Android camera helper components..."
cp $(PJDIR)/pjmedia/src/pjmedia-videodev/android/PjCamera*.java $(MY_PACKAGE_PATH)/..
endif
ifneq (,$(findstring PJMEDIA_AUDIO_DEV_HAS_OBOE=1,$(OBOE_CFLAGS)))
@echo "Copying Android Oboe audio device helper components..."
cp $(PJDIR)/pjmedia/src/pjmedia-audiodev/android/PjAudioDevInfo.java $(MY_PACKAGE_PATH)/..
endif
$(MY_PACKAGE_PATH)/Error.class: $(MY_PACKAGE_PATH)/Error.java
$(MY_JAVAC) -d $(OUT_DIR) $(MY_PACKAGE_PATH)/*.java $(MY_APP_JAVA)

View File

@ -3,12 +3,11 @@
<component name="FacetManager">
<facet type="java-gradle" name="Java-Gradle">
<configuration>
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
<option name="BUILDABLE" value="false" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<component name="NewModuleRootManager">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" />

View File

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip