| /* |
| * 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; |
| } |
| |
| } |