Merge "Don't send OnCompletion events when looping" into mnc-dr-dev
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index c10963d..cdfa159 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -176,7 +176,7 @@
private:
// used by ResourceManagerClient
- status_t reclaim();
+ status_t reclaim(bool force = false);
friend struct ResourceManagerClient;
private:
@@ -385,6 +385,9 @@
uint64_t getGraphicBufferSize();
void addResource(const String8 &type, const String8 &subtype, uint64_t value);
+ bool hasPendingBuffer(int portIndex);
+ bool hasPendingBuffer();
+
/* called to get the last codec error when the sticky flag is set.
* if no such codec error is found, returns UNKNOWN_ERROR.
*/
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index c0146d5..26532d7 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -1075,6 +1075,12 @@
int32_t audio;
CHECK(msg->findInt32("audio", &audio));
+ if (audio) {
+ mAudioEOS = false;
+ } else {
+ mVideoEOS = false;
+ }
+
ALOGV("renderer %s flush completed.", audio ? "audio" : "video");
if (audio && (mFlushingAudio == NONE || mFlushingAudio == FLUSHED
|| mFlushingAudio == SHUT_DOWN)) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 6419be0..f288c36 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -362,9 +362,9 @@
}
status_t NuPlayerDriver::setPlaybackSettings(const AudioPlaybackRate &rate) {
- Mutex::Autolock autoLock(mLock);
status_t err = mPlayer->setPlaybackSettings(rate);
if (err == OK) {
+ Mutex::Autolock autoLock(mLock);
if (rate.mSpeed == 0.f && mState == STATE_RUNNING) {
mState = STATE_PAUSED;
// try to update position
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 776dba8..8053245f 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -910,6 +910,13 @@
{
Mutex::Autolock autoLock(mLock);
+ int64_t maxTimeMedia;
+ maxTimeMedia =
+ mAnchorTimeMediaUs +
+ (int64_t)(max((long long)mNumFramesWritten - mAnchorNumFramesWritten, 0LL)
+ * 1000LL * mAudioSink->msecsPerFrame());
+ mMediaClock->updateMaxTimeMedia(maxTimeMedia);
+
notifyIfMediaRenderingStarted_l();
}
@@ -936,15 +943,6 @@
break;
}
}
- int64_t maxTimeMedia;
- {
- Mutex::Autolock autoLock(mLock);
- maxTimeMedia =
- mAnchorTimeMediaUs +
- (int64_t)(max((long long)mNumFramesWritten - mAnchorNumFramesWritten, 0LL)
- * 1000LL * mAudioSink->msecsPerFrame());
- }
- mMediaClock->updateMaxTimeMedia(maxTimeMedia);
// calculate whether we need to reschedule another write.
bool reschedule = !mAudioQueue.empty()
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 7019537..dc6009b 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -63,6 +63,7 @@
}
static const int kMaxRetry = 2;
+static const int kMaxReclaimWaitTimeInUs = 500000; // 0.5s
struct ResourceManagerClient : public BnResourceManagerClient {
ResourceManagerClient(MediaCodec* codec) : mMediaCodec(codec) {}
@@ -74,6 +75,12 @@
return true;
}
status_t err = codec->reclaim();
+ if (err == WOULD_BLOCK) {
+ ALOGD("Wait for the client to release codec.");
+ usleep(kMaxReclaimWaitTimeInUs);
+ ALOGD("Try to reclaim again.");
+ err = codec->reclaim(true /* force */);
+ }
if (err != OK) {
ALOGW("ResourceManagerClient failed to release codec with err %d", err);
}
@@ -571,10 +578,26 @@
return PostAndAwaitResponse(msg, &response);
}
-status_t MediaCodec::reclaim() {
+bool MediaCodec::hasPendingBuffer(int portIndex) {
+ const Vector<BufferInfo> &buffers = mPortBuffers[portIndex];
+ for (size_t i = 0; i < buffers.size(); ++i) {
+ const BufferInfo &info = buffers.itemAt(i);
+ if (info.mOwnedByClient) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool MediaCodec::hasPendingBuffer() {
+ return hasPendingBuffer(kPortIndexInput) || hasPendingBuffer(kPortIndexOutput);
+}
+
+status_t MediaCodec::reclaim(bool force) {
ALOGD("MediaCodec::reclaim(%p) %s", this, mInitName.c_str());
sp<AMessage> msg = new AMessage(kWhatRelease, this);
msg->setInt32("reclaimed", 1);
+ msg->setInt32("force", force ? 1 : 0);
sp<AMessage> response;
return PostAndAwaitResponse(msg, &response);
@@ -1787,6 +1810,23 @@
msg->findInt32("reclaimed", &reclaimed);
if (reclaimed) {
mReleasedByResourceManager = true;
+
+ int32_t force = 0;
+ msg->findInt32("force", &force);
+ if (!force && hasPendingBuffer()) {
+ ALOGW("Can't reclaim codec right now due to pending buffers.");
+
+ // return WOULD_BLOCK to ask resource manager to retry later.
+ sp<AMessage> response = new AMessage;
+ response->setInt32("err", WOULD_BLOCK);
+ response->postReply(replyID);
+
+ // notify the async client
+ if (mFlags & kFlagIsAsync) {
+ onError(DEAD_OBJECT, ACTION_CODE_FATAL);
+ }
+ break;
+ }
}
if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1
diff --git a/services/audioflinger/FastCapture.cpp b/services/audioflinger/FastCapture.cpp
index 79ac12b..1bba5f6 100644
--- a/services/audioflinger/FastCapture.cpp
+++ b/services/audioflinger/FastCapture.cpp
@@ -131,7 +131,9 @@
// FIXME new may block for unbounded time at internal mutex of the heap
// implementation; it would be better to have normal capture thread allocate for
// us to avoid blocking here and to prevent possible priority inversion
- (void)posix_memalign(&mReadBuffer, 32, frameCount * Format_frameSize(mFormat));
+ size_t bufferSize = frameCount * Format_frameSize(mFormat);
+ (void)posix_memalign(&mReadBuffer, 32, bufferSize);
+ memset(mReadBuffer, 0, bufferSize); // if posix_memalign fails, will segv here.
mPeriodNs = (frameCount * 1000000000LL) / mSampleRate; // 1.00
mUnderrunNs = (frameCount * 1750000000LL) / mSampleRate; // 1.75
mOverrunNs = (frameCount * 500000000LL) / mSampleRate; // 0.50
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index f586291..71fc498 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -6932,6 +6932,7 @@
mRsmpInFrames = mFrameCount * 7;
mRsmpInFramesP2 = roundup(mRsmpInFrames);
free(mRsmpInBuffer);
+ mRsmpInBuffer = NULL;
// TODO optimize audio capture buffer sizes ...
// Here we calculate the size of the sliding buffer used as a source
@@ -6941,7 +6942,9 @@
// The current value is higher than necessary. However it should not add to latency.
// Over-allocate beyond mRsmpInFramesP2 to permit a HAL read past end of buffer
- (void)posix_memalign(&mRsmpInBuffer, 32, (mRsmpInFramesP2 + mFrameCount - 1) * mFrameSize);
+ size_t bufferSize = (mRsmpInFramesP2 + mFrameCount - 1) * mFrameSize;
+ (void)posix_memalign(&mRsmpInBuffer, 32, bufferSize);
+ memset(mRsmpInBuffer, 0, bufferSize); // if posix_memalign fails, will segv here.
// AudioRecord mSampleRate and mChannelCount are constant due to AudioRecord API constraints.
// But if thread's mSampleRate or mChannelCount changes, how will that affect active tracks?