Merge "CCodec: protect C2OMXNode::mBufferIdsInUse" into qt-dev
diff --git a/media/OWNERS b/media/OWNERS
index 1e2d123..1afc253 100644
--- a/media/OWNERS
+++ b/media/OWNERS
@@ -1,3 +1,4 @@
+andrewlewis@google.com
chz@google.com
dwkang@google.com
elaurent@google.com
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index ded9cb7..8d1f511 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -250,10 +250,7 @@
mPreviousSchedulingGroup(SP_DEFAULT),
mPausedPosition(0)
{
- mAttributes.content_type = AUDIO_CONTENT_TYPE_UNKNOWN;
- mAttributes.usage = AUDIO_USAGE_UNKNOWN;
- mAttributes.flags = 0x0;
- strcpy(mAttributes.tags, "");
+ mAttributes = AUDIO_ATTRIBUTES_INITIALIZER;
(void)set(streamType, sampleRate, format, channelMask,
frameCount, flags, cbf, user, notificationFrames,
@@ -286,10 +283,7 @@
mPausedPosition(0),
mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE)
{
- mAttributes.content_type = AUDIO_CONTENT_TYPE_UNKNOWN;
- mAttributes.usage = AUDIO_USAGE_UNKNOWN;
- mAttributes.flags = 0x0;
- strcpy(mAttributes.tags, "");
+ mAttributes = AUDIO_ATTRIBUTES_INITIALIZER;
(void)set(streamType, sampleRate, format, channelMask,
0 /*frameCount*/, flags, cbf, user, notificationFrames,
@@ -2754,27 +2748,32 @@
// Prevent retrograde motion in timestamp.
// This is sometimes caused by erratic reports of the available space in the ALSA drivers.
if (status == NO_ERROR) {
+ // Fix stale time when checking timestamp right after start().
+ // The position is at the last reported location but the time can be stale
+ // due to pause or standby or cold start latency.
+ //
+ // We keep advancing the time (but not the position) to ensure that the
+ // stale value does not confuse the application.
+ //
+ // For offload compatibility, use a default lag value here.
+ // Any time discrepancy between this update and the pause timestamp is handled
+ // by the retrograde check afterwards.
+ int64_t currentTimeNanos = audio_utils_ns_from_timespec(×tamp.mTime);
+ const int64_t lagNs = int64_t(mAfLatency * 1000000LL);
+ const int64_t limitNs = mStartNs - lagNs;
+ if (currentTimeNanos < limitNs) {
+ ALOGD("%s(%d): correcting timestamp time for pause, "
+ "currentTimeNanos: %lld < limitNs: %lld < mStartNs: %lld",
+ __func__, mPortId,
+ (long long)currentTimeNanos, (long long)limitNs, (long long)mStartNs);
+ timestamp.mTime = convertNsToTimespec(limitNs);
+ currentTimeNanos = limitNs;
+ }
+
// previousTimestampValid is set to false when starting after a stop or flush.
if (previousTimestampValid) {
const int64_t previousTimeNanos =
audio_utils_ns_from_timespec(&mPreviousTimestamp.mTime);
- int64_t currentTimeNanos = audio_utils_ns_from_timespec(×tamp.mTime);
-
- // Fix stale time when checking timestamp right after start().
- //
- // For offload compatibility, use a default lag value here.
- // Any time discrepancy between this update and the pause timestamp is handled
- // by the retrograde check afterwards.
- const int64_t lagNs = int64_t(mAfLatency * 1000000LL);
- const int64_t limitNs = mStartNs - lagNs;
- if (currentTimeNanos < limitNs) {
- ALOGD("%s(%d): correcting timestamp time for pause, "
- "currentTimeNanos: %lld < limitNs: %lld < mStartNs: %lld",
- __func__, mPortId,
- (long long)currentTimeNanos, (long long)limitNs, (long long)mStartNs);
- timestamp.mTime = convertNsToTimespec(limitNs);
- currentTimeNanos = limitNs;
- }
// retrograde check
if (currentTimeNanos < previousTimeNanos) {
diff --git a/media/libmedia/include/media/TypeConverter.h b/media/libmedia/include/media/TypeConverter.h
index 3acfe98..2f8c209 100644
--- a/media/libmedia/include/media/TypeConverter.h
+++ b/media/libmedia/include/media/TypeConverter.h
@@ -305,8 +305,8 @@
result << "{ Content type: " << toString(attributes.content_type)
<< " Usage: " << toString(attributes.usage)
<< " Source: " << toString(attributes.source)
- << " Flags: " << attributes.flags
- << " Tags: " << attributes.tags
+ << std::hex << " Flags: 0x" << attributes.flags
+ << std::dec << " Tags: " << attributes.tags
<< " }";
return result.str();
diff --git a/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h b/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
index 2993ab1..1e8a1d5 100644
--- a/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
+++ b/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
@@ -143,6 +143,7 @@
Mutex mNotifyLock;
sp<MediaPlayer2Listener> mListener;
media_player2_internal_states mCurrentState;
+ bool mTransitionToNext;
int64_t mCurrentPosition;
MediaPlayer2SeekMode mCurrentSeekMode;
int64_t mSeekPosition;
diff --git a/media/libmediaplayer2/mediaplayer2.cpp b/media/libmediaplayer2/mediaplayer2.cpp
index c34f1c9..de65f8d 100644
--- a/media/libmediaplayer2/mediaplayer2.cpp
+++ b/media/libmediaplayer2/mediaplayer2.cpp
@@ -241,6 +241,7 @@
mSeekPosition = -1;
mSeekMode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC;
mCurrentState = MEDIA_PLAYER2_IDLE;
+ mTransitionToNext = false;
mLoop = false;
mVolume = 1.0;
mVideoWidth = mVideoHeight = 0;
@@ -389,6 +390,7 @@
return INVALID_OPERATION;
}
mSrcId = srcId;
+ mTransitionToNext = true;
return mPlayer->playNextDataSource(srcId);
}
@@ -568,6 +570,7 @@
mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
} else {
mCurrentState = MEDIA_PLAYER2_PAUSED;
+ mTransitionToNext = false;
}
return ret;
}
@@ -815,6 +818,7 @@
} else {
mPlayer->setListener(NULL);
mCurrentState = MEDIA_PLAYER2_IDLE;
+ mTransitionToNext = false;
}
// setDataSource has to be called again to create a
// new mediaplayer.
@@ -1031,12 +1035,6 @@
mCurrentState = MEDIA_PLAYER2_PREPARED;
}
break;
- case MEDIA2_STARTED:
- ALOGV("MediaPlayer2::notify() started, srcId=%lld", (long long)srcId);
- if (srcId == mSrcId) {
- mCurrentState = MEDIA_PLAYER2_STARTED;
- }
- break;
case MEDIA2_DRM_INFO:
ALOGV("MediaPlayer2::notify() MEDIA2_DRM_INFO(%lld, %d, %d, %d, %p)",
(long long)srcId, msg, ext1, ext2, obj);
@@ -1063,8 +1061,9 @@
if (ext1 != MEDIA2_INFO_VIDEO_TRACK_LAGGING) {
ALOGW("info/warning (%d, %d)", ext1, ext2);
- if (ext1 == MEDIA2_INFO_DATA_SOURCE_START && srcId == mSrcId) {
+ if (ext1 == MEDIA2_INFO_DATA_SOURCE_START && srcId == mSrcId && mTransitionToNext) {
mCurrentState = MEDIA_PLAYER2_STARTED;
+ mTransitionToNext = false;
}
}
break;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 80393ca..af29f87 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1641,7 +1641,14 @@
outputDesc->setClientActive(client, true);
if (client->hasPreferredDevice(true)) {
- devices = getNewOutputDevices(outputDesc, false /*fromCache*/);
+ if (outputDesc->clientsList(true /*activeOnly*/).size() == 1 &&
+ client->isPreferredDeviceForExclusiveUse()) {
+ // Preferred device may be exclusive, use only if no other active clients on this output
+ devices = DeviceVector(
+ mAvailableOutputDevices.getDeviceFromId(client->preferredDeviceId()));
+ } else {
+ devices = getNewOutputDevices(outputDesc, false /*fromCache*/);
+ }
if (devices != outputDesc->devices()) {
checkStrategyRoute(clientStrategy, outputDesc->mIoHandle);
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index a700868..de447fb 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -348,7 +348,8 @@
}
virtual const DeviceVector getAvailableInputDevices() const
{
- return mAvailableInputDevices.filterForEngine();
+ // legacy and non-legacy remote-submix are managed by the engine, do not filter
+ return mAvailableInputDevices;
}
virtual const sp<DeviceDescriptor> &getDefaultOutputDevice() const
{
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index b8036bb..2eb272e 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -225,6 +225,21 @@
return result;
}
+void AudioPolicyService::getPlaybackClientAndEffects(audio_port_handle_t portId,
+ sp<AudioPlaybackClient>& client,
+ sp<AudioPolicyEffects>& effects,
+ const char *context)
+{
+ Mutex::Autolock _l(mLock);
+ const ssize_t index = mAudioPlaybackClients.indexOfKey(portId);
+ if (index < 0) {
+ ALOGE("%s AudioTrack client not found for portId %d", context, portId);
+ return;
+ }
+ client = mAudioPlaybackClients.valueAt(index);
+ effects = mAudioPolicyEffects;
+}
+
status_t AudioPolicyService::startOutput(audio_port_handle_t portId)
{
if (mAudioPolicyManager == NULL) {
@@ -233,16 +248,9 @@
ALOGV("startOutput()");
sp<AudioPlaybackClient> client;
sp<AudioPolicyEffects>audioPolicyEffects;
- {
- Mutex::Autolock _l(mLock);
- const ssize_t index = mAudioPlaybackClients.indexOfKey(portId);
- if (index < 0) {
- ALOGE("%s AudioTrack client not found for portId %d", __FUNCTION__, portId);
- return INVALID_OPERATION;
- }
- client = mAudioPlaybackClients.valueAt(index);
- audioPolicyEffects = mAudioPolicyEffects;
- }
+
+ getPlaybackClientAndEffects(portId, client, audioPolicyEffects, __func__);
+
if (audioPolicyEffects != 0) {
// create audio processors according to stream
status_t status = audioPolicyEffects->addOutputSessionEffects(
@@ -275,17 +283,9 @@
ALOGV("doStopOutput");
sp<AudioPlaybackClient> client;
sp<AudioPolicyEffects>audioPolicyEffects;
- {
- Mutex::Autolock _l(mLock);
- const ssize_t index = mAudioPlaybackClients.indexOfKey(portId);
- if (index < 0) {
- ALOGE("%s AudioTrack client not found for portId %d", __FUNCTION__, portId);
- return INVALID_OPERATION;
- }
- client = mAudioPlaybackClients.valueAt(index);
- audioPolicyEffects = mAudioPolicyEffects;
- }
+ getPlaybackClientAndEffects(portId, client, audioPolicyEffects, __func__);
+
if (audioPolicyEffects != 0) {
// release audio processors from the stream
status_t status = audioPolicyEffects->releaseOutputSessionEffects(
@@ -315,13 +315,17 @@
void AudioPolicyService::doReleaseOutput(audio_port_handle_t portId)
{
ALOGV("doReleaseOutput from tid %d", gettid());
- Mutex::Autolock _l(mLock);
- const ssize_t index = mAudioPlaybackClients.indexOfKey(portId);
- if (index < 0) {
- ALOGE("%s AudioTrack client not found for portId %d", __FUNCTION__, portId);
- return;
+ sp<AudioPlaybackClient> client;
+ sp<AudioPolicyEffects> audioPolicyEffects;
+
+ getPlaybackClientAndEffects(portId, client, audioPolicyEffects, __func__);
+
+ if (audioPolicyEffects != 0 && client->active) {
+ // clean up effects if output was not stopped before being released
+ audioPolicyEffects->releaseOutputSessionEffects(
+ client->io, client->stream, client->session);
}
- sp<AudioPlaybackClient> client = mAudioPlaybackClients.valueAt(index);
+ Mutex::Autolock _l(mLock);
mAudioPlaybackClients.removeItem(portId);
// called from internal thread: no need to clear caller identity
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index efdba56..189322f 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -782,6 +782,12 @@
const audio_stream_type_t stream;
};
+ void getPlaybackClientAndEffects(audio_port_handle_t portId,
+ sp<AudioPlaybackClient>& client,
+ sp<AudioPolicyEffects>& effects,
+ const char *context);
+
+
// A class automatically clearing and restoring binder caller identity inside
// a code block (scoped variable)
// Declare one systematically before calling AudioPolicyManager methods so that they are