summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt2
-rw-r--r--core/jni/android_media_AudioTrack.cpp40
-rw-r--r--media/java/android/media/AudioTrack.java61
3 files changed, 103 insertions, 0 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index 8224a754ec69..be9dccce637a 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -19852,6 +19852,7 @@ package android.media {
method public android.media.AudioDeviceInfo getPreferredDevice();
method public android.media.AudioDeviceInfo getRoutedDevice();
method public int getSampleRate();
+ method @IntRange(from=1) public int getStartThresholdInFrames();
method public int getState();
method public int getStreamType();
method public boolean getTimestamp(android.media.AudioTimestamp);
@@ -19882,6 +19883,7 @@ package android.media {
method public int setPositionNotificationPeriod(int);
method public boolean setPreferredDevice(android.media.AudioDeviceInfo);
method public int setPresentation(@NonNull android.media.AudioPresentation);
+ method @IntRange(from=1) public int setStartThresholdInFrames(@IntRange(from=1) int);
method @Deprecated protected void setState(int);
method @Deprecated public int setStereoVolume(float, float);
method public int setVolume(float);
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 065c79b8601f..452f55a0ba97 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -1419,6 +1419,42 @@ static jint android_media_AudioTrack_getDualMonoMode(JNIEnv *env, jobject thiz,
return nativeToJavaStatus(status);
}
+static jint android_media_AudioTrack_getStartThresholdInFrames(JNIEnv *env, jobject thiz) {
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+ if (lpTrack == nullptr) {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "Unable to retrieve AudioTrack pointer for getStartThresholdInFrames()");
+ return (jint)AUDIO_JAVA_ERROR;
+ }
+ const ssize_t result = lpTrack->getStartThresholdInFrames();
+ if (result <= 0) {
+ jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
+ "Internal error detected in getStartThresholdInFrames() = %zd",
+ result);
+ return (jint)AUDIO_JAVA_ERROR;
+ }
+ return (jint)result; // this should be a positive value.
+}
+
+static jint android_media_AudioTrack_setStartThresholdInFrames(JNIEnv *env, jobject thiz,
+ jint startThresholdInFrames) {
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+ if (lpTrack == nullptr) {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "Unable to retrieve AudioTrack pointer for setStartThresholdInFrames()");
+ return (jint)AUDIO_JAVA_ERROR;
+ }
+ // non-positive values of startThresholdInFrames are not allowed by the Java layer.
+ const ssize_t result = lpTrack->setStartThresholdInFrames(startThresholdInFrames);
+ if (result <= 0) {
+ jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
+ "Internal error detected in setStartThresholdInFrames() = %zd",
+ result);
+ return (jint)AUDIO_JAVA_ERROR;
+ }
+ return (jint)result; // this should be a positive value.
+}
+
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
static const JNINativeMethod gMethods[] = {
@@ -1496,6 +1532,10 @@ static const JNINativeMethod gMethods[] = {
(void *)android_media_AudioTrack_getAudioDescriptionMixLeveldB},
{"native_set_dual_mono_mode", "(I)I", (void *)android_media_AudioTrack_setDualMonoMode},
{"native_get_dual_mono_mode", "([I)I", (void *)android_media_AudioTrack_getDualMonoMode},
+ {"native_setStartThresholdInFrames", "(I)I",
+ (void *)android_media_AudioTrack_setStartThresholdInFrames},
+ {"native_getStartThresholdInFrames", "()I",
+ (void *)android_media_AudioTrack_getStartThresholdInFrames},
};
// field names found in android/media/AudioTrack.java
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 1b05c3b57256..b265ebfc02a0 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -2077,6 +2077,65 @@ public class AudioTrack extends PlayerBase
}
/**
+ * Sets the streaming start threshold for an <code>AudioTrack</code>.
+ * <p> The streaming start threshold is the buffer level that the written audio
+ * data must reach for audio streaming to start after {@link #play()} is called.
+ * <p> For compressed streams, the size of a frame is considered to be exactly one byte.
+ *
+ * @param startThresholdInFrames the desired start threshold.
+ * @return the actual start threshold in frames value. This is
+ * an integer between 1 to the buffer capacity
+ * (see {@link #getBufferCapacityInFrames()}),
+ * and might change if the output sink changes after track creation.
+ * @throws IllegalStateException if the track is not initialized or the
+ * track transfer mode is not {@link #MODE_STREAM}.
+ * @throws IllegalArgumentException if startThresholdInFrames is not positive.
+ * @see #getStartThresholdInFrames()
+ */
+ public @IntRange(from = 1) int setStartThresholdInFrames(
+ @IntRange (from = 1) int startThresholdInFrames) {
+ if (mState != STATE_INITIALIZED) {
+ throw new IllegalStateException("AudioTrack is not initialized");
+ }
+ if (mDataLoadMode != MODE_STREAM) {
+ throw new IllegalStateException("AudioTrack must be a streaming track");
+ }
+ if (startThresholdInFrames < 1) {
+ throw new IllegalArgumentException("startThresholdInFrames "
+ + startThresholdInFrames + " must be positive");
+ }
+ return native_setStartThresholdInFrames(startThresholdInFrames);
+ }
+
+ /**
+ * Returns the streaming start threshold of the <code>AudioTrack</code>.
+ * <p> The streaming start threshold is the buffer level that the written audio
+ * data must reach for audio streaming to start after {@link #play()} is called.
+ * When an <code>AudioTrack</code> is created, the streaming start threshold
+ * is the buffer capacity in frames. If the buffer size in frames is reduced
+ * by {@link #setBufferSizeInFrames(int)} to a value smaller than the start threshold
+ * then that value will be used instead for the streaming start threshold.
+ * <p> For compressed streams, the size of a frame is considered to be exactly one byte.
+ *
+ * @return the current start threshold in frames value. This is
+ * an integer between 1 to the buffer capacity
+ * (see {@link #getBufferCapacityInFrames()}),
+ * and might change if the output sink changes after track creation.
+ * @throws IllegalStateException if the track is not initialized or the
+ * track is not {@link #MODE_STREAM}.
+ * @see #setStartThresholdInFrames(int)
+ */
+ public @IntRange (from = 1) int getStartThresholdInFrames() {
+ if (mState != STATE_INITIALIZED) {
+ throw new IllegalStateException("AudioTrack is not initialized");
+ }
+ if (mDataLoadMode != MODE_STREAM) {
+ throw new IllegalStateException("AudioTrack must be a streaming track");
+ }
+ return native_getStartThresholdInFrames();
+ }
+
+ /**
* Returns the frame count of the native <code>AudioTrack</code> buffer.
* @return current size in frames of the <code>AudioTrack</code> buffer.
* @throws IllegalStateException
@@ -4179,6 +4238,8 @@ public class AudioTrack extends PlayerBase
private native int native_get_audio_description_mix_level_db(float[] level);
private native int native_set_dual_mono_mode(int dualMonoMode);
private native int native_get_dual_mono_mode(int[] dualMonoMode);
+ private native int native_setStartThresholdInFrames(int startThresholdInFrames);
+ private native int native_getStartThresholdInFrames();
//---------------------------------------------------------
// Utility methods