Home | History | Annotate | Download | only in media
      1 /*
      2  * Copyright 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.media;
     18 
     19 import java.lang.annotation.Retention;
     20 import java.lang.annotation.RetentionPolicy;
     21 
     22 import android.annotation.IntDef;
     23 
     24 /**
     25  * Structure for common A/V sync params.
     26  *
     27  * Used by {@link MediaSync} {link MediaSync#getSyncParams()} and
     28  * {link MediaSync#setSyncParams(SyncParams)}
     29  * to control A/V sync behavior.
     30  * <p> <strong>audio adjust mode:</strong>
     31  * select handling of audio track when changing playback speed due to sync.
     32  * <ul>
     33  * <li> {@link SyncParams#AUDIO_ADJUST_MODE_DEFAULT}:
     34  *   System will determine best handling. </li>
     35  * <li> {@link SyncParams#AUDIO_ADJUST_MODE_STRETCH}:
     36  *   Change the speed of audio playback without altering its pitch.</li>
     37  * <li> {@link SyncParams#AUDIO_ADJUST_MODE_RESAMPLE}:
     38  *   Change the speed of audio playback by resampling the audio.</li>
     39  * </ul>
     40  * <p> <strong>sync source:</strong> select
     41  * clock source for sync.
     42  * <ul>
     43  * <li> {@link SyncParams#SYNC_SOURCE_DEFAULT}:
     44  *   System will determine best selection.</li>
     45  * <li> {@link SyncParams#SYNC_SOURCE_SYSTEM_CLOCK}:
     46  *   Use system clock for sync source.</li>
     47  * <li> {@link SyncParams#SYNC_SOURCE_AUDIO}:
     48  *   Use audio track for sync source.</li>
     49  * <li> {@link SyncParams#SYNC_SOURCE_VSYNC}:
     50  *   Syncronize media to vsync.</li>
     51  * </ul>
     52  * <p> <strong>tolerance:</strong> specifies the amount of allowed playback rate
     53  * change to keep media in sync with the sync source. The handling of this depends
     54  * on the sync source, but must not be negative, and must be less than one.
     55  * <p> <strong>frameRate:</strong> initial hint for video frame rate. Used when
     56  * sync source is vsync. Negative values can be used to clear a previous hint.
     57  */
     58 public final class SyncParams {
     59     /** @hide */
     60     @IntDef(
     61         value = {
     62                 SYNC_SOURCE_DEFAULT,
     63                 SYNC_SOURCE_SYSTEM_CLOCK,
     64                 SYNC_SOURCE_AUDIO,
     65                 SYNC_SOURCE_VSYNC,
     66         }
     67     )
     68     @Retention(RetentionPolicy.SOURCE)
     69     public @interface SyncSource {}
     70 
     71     /**
     72      * Use the default sync source (default). If media has video, the sync renders to a
     73      * surface that directly renders to a display, and tolerance is non zero (e.g. not
     74      * less than 0.001) vsync source is used for clock source.  Otherwise, if media has
     75      * audio, audio track is used. Finally, if media has no audio, system clock is used.
     76      */
     77     public static final int SYNC_SOURCE_DEFAULT = 0;
     78 
     79     /**
     80      * Use system monotonic clock for sync source.
     81      *
     82      * @see System#nanoTime
     83      */
     84     public static final int SYNC_SOURCE_SYSTEM_CLOCK = 1;
     85 
     86     /**
     87      * Use audio track for sync source. This requires audio data and an audio track.
     88      *
     89      * @see AudioTrack#getTimeStamp
     90      */
     91     public static final int SYNC_SOURCE_AUDIO = 2;
     92 
     93     /**
     94      * Use vsync as the sync source. This requires video data and an output surface that
     95      * directly renders to the display, e.g. {@link android.view.SurfaceView}
     96      * <p>
     97      * This mode allows smoother playback experience by adjusting the playback speed
     98      * to match the vsync rate, e.g. playing 30fps content on a 59.94Hz display.
     99      * When using this mode, the tolerance should be set to greater than 0 (e.g. at least
    100      * 1/1000), so that the playback speed can actually be adjusted.
    101      * <p>
    102      * This mode can also be used to play 25fps content on a 60Hz display using
    103      * a 2:3 pulldown (basically playing the content at 24fps), which results on
    104      * better playback experience on most devices. In this case the tolerance should be
    105      * at least (1/24).
    106      *
    107      * @see android.view.Choreographer.FrameCallback#doFrame
    108      * @see android.view.Display#getAppVsyncOffsetNanos
    109      */
    110     public static final int SYNC_SOURCE_VSYNC = 3;
    111 
    112     /** @hide */
    113     @IntDef(
    114         value = {
    115                 AUDIO_ADJUST_MODE_DEFAULT,
    116                 AUDIO_ADJUST_MODE_STRETCH,
    117                 AUDIO_ADJUST_MODE_RESAMPLE,
    118         }
    119     )
    120     @Retention(RetentionPolicy.SOURCE)
    121     public @interface AudioAdjustMode {}
    122 
    123     /**
    124      * System will determine best handling of audio for playback rate
    125      * adjustments.
    126      * <p>
    127      * Used by default. This will make audio play faster or slower as required
    128      * by the sync source without changing its pitch; however, system may fall
    129      * back to some other method (e.g. change the pitch, or mute the audio) if
    130      * time stretching is no longer supported for the playback rate.
    131      */
    132     public static final int AUDIO_ADJUST_MODE_DEFAULT = 0;
    133 
    134     /**
    135      * Time stretch audio when playback rate must be adjusted.
    136      * <p>
    137      * This will make audio play faster or slower as required by the sync source
    138      * without changing its pitch, as long as it is supported for the playback
    139      * rate.
    140      *
    141      * @see MediaSync#PLAYBACK_RATE_AUDIO_MODE_STRETCH
    142      * @see MediaPlayer#PLAYBACK_RATE_AUDIO_MODE_STRETCH
    143      */
    144     public static final int AUDIO_ADJUST_MODE_STRETCH = 1;
    145 
    146     /**
    147      * Resample audio when playback rate must be adjusted.
    148      * <p>
    149      * This will make audio play faster or slower as required by the sync source
    150      * by changing its pitch (making it lower to play slower, and higher to play
    151      * faster.)
    152      *
    153      * @see MediaSync#PLAYBACK_RATE_AUDIO_MODE_RESAMPLE
    154      * @see MediaPlayer#PLAYBACK_RATE_AUDIO_MODE_RESAMPLE
    155      */
    156     public static final int AUDIO_ADJUST_MODE_RESAMPLE = 2;
    157 
    158     // flags to indicate which params are actually set
    159     private static final int SET_SYNC_SOURCE         = 1 << 0;
    160     private static final int SET_AUDIO_ADJUST_MODE   = 1 << 1;
    161     private static final int SET_TOLERANCE           = 1 << 2;
    162     private static final int SET_FRAME_RATE          = 1 << 3;
    163     private int mSet = 0;
    164 
    165     // params
    166     private int mAudioAdjustMode = AUDIO_ADJUST_MODE_DEFAULT;
    167     private int mSyncSource = SYNC_SOURCE_DEFAULT;
    168     private float mTolerance = 0.f;
    169     private float mFrameRate = 0.f;
    170 
    171     /**
    172      * Allows defaults to be returned for properties not set.
    173      * Otherwise a {@link java.lang.IllegalArgumentException} exception
    174      * is raised when getting those properties
    175      * which have defaults but have never been set.
    176      * @return this <code>SyncParams</code> instance.
    177      */
    178     public SyncParams allowDefaults() {
    179         mSet |= SET_SYNC_SOURCE | SET_AUDIO_ADJUST_MODE | SET_TOLERANCE;
    180         return this;
    181     }
    182 
    183     /**
    184      * Sets the audio adjust mode.
    185      * @param audioAdjustMode
    186      * @return this <code>SyncParams</code> instance.
    187      */
    188     public SyncParams setAudioAdjustMode(@AudioAdjustMode int audioAdjustMode) {
    189         mAudioAdjustMode = audioAdjustMode;
    190         mSet |= SET_AUDIO_ADJUST_MODE;
    191         return this;
    192     }
    193 
    194     /**
    195      * Retrieves the audio adjust mode.
    196      * @return audio adjust mode
    197      * @throws IllegalStateException if the audio adjust mode is not set.
    198      */
    199     public @AudioAdjustMode int getAudioAdjustMode() {
    200         if ((mSet & SET_AUDIO_ADJUST_MODE) == 0) {
    201             throw new IllegalStateException("audio adjust mode not set");
    202         }
    203         return mAudioAdjustMode;
    204     }
    205 
    206     /**
    207      * Sets the sync source.
    208      * @param syncSource
    209      * @return this <code>SyncParams</code> instance.
    210      */
    211     public SyncParams setSyncSource(@SyncSource int syncSource) {
    212         mSyncSource = syncSource;
    213         mSet |= SET_SYNC_SOURCE;
    214         return this;
    215     }
    216 
    217     /**
    218      * Retrieves the sync source.
    219      * @return sync source
    220      * @throws IllegalStateException if the sync source is not set.
    221      */
    222     public @SyncSource int getSyncSource() {
    223         if ((mSet & SET_SYNC_SOURCE) == 0) {
    224             throw new IllegalStateException("sync source not set");
    225         }
    226         return mSyncSource;
    227     }
    228 
    229     /**
    230      * Sets the tolerance. The default tolerance is platform specific, but is never more than 1/24.
    231      * @param tolerance A non-negative number representing
    232      *     the maximum deviation of the playback rate from the playback rate
    233      *     set. ({@code abs(actual_rate - set_rate) / set_rate})
    234      * @return this <code>SyncParams</code> instance.
    235      * @throws IllegalArgumentException if the tolerance is negative, or not less than one.
    236      */
    237     public SyncParams setTolerance(float tolerance) {
    238         if (tolerance < 0.f || tolerance >= 1.f) {
    239             throw new IllegalArgumentException("tolerance must be less than one and non-negative");
    240         }
    241         mTolerance = tolerance;
    242         mSet |= SET_TOLERANCE;
    243         return this;
    244     }
    245 
    246     /**
    247      * Retrieves the tolerance factor.
    248      * @return tolerance factor. A non-negative number representing
    249      *     the maximum deviation of the playback rate from the playback rate
    250      *     set. ({@code abs(actual_rate - set_rate) / set_rate})
    251      * @throws IllegalStateException if tolerance is not set.
    252      */
    253     public float getTolerance() {
    254         if ((mSet & SET_TOLERANCE) == 0) {
    255             throw new IllegalStateException("tolerance not set");
    256         }
    257         return mTolerance;
    258     }
    259 
    260     /**
    261      * Sets the video frame rate hint to be used. By default the frame rate is unspecified.
    262      * @param frameRate A non-negative number used as an initial hint on
    263      *     the video frame rate to be used when using vsync as the sync source. A negative
    264      *     number is used to clear a previous hint.
    265      * @return this <code>SyncParams</code> instance.
    266      */
    267     public SyncParams setFrameRate(float frameRate) {
    268         mFrameRate = frameRate;
    269         mSet |= SET_FRAME_RATE;
    270         return this;
    271     }
    272 
    273     /**
    274      * Retrieves the video frame rate hint.
    275      * @return frame rate factor. A non-negative number representing
    276      *     the maximum deviation of the playback rate from the playback rate
    277      *     set. ({@code abs(actual_rate - set_rate) / set_rate}), or a negative
    278      *     number representing the desire to clear a previous hint using these params.
    279      * @throws IllegalStateException if frame rate is not set.
    280      */
    281     public float getFrameRate() {
    282         if ((mSet & SET_FRAME_RATE) == 0) {
    283             throw new IllegalStateException("frame rate not set");
    284         }
    285         return mFrameRate;
    286     }
    287 
    288 }
    289