* commit '607dab369580d8510f42b1a796ee623eaf4b2adf': media: Hook up MediaPlayer and MediaSync to new settings
This commit is contained in:
@@ -199,6 +199,7 @@ final public class MediaSync {
|
|||||||
private final Object mAudioLock = new Object();
|
private final Object mAudioLock = new Object();
|
||||||
private AudioTrack mAudioTrack = null;
|
private AudioTrack mAudioTrack = null;
|
||||||
private List<AudioBuffer> mAudioBuffers = new LinkedList<AudioBuffer>();
|
private List<AudioBuffer> mAudioBuffers = new LinkedList<AudioBuffer>();
|
||||||
|
// this is only used for paused/running decisions, so it is not affected by clock drift
|
||||||
private float mPlaybackRate = 0.0f;
|
private float mPlaybackRate = 0.0f;
|
||||||
|
|
||||||
private long mNativeContext;
|
private long mNativeContext;
|
||||||
@@ -459,36 +460,11 @@ final public class MediaSync {
|
|||||||
* @throws IllegalArgumentException if the settings are not supported.
|
* @throws IllegalArgumentException if the settings are not supported.
|
||||||
*/
|
*/
|
||||||
public void setPlaybackSettings(@NonNull PlaybackSettings settings) {
|
public void setPlaybackSettings(@NonNull PlaybackSettings settings) {
|
||||||
float rate;
|
synchronized(mAudioLock) {
|
||||||
try {
|
mPlaybackRate = native_setPlaybackSettings(settings);;
|
||||||
rate = settings.getSpeed();
|
}
|
||||||
|
if (mPlaybackRate != 0.0 && mAudioThread != null) {
|
||||||
// rate is specified
|
postRenderAudio(0);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -501,18 +477,9 @@ final public class MediaSync {
|
|||||||
* been initialized.
|
* been initialized.
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public PlaybackSettings getPlaybackSettings() {
|
public native PlaybackSettings getPlaybackSettings();
|
||||||
if (mAudioTrack != null) {
|
|
||||||
return mAudioTrack.getPlaybackSettings();
|
|
||||||
} else {
|
|
||||||
PlaybackSettings settings = new PlaybackSettings();
|
|
||||||
settings.allowDefaults();
|
|
||||||
settings.setSpeed(mPlaybackRate);
|
|
||||||
return settings;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private native final void native_setPlaybackRate(float rate);
|
private native float native_setPlaybackSettings(@NonNull PlaybackSettings settings);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets A/V sync mode.
|
* Sets A/V sync mode.
|
||||||
@@ -523,7 +490,16 @@ final public class MediaSync {
|
|||||||
* initialized.
|
* initialized.
|
||||||
* @throws IllegalArgumentException if settings are not supported.
|
* @throws IllegalArgumentException if settings are not supported.
|
||||||
*/
|
*/
|
||||||
public native void setSyncSettings(@NonNull SyncSettings settings);
|
public void setSyncSettings(@NonNull SyncSettings settings) {
|
||||||
|
synchronized(mAudioLock) {
|
||||||
|
mPlaybackRate = native_setSyncSettings(settings);;
|
||||||
|
}
|
||||||
|
if (mPlaybackRate != 0.0 && mAudioThread != null) {
|
||||||
|
postRenderAudio(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private native float native_setSyncSettings(@NonNull SyncSettings settings);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the A/V sync mode.
|
* Gets the A/V sync mode.
|
||||||
|
|||||||
@@ -174,6 +174,8 @@ static void process_media_player_call(JNIEnv *env, jobject thiz, status_t opStat
|
|||||||
} else { // Throw exception!
|
} else { // Throw exception!
|
||||||
if ( opStatus == (status_t) INVALID_OPERATION ) {
|
if ( opStatus == (status_t) INVALID_OPERATION ) {
|
||||||
jniThrowException(env, "java/lang/IllegalStateException", NULL);
|
jniThrowException(env, "java/lang/IllegalStateException", NULL);
|
||||||
|
} else if ( opStatus == (status_t) BAD_VALUE ) {
|
||||||
|
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
|
||||||
} else if ( opStatus == (status_t) PERMISSION_DENIED ) {
|
} else if ( opStatus == (status_t) PERMISSION_DENIED ) {
|
||||||
jniThrowException(env, "java/lang/SecurityException", NULL);
|
jniThrowException(env, "java/lang/SecurityException", NULL);
|
||||||
} else if ( opStatus != (status_t) OK ) {
|
} else if ( opStatus != (status_t) OK ) {
|
||||||
@@ -442,8 +444,33 @@ android_media_MediaPlayer_setPlaybackSettings(JNIEnv *env, jobject thiz, jobject
|
|||||||
pbs.audioFallbackModeSet, pbs.audioRate.mFallbackMode,
|
pbs.audioFallbackModeSet, pbs.audioRate.mFallbackMode,
|
||||||
pbs.audioStretchModeSet, pbs.audioRate.mStretchMode);
|
pbs.audioStretchModeSet, pbs.audioRate.mStretchMode);
|
||||||
|
|
||||||
// TODO: pass playback settings to mediaplayer when audiotrack supports it
|
AudioPlaybackRate rate;
|
||||||
process_media_player_call(env, thiz, mp->setPlaybackRate(pbs.audioRate.mSpeed), NULL, NULL);
|
status_t err = mp->getPlaybackSettings(&rate);
|
||||||
|
if (err == OK) {
|
||||||
|
bool updatedRate = false;
|
||||||
|
if (pbs.speedSet) {
|
||||||
|
rate.mSpeed = pbs.audioRate.mSpeed;
|
||||||
|
updatedRate = true;
|
||||||
|
}
|
||||||
|
if (pbs.pitchSet) {
|
||||||
|
rate.mPitch = pbs.audioRate.mPitch;
|
||||||
|
updatedRate = true;
|
||||||
|
}
|
||||||
|
if (pbs.audioFallbackModeSet) {
|
||||||
|
rate.mFallbackMode = pbs.audioRate.mFallbackMode;
|
||||||
|
updatedRate = true;
|
||||||
|
}
|
||||||
|
if (pbs.audioStretchModeSet) {
|
||||||
|
rate.mStretchMode = pbs.audioRate.mStretchMode;
|
||||||
|
updatedRate = true;
|
||||||
|
}
|
||||||
|
if (updatedRate) {
|
||||||
|
err = mp->setPlaybackSettings(rate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
process_media_player_call(
|
||||||
|
env, thiz, err,
|
||||||
|
"java/lang/IllegalStateException", "unexpected error");
|
||||||
}
|
}
|
||||||
|
|
||||||
static jobject
|
static jobject
|
||||||
@@ -457,15 +484,9 @@ android_media_MediaPlayer_getPlaybackSettings(JNIEnv *env, jobject thiz)
|
|||||||
|
|
||||||
PlaybackSettings pbs;
|
PlaybackSettings pbs;
|
||||||
AudioPlaybackRate &audioRate = pbs.audioRate;
|
AudioPlaybackRate &audioRate = pbs.audioRate;
|
||||||
|
process_media_player_call(
|
||||||
audioRate.mSpeed = 1.0f;
|
env, thiz, mp->getPlaybackSettings(&audioRate),
|
||||||
audioRate.mPitch = 1.0f;
|
"java/lang/IllegalStateException", "unexpected error");
|
||||||
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",
|
ALOGV("getPlaybackSettings: %f %f %d %d",
|
||||||
audioRate.mSpeed, audioRate.mPitch, audioRate.mFallbackMode, audioRate.mStretchMode);
|
audioRate.mSpeed, audioRate.mPitch, audioRate.mFallbackMode, audioRate.mStretchMode);
|
||||||
|
|
||||||
@@ -489,13 +510,35 @@ android_media_MediaPlayer_setSyncSettings(JNIEnv *env, jobject thiz, jobject set
|
|||||||
SyncSettings scs;
|
SyncSettings scs;
|
||||||
scs.fillFromJobject(env, gSyncSettingsFields, settings);
|
scs.fillFromJobject(env, gSyncSettingsFields, settings);
|
||||||
ALOGV("setSyncSettings: %d:%d %d:%d %d:%f %d:%f",
|
ALOGV("setSyncSettings: %d:%d %d:%d %d:%f %d:%f",
|
||||||
scs.syncSourceSet, scs.syncSource,
|
scs.syncSourceSet, scs.sync.mSource,
|
||||||
scs.audioAdjustModeSet, scs.audioAdjustMode,
|
scs.audioAdjustModeSet, scs.sync.mAudioAdjustMode,
|
||||||
scs.toleranceSet, scs.tolerance,
|
scs.toleranceSet, scs.sync.mTolerance,
|
||||||
scs.frameRateSet, scs.frameRate);
|
scs.frameRateSet, scs.frameRate);
|
||||||
|
|
||||||
// TODO: pass sync settings to mediaplayer when it supports it
|
AVSyncSettings avsync;
|
||||||
// process_media_player_call(env, thiz, mp->setSyncSettings(scs), NULL, NULL);
|
float videoFrameRate;
|
||||||
|
status_t err = mp->getSyncSettings(&avsync, &videoFrameRate);
|
||||||
|
if (err == OK) {
|
||||||
|
bool updatedSync = scs.frameRateSet;
|
||||||
|
if (scs.syncSourceSet) {
|
||||||
|
avsync.mSource = scs.sync.mSource;
|
||||||
|
updatedSync = true;
|
||||||
|
}
|
||||||
|
if (scs.audioAdjustModeSet) {
|
||||||
|
avsync.mAudioAdjustMode = scs.sync.mAudioAdjustMode;
|
||||||
|
updatedSync = true;
|
||||||
|
}
|
||||||
|
if (scs.toleranceSet) {
|
||||||
|
avsync.mTolerance = scs.sync.mTolerance;
|
||||||
|
updatedSync = true;
|
||||||
|
}
|
||||||
|
if (updatedSync) {
|
||||||
|
err = mp->setSyncSettings(avsync, scs.frameRateSet ? scs.frameRate : -1.f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
process_media_player_call(
|
||||||
|
env, thiz, err,
|
||||||
|
"java/lang/IllegalStateException", "unexpected error");
|
||||||
}
|
}
|
||||||
|
|
||||||
static jobject
|
static jobject
|
||||||
@@ -508,21 +551,27 @@ android_media_MediaPlayer_getSyncSettings(JNIEnv *env, jobject thiz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SyncSettings scs;
|
SyncSettings scs;
|
||||||
scs.syncSource = 0; // SYNC_SOURCE_DEFAULT
|
scs.frameRate = -1.f;
|
||||||
scs.audioAdjustMode = 0; // AUDIO_ADJUST_MODE_DEFAULT
|
process_media_player_call(
|
||||||
scs.tolerance = 0.f;
|
env, thiz, mp->getSyncSettings(&scs.sync, &scs.frameRate),
|
||||||
scs.frameRate = 0.f;
|
"java/lang/IllegalStateException", "unexpected error");
|
||||||
|
|
||||||
// TODO: get this from mediaplayer when it supports it
|
|
||||||
// process_media_player_call(
|
|
||||||
// env, thiz, mp->getSyncSettings(&scs), NULL, NULL);
|
|
||||||
ALOGV("getSyncSettings: %d %d %f %f",
|
ALOGV("getSyncSettings: %d %d %f %f",
|
||||||
scs.syncSource, scs.audioAdjustMode, scs.tolerance, scs.frameRate);
|
scs.sync.mSource, scs.sync.mAudioAdjustMode, scs.sync.mTolerance, scs.frameRate);
|
||||||
|
|
||||||
|
// sanity check settings
|
||||||
|
if (scs.sync.mSource >= AVSYNC_SOURCE_MAX
|
||||||
|
|| scs.sync.mAudioAdjustMode >= AVSYNC_AUDIO_ADJUST_MODE_MAX
|
||||||
|
|| scs.sync.mTolerance < 0.f
|
||||||
|
|| scs.sync.mTolerance >= AVSYNC_TOLERANCE_MAX) {
|
||||||
|
jniThrowException(env, "java/lang/IllegalStateException", NULL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
scs.syncSourceSet = true;
|
scs.syncSourceSet = true;
|
||||||
scs.audioAdjustModeSet = true;
|
scs.audioAdjustModeSet = true;
|
||||||
scs.toleranceSet = true;
|
scs.toleranceSet = true;
|
||||||
scs.frameRateSet = false;
|
scs.frameRateSet = scs.frameRate >= 0.f;
|
||||||
|
|
||||||
return scs.asJobject(env, gSyncSettingsFields);
|
return scs.asJobject(env, gSyncSettingsFields);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "android_media_MediaSync.h"
|
#include "android_media_MediaSync.h"
|
||||||
|
|
||||||
#include "android_media_AudioTrack.h"
|
#include "android_media_AudioTrack.h"
|
||||||
|
#include "android_media_PlaybackSettings.h"
|
||||||
#include "android_media_SyncSettings.h"
|
#include "android_media_SyncSettings.h"
|
||||||
#include "android_runtime/AndroidRuntime.h"
|
#include "android_runtime/AndroidRuntime.h"
|
||||||
#include "android_runtime/android_view_Surface.h"
|
#include "android_runtime/android_view_Surface.h"
|
||||||
@@ -29,6 +30,7 @@
|
|||||||
|
|
||||||
#include <gui/Surface.h>
|
#include <gui/Surface.h>
|
||||||
|
|
||||||
|
#include <media/AudioResamplerPublic.h>
|
||||||
#include <media/AudioTrack.h>
|
#include <media/AudioTrack.h>
|
||||||
#include <media/stagefright/MediaClock.h>
|
#include <media/stagefright/MediaClock.h>
|
||||||
#include <media/stagefright/MediaSync.h>
|
#include <media/stagefright/MediaSync.h>
|
||||||
@@ -47,6 +49,7 @@ struct fields_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static fields_t gFields;
|
static fields_t gFields;
|
||||||
|
static PlaybackSettings::fields_t gPlaybackSettingsFields;
|
||||||
static SyncSettings::fields_t gSyncSettingsFields;
|
static SyncSettings::fields_t gSyncSettingsFields;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -62,10 +65,8 @@ status_t JMediaSync::configureSurface(const sp<IGraphicBufferProducer> &bufferPr
|
|||||||
return mSync->configureSurface(bufferProducer);
|
return mSync->configureSurface(bufferProducer);
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t JMediaSync::configureAudioTrack(
|
status_t JMediaSync::configureAudioTrack(const sp<AudioTrack> &audioTrack) {
|
||||||
const sp<AudioTrack> &audioTrack,
|
return mSync->configureAudioTrack(audioTrack);
|
||||||
int32_t nativeSampleRateInHz) {
|
|
||||||
return mSync->configureAudioTrack(audioTrack, nativeSampleRateInHz);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t JMediaSync::createInputSurface(
|
status_t JMediaSync::createInputSurface(
|
||||||
@@ -73,14 +74,34 @@ status_t JMediaSync::createInputSurface(
|
|||||||
return mSync->createInputSurface(bufferProducer);
|
return mSync->createInputSurface(bufferProducer);
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t JMediaSync::setPlaybackRate(float rate) {
|
|
||||||
return mSync->setPlaybackRate(rate);
|
|
||||||
}
|
|
||||||
|
|
||||||
sp<const MediaClock> JMediaSync::getMediaClock() {
|
sp<const MediaClock> JMediaSync::getMediaClock() {
|
||||||
return mSync->getMediaClock();
|
return mSync->getMediaClock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t JMediaSync::setPlaybackSettings(const AudioPlaybackRate& rate) {
|
||||||
|
return mSync->setPlaybackSettings(rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JMediaSync::getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */) {
|
||||||
|
mSync->getPlaybackSettings(rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t JMediaSync::setSyncSettings(const AVSyncSettings& syncSettings) {
|
||||||
|
return mSync->setSyncSettings(syncSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JMediaSync::getSyncSettings(AVSyncSettings* syncSettings /* nonnull */) {
|
||||||
|
mSync->getSyncSettings(syncSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t JMediaSync::setVideoFrameRateHint(float rate) {
|
||||||
|
return mSync->setVideoFrameRateHint(rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
float JMediaSync::getVideoFrameRate() {
|
||||||
|
return mSync->getVideoFrameRate();
|
||||||
|
}
|
||||||
|
|
||||||
status_t JMediaSync::updateQueuedAudioData(
|
status_t JMediaSync::updateQueuedAudioData(
|
||||||
int sizeInBytes, int64_t presentationTimeUs) {
|
int sizeInBytes, int64_t presentationTimeUs) {
|
||||||
return mSync->updateQueuedAudioData(sizeInBytes, presentationTimeUs);
|
return mSync->updateQueuedAudioData(sizeInBytes, presentationTimeUs);
|
||||||
@@ -176,7 +197,7 @@ static void android_media_MediaSync_native_configureSurface(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void android_media_MediaSync_native_configureAudioTrack(
|
static void android_media_MediaSync_native_configureAudioTrack(
|
||||||
JNIEnv *env, jobject thiz, jobject jaudioTrack, jint nativeSampleRateInHz) {
|
JNIEnv *env, jobject thiz, jobject jaudioTrack) {
|
||||||
ALOGV("android_media_MediaSync_configureAudioTrack");
|
ALOGV("android_media_MediaSync_configureAudioTrack");
|
||||||
|
|
||||||
sp<JMediaSync> sync = getMediaSync(env, thiz);
|
sp<JMediaSync> sync = getMediaSync(env, thiz);
|
||||||
@@ -194,7 +215,7 @@ static void android_media_MediaSync_native_configureAudioTrack(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t err = sync->configureAudioTrack(audioTrack, nativeSampleRateInHz);
|
status_t err = sync->configureAudioTrack(audioTrack);
|
||||||
|
|
||||||
if (err == INVALID_OPERATION) {
|
if (err == INVALID_OPERATION) {
|
||||||
throwExceptionAsNecessary(
|
throwExceptionAsNecessary(
|
||||||
@@ -287,29 +308,132 @@ static jlong android_media_MediaSync_native_getPlayTimeForPendingAudioFrames(
|
|||||||
return (jlong)playTimeUs;
|
return (jlong)playTimeUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static jfloat android_media_MediaSync_setPlaybackSettings(
|
||||||
android_media_MediaSync_setSyncSettings(JNIEnv *env, jobject thiz, jobject settings)
|
JNIEnv *env, jobject thiz, jobject settings) {
|
||||||
{
|
|
||||||
sp<JMediaSync> sync = getMediaSync(env, thiz);
|
sp<JMediaSync> sync = getMediaSync(env, thiz);
|
||||||
if (sync == NULL) {
|
if (sync == NULL) {
|
||||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||||
return;
|
return (jfloat)0.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
AudioPlaybackRate rate;
|
||||||
|
sync->getPlaybackSettings(&rate);
|
||||||
|
bool updatedRate = false;
|
||||||
|
if (pbs.speedSet) {
|
||||||
|
rate.mSpeed = pbs.audioRate.mSpeed;
|
||||||
|
updatedRate = true;
|
||||||
|
}
|
||||||
|
if (pbs.pitchSet) {
|
||||||
|
rate.mPitch = pbs.audioRate.mPitch;
|
||||||
|
updatedRate = true;
|
||||||
|
}
|
||||||
|
if (pbs.audioFallbackModeSet) {
|
||||||
|
rate.mFallbackMode = pbs.audioRate.mFallbackMode;
|
||||||
|
updatedRate = true;
|
||||||
|
}
|
||||||
|
if (pbs.audioStretchModeSet) {
|
||||||
|
rate.mStretchMode = pbs.audioRate.mStretchMode;
|
||||||
|
updatedRate = true;
|
||||||
|
}
|
||||||
|
if (updatedRate) {
|
||||||
|
status_t err = sync->setPlaybackSettings(rate);
|
||||||
|
if (err != OK) {
|
||||||
|
throwExceptionAsNecessary(env, err);
|
||||||
|
return (jfloat)0.f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sp<const MediaClock> mediaClock = sync->getMediaClock();
|
||||||
|
if (mediaClock == NULL) {
|
||||||
|
return (jfloat)0.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (jfloat)mediaClock->getPlaybackRate();
|
||||||
|
}
|
||||||
|
|
||||||
|
static jobject android_media_MediaSync_getPlaybackSettings(
|
||||||
|
JNIEnv *env, jobject thiz) {
|
||||||
|
sp<JMediaSync> sync = getMediaSync(env, thiz);
|
||||||
|
if (sync == NULL) {
|
||||||
|
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PlaybackSettings pbs;
|
||||||
|
AudioPlaybackRate &audioRate = pbs.audioRate;
|
||||||
|
sync->getPlaybackSettings(&audioRate);
|
||||||
|
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 jfloat android_media_MediaSync_setSyncSettings(
|
||||||
|
JNIEnv *env, jobject thiz, jobject settings) {
|
||||||
|
sp<JMediaSync> sync = getMediaSync(env, thiz);
|
||||||
|
if (sync == NULL) {
|
||||||
|
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||||
|
return (jfloat)0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
SyncSettings scs;
|
SyncSettings scs;
|
||||||
scs.fillFromJobject(env, gSyncSettingsFields, settings);
|
scs.fillFromJobject(env, gSyncSettingsFields, settings);
|
||||||
ALOGV("setSyncSettings: %d:%d %d:%d %d:%f %d:%f",
|
ALOGV("setSyncSettings: %d:%d %d:%d %d:%f %d:%f",
|
||||||
scs.syncSourceSet, scs.syncSource,
|
scs.syncSourceSet, scs.sync.mSource,
|
||||||
scs.audioAdjustModeSet, scs.audioAdjustMode,
|
scs.audioAdjustModeSet, scs.sync.mAudioAdjustMode,
|
||||||
scs.toleranceSet, scs.tolerance,
|
scs.toleranceSet, scs.sync.mTolerance,
|
||||||
scs.frameRateSet, scs.frameRate);
|
scs.frameRateSet, scs.frameRate);
|
||||||
|
|
||||||
// TODO: pass sync settings to mediasync when it supports it
|
AVSyncSettings avsync;
|
||||||
|
sync->getSyncSettings(&avsync);
|
||||||
|
bool updatedSync = false;
|
||||||
|
status_t err = OK;
|
||||||
|
if (scs.syncSourceSet) {
|
||||||
|
avsync.mSource = scs.sync.mSource;
|
||||||
|
updatedSync = true;
|
||||||
|
}
|
||||||
|
if (scs.audioAdjustModeSet) {
|
||||||
|
avsync.mAudioAdjustMode = scs.sync.mAudioAdjustMode;
|
||||||
|
updatedSync = true;
|
||||||
|
}
|
||||||
|
if (scs.toleranceSet) {
|
||||||
|
avsync.mTolerance = scs.sync.mTolerance;
|
||||||
|
updatedSync = true;
|
||||||
|
}
|
||||||
|
if (updatedSync) {
|
||||||
|
err = sync->setSyncSettings(avsync);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scs.frameRateSet && err == OK) {
|
||||||
|
err = sync->setVideoFrameRateHint(scs.frameRate);
|
||||||
|
}
|
||||||
|
if (err != OK) {
|
||||||
|
throwExceptionAsNecessary(env, err);
|
||||||
|
return (jfloat)0.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp<const MediaClock> mediaClock = sync->getMediaClock();
|
||||||
|
if (mediaClock == NULL) {
|
||||||
|
return (jfloat)0.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (jfloat)mediaClock->getPlaybackRate();
|
||||||
}
|
}
|
||||||
|
|
||||||
static jobject
|
static jobject android_media_MediaSync_getSyncSettings(JNIEnv *env, jobject thiz) {
|
||||||
android_media_MediaSync_getSyncSettings(JNIEnv *env, jobject thiz)
|
|
||||||
{
|
|
||||||
sp<JMediaSync> sync = getMediaSync(env, thiz);
|
sp<JMediaSync> sync = getMediaSync(env, thiz);
|
||||||
if (sync == NULL) {
|
if (sync == NULL) {
|
||||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||||
@@ -317,21 +441,25 @@ android_media_MediaSync_getSyncSettings(JNIEnv *env, jobject thiz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SyncSettings scs;
|
SyncSettings scs;
|
||||||
scs.syncSource = 0; // SYNC_SOURCE_DEFAULT
|
sync->getSyncSettings(&scs.sync);
|
||||||
scs.audioAdjustMode = 0; // AUDIO_ADJUST_MODE_DEFAULT
|
scs.frameRate = sync->getVideoFrameRate();
|
||||||
scs.tolerance = 0.f;
|
|
||||||
scs.frameRate = 0.f;
|
|
||||||
|
|
||||||
// TODO: get this from mediaplayer when it supports it
|
|
||||||
// process_media_player_call(
|
|
||||||
// env, thiz, mp->getSyncSettings(&scs), NULL, NULL);
|
|
||||||
ALOGV("getSyncSettings: %d %d %f %f",
|
ALOGV("getSyncSettings: %d %d %f %f",
|
||||||
scs.syncSource, scs.audioAdjustMode, scs.tolerance, scs.frameRate);
|
scs.sync.mSource, scs.sync.mAudioAdjustMode, scs.sync.mTolerance, scs.frameRate);
|
||||||
|
|
||||||
|
// sanity check settings
|
||||||
|
if (scs.sync.mSource >= AVSYNC_SOURCE_MAX
|
||||||
|
|| scs.sync.mAudioAdjustMode >= AVSYNC_AUDIO_ADJUST_MODE_MAX
|
||||||
|
|| scs.sync.mTolerance < 0.f
|
||||||
|
|| scs.sync.mTolerance >= AVSYNC_TOLERANCE_MAX) {
|
||||||
|
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
scs.syncSourceSet = true;
|
scs.syncSourceSet = true;
|
||||||
scs.audioAdjustModeSet = true;
|
scs.audioAdjustModeSet = true;
|
||||||
scs.toleranceSet = true;
|
scs.toleranceSet = true;
|
||||||
scs.frameRateSet = false;
|
scs.frameRateSet = scs.frameRate >= 0.f;
|
||||||
|
|
||||||
return scs.asJobject(env, gSyncSettingsFields);
|
return scs.asJobject(env, gSyncSettingsFields);
|
||||||
}
|
}
|
||||||
@@ -359,6 +487,7 @@ static void android_media_MediaSync_native_init(JNIEnv *env) {
|
|||||||
CHECK(gFields.mediaTimestampClockRateID != NULL);
|
CHECK(gFields.mediaTimestampClockRateID != NULL);
|
||||||
|
|
||||||
gSyncSettingsFields.init(env);
|
gSyncSettingsFields.init(env);
|
||||||
|
gPlaybackSettingsFields.init(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void android_media_MediaSync_native_setup(JNIEnv *env, jobject thiz) {
|
static void android_media_MediaSync_native_setup(JNIEnv *env, jobject thiz) {
|
||||||
@@ -367,21 +496,6 @@ static void android_media_MediaSync_native_setup(JNIEnv *env, jobject thiz) {
|
|||||||
setMediaSync(env, thiz, sync);
|
setMediaSync(env, thiz, sync);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void android_media_MediaSync_native_setPlaybackRate(
|
|
||||||
JNIEnv *env, jobject thiz, jfloat rate) {
|
|
||||||
sp<JMediaSync> sync = getMediaSync(env, thiz);
|
|
||||||
if (sync == NULL) {
|
|
||||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t err = sync->setPlaybackRate(rate);
|
|
||||||
if (err != NO_ERROR) {
|
|
||||||
throwExceptionAsNecessary(env, err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void android_media_MediaSync_native_finalize(JNIEnv *env, jobject thiz) {
|
static void android_media_MediaSync_native_finalize(JNIEnv *env, jobject thiz) {
|
||||||
android_media_MediaSync_release(env, thiz);
|
android_media_MediaSync_release(env, thiz);
|
||||||
}
|
}
|
||||||
@@ -416,11 +530,17 @@ static JNINativeMethod gMethods[] = {
|
|||||||
|
|
||||||
{ "native_release", "()V", (void *)android_media_MediaSync_release },
|
{ "native_release", "()V", (void *)android_media_MediaSync_release },
|
||||||
|
|
||||||
{ "native_setPlaybackRate", "(F)V", (void *)android_media_MediaSync_native_setPlaybackRate },
|
{ "native_setPlaybackSettings", "(Landroid/media/PlaybackSettings;)F",
|
||||||
|
(void *)android_media_MediaSync_setPlaybackSettings },
|
||||||
|
|
||||||
{ "setSyncSettings", "(Landroid/media/SyncSettings;)V", (void *)android_media_MediaSync_setSyncSettings},
|
{ "getPlaybackSettings", "()Landroid/media/PlaybackSettings;",
|
||||||
|
(void *)android_media_MediaSync_getPlaybackSettings },
|
||||||
|
|
||||||
{ "getSyncSettings", "()Landroid/media/SyncSettings;", (void *)android_media_MediaSync_getSyncSettings},
|
{ "native_setSyncSettings", "(Landroid/media/SyncSettings;)F",
|
||||||
|
(void *)android_media_MediaSync_setSyncSettings },
|
||||||
|
|
||||||
|
{ "getSyncSettings", "()Landroid/media/SyncSettings;",
|
||||||
|
(void *)android_media_MediaSync_getSyncSettings },
|
||||||
|
|
||||||
{ "native_finalize", "()V", (void *)android_media_MediaSync_native_finalize },
|
{ "native_finalize", "()V", (void *)android_media_MediaSync_native_finalize },
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,11 +18,13 @@
|
|||||||
#define _ANDROID_MEDIA_MEDIASYNC_H_
|
#define _ANDROID_MEDIA_MEDIASYNC_H_
|
||||||
|
|
||||||
#include <media/stagefright/foundation/ABase.h>
|
#include <media/stagefright/foundation/ABase.h>
|
||||||
|
#include <media/stagefright/MediaSync.h>
|
||||||
#include <utils/Errors.h>
|
#include <utils/Errors.h>
|
||||||
#include <utils/RefBase.h>
|
#include <utils/RefBase.h>
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
|
struct AudioPlaybackRate;
|
||||||
class AudioTrack;
|
class AudioTrack;
|
||||||
struct IGraphicBufferProducer;
|
struct IGraphicBufferProducer;
|
||||||
struct MediaClock;
|
struct MediaClock;
|
||||||
@@ -32,17 +34,21 @@ struct JMediaSync : public RefBase {
|
|||||||
JMediaSync();
|
JMediaSync();
|
||||||
|
|
||||||
status_t configureSurface(const sp<IGraphicBufferProducer> &bufferProducer);
|
status_t configureSurface(const sp<IGraphicBufferProducer> &bufferProducer);
|
||||||
status_t configureAudioTrack(
|
status_t configureAudioTrack(const sp<AudioTrack> &audioTrack);
|
||||||
const sp<AudioTrack> &audioTrack, int32_t nativeSampleRateInHz);
|
|
||||||
|
|
||||||
status_t createInputSurface(sp<IGraphicBufferProducer>* bufferProducer);
|
status_t createInputSurface(sp<IGraphicBufferProducer>* bufferProducer);
|
||||||
|
|
||||||
status_t updateQueuedAudioData(int sizeInBytes, int64_t presentationTimeUs);
|
status_t updateQueuedAudioData(int sizeInBytes, int64_t presentationTimeUs);
|
||||||
|
|
||||||
status_t setPlaybackRate(float rate);
|
|
||||||
|
|
||||||
status_t getPlayTimeForPendingAudioFrames(int64_t *outTimeUs);
|
status_t getPlayTimeForPendingAudioFrames(int64_t *outTimeUs);
|
||||||
|
|
||||||
|
status_t setPlaybackSettings(const AudioPlaybackRate& rate);
|
||||||
|
void getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */);
|
||||||
|
status_t setSyncSettings(const AVSyncSettings& syncSettings);
|
||||||
|
void getSyncSettings(AVSyncSettings* syncSettings /* nonnull */);
|
||||||
|
status_t setVideoFrameRateHint(float rate);
|
||||||
|
float getVideoFrameRate();
|
||||||
|
|
||||||
sp<const MediaClock> getMediaClock();
|
sp<const MediaClock> getMediaClock();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -57,9 +57,9 @@ void SyncSettings::fields_t::exit(JNIEnv *env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SyncSettings::fillFromJobject(JNIEnv *env, const fields_t& fields, jobject settings) {
|
void SyncSettings::fillFromJobject(JNIEnv *env, const fields_t& fields, jobject settings) {
|
||||||
syncSource = env->GetIntField(settings, fields.sync_source);
|
sync.mSource = (AVSyncSource)env->GetIntField(settings, fields.sync_source);
|
||||||
audioAdjustMode = env->GetIntField(settings, fields.audio_adjust_mode);
|
sync.mAudioAdjustMode = (AVSyncAudioAdjustMode)env->GetIntField(settings, fields.audio_adjust_mode);
|
||||||
tolerance = env->GetFloatField(settings, fields.tolerance);
|
sync.mTolerance = env->GetFloatField(settings, fields.tolerance);
|
||||||
frameRate = env->GetFloatField(settings, fields.frame_rate);
|
frameRate = env->GetFloatField(settings, fields.frame_rate);
|
||||||
int set = env->GetIntField(settings, fields.set);
|
int set = env->GetIntField(settings, fields.set);
|
||||||
|
|
||||||
@@ -74,9 +74,9 @@ jobject SyncSettings::asJobject(JNIEnv *env, const fields_t& fields) {
|
|||||||
if (settings == NULL) {
|
if (settings == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
env->SetIntField(settings, fields.sync_source, (jint)syncSource);
|
env->SetIntField(settings, fields.sync_source, (jint)sync.mSource);
|
||||||
env->SetIntField(settings, fields.audio_adjust_mode, (jint)audioAdjustMode);
|
env->SetIntField(settings, fields.audio_adjust_mode, (jint)sync.mAudioAdjustMode);
|
||||||
env->SetFloatField(settings, fields.tolerance, (jfloat)tolerance);
|
env->SetFloatField(settings, fields.tolerance, (jfloat)sync.mTolerance);
|
||||||
env->SetFloatField(settings, fields.frame_rate, (jfloat)frameRate);
|
env->SetFloatField(settings, fields.frame_rate, (jfloat)frameRate);
|
||||||
env->SetIntField(
|
env->SetIntField(
|
||||||
settings, fields.set,
|
settings, fields.set,
|
||||||
|
|||||||
@@ -19,13 +19,12 @@
|
|||||||
|
|
||||||
#include "jni.h"
|
#include "jni.h"
|
||||||
|
|
||||||
|
#include <media/stagefright/MediaSync.h>
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
struct SyncSettings {
|
struct SyncSettings {
|
||||||
// keep this here until it is implemented
|
AVSyncSettings sync;
|
||||||
int syncSource;
|
|
||||||
int audioAdjustMode;
|
|
||||||
float tolerance;
|
|
||||||
float frameRate;
|
float frameRate;
|
||||||
|
|
||||||
bool syncSourceSet;
|
bool syncSourceSet;
|
||||||
|
|||||||
Reference in New Issue
Block a user