283 lines
10 KiB
Java
283 lines
10 KiB
Java
/*
|
|
* Copyright 2015 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;
|
|
|
|
import java.lang.annotation.Retention;
|
|
import java.lang.annotation.RetentionPolicy;
|
|
|
|
import android.annotation.IntDef;
|
|
|
|
/**
|
|
* Structure for common A/V sync params.
|
|
*
|
|
* Used by {@link MediaSync} {link MediaSync#getSyncParams()} and
|
|
* {link MediaSync#setSyncParams(SyncParams)}
|
|
* to control A/V sync behavior.
|
|
* <p> <strong>audio adjust mode:</strong>
|
|
* select handling of audio track when changing playback speed due to sync.
|
|
* <ul>
|
|
* <li> {@link SyncParams#AUDIO_ADJUST_MODE_DEFAULT}:
|
|
* System will determine best handling. </li>
|
|
* <li> {@link SyncParams#AUDIO_ADJUST_MODE_STRETCH}:
|
|
* Change the speed of audio playback without altering its pitch.</li>
|
|
* <li> {@link SyncParams#AUDIO_ADJUST_MODE_RESAMPLE}:
|
|
* Change the speed of audio playback by resampling the audio.</li>
|
|
* </ul>
|
|
* <p> <strong>sync source:</strong> select
|
|
* clock source for sync.
|
|
* <ul>
|
|
* <li> {@link SyncParams#SYNC_SOURCE_DEFAULT}:
|
|
* System will determine best selection.</li>
|
|
* <li> {@link SyncParams#SYNC_SOURCE_SYSTEM_CLOCK}:
|
|
* Use system clock for sync source.</li>
|
|
* <li> {@link SyncParams#SYNC_SOURCE_AUDIO}:
|
|
* Use audio track for sync source.</li>
|
|
* <li> {@link SyncParams#SYNC_SOURCE_VSYNC}:
|
|
* Syncronize media to vsync.</li>
|
|
* </ul>
|
|
* <p> <strong>tolerance:</strong> specifies the amount of allowed playback rate
|
|
* change to keep media in sync with the sync source. The handling of this depends
|
|
* on the sync source, but must not be negative, and must be less than one.
|
|
* <p> <strong>frameRate:</strong> initial hint for video frame rate. Used when
|
|
* sync source is vsync. Negative values can be used to clear a previous hint.
|
|
*/
|
|
public final class SyncParams {
|
|
/** @hide */
|
|
@IntDef(
|
|
value = {
|
|
SYNC_SOURCE_DEFAULT,
|
|
SYNC_SOURCE_SYSTEM_CLOCK,
|
|
SYNC_SOURCE_AUDIO,
|
|
SYNC_SOURCE_VSYNC,
|
|
}
|
|
)
|
|
@Retention(RetentionPolicy.SOURCE)
|
|
public @interface SyncSource {}
|
|
|
|
/**
|
|
* Use the default sync source (default). If media has video, the sync renders to a
|
|
* surface that directly renders to a display, and tolerance is non zero (e.g. not
|
|
* less than 0.001) vsync source is used for clock source. Otherwise, if media has
|
|
* audio, audio track is used. Finally, if media has no audio, system clock is used.
|
|
*/
|
|
public static final int SYNC_SOURCE_DEFAULT = 0;
|
|
|
|
/**
|
|
* Use system monotonic clock for sync source.
|
|
*
|
|
* @see System#nanoTime
|
|
*/
|
|
public static final int SYNC_SOURCE_SYSTEM_CLOCK = 1;
|
|
|
|
/**
|
|
* Use audio track for sync source. This requires audio data and an audio track.
|
|
*
|
|
* @see android.media.AudioTrack#getTimestamp(android.media.AudioTimestamp)
|
|
*/
|
|
public static final int SYNC_SOURCE_AUDIO = 2;
|
|
|
|
/**
|
|
* Use vsync as the sync source. This requires video data and an output surface that
|
|
* directly renders to the display, e.g. {@link android.view.SurfaceView}
|
|
* <p>
|
|
* This mode allows smoother playback experience by adjusting the playback speed
|
|
* to match the vsync rate, e.g. playing 30fps content on a 59.94Hz display.
|
|
* When using this mode, the tolerance should be set to greater than 0 (e.g. at least
|
|
* 1/1000), so that the playback speed can actually be adjusted.
|
|
* <p>
|
|
* This mode can also be used to play 25fps content on a 60Hz display using
|
|
* a 2:3 pulldown (basically playing the content at 24fps), which results on
|
|
* better playback experience on most devices. In this case the tolerance should be
|
|
* at least (1/24).
|
|
*
|
|
* @see android.view.Choreographer.FrameCallback#doFrame
|
|
* @see android.view.Display#getAppVsyncOffsetNanos
|
|
*/
|
|
public static final int SYNC_SOURCE_VSYNC = 3;
|
|
|
|
/** @hide */
|
|
@IntDef(
|
|
value = {
|
|
AUDIO_ADJUST_MODE_DEFAULT,
|
|
AUDIO_ADJUST_MODE_STRETCH,
|
|
AUDIO_ADJUST_MODE_RESAMPLE,
|
|
}
|
|
)
|
|
@Retention(RetentionPolicy.SOURCE)
|
|
public @interface AudioAdjustMode {}
|
|
|
|
/**
|
|
* System will determine best handling of audio for playback rate
|
|
* adjustments.
|
|
* <p>
|
|
* Used by default. This will make audio play faster or slower as required
|
|
* by the sync source without changing its pitch; however, system may fall
|
|
* back to some other method (e.g. change the pitch, or mute the audio) if
|
|
* time stretching is no longer supported for the playback rate.
|
|
*/
|
|
public static final int AUDIO_ADJUST_MODE_DEFAULT = 0;
|
|
|
|
/**
|
|
* Time stretch audio when playback rate must be adjusted.
|
|
* <p>
|
|
* This will make audio play faster or slower as required by the sync source
|
|
* without changing its pitch, as long as it is supported for the playback
|
|
* rate.
|
|
*/
|
|
public static final int AUDIO_ADJUST_MODE_STRETCH = 1;
|
|
|
|
/**
|
|
* Resample audio when playback rate must be adjusted.
|
|
* <p>
|
|
* This will make audio play faster or slower as required by the sync source
|
|
* by changing its pitch (making it lower to play slower, and higher to play
|
|
* faster.)
|
|
*/
|
|
public static final int AUDIO_ADJUST_MODE_RESAMPLE = 2;
|
|
|
|
// flags to indicate which params are actually set
|
|
private static final int SET_SYNC_SOURCE = 1 << 0;
|
|
private static final int SET_AUDIO_ADJUST_MODE = 1 << 1;
|
|
private static final int SET_TOLERANCE = 1 << 2;
|
|
private static final int SET_FRAME_RATE = 1 << 3;
|
|
private int mSet = 0;
|
|
|
|
// params
|
|
private int mAudioAdjustMode = AUDIO_ADJUST_MODE_DEFAULT;
|
|
private int mSyncSource = SYNC_SOURCE_DEFAULT;
|
|
private float mTolerance = 0.f;
|
|
private float mFrameRate = 0.f;
|
|
|
|
/**
|
|
* Allows defaults to be returned for properties not set.
|
|
* Otherwise a {@link java.lang.IllegalArgumentException} exception
|
|
* is raised when getting those properties
|
|
* which have defaults but have never been set.
|
|
* @return this <code>SyncParams</code> instance.
|
|
*/
|
|
public SyncParams allowDefaults() {
|
|
mSet |= SET_SYNC_SOURCE | SET_AUDIO_ADJUST_MODE | SET_TOLERANCE;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the audio adjust mode.
|
|
* @param audioAdjustMode
|
|
* @return this <code>SyncParams</code> instance.
|
|
*/
|
|
public SyncParams setAudioAdjustMode(@AudioAdjustMode int audioAdjustMode) {
|
|
mAudioAdjustMode = audioAdjustMode;
|
|
mSet |= SET_AUDIO_ADJUST_MODE;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the audio adjust mode.
|
|
* @return audio adjust mode
|
|
* @throws IllegalStateException if the audio adjust mode is not set.
|
|
*/
|
|
public @AudioAdjustMode int getAudioAdjustMode() {
|
|
if ((mSet & SET_AUDIO_ADJUST_MODE) == 0) {
|
|
throw new IllegalStateException("audio adjust mode not set");
|
|
}
|
|
return mAudioAdjustMode;
|
|
}
|
|
|
|
/**
|
|
* Sets the sync source.
|
|
* @param syncSource
|
|
* @return this <code>SyncParams</code> instance.
|
|
*/
|
|
public SyncParams setSyncSource(@SyncSource int syncSource) {
|
|
mSyncSource = syncSource;
|
|
mSet |= SET_SYNC_SOURCE;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the sync source.
|
|
* @return sync source
|
|
* @throws IllegalStateException if the sync source is not set.
|
|
*/
|
|
public @SyncSource int getSyncSource() {
|
|
if ((mSet & SET_SYNC_SOURCE) == 0) {
|
|
throw new IllegalStateException("sync source not set");
|
|
}
|
|
return mSyncSource;
|
|
}
|
|
|
|
/**
|
|
* Sets the tolerance. The default tolerance is platform specific, but is never more than 1/24.
|
|
* @param tolerance A non-negative number representing
|
|
* the maximum deviation of the playback rate from the playback rate
|
|
* set. ({@code abs(actual_rate - set_rate) / set_rate})
|
|
* @return this <code>SyncParams</code> instance.
|
|
* @throws IllegalArgumentException if the tolerance is negative, or not less than one.
|
|
*/
|
|
public SyncParams setTolerance(float tolerance) {
|
|
if (tolerance < 0.f || tolerance >= 1.f) {
|
|
throw new IllegalArgumentException("tolerance must be less than one and non-negative");
|
|
}
|
|
mTolerance = tolerance;
|
|
mSet |= SET_TOLERANCE;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the tolerance factor.
|
|
* @return tolerance factor. A non-negative number representing
|
|
* the maximum deviation of the playback rate from the playback rate
|
|
* set. ({@code abs(actual_rate - set_rate) / set_rate})
|
|
* @throws IllegalStateException if tolerance is not set.
|
|
*/
|
|
public float getTolerance() {
|
|
if ((mSet & SET_TOLERANCE) == 0) {
|
|
throw new IllegalStateException("tolerance not set");
|
|
}
|
|
return mTolerance;
|
|
}
|
|
|
|
/**
|
|
* Sets the video frame rate hint to be used. By default the frame rate is unspecified.
|
|
* @param frameRate A non-negative number used as an initial hint on
|
|
* the video frame rate to be used when using vsync as the sync source. A negative
|
|
* number is used to clear a previous hint.
|
|
* @return this <code>SyncParams</code> instance.
|
|
*/
|
|
public SyncParams setFrameRate(float frameRate) {
|
|
mFrameRate = frameRate;
|
|
mSet |= SET_FRAME_RATE;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the video frame rate hint.
|
|
* @return frame rate factor. A non-negative number representing
|
|
* the maximum deviation of the playback rate from the playback rate
|
|
* set. ({@code abs(actual_rate - set_rate) / set_rate}), or a negative
|
|
* number representing the desire to clear a previous hint using these params.
|
|
* @throws IllegalStateException if frame rate is not set.
|
|
*/
|
|
public float getFrameRate() {
|
|
if ((mSet & SET_FRAME_RATE) == 0) {
|
|
throw new IllegalStateException("frame rate not set");
|
|
}
|
|
return mFrameRate;
|
|
}
|
|
|
|
}
|