Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 28fa1ac5 authored by Lajos Molnar's avatar Lajos Molnar Committed by Android (Google) Code Review
Browse files

Merge "media: add SyncSettings to MediaSync and MediaPlayer"

parents 3239a62d c98f58ef
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -15990,6 +15990,7 @@ package android.media {
    method public int getDuration();
    method public android.media.PlaybackSettings getPlaybackSettings();
    method public int getSelectedTrack(int) throws java.lang.IllegalStateException;
    method public android.media.SyncSettings getSyncSettings();
    method public android.media.MediaPlayer.TrackInfo[] getTrackInfo() throws java.lang.IllegalStateException;
    method public int getVideoHeight();
    method public int getVideoWidth();
@@ -16028,6 +16029,7 @@ package android.media {
    method public void setPlaybackSettings(android.media.PlaybackSettings);
    method public void setScreenOnWhilePlaying(boolean);
    method public void setSurface(android.view.Surface);
    method public void setSyncSettings(android.media.SyncSettings);
    method public void setVideoScalingMode(int);
    method public void setVolume(float, float);
    method public void setWakeMode(android.content.Context, int);
@@ -16346,13 +16348,16 @@ package android.media {
    method public void configureAudioTrack(android.media.AudioTrack);
    method public void configureSurface(android.view.Surface);
    method public final android.view.Surface createInputSurface();
    method public void flush();
    method public android.media.PlaybackSettings getPlaybackSettings();
    method public android.media.SyncSettings getSyncSettings();
    method public boolean getTimestamp(android.media.MediaTimestamp);
    method public void queueAudio(java.nio.ByteBuffer, int, int, long);
    method public final void release();
    method public void setCallback(android.media.MediaSync.Callback, android.os.Handler);
    method public void setPlaybackRate(float, int);
    method public void setPlaybackSettings(android.media.PlaybackSettings);
    method public void setSyncSettings(android.media.SyncSettings);
    field public static final int PLAYBACK_RATE_AUDIO_MODE_DEFAULT = 0; // 0x0
    field public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 2; // 0x2
    field public static final int PLAYBACK_RATE_AUDIO_MODE_STRETCH = 1; // 0x1
@@ -16590,6 +16595,26 @@ package android.media {
    method public abstract void onLoadComplete(android.media.SoundPool, int, int);
  }
  public final class SyncSettings {
    ctor public SyncSettings();
    method public android.media.SyncSettings allowDefaults();
    method public int getAudioAdjustMode();
    method public float getFrameRate();
    method public int getSyncSource();
    method public float getTolerance();
    method public android.media.SyncSettings setAudioAdjustMode(int);
    method public android.media.SyncSettings setFrameRate(float);
    method public android.media.SyncSettings setSyncSource(int);
    method public android.media.SyncSettings setTolerance(float);
    field public static final int AUDIO_ADJUST_MODE_DEFAULT = 0; // 0x0
    field public static final int AUDIO_ADJUST_MODE_RESAMPLE = 2; // 0x2
    field public static final int AUDIO_ADJUST_MODE_STRETCH = 1; // 0x1
    field public static final int SYNC_SOURCE_AUDIO = 2; // 0x2
    field public static final int SYNC_SOURCE_DEFAULT = 0; // 0x0
    field public static final int SYNC_SOURCE_SYSTEM_CLOCK = 1; // 0x1
    field public static final int SYNC_SOURCE_VSYNC = 3; // 0x3
  }
  public class ThumbnailUtils {
    ctor public ThumbnailUtils();
    method public static android.graphics.Bitmap createVideoThumbnail(java.lang.String, int);
+25 −0
Original line number Diff line number Diff line
@@ -17203,6 +17203,7 @@ package android.media {
    method public int getDuration();
    method public android.media.PlaybackSettings getPlaybackSettings();
    method public int getSelectedTrack(int) throws java.lang.IllegalStateException;
    method public android.media.SyncSettings getSyncSettings();
    method public android.media.MediaPlayer.TrackInfo[] getTrackInfo() throws java.lang.IllegalStateException;
    method public int getVideoHeight();
    method public int getVideoWidth();
@@ -17241,6 +17242,7 @@ package android.media {
    method public void setPlaybackSettings(android.media.PlaybackSettings);
    method public void setScreenOnWhilePlaying(boolean);
    method public void setSurface(android.view.Surface);
    method public void setSyncSettings(android.media.SyncSettings);
    method public void setVideoScalingMode(int);
    method public void setVolume(float, float);
    method public void setWakeMode(android.content.Context, int);
@@ -17561,13 +17563,16 @@ package android.media {
    method public void configureAudioTrack(android.media.AudioTrack);
    method public void configureSurface(android.view.Surface);
    method public final android.view.Surface createInputSurface();
    method public void flush();
    method public android.media.PlaybackSettings getPlaybackSettings();
    method public android.media.SyncSettings getSyncSettings();
    method public boolean getTimestamp(android.media.MediaTimestamp);
    method public void queueAudio(java.nio.ByteBuffer, int, int, long);
    method public final void release();
    method public void setCallback(android.media.MediaSync.Callback, android.os.Handler);
    method public void setPlaybackRate(float, int);
    method public void setPlaybackSettings(android.media.PlaybackSettings);
    method public void setSyncSettings(android.media.SyncSettings);
    field public static final int PLAYBACK_RATE_AUDIO_MODE_DEFAULT = 0; // 0x0
    field public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 2; // 0x2
    field public static final int PLAYBACK_RATE_AUDIO_MODE_STRETCH = 1; // 0x1
@@ -17805,6 +17810,26 @@ package android.media {
    method public abstract void onLoadComplete(android.media.SoundPool, int, int);
  }
  public final class SyncSettings {
    ctor public SyncSettings();
    method public android.media.SyncSettings allowDefaults();
    method public int getAudioAdjustMode();
    method public float getFrameRate();
    method public int getSyncSource();
    method public float getTolerance();
    method public android.media.SyncSettings setAudioAdjustMode(int);
    method public android.media.SyncSettings setFrameRate(float);
    method public android.media.SyncSettings setSyncSource(int);
    method public android.media.SyncSettings setTolerance(float);
    field public static final int AUDIO_ADJUST_MODE_DEFAULT = 0; // 0x0
    field public static final int AUDIO_ADJUST_MODE_RESAMPLE = 2; // 0x2
    field public static final int AUDIO_ADJUST_MODE_STRETCH = 1; // 0x1
    field public static final int SYNC_SOURCE_AUDIO = 2; // 0x2
    field public static final int SYNC_SOURCE_DEFAULT = 0; // 0x0
    field public static final int SYNC_SOURCE_SYSTEM_CLOCK = 1; // 0x1
    field public static final int SYNC_SOURCE_VSYNC = 3; // 0x3
  }
  public class ThumbnailUtils {
    ctor public ThumbnailUtils();
    method public static android.graphics.Bitmap createVideoThumbnail(java.lang.String, int);
+23 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import android.media.SubtitleController;
import android.media.SubtitleController.Anchor;
import android.media.SubtitleData;
import android.media.SubtitleTrack.RenderingWidget;
import android.media.SyncSettings;

import com.android.internal.app.IAppOpsService;

@@ -1446,6 +1447,28 @@ public class MediaPlayer implements SubtitleController.Listener
    @NonNull
    public native PlaybackSettings getPlaybackSettings();

    /**
     * Sets A/V sync mode.
     *
     * @param settings the A/V sync settings to apply
     *
     * @throws IllegalStateException if the internal player engine has not been
     * initialized.
     * @throws IllegalArgumentException if settings are not supported.
     */
    public native void setSyncSettings(@NonNull SyncSettings settings);

    /**
     * Gets the A/V sync mode.
     *
     * @return the A/V sync settings
     *
     * @throws IllegalStateException if the internal player engine has not been
     * initialized.
     */
    @NonNull
    public native SyncSettings getSyncSettings();

    /**
     * Seeks to specified time position.
     *
+38 −0
Original line number Diff line number Diff line
@@ -441,6 +441,44 @@ final public class MediaSync {

    private native final void native_setPlaybackRate(float rate);

    /**
     * Sets A/V sync mode.
     *
     * @param settings the A/V sync settings to apply
     *
     * @throws IllegalStateException if the internal player engine has not been
     * initialized.
     * @throws IllegalArgumentException if settings are not supported.
     */
    public native void setSyncSettings(@NonNull SyncSettings settings);

    /**
     * Gets the A/V sync mode.
     *
     * @return the A/V sync settings
     *
     * @throws IllegalStateException if the internal player engine has not been
     * initialized.
     */
    @NonNull
    public native SyncSettings getSyncSettings();

    /**
     * Flushes all buffers from the sync object.
     * <p>
     * No callbacks are received for the flushed buffers.
     *
     * @throws IllegalStateException if the internal player engine has not been
     * initialized.
     */
    public void flush() {
        synchronized(mAudioLock) {
            mAudioBuffers.clear();
            mCallbackHandler.removeCallbacksAndMessages(null);
        }
        // TODO implement this for surface buffers.
    }

   /**
    * Get current playback position.
    * <p>
+282 −0
Original line number Diff line number Diff line
/*
 * 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 settings.
 *
 * Used by {@link MediaSync} {link MediaSync#getSyncSettings()} and
 * {link MediaSync#setSyncSettings(SyncSettings)}
 * 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 SyncSettings#AUDIO_ADJUST_MODE_DEFAULT}:
 *   System will determine best handling. </li>
 * <li> {@link SyncSettings#AUDIO_ADJUST_MODE_STRETCH}:
 *   Change the speed of audio playback without altering its pitch.</li>
 * <li> {@link SyncSettings#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 SyncSettings#SYNC_SOURCE_DEFAULT}:
 *   System will determine best selection.</li>
 * <li> {@link SyncSettings#SYNC_SOURCE_SYSTEM_CLOCK}:
 *   Use system clock for sync source.</li>
 * <li> {@link SyncSettings#SYNC_SOURCE_AUDIO}:
 *   Use audio track for sync source.</li>
 * <li> {@link SyncSettings#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.
 * <p> <strong>frameRate:</strong> initial hint for video frame rate. Used when
 * sync source is vsync.
 */
public final class SyncSettings {
    /** @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 AudioTrack#getTimeStamp
     */
    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.
     *
     * @see MediaSync#PLAYBACK_RATE_AUDIO_MODE_STRETCH
     * @see MediaPlayer#PLAYBACK_RATE_AUDIO_MODE_STRETCH
     */
    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.)
     *
     * @see MediaSync#PLAYBACK_RATE_AUDIO_MODE_RESAMPLE
     * @see MediaPlayer#PLAYBACK_RATE_AUDIO_MODE_RESAMPLE
     */
    public static final int AUDIO_ADJUST_MODE_RESAMPLE = 2;

    // flags to indicate which settings 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;

    // settings
    private int mAudioAdjustMode = AUDIO_ADJUST_MODE_STRETCH;
    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>SyncSettings</code> instance.
     */
    public SyncSettings allowDefaults() {
        mSet |= SET_SYNC_SOURCE | SET_AUDIO_ADJUST_MODE | SET_TOLERANCE;
        return this;
    }

    /**
     * Sets the audio adjust mode.
     * @param audioAdjustMode
     * @return this <code>SyncSettings</code> instance.
     */
    public SyncSettings 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>SyncSettings</code> instance.
     */
    public SyncSettings 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 0.
     * @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>SyncSettings</code> instance.
     */
    public SyncSettings setTolerance(float tolerance) {
        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.
     * @return this <code>SyncSettings</code> instance.
     */
    public SyncSettings 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})
     * @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;
    }

}
Loading