summaryrefslogtreecommitdiff
path: root/android/media
diff options
context:
space:
mode:
authorJustin Klaassen <justinklaassen@google.com>2017-09-18 17:38:50 -0400
committerJustin Klaassen <justinklaassen@google.com>2017-09-18 17:38:50 -0400
commitbc81c7ada5aab3806dd0b17498f5c9672c9b33c4 (patch)
tree7fdcc541a9ac9e92134f1a80cec557fee772bcf8 /android/media
parent10d07c88d69cc64f73a069163e7ea5ba2519a099 (diff)
downloadandroid-28-bc81c7ada5aab3806dd0b17498f5c9672c9b33c4.tar.gz
Import Android SDK Platform P [4344336]
/google/data/ro/projects/android/fetch_artifact \ --bid 4344336 \ --target sdk_phone_armv7-win_sdk \ sdk-repo-linux-sources-4344336.zip AndroidVersion.ApiLevel has been modified to appear as 28 Change-Id: If482fcd4cfaf6c5e544e5574926be25a293e9a6d
Diffstat (limited to 'android/media')
-rw-r--r--android/media/AudioManager.java6
-rw-r--r--android/media/AudioPlaybackConfiguration.java52
-rw-r--r--android/media/MediaMuxer.java2
-rw-r--r--android/media/MediaPlayer.java124
-rw-r--r--android/media/MediaRouter.java4
5 files changed, 110 insertions, 78 deletions
diff --git a/android/media/AudioManager.java b/android/media/AudioManager.java
index 15754574..186b2650 100644
--- a/android/media/AudioManager.java
+++ b/android/media/AudioManager.java
@@ -3058,7 +3058,11 @@ public class AudioManager {
private final IPlaybackConfigDispatcher mPlayCb = new IPlaybackConfigDispatcher.Stub() {
@Override
- public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs) {
+ public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs,
+ boolean flush) {
+ if (flush) {
+ Binder.flushPendingCommands();
+ }
synchronized(mPlaybackCallbackLock) {
if (mPlaybackCallbackList != null) {
for (int i=0 ; i < mPlaybackCallbackList.size() ; i++) {
diff --git a/android/media/AudioPlaybackConfiguration.java b/android/media/AudioPlaybackConfiguration.java
index 14bc5551..8a36f91c 100644
--- a/android/media/AudioPlaybackConfiguration.java
+++ b/android/media/AudioPlaybackConfiguration.java
@@ -212,8 +212,10 @@ public final class AudioPlaybackConfiguration implements Parcelable {
* @hide
*/
public void init() {
- if (mIPlayerShell != null) {
- mIPlayerShell.monitorDeath();
+ synchronized (this) {
+ if (mIPlayerShell != null) {
+ mIPlayerShell.monitorDeath();
+ }
}
}
@@ -322,7 +324,11 @@ public final class AudioPlaybackConfiguration implements Parcelable {
*/
@SystemApi
public PlayerProxy getPlayerProxy() {
- return mIPlayerShell == null ? null : new PlayerProxy(this);
+ final IPlayerShell ips;
+ synchronized (this) {
+ ips = mIPlayerShell;
+ }
+ return ips == null ? null : new PlayerProxy(this);
}
/**
@@ -330,7 +336,11 @@ public final class AudioPlaybackConfiguration implements Parcelable {
* @return the IPlayer interface for the associated player
*/
IPlayer getIPlayer() {
- return mIPlayerShell == null ? null : mIPlayerShell.getIPlayer();
+ final IPlayerShell ips;
+ synchronized (this) {
+ ips = mIPlayerShell;
+ }
+ return ips == null ? null : ips.getIPlayer();
}
/**
@@ -351,10 +361,14 @@ public final class AudioPlaybackConfiguration implements Parcelable {
* @return true if the state changed, false otherwise
*/
public boolean handleStateEvent(int event) {
- final boolean changed = (mPlayerState != event);
- mPlayerState = event;
- if ((event == PLAYER_STATE_RELEASED) && (mIPlayerShell != null)) {
- mIPlayerShell.release();
+ final boolean changed;
+ synchronized (this) {
+ changed = (mPlayerState != event);
+ mPlayerState = event;
+ if (changed && (event == PLAYER_STATE_RELEASED) && (mIPlayerShell != null)) {
+ mIPlayerShell.release();
+ mIPlayerShell = null;
+ }
}
return changed;
}
@@ -447,7 +461,11 @@ public final class AudioPlaybackConfiguration implements Parcelable {
dest.writeInt(mClientPid);
dest.writeInt(mPlayerState);
mPlayerAttr.writeToParcel(dest, 0);
- dest.writeStrongInterface(mIPlayerShell == null ? null : mIPlayerShell.getIPlayer());
+ final IPlayerShell ips;
+ synchronized (this) {
+ ips = mIPlayerShell;
+ }
+ dest.writeStrongInterface(ips == null ? null : ips.getIPlayer());
}
private AudioPlaybackConfiguration(Parcel in) {
@@ -479,14 +497,17 @@ public final class AudioPlaybackConfiguration implements Parcelable {
static final class IPlayerShell implements IBinder.DeathRecipient {
final AudioPlaybackConfiguration mMonitor; // never null
- private IPlayer mIPlayer;
+ private volatile IPlayer mIPlayer;
IPlayerShell(@NonNull AudioPlaybackConfiguration monitor, @NonNull IPlayer iplayer) {
mMonitor = monitor;
mIPlayer = iplayer;
}
- void monitorDeath() {
+ synchronized void monitorDeath() {
+ if (mIPlayer == null) {
+ return;
+ }
try {
mIPlayer.asBinder().linkToDeath(this, 0);
} catch (RemoteException e) {
@@ -509,8 +530,13 @@ public final class AudioPlaybackConfiguration implements Parcelable {
} else if (DEBUG) { Log.i(TAG, "IPlayerShell binderDied"); }
}
- void release() {
+ synchronized void release() {
+ if (mIPlayer == null) {
+ return;
+ }
mIPlayer.asBinder().unlinkToDeath(this, 0);
+ mIPlayer = null;
+ Binder.flushPendingCommands();
}
}
@@ -532,7 +558,7 @@ public final class AudioPlaybackConfiguration implements Parcelable {
case PLAYER_TYPE_HW_SOURCE: return "hardware source";
case PLAYER_TYPE_EXTERNAL_PROXY: return "external proxy";
default:
- return "unknown player type - FIXME";
+ return "unknown player type " + type + " - FIXME";
}
}
diff --git a/android/media/MediaMuxer.java b/android/media/MediaMuxer.java
index 832b2974..91e57ee0 100644
--- a/android/media/MediaMuxer.java
+++ b/android/media/MediaMuxer.java
@@ -70,7 +70,7 @@ import java.util.Map;
<p>
Per-frame metadata is useful in carrying extra information that correlated with video or audio to
facilitate offline processing, e.g. gyro signals from the sensor could help video stabilization when
- doing offline processing. Metaadata track is only supported in MP4 container. When adding a new
+ doing offline processing. Metadata track is only supported in MP4 container. When adding a new
metadata track, track's mime format must start with prefix "application/", e.g. "applicaton/gyro".
Metadata's format/layout will be defined by the application. Writing metadata is nearly the same as
writing video/audio data except that the data will not be from mediacodec. Application just needs
diff --git a/android/media/MediaPlayer.java b/android/media/MediaPlayer.java
index 0d99473c..7787d4b5 100644
--- a/android/media/MediaPlayer.java
+++ b/android/media/MediaPlayer.java
@@ -2072,6 +2072,20 @@ public class MediaPlayer extends PlayerBase
private native void _reset();
/**
+ * Set up a timer for {@link #TimeProvider}. {@link #TimeProvider} will be
+ * notified when the presentation time reaches (becomes greater than or equal to)
+ * the value specified.
+ *
+ * @param mediaTimeUs presentation time to get timed event callback at
+ * @hide
+ */
+ public void notifyAt(long mediaTimeUs) {
+ _notifyAt(mediaTimeUs);
+ }
+
+ private native void _notifyAt(long mediaTimeUs);
+
+ /**
* Sets the audio stream type for this MediaPlayer. See {@link AudioManager}
* for a list of stream types. Must call this method before prepare() or
* prepareAsync() in order for the target stream type to become effective
@@ -3155,6 +3169,7 @@ public class MediaPlayer extends PlayerBase
private static final int MEDIA_PAUSED = 7;
private static final int MEDIA_STOPPED = 8;
private static final int MEDIA_SKIPPED = 9;
+ private static final int MEDIA_NOTIFY_TIME = 98;
private static final int MEDIA_TIMED_TEXT = 99;
private static final int MEDIA_ERROR = 100;
private static final int MEDIA_INFO = 200;
@@ -3345,6 +3360,14 @@ public class MediaPlayer extends PlayerBase
}
// No real default action so far.
return;
+
+ case MEDIA_NOTIFY_TIME:
+ TimeProvider timeProvider = mTimeProvider;
+ if (timeProvider != null) {
+ timeProvider.onNotifyTime();
+ }
+ return;
+
case MEDIA_TIMED_TEXT:
OnTimedTextListener onTimedTextListener = mOnTimedTextListener;
if (onTimedTextListener == null)
@@ -5144,19 +5167,16 @@ public class MediaPlayer extends PlayerBase
private boolean mStopped = true;
private boolean mBuffering;
private long mLastReportedTime;
- private long mTimeAdjustment;
// since we are expecting only a handful listeners per stream, there is
// no need for log(N) search performance
private MediaTimeProvider.OnMediaTimeListener mListeners[];
private long mTimes[];
- private long mLastNanoTime;
private Handler mEventHandler;
private boolean mRefresh = false;
private boolean mPausing = false;
private boolean mSeeking = false;
private static final int NOTIFY = 1;
private static final int NOTIFY_TIME = 0;
- private static final int REFRESH_AND_NOTIFY_TIME = 1;
private static final int NOTIFY_STOP = 2;
private static final int NOTIFY_SEEK = 3;
private static final int NOTIFY_TRACK_DATA = 4;
@@ -5188,13 +5208,11 @@ public class MediaPlayer extends PlayerBase
mListeners = new MediaTimeProvider.OnMediaTimeListener[0];
mTimes = new long[0];
mLastTimeUs = 0;
- mTimeAdjustment = 0;
}
private void scheduleNotification(int type, long delayUs) {
// ignore time notifications until seek is handled
- if (mSeeking &&
- (type == NOTIFY_TIME || type == REFRESH_AND_NOTIFY_TIME)) {
+ if (mSeeking && type == NOTIFY_TIME) {
return;
}
@@ -5221,6 +5239,14 @@ public class MediaPlayer extends PlayerBase
}
/** @hide */
+ public void onNotifyTime() {
+ synchronized (this) {
+ if (DEBUG) Log.d(TAG, "onNotifyTime: ");
+ scheduleNotification(NOTIFY_TIME, 0 /* delay */);
+ }
+ }
+
+ /** @hide */
public void onPaused(boolean paused) {
synchronized(this) {
if (DEBUG) Log.d(TAG, "onPaused: " + paused);
@@ -5231,7 +5257,7 @@ public class MediaPlayer extends PlayerBase
} else {
mPausing = paused; // special handling if player disappeared
mSeeking = false;
- scheduleNotification(REFRESH_AND_NOTIFY_TIME, 0 /* delay */);
+ scheduleNotification(NOTIFY_TIME, 0 /* delay */);
}
}
}
@@ -5241,7 +5267,7 @@ public class MediaPlayer extends PlayerBase
synchronized (this) {
if (DEBUG) Log.d(TAG, "onBuffering: " + buffering);
mBuffering = buffering;
- scheduleNotification(REFRESH_AND_NOTIFY_TIME, 0 /* delay */);
+ scheduleNotification(NOTIFY_TIME, 0 /* delay */);
}
}
@@ -5438,7 +5464,7 @@ public class MediaPlayer extends PlayerBase
if (nextTimeUs > nowUs && !mPaused) {
// schedule callback at nextTimeUs
if (DEBUG) Log.d(TAG, "scheduling for " + nextTimeUs + " and " + nowUs);
- scheduleNotification(NOTIFY_TIME, nextTimeUs - nowUs);
+ mPlayer.notifyAt(nextTimeUs);
} else {
mEventHandler.removeMessages(NOTIFY);
// no more callbacks
@@ -5449,25 +5475,6 @@ public class MediaPlayer extends PlayerBase
}
}
- private long getEstimatedTime(long nanoTime, boolean monotonic) {
- if (mPaused) {
- mLastReportedTime = mLastTimeUs + mTimeAdjustment;
- } else {
- long timeSinceRead = (nanoTime - mLastNanoTime) / 1000;
- mLastReportedTime = mLastTimeUs + timeSinceRead;
- if (mTimeAdjustment > 0) {
- long adjustment =
- mTimeAdjustment - timeSinceRead / TIME_ADJUSTMENT_RATE;
- if (adjustment <= 0) {
- mTimeAdjustment = 0;
- } else {
- mLastReportedTime += adjustment;
- }
- }
- }
- return mLastReportedTime;
- }
-
public long getCurrentTimeUs(boolean refreshTime, boolean monotonic)
throws IllegalStateException {
synchronized (this) {
@@ -5477,42 +5484,38 @@ public class MediaPlayer extends PlayerBase
return mLastReportedTime;
}
- long nanoTime = System.nanoTime();
- if (refreshTime ||
- nanoTime >= mLastNanoTime + MAX_NS_WITHOUT_POSITION_CHECK) {
- try {
- mLastTimeUs = mPlayer.getCurrentPosition() * 1000L;
- mPaused = !mPlayer.isPlaying() || mBuffering;
- if (DEBUG) Log.v(TAG, (mPaused ? "paused" : "playing") + " at " + mLastTimeUs);
- } catch (IllegalStateException e) {
- if (mPausing) {
- // if we were pausing, get last estimated timestamp
- mPausing = false;
- getEstimatedTime(nanoTime, monotonic);
- mPaused = true;
- if (DEBUG) Log.d(TAG, "illegal state, but pausing: estimating at " + mLastReportedTime);
- return mLastReportedTime;
+ try {
+ mLastTimeUs = mPlayer.getCurrentPosition() * 1000L;
+ mPaused = !mPlayer.isPlaying() || mBuffering;
+ if (DEBUG) Log.v(TAG, (mPaused ? "paused" : "playing") + " at " + mLastTimeUs);
+ } catch (IllegalStateException e) {
+ if (mPausing) {
+ // if we were pausing, get last estimated timestamp
+ mPausing = false;
+ if (!monotonic || mLastReportedTime < mLastTimeUs) {
+ mLastReportedTime = mLastTimeUs;
}
- // TODO get time when prepared
- throw e;
+ mPaused = true;
+ if (DEBUG) Log.d(TAG, "illegal state, but pausing: estimating at " + mLastReportedTime);
+ return mLastReportedTime;
}
- mLastNanoTime = nanoTime;
- if (monotonic && mLastTimeUs < mLastReportedTime) {
- /* have to adjust time */
- mTimeAdjustment = mLastReportedTime - mLastTimeUs;
- if (mTimeAdjustment > 1000000) {
- // schedule seeked event if time jumped significantly
- // TODO: do this properly by introducing an exception
- mStopped = false;
- mSeeking = true;
- scheduleNotification(NOTIFY_SEEK, 0 /* delay */);
- }
- } else {
- mTimeAdjustment = 0;
+ // TODO get time when prepared
+ throw e;
+ }
+ if (monotonic && mLastTimeUs < mLastReportedTime) {
+ /* have to adjust time */
+ if (mLastReportedTime - mLastTimeUs > 1000000) {
+ // schedule seeked event if time jumped significantly
+ // TODO: do this properly by introducing an exception
+ mStopped = false;
+ mSeeking = true;
+ scheduleNotification(NOTIFY_SEEK, 0 /* delay */);
}
+ } else {
+ mLastReportedTime = mLastTimeUs;
}
- return getEstimatedTime(nanoTime, monotonic);
+ return mLastReportedTime;
}
}
@@ -5526,9 +5529,6 @@ public class MediaPlayer extends PlayerBase
if (msg.what == NOTIFY) {
switch (msg.arg1) {
case NOTIFY_TIME:
- notifyTimedEvent(false /* refreshTime */);
- break;
- case REFRESH_AND_NOTIFY_TIME:
notifyTimedEvent(true /* refreshTime */);
break;
case NOTIFY_STOP:
diff --git a/android/media/MediaRouter.java b/android/media/MediaRouter.java
index 2894e895..fe427a73 100644
--- a/android/media/MediaRouter.java
+++ b/android/media/MediaRouter.java
@@ -193,7 +193,9 @@ public class MediaRouter {
} else if ((newRoutes.mainType&AudioRoutesInfo.MAIN_DOCK_SPEAKERS) != 0) {
name = com.android.internal.R.string.default_audio_route_name_dock_speakers;
} else if ((newRoutes.mainType&AudioRoutesInfo.MAIN_HDMI) != 0) {
- name = com.android.internal.R.string.default_media_route_name_hdmi;
+ name = com.android.internal.R.string.default_audio_route_name_hdmi;
+ } else if ((newRoutes.mainType&AudioRoutesInfo.MAIN_USB) != 0) {
+ name = com.android.internal.R.string.default_audio_route_name_usb;
} else {
name = com.android.internal.R.string.default_audio_route_name;
}