am 04c58e9e
: Merge "Java API for AudioTrack timestamps" into klp-dev
* commit '04c58e9ec12c65c15738ba456f18a1f36416b0cc': Java API for AudioTrack timestamps
This commit is contained in:
@ -741,6 +741,30 @@ static jint android_media_AudioTrack_get_latency(JNIEnv *env, jobject thiz) {
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
static jint android_media_AudioTrack_get_timestamp(JNIEnv *env, jobject thiz, jlongArray jTimestamp) {
|
||||
sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
|
||||
|
||||
if (lpTrack == NULL) {
|
||||
ALOGE("Unable to retrieve AudioTrack pointer for getTimestamp()");
|
||||
return AUDIOTRACK_ERROR;
|
||||
}
|
||||
AudioTimestamp timestamp;
|
||||
status_t status = lpTrack->getTimestamp(timestamp);
|
||||
if (status == OK) {
|
||||
jlong* nTimestamp = (jlong *) env->GetPrimitiveArrayCritical(jTimestamp, NULL);
|
||||
if (nTimestamp == NULL) {
|
||||
ALOGE("Unable to get array for getTimestamp()");
|
||||
return AUDIOTRACK_ERROR;
|
||||
}
|
||||
nTimestamp[0] = (jlong) timestamp.mPosition;
|
||||
nTimestamp[1] = (jlong) ((timestamp.mTime.tv_sec * 1000000000LL) + timestamp.mTime.tv_nsec);
|
||||
env->ReleasePrimitiveArrayCritical(jTimestamp, nTimestamp, 0);
|
||||
}
|
||||
return (jint) android_media_translateErrorCode(status);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
static jint android_media_AudioTrack_set_loop(JNIEnv *env, jobject thiz,
|
||||
jint loopStart, jint loopEnd, jint loopCount) {
|
||||
@ -869,6 +893,7 @@ static JNINativeMethod gMethods[] = {
|
||||
{"native_set_position", "(I)I", (void *)android_media_AudioTrack_set_position},
|
||||
{"native_get_position", "()I", (void *)android_media_AudioTrack_get_position},
|
||||
{"native_get_latency", "()I", (void *)android_media_AudioTrack_get_latency},
|
||||
{"native_get_timestamp", "([J)I", (void *)android_media_AudioTrack_get_timestamp},
|
||||
{"native_set_loop", "(III)I", (void *)android_media_AudioTrack_set_loop},
|
||||
{"native_reload_static", "()I", (void *)android_media_AudioTrack_reload},
|
||||
{"native_get_output_sample_rate",
|
||||
|
47
media/java/android/media/AudioTimestamp.java
Normal file
47
media/java/android/media/AudioTimestamp.java
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.media;
|
||||
|
||||
/**
|
||||
* Structure that groups a position in frame units relative to an assumed audio stream,
|
||||
* together with the estimated time when that frame was presented or is committed to be
|
||||
* presented.
|
||||
* In the case of audio output, "present" means that audio produced on device
|
||||
* is detectable by an external observer off device.
|
||||
* The time is based on the implementation's best effort, using whatever knowledge
|
||||
* is available to the system, but cannot account for any delay unknown to the implementation.
|
||||
*
|
||||
* @see AudioTrack#getTimestamp
|
||||
* @see AudioTrack.TimestampListener
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class AudioTimestamp
|
||||
{
|
||||
/**
|
||||
* Position in frames relative to start of an assumed audio stream.
|
||||
* The low-order 32 bits of position is in wrapping frame units similar to
|
||||
* {@link AudioTrack#getPlaybackHeadPosition}.
|
||||
*/
|
||||
public long framePosition;
|
||||
|
||||
/**
|
||||
* The estimated time when frame was presented or is committed to be presented,
|
||||
* in the same units and timebase as {@link java.lang.System#nanoTime}.
|
||||
*/
|
||||
public long nanoTime;
|
||||
}
|
@ -732,6 +732,51 @@ public class AudioTrack
|
||||
return mSessionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Poll for a timestamp on demand.
|
||||
*
|
||||
* Use if {@link TimestampListener} is not delivered often enough for your needs,
|
||||
* or if you need to get the most recent timestamp outside of the event callback handler.
|
||||
* Calling this method too often may be inefficient;
|
||||
* if you need a high-resolution mapping between frame position and presentation time,
|
||||
* consider implementing that at application level, based on low-resolution timestamps.
|
||||
* The audio data at the returned position may either already have been
|
||||
* presented, or may have not yet been presented but is committed to be presented.
|
||||
* It is not possible to request the time corresponding to a particular position,
|
||||
* or to request the (fractional) position corresponding to a particular time.
|
||||
* If you need such features, consider implementing them at application level.
|
||||
*
|
||||
* @param timestamp a reference to a non-null AudioTimestamp instance allocated
|
||||
* and owned by caller, or null.
|
||||
* @return that same instance if timestamp parameter is non-null and a timestamp is available,
|
||||
* or a reference to a new AudioTimestamp instance which is now owned by caller
|
||||
* if timestamp parameter is null and a timestamp is available,
|
||||
* or null if no timestamp is available. In either successful case,
|
||||
* the AudioTimestamp instance is filled in with a position in frame units, together
|
||||
* with the estimated time when that frame was presented or is committed to
|
||||
* be presented.
|
||||
* In the case that no timestamp is available, any supplied instance is left unaltered.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public AudioTimestamp getTimestamp(AudioTimestamp timestamp)
|
||||
{
|
||||
// It's unfortunate, but we have to either create garbage every time or use synchronized
|
||||
long[] longArray = new long[2];
|
||||
int ret = native_get_timestamp(longArray);
|
||||
if (ret == SUCCESS) {
|
||||
if (timestamp == null) {
|
||||
timestamp = new AudioTimestamp();
|
||||
}
|
||||
timestamp.framePosition = longArray[0];
|
||||
timestamp.nanoTime = longArray[1];
|
||||
} else {
|
||||
timestamp = null;
|
||||
}
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Initialization / configuration
|
||||
//--------------------
|
||||
@ -1321,6 +1366,11 @@ public class AudioTrack
|
||||
|
||||
private native final int native_get_latency();
|
||||
|
||||
// longArray must be a non-null array of length >= 2
|
||||
// [0] is assigned the frame position
|
||||
// [1] is assigned the time in CLOCK_MONOTONIC nanoseconds
|
||||
private native final int native_get_timestamp(long[] longArray);
|
||||
|
||||
private native final int native_set_loop(int start, int end, int loopCount);
|
||||
|
||||
static private native final int native_get_output_sample_rate(int streamType);
|
||||
|
Reference in New Issue
Block a user