Merge "media: use PlaybackSettings in MediaSync and MediaPlayer"

This commit is contained in:
Lajos Molnar
2015-04-23 05:42:55 +00:00
committed by Android (Google) Code Review
6 changed files with 385 additions and 103 deletions

View File

@@ -15988,6 +15988,7 @@ package android.media {
method public int getAudioSessionId();
method public int getCurrentPosition();
method public int getDuration();
method public android.media.PlaybackSettings getPlaybackSettings();
method public int getSelectedTrack(int) throws java.lang.IllegalStateException;
method public android.media.MediaPlayer.TrackInfo[] getTrackInfo() throws java.lang.IllegalStateException;
method public int getVideoHeight();
@@ -16024,6 +16025,7 @@ package android.media {
method public void setOnTimedTextListener(android.media.MediaPlayer.OnTimedTextListener);
method public void setOnVideoSizeChangedListener(android.media.MediaPlayer.OnVideoSizeChangedListener);
method public void setPlaybackRate(float, int);
method public void setPlaybackSettings(android.media.PlaybackSettings);
method public void setScreenOnWhilePlaying(boolean);
method public void setSurface(android.view.Surface);
method public void setVideoScalingMode(int);
@@ -16049,7 +16051,9 @@ package android.media {
field public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; // 0x3
field public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; // 0x2bc
field public static final java.lang.String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
field public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 0; // 0x0
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
field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT = 1; // 0x1
field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2; // 0x2
}
@@ -16342,12 +16346,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 android.media.PlaybackSettings getPlaybackSettings();
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);
field public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 0; // 0x0
method public void setPlaybackSettings(android.media.PlaybackSettings);
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
}
public static abstract class MediaSync.Callback {

View File

@@ -17201,6 +17201,7 @@ package android.media {
method public int getAudioSessionId();
method public int getCurrentPosition();
method public int getDuration();
method public android.media.PlaybackSettings getPlaybackSettings();
method public int getSelectedTrack(int) throws java.lang.IllegalStateException;
method public android.media.MediaPlayer.TrackInfo[] getTrackInfo() throws java.lang.IllegalStateException;
method public int getVideoHeight();
@@ -17237,6 +17238,7 @@ package android.media {
method public void setOnTimedTextListener(android.media.MediaPlayer.OnTimedTextListener);
method public void setOnVideoSizeChangedListener(android.media.MediaPlayer.OnVideoSizeChangedListener);
method public void setPlaybackRate(float, int);
method public void setPlaybackSettings(android.media.PlaybackSettings);
method public void setScreenOnWhilePlaying(boolean);
method public void setSurface(android.view.Surface);
method public void setVideoScalingMode(int);
@@ -17262,7 +17264,9 @@ package android.media {
field public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; // 0x3
field public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; // 0x2bc
field public static final java.lang.String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
field public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 0; // 0x0
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
field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT = 1; // 0x1
field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2; // 0x2
}
@@ -17557,12 +17561,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 android.media.PlaybackSettings getPlaybackSettings();
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);
field public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 0; // 0x0
method public void setPlaybackSettings(android.media.PlaybackSettings);
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
}
public static abstract class MediaSync.Callback {

View File

@@ -17,6 +17,7 @@
package android.media;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.app.ActivityThread;
import android.app.AppOpsManager;
import android.content.ContentResolver;
@@ -44,6 +45,7 @@ import android.graphics.SurfaceTexture;
import android.media.AudioManager;
import android.media.MediaFormat;
import android.media.MediaTimeProvider;
import android.media.PlaybackSettings;
import android.media.SubtitleController;
import android.media.SubtitleController.Anchor;
import android.media.SubtitleData;
@@ -471,16 +473,21 @@ import java.lang.ref.WeakReference;
* <td>{} </p></td>
* <td>This method can be called in any state and calling it does not change
* the object state. </p></td></tr>
* <tr><td>setScreenOnWhilePlaying</></td>
* <td>any </p></td>
* <td>{} </p></td>
* <td>This method can be called in any state and calling it does not change
* the object state. </p></td></tr>
* <tr><td>setPlaybackRate</p></td>
* <td>any </p></td>
* <td>{} </p></td>
* <td>This method can be called in any state and calling it does not change
* the object state. </p></td></tr>
* <tr><td>setPlaybackSettings</p></td>
* <td>any </p></td>
* <td>{} </p></td>
* <td>This method can be called in any state and calling it does not change
* the object state. </p></td></tr>
* <tr><td>setScreenOnWhilePlaying</></td>
* <td>any </p></td>
* <td>{} </p></td>
* <td>This method can be called in any state and calling it does not change
* the object state. </p></td></tr>
* <tr><td>setVolume </p></td>
* <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
* PlaybackCompleted}</p></td>
@@ -1342,6 +1349,8 @@ public class MediaPlayer implements SubtitleController.Listener
public native boolean isPlaying();
/**
* Change playback speed of audio by resampling the audio.
* <p>
* Specifies resampling as audio mode for variable rate playback, i.e.,
* resample the waveform based on the requested playback rate to get
* a new waveform, and play back the new waveform at the original sampling
@@ -1349,33 +1358,44 @@ public class MediaPlayer implements SubtitleController.Listener
* When rate is larger than 1.0, pitch becomes higher.
* When rate is smaller than 1.0, pitch becomes lower.
*/
public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 0;
public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 2;
/**
* Change playback speed of audio without changing its pitch.
* <p>
* Specifies time stretching as audio mode for variable rate playback.
* Time stretching changes the duration of the audio samples without
* affecting its pitch.
* FIXME: implement time strectching.
* @hide
* <p>
* This mode is only supported for a limited range of playback speed factors,
* e.g. between 1/2x and 2x.
*/
public static final int PLAYBACK_RATE_AUDIO_MODE_STRETCH = 1;
/**
* Change playback speed of audio without changing its pitch, and
* possibly mute audio if time stretching is not supported for the playback
* speed.
* <p>
* Try to keep audio pitch when changing the playback rate, but allow the
* system to determine how to change audio playback if the rate is out
* of range.
*/
public static final int PLAYBACK_RATE_AUDIO_MODE_DEFAULT = 0;
/** @hide */
@IntDef(
value = {
PLAYBACK_RATE_AUDIO_MODE_DEFAULT,
PLAYBACK_RATE_AUDIO_MODE_STRETCH,
PLAYBACK_RATE_AUDIO_MODE_RESAMPLE,
PLAYBACK_RATE_AUDIO_MODE_STRETCH })
})
@Retention(RetentionPolicy.SOURCE)
public @interface PlaybackRateAudioMode {}
/**
* Sets playback rate and audio mode.
*
* <p> The supported audio modes are:
* <ul>
* <li> {@link #PLAYBACK_RATE_AUDIO_MODE_RESAMPLE}
* </ul>
*
* @param rate the ratio between desired playback rate and normal one.
* @param audioMode audio playback mode. Must be one of the supported
* audio modes.
@@ -1385,14 +1405,46 @@ public class MediaPlayer implements SubtitleController.Listener
* @throws IllegalArgumentException if audioMode is not supported.
*/
public void setPlaybackRate(float rate, @PlaybackRateAudioMode int audioMode) {
if (!isAudioPlaybackModeSupported(audioMode)) {
PlaybackSettings settings = new PlaybackSettings();
settings.allowDefaults();
switch (audioMode) {
case PLAYBACK_RATE_AUDIO_MODE_DEFAULT:
settings.setSpeed(rate).setPitch(1.0f);
break;
case PLAYBACK_RATE_AUDIO_MODE_STRETCH:
settings.setSpeed(rate).setPitch(1.0f)
.setAudioFallbackMode(settings.AUDIO_FALLBACK_MODE_FAIL);
break;
case PLAYBACK_RATE_AUDIO_MODE_RESAMPLE:
settings.setSpeed(rate).setPitch(rate);
break;
default:
final String msg = "Audio playback mode " + audioMode + " is not supported";
throw new IllegalArgumentException(msg);
}
_setPlaybackRate(rate);
setPlaybackSettings(settings);
}
private native void _setPlaybackRate(float rate) throws IllegalStateException;
/**
* Sets playback rate using {@link PlaybackSettings}.
*
* @param settings the playback settings.
*
* @throws IllegalStateException if the internal player engine has not been
* initialized.
* @throws IllegalArgumentException if settings is not supported.
*/
public native void setPlaybackSettings(@NonNull PlaybackSettings settings);
/**
* Gets the playback settings, containing the current playback rate.
*
* @return the playback settings.
* @throws IllegalStateException if the internal player engine has not been
* initialized.
*/
@NonNull
public native PlaybackSettings getPlaybackSettings();
/**
* Seeks to specified time position.
@@ -3219,14 +3271,6 @@ public class MediaPlayer implements SubtitleController.Listener
mode == VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
}
/*
* Test whether a given audio playback mode is supported.
* TODO query supported AudioPlaybackMode from player.
*/
private boolean isAudioPlaybackModeSupported(int mode) {
return (mode == PLAYBACK_RATE_AUDIO_MODE_RESAMPLE);
}
/** @hide */
static class TimeProvider implements MediaPlayer.OnSeekCompleteListener,
MediaTimeProvider {

View File

@@ -20,6 +20,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.media.AudioTrack;
import android.media.PlaybackSettings;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -282,60 +283,58 @@ final public class MediaSync {
public native final Surface createInputSurface();
/**
* Specifies resampling as audio mode for variable rate playback, i.e.,
* resample the waveform based on the requested playback rate to get
* Resample audio data when changing playback speed.
* <p>
* Resample the waveform based on the requested playback rate to get
* a new waveform, and play back the new waveform at the original sampling
* frequency.
* When rate is larger than 1.0, pitch becomes higher.
* When rate is smaller than 1.0, pitch becomes lower.
* <p><ul>
* <li>When rate is larger than 1.0, pitch becomes higher.
* <li>When rate is smaller than 1.0, pitch becomes lower.
* </ul>
*/
public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 0;
public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 2;
/**
* Specifies time stretching as audio mode for variable rate playback.
* Time stretch audio when changing playback speed.
* <p>
* Time stretching changes the duration of the audio samples without
* affecting its pitch.
* FIXME: implement time strectching.
* @hide
* affecting their pitch. This is only supported for a limited range
* of playback speeds, e.g. from 1/2x to 2x. If the rate is adjusted
* beyond this limit, the rate change will fail.
*/
public static final int PLAYBACK_RATE_AUDIO_MODE_STRETCH = 1;
/**
* Time stretch audio when changing playback speed, and may mute if
* stretching is no longer supported.
* <p>
* Time stretching changes the duration of the audio samples without
* affecting their pitch. This is only supported for a limited range
* of playback speeds, e.g. from 1/2x to 2x. When it is no longer
* supported, the audio may be muted. Using this mode will not fail
* for non-negative playback rates.
*/
public static final int PLAYBACK_RATE_AUDIO_MODE_DEFAULT = 0;
/** @hide */
@IntDef(
value = {
PLAYBACK_RATE_AUDIO_MODE_DEFAULT,
PLAYBACK_RATE_AUDIO_MODE_STRETCH,
PLAYBACK_RATE_AUDIO_MODE_RESAMPLE,
PLAYBACK_RATE_AUDIO_MODE_STRETCH })
})
@Retention(RetentionPolicy.SOURCE)
public @interface PlaybackRateAudioMode {}
/**
* Sets playback rate. It does same as {@link #setPlaybackRate(float, int)},
* except that it always uses {@link #PLAYBACK_RATE_AUDIO_MODE_STRETCH} for audioMode.
*
* @param rate the ratio between desired playback rate and normal one. 1.0 means normal
* playback speed. 0.0 means stop or pause. Value larger than 1.0 means faster playback,
* while value between 0.0 and 1.0 for slower playback.
*
* @throws IllegalStateException if the internal sync engine or the audio track has not
* been initialized.
* TODO: unhide when PLAYBACK_RATE_AUDIO_MODE_STRETCH is supported.
* @hide
*/
public void setPlaybackRate(float rate) {
setPlaybackRate(rate, PLAYBACK_RATE_AUDIO_MODE_STRETCH);
}
/**
* Sets playback rate and audio mode.
*
* <p> The supported audio modes are:
* <ul>
* <li> {@link #PLAYBACK_RATE_AUDIO_MODE_RESAMPLE}
* </ul>
*
* @param rate the ratio between desired playback rate and normal one. 1.0 means normal
* playback speed. 0.0 means stop or pause. Value larger than 1.0 means faster playback,
* while value between 0.0 and 1.0 for slower playback.
* playback speed. 0.0 means pause. Value larger than 1.0 means faster playback,
* while value between 0.0 and 1.0 for slower playback. <b>Note:</b> the normal rate
* does not change as a result of this call. To restore the original rate at any time,
* use 1.0.
* @param audioMode audio playback mode. Must be one of the supported
* audio modes.
*
@@ -344,52 +343,104 @@ final public class MediaSync {
* @throws IllegalArgumentException if audioMode is not supported.
*/
public void setPlaybackRate(float rate, @PlaybackRateAudioMode int audioMode) {
if (!isAudioPlaybackModeSupported(audioMode)) {
final String msg = "Audio playback mode " + audioMode + " is not supported";
throw new IllegalArgumentException(msg);
}
int status = AudioTrack.SUCCESS;
if (mAudioTrack != null) {
int nativeSampleRateInHz = mAudioTrack.getSampleRate();
int playbackSampleRate = (int)(rate * nativeSampleRateInHz + 0.5);
rate = playbackSampleRate / (float)nativeSampleRateInHz;
try {
if (rate == 0.0) {
mAudioTrack.pause();
} else {
status = mAudioTrack.setPlaybackRate(playbackSampleRate);
mAudioTrack.play();
}
} catch (IllegalStateException e) {
throw e;
PlaybackSettings rateSettings = new PlaybackSettings();
rateSettings.allowDefaults();
switch (audioMode) {
case PLAYBACK_RATE_AUDIO_MODE_DEFAULT:
rateSettings.setSpeed(rate).setPitch(1.0f);
break;
case PLAYBACK_RATE_AUDIO_MODE_STRETCH:
rateSettings.setSpeed(rate).setPitch(1.0f)
.setAudioFallbackMode(rateSettings.AUDIO_FALLBACK_MODE_FAIL);
break;
case PLAYBACK_RATE_AUDIO_MODE_RESAMPLE:
rateSettings.setSpeed(rate).setPitch(rate);
break;
default:
{
final String msg = "Audio playback mode " + audioMode + " is not supported";
throw new IllegalArgumentException(msg);
}
}
setPlaybackSettings(rateSettings);
}
if (status != AudioTrack.SUCCESS) {
throw new IllegalArgumentException("Fail to set playback rate in audio track");
}
/**
* Sets playback rate using {@link PlaybackSettings}.
* <p>
* When using MediaSync with {@link AudioTrack}, set playback settings using this
* call instead of calling it directly on the track, so that the sync is aware of
* the settings change.
* <p>
* This call also works if there is no audio track.
*
* @param settings the playback settings to use. {@link PlaybackSettings#getSpeed
* Speed} is the ratio between desired playback rate and normal one. 1.0 means
* normal playback speed. 0.0 means pause. Value larger than 1.0 means faster playback,
* while value between 0.0 and 1.0 for slower playback. <b>Note:</b> the normal rate
* does not change as a result of this call. To restore the original rate at any time,
* use speed of 1.0.
*
* @throws IllegalStateException if the internal sync engine or the audio track has not
* been initialized.
* @throws IllegalArgumentException if the settings are not supported.
*/
public void setPlaybackSettings(@NonNull PlaybackSettings settings) {
float rate;
try {
rate = settings.getSpeed();
synchronized(mAudioLock) {
mPlaybackRate = rate;
// rate is specified
if (mAudioTrack != null) {
try {
if (rate == 0.0) {
mAudioTrack.pause();
} else {
mAudioTrack.setPlaybackSettings(settings);
mAudioTrack.play();
}
} catch (IllegalStateException e) {
throw e;
}
}
synchronized(mAudioLock) {
mPlaybackRate = rate;
}
if (mPlaybackRate != 0.0 && mAudioThread != null) {
postRenderAudio(0);
}
native_setPlaybackRate(mPlaybackRate);
} catch (IllegalStateException e) {
// rate is not specified; still, propagate settings to audio track
if (mAudioTrack != null) {
mAudioTrack.setPlaybackSettings(settings);
}
}
if (mPlaybackRate != 0.0 && mAudioThread != null) {
postRenderAudio(0);
}
/**
* Gets the playback rate using {@link PlaybackSettings}.
*
* @return the playback rate being used.
*
* @throws IllegalStateException if the internal sync engine or the audio track has not
* been initialized.
*/
@NonNull
public PlaybackSettings getPlaybackSettings() {
if (mAudioTrack != null) {
return mAudioTrack.getPlaybackSettings();
} else {
PlaybackSettings settings = new PlaybackSettings();
settings.allowDefaults();
settings.setSpeed(mPlaybackRate);
return settings;
}
native_setPlaybackRate(mPlaybackRate);
}
private native final void native_setPlaybackRate(float rate);
/*
* Test whether a given audio playback mode is supported.
* TODO query supported AudioPlaybackMode from audio track.
*/
private boolean isAudioPlaybackModeSupported(int mode) {
return (mode == PLAYBACK_RATE_AUDIO_MODE_RESAMPLE);
}
/**
* Get current playback position.
* <p>

View File

@@ -20,6 +20,7 @@
#include "utils/Log.h"
#include <media/mediaplayer.h>
#include <media/AudioResamplerPublic.h>
#include <media/IMediaHTTPService.h>
#include <media/MediaPlayerInterface.h>
#include <stdio.h>
@@ -37,6 +38,7 @@
#include "utils/KeyedVector.h"
#include "utils/String8.h"
#include "android_media_MediaDataSource.h"
#include "android_media_PlaybackSettings.h"
#include "android_media_Utils.h"
#include "android_os_Parcel.h"
@@ -66,6 +68,8 @@ struct fields_t {
};
static fields_t fields;
static PlaybackSettings::fields_t gPlaybackSettingsFields;
static Mutex sLock;
// ----------------------------------------------------------------------------
@@ -420,15 +424,55 @@ android_media_MediaPlayer_isPlaying(JNIEnv *env, jobject thiz)
}
static void
android_media_MediaPlayer_setPlaybackRate(JNIEnv *env, jobject thiz, jfloat rate)
android_media_MediaPlayer_setPlaybackSettings(JNIEnv *env, jobject thiz, jobject settings)
{
sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
if (mp == NULL) {
jniThrowException(env, "java/lang/IllegalStateException", NULL);
return;
}
ALOGV("setPlaybackRate: %f", rate);
process_media_player_call(env, thiz, mp->setPlaybackRate(rate), NULL, NULL);
PlaybackSettings pbs;
pbs.fillFromJobject(env, gPlaybackSettingsFields, settings);
ALOGV("setPlaybackSettings: %d:%f %d:%f %d:%u %d:%u",
pbs.speedSet, pbs.audioRate.mSpeed,
pbs.pitchSet, pbs.audioRate.mPitch,
pbs.audioFallbackModeSet, pbs.audioRate.mFallbackMode,
pbs.audioStretchModeSet, pbs.audioRate.mStretchMode);
// TODO: pass playback settings to mediaplayer when audiotrack supports it
process_media_player_call(env, thiz, mp->setPlaybackRate(pbs.audioRate.mSpeed), NULL, NULL);
}
static jobject
android_media_MediaPlayer_getPlaybackSettings(JNIEnv *env, jobject thiz)
{
sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
if (mp == NULL) {
jniThrowException(env, "java/lang/IllegalStateException", NULL);
return NULL;
}
PlaybackSettings pbs;
AudioPlaybackRate &audioRate = pbs.audioRate;
audioRate.mSpeed = 1.0f;
audioRate.mPitch = 1.0f;
audioRate.mFallbackMode = AUDIO_TIMESTRETCH_FALLBACK_DEFAULT;
audioRate.mStretchMode = AUDIO_TIMESTRETCH_STRETCH_DEFAULT;
// TODO: get this from mediaplayer when audiotrack supports it
// process_media_player_call(
// env, thiz, mp->getPlaybackSettings(&audioRate), NULL, NULL);
ALOGV("getPlaybackSettings: %f %f %d %d",
audioRate.mSpeed, audioRate.mPitch, audioRate.mFallbackMode, audioRate.mStretchMode);
pbs.speedSet = true;
pbs.pitchSet = true;
pbs.audioFallbackModeSet = true;
pbs.audioStretchModeSet = true;
return pbs.asJobject(env, gPlaybackSettingsFields);
}
static void
@@ -697,6 +741,8 @@ android_media_MediaPlayer_native_init(JNIEnv *env)
return;
}
env->DeleteLocalRef(clazz);
clazz = env->FindClass("android/net/ProxyInfo");
if (clazz == NULL) {
return;
@@ -710,6 +756,10 @@ android_media_MediaPlayer_native_init(JNIEnv *env)
fields.proxyConfigGetExclusionList =
env->GetMethodID(clazz, "getExclusionListAsString", "()Ljava/lang/String;");
env->DeleteLocalRef(clazz);
gPlaybackSettingsFields.init(env);
}
static void
@@ -898,7 +948,8 @@ static JNINativeMethod gMethods[] = {
{"_stop", "()V", (void *)android_media_MediaPlayer_stop},
{"getVideoWidth", "()I", (void *)android_media_MediaPlayer_getVideoWidth},
{"getVideoHeight", "()I", (void *)android_media_MediaPlayer_getVideoHeight},
{"_setPlaybackRate", "(F)V", (void *)android_media_MediaPlayer_setPlaybackRate},
{"setPlaybackSettings", "(Landroid/media/PlaybackSettings;)V", (void *)android_media_MediaPlayer_setPlaybackSettings},
{"getPlaybackSettings", "()Landroid/media/PlaybackSettings;", (void *)android_media_MediaPlayer_getPlaybackSettings},
{"seekTo", "(I)V", (void *)android_media_MediaPlayer_seekTo},
{"_pause", "()V", (void *)android_media_MediaPlayer_pause},
{"isPlaying", "()Z", (void *)android_media_MediaPlayer_isPlaying},

View File

@@ -0,0 +1,120 @@
/*
* 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.
*/
#ifndef _ANDROID_MEDIA_PLAYBACK_SETTINGS_H_
#define _ANDROID_MEDIA_PLAYBACK_SETTINGS_H_
#include <media/AudioResamplerPublic.h>
namespace android {
// This entire class is inline as it is used from both core and media
struct PlaybackSettings {
AudioPlaybackRate audioRate;
bool speedSet;
bool pitchSet;
bool audioFallbackModeSet;
bool audioStretchModeSet;
struct fields_t {
jclass clazz;
jmethodID constructID;
jfieldID speed;
jfieldID pitch;
jfieldID audio_fallback_mode;
jfieldID audio_stretch_mode;
jfieldID set;
jint set_speed;
jint set_pitch;
jint set_audio_fallback_mode;
jint set_audio_stretch_mode;
void init(JNIEnv *env) {
jclass lclazz = env->FindClass("android/media/PlaybackSettings");
if (lclazz == NULL) {
return;
}
clazz = (jclass)env->NewGlobalRef(lclazz);
if (clazz == NULL) {
return;
}
constructID = env->GetMethodID(clazz, "<init>", "()V");
speed = env->GetFieldID(clazz, "mSpeed", "F");
pitch = env->GetFieldID(clazz, "mPitch", "F");
audio_fallback_mode = env->GetFieldID(clazz, "mAudioFallbackMode", "I");
audio_stretch_mode = env->GetFieldID(clazz, "mAudioStretchMode", "I");
set = env->GetFieldID(clazz, "mSet", "I");
set_speed =
env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "SET_SPEED", "I"));
set_pitch =
env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "SET_PITCH", "I"));
set_audio_fallback_mode = env->GetStaticIntField(
clazz, env->GetStaticFieldID(clazz, "SET_AUDIO_FALLBACK_MODE", "I"));
set_audio_stretch_mode = env->GetStaticIntField(
clazz, env->GetStaticFieldID(clazz, "SET_AUDIO_STRETCH_MODE", "I"));
env->DeleteLocalRef(lclazz);
}
void exit(JNIEnv *env) {
env->DeleteGlobalRef(clazz);
clazz = NULL;
}
};
void fillFromJobject(JNIEnv *env, const fields_t& fields, jobject settings) {
audioRate.mSpeed = env->GetFloatField(settings, fields.speed);
audioRate.mPitch = env->GetFloatField(settings, fields.pitch);
audioRate.mFallbackMode =
(AudioTimestretchFallbackMode)env->GetIntField(settings, fields.audio_fallback_mode);
audioRate.mStretchMode =
(AudioTimestretchStretchMode)env->GetIntField(settings, fields.audio_stretch_mode);
int set = env->GetIntField(settings, fields.set);
speedSet = set & fields.set_speed;
pitchSet = set & fields.set_pitch;
audioFallbackModeSet = set & fields.set_audio_fallback_mode;
audioStretchModeSet = set & fields.set_audio_stretch_mode;
}
jobject asJobject(JNIEnv *env, const fields_t& fields) {
jobject settings = env->NewObject(fields.clazz, fields.constructID);
if (settings == NULL) {
return NULL;
}
env->SetFloatField(settings, fields.speed, (jfloat)audioRate.mSpeed);
env->SetFloatField(settings, fields.pitch, (jfloat)audioRate.mPitch);
env->SetIntField(settings, fields.audio_fallback_mode, (jint)audioRate.mFallbackMode);
env->SetIntField(settings, fields.audio_stretch_mode, (jint)audioRate.mStretchMode);
env->SetIntField(
settings, fields.set,
(speedSet ? fields.set_speed : 0)
| (pitchSet ? fields.set_pitch : 0)
| (audioFallbackModeSet ? fields.set_audio_fallback_mode : 0)
| (audioStretchModeSet ? fields.set_audio_stretch_mode : 0));
return settings;
}
};
} // namespace android
#endif // _ANDROID_MEDIA_PLAYBACK_SETTINGS_H_