summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp19
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp34
-rw-r--r--media/libstagefright/foundation/AMessage.cpp2
3 files changed, 40 insertions, 15 deletions
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index ceedb40..ef4abd4 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -832,24 +832,31 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
finishFlushIfPossible();
} else if (what == Decoder::kWhatError) {
- ALOGE("Received error from %s decoder, aborting playback.",
- audio ? "audio" : "video");
-
status_t err;
if (!msg->findInt32("err", &err)) {
err = UNKNOWN_ERROR;
}
- mRenderer->queueEOS(audio, err);
+ ALOGE("received error from %s decoder %#x", audio ? "audio" : "video", err);
+
+ ALOGI("shutting down %s", audio ? "audio" : "video");
if (audio && mFlushingAudio != NONE) {
+ mRenderer->queueEOS(audio, err);
mAudioDecoder.clear();
++mAudioDecoderGeneration;
mFlushingAudio = SHUT_DOWN;
- } else if (!audio && mFlushingVideo != NONE){
+ finishFlushIfPossible();
+ } else if (!audio && mFlushingVideo != NONE) {
+ mRenderer->queueEOS(audio, err);
mVideoDecoder.clear();
++mVideoDecoderGeneration;
mFlushingVideo = SHUT_DOWN;
+ finishFlushIfPossible();
+ } else {
+ mDeferredActions.push_back(
+ new ShutdownDecoderAction(audio, !audio /* video */));
+ processDeferredActions();
+ notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
}
- finishFlushIfPossible();
} else if (what == Decoder::kWhatDrainThisBuffer) {
renderBuffer(audio, msg);
} else {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 1b1b1c8..1a066b7 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -227,7 +227,11 @@ status_t NuPlayer::Decoder::getInputBuffers(Vector<sp<ABuffer> > *buffers) const
void NuPlayer::Decoder::handleError(int32_t err)
{
- mCodec->release();
+ // We cannot immediately release the codec due to buffers still outstanding
+ // in the renderer. We signal to the player the error so it can shutdown/release the
+ // decoder after flushing and increment the generation to discard unnecessary messages.
+
+ ++mBufferGeneration;
sp<AMessage> notify = mNotify->dup();
notify->setInt32("what", kWhatError);
@@ -242,6 +246,8 @@ bool NuPlayer::Decoder::handleAnInputBuffer() {
mComponentName.c_str(), res == OK ? (int)bufferIx : res);
if (res != OK) {
if (res != -EAGAIN) {
+ ALOGE("Failed to dequeue input buffer for %s (err=%d)",
+ mComponentName.c_str(), res);
handleError(res);
}
return false;
@@ -315,7 +321,7 @@ void android::NuPlayer::Decoder::onInputBufferFilled(const sp<AMessage> &msg) {
}
}
- mInputBufferIsDequeued.editItemAt(bufferIx) = false;
+
if (buffer == NULL /* includes !hasBuffer */) {
int32_t streamErr = ERROR_END_OF_STREAM;
@@ -333,12 +339,18 @@ void android::NuPlayer::Decoder::onInputBufferFilled(const sp<AMessage> &msg) {
0,
0,
MediaCodec::BUFFER_FLAG_EOS);
- if (streamErr == ERROR_END_OF_STREAM && err != OK) {
+ if (err == OK) {
+ mInputBufferIsDequeued.editItemAt(bufferIx) = false;
+ } else if (streamErr == ERROR_END_OF_STREAM) {
streamErr = err;
// err will not be ERROR_END_OF_STREAM
}
if (streamErr != ERROR_END_OF_STREAM) {
+ ALOGE("Stream error for %s (err=%d), EOS %s queued",
+ mComponentName.c_str(),
+ streamErr,
+ err == OK ? "successfully" : "unsuccessfully");
handleError(streamErr);
}
} else {
@@ -368,14 +380,18 @@ void android::NuPlayer::Decoder::onInputBufferFilled(const sp<AMessage> &msg) {
timeUs,
flags);
if (err != OK) {
+ if (mediaBuffer != NULL) {
+ mediaBuffer->release();
+ }
ALOGE("Failed to queue input buffer for %s (err=%d)",
mComponentName.c_str(), err);
handleError(err);
- }
-
- if (mediaBuffer != NULL) {
- CHECK(mMediaBuffers[bufferIx] == NULL);
- mMediaBuffers.editItemAt(bufferIx) = mediaBuffer;
+ } else {
+ mInputBufferIsDequeued.editItemAt(bufferIx) = false;
+ if (mediaBuffer != NULL) {
+ CHECK(mMediaBuffers[bufferIx] == NULL);
+ mMediaBuffers.editItemAt(bufferIx) = mediaBuffer;
+ }
}
}
}
@@ -426,6 +442,8 @@ bool NuPlayer::Decoder::handleAnOutputBuffer() {
return true;
} else if (res != OK) {
if (res != -EAGAIN) {
+ ALOGE("Failed to dequeue output buffer for %s (err=%d)",
+ mComponentName.c_str(), res);
handleError(res);
}
return false;
diff --git a/media/libstagefright/foundation/AMessage.cpp b/media/libstagefright/foundation/AMessage.cpp
index bc3e3fb..795e8a6 100644
--- a/media/libstagefright/foundation/AMessage.cpp
+++ b/media/libstagefright/foundation/AMessage.cpp
@@ -485,7 +485,7 @@ AString AMessage::debugString(int32_t indent) const {
{
sp<ABuffer> buffer = static_cast<ABuffer *>(item.u.refValue);
- if (buffer != NULL && buffer->size() <= 64) {
+ if (buffer != NULL && buffer->data() != NULL && buffer->size() <= 64) {
tmp = StringPrintf("Buffer %s = {\n", item.mName);
hexdump(buffer->data(), buffer->size(), indent + 4, &tmp);
appendIndent(&tmp, indent + 2);