Loading media/libstagefright/MediaCodec.cpp +157 −47 Original line number Diff line number Diff line Loading @@ -1008,6 +1008,12 @@ status_t MediaCodec::PostAndAwaitResponse( return err; } void MediaCodec::PostReplyWithError(const sp<AMessage> &msg, int32_t err) { sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); PostReplyWithError(replyID, err); } void MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) { int32_t finalErr = err; if (mReleasedByResourceManager) { Loading Loading @@ -1511,7 +1517,6 @@ status_t MediaCodec::reset() { mStickyError = OK; // reset state not reset by setState(UNINITIALIZED) mReplyID = 0; mDequeueInputReplyID = 0; mDequeueOutputReplyID = 0; mDequeueInputTimeoutGeneration = 0; Loading Loading @@ -2159,7 +2164,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { if (mState == RELEASING) { mComponentName.clear(); } (new AMessage)->postReply(mReplyID); postPendingRepliesAndDeferredMessages(); sendErrorResponse = false; } break; Loading @@ -2185,7 +2190,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { case FLUSHED: case STARTED: { sendErrorResponse = false; sendErrorResponse = (mReplyID != nullptr); setStickyError(err); postActivityNotificationIfPossible(); Loading Loading @@ -2215,7 +2220,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { default: { sendErrorResponse = false; sendErrorResponse = (mReplyID != nullptr); setStickyError(err); postActivityNotificationIfPossible(); Loading @@ -2242,7 +2247,15 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { } if (sendErrorResponse) { PostReplyWithError(mReplyID, err); // TRICKY: replicate PostReplyWithError logic for // err code override int32_t finalErr = err; if (mReleasedByResourceManager) { // override the err code if MediaCodec has been // released by ResourceManager. finalErr = DEAD_OBJECT; } postPendingRepliesAndDeferredMessages(finalErr); } break; } Loading Loading @@ -2290,7 +2303,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { MediaResource::CodecResource(mFlags & kFlagIsSecure, mIsVideo)); } (new AMessage)->postReply(mReplyID); postPendingRepliesAndDeferredMessages(); break; } Loading Loading @@ -2329,7 +2342,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { mFlags |= kFlagUsesSoftwareRenderer; } setState(CONFIGURED); (new AMessage)->postReply(mReplyID); postPendingRepliesAndDeferredMessages(); // augment our media metrics info, now that we know more things // such as what the codec extracted from any CSD passed in. Loading Loading @@ -2374,6 +2387,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { case kWhatInputSurfaceCreated: { if (mState != CONFIGURED) { // state transitioned unexpectedly; we should have replied already. ALOGD("received kWhatInputSurfaceCreated message in state %s", stateString(mState).c_str()); break; } // response to initiateCreateInputSurface() status_t err = NO_ERROR; sp<AMessage> response = new AMessage; Loading @@ -2392,12 +2411,18 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { } else { response->setInt32("err", err); } response->postReply(mReplyID); postPendingRepliesAndDeferredMessages(response); break; } case kWhatInputSurfaceAccepted: { if (mState != CONFIGURED) { // state transitioned unexpectedly; we should have replied already. ALOGD("received kWhatInputSurfaceAccepted message in state %s", stateString(mState).c_str()); break; } // response to initiateSetInputSurface() status_t err = NO_ERROR; sp<AMessage> response = new AMessage(); Loading @@ -2408,19 +2433,25 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { } else { response->setInt32("err", err); } response->postReply(mReplyID); postPendingRepliesAndDeferredMessages(response); break; } case kWhatSignaledInputEOS: { if (!isExecuting()) { // state transitioned unexpectedly; we should have replied already. ALOGD("received kWhatSignaledInputEOS message in state %s", stateString(mState).c_str()); break; } // response to signalEndOfInputStream() sp<AMessage> response = new AMessage; status_t err; if (msg->findInt32("err", &err)) { response->setInt32("err", err); } response->postReply(mReplyID); postPendingRepliesAndDeferredMessages(response); break; } Loading @@ -2439,7 +2470,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { MediaResource::GraphicMemoryResource(getGraphicBufferSize())); } setState(STARTED); (new AMessage)->postReply(mReplyID); postPendingRepliesAndDeferredMessages(); break; } Loading Loading @@ -2669,7 +2700,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { break; } setState(INITIALIZED); (new AMessage)->postReply(mReplyID); postPendingRepliesAndDeferredMessages(); break; } Loading @@ -2693,7 +2724,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { mReleaseSurface.reset(); if (mReplyID != nullptr) { (new AMessage)->postReply(mReplyID); postPendingRepliesAndDeferredMessages(); } if (mAsyncReleaseCompleteNotification != nullptr) { flushMediametrics(); Loading @@ -2718,7 +2749,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { mCodec->signalResume(); } (new AMessage)->postReply(mReplyID); postPendingRepliesAndDeferredMessages(); break; } Loading @@ -2730,14 +2761,18 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { case kWhatInit: { sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); if (mState != UNINITIALIZED) { PostReplyWithError(replyID, INVALID_OPERATION); PostReplyWithError(msg, INVALID_OPERATION); break; } if (mReplyID) { mDeferredMessages.push_back(msg); break; } sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); mReplyID = replyID; setState(INITIALIZING); Loading Loading @@ -2799,13 +2834,17 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { case kWhatConfigure: { sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); if (mState != INITIALIZED) { PostReplyWithError(replyID, INVALID_OPERATION); PostReplyWithError(msg, INVALID_OPERATION); break; } if (mReplyID) { mDeferredMessages.push_back(msg); break; } sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); sp<RefBase> obj; CHECK(msg->findObject("surface", &obj)); Loading Loading @@ -2944,14 +2983,18 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { case kWhatCreateInputSurface: case kWhatSetInputSurface: { sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); // Must be configured, but can't have been started yet. if (mState != CONFIGURED) { PostReplyWithError(replyID, INVALID_OPERATION); PostReplyWithError(msg, INVALID_OPERATION); break; } if (mReplyID) { mDeferredMessages.push_back(msg); break; } sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); mReplyID = replyID; if (msg->what() == kWhatCreateInputSurface) { Loading @@ -2967,9 +3010,6 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { } case kWhatStart: { sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); if (mState == FLUSHED) { setState(STARTED); if (mHavePendingInputBuffers) { Loading @@ -2977,12 +3017,19 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { mHavePendingInputBuffers = false; } mCodec->signalResume(); PostReplyWithError(replyID, OK); PostReplyWithError(msg, OK); break; } else if (mState != CONFIGURED) { PostReplyWithError(replyID, INVALID_OPERATION); PostReplyWithError(msg, INVALID_OPERATION); break; } if (mReplyID) { mDeferredMessages.push_back(msg); break; } sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); mReplyID = replyID; setState(STARTING); Loading @@ -2991,15 +3038,42 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { break; } case kWhatStop: case kWhatStop: { if (mReplyID) { mDeferredMessages.push_back(msg); break; } [[fallthrough]]; } case kWhatRelease: { State targetState = (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED; if ((mState == RELEASING && targetState == UNINITIALIZED) || (mState == STOPPING && targetState == INITIALIZED)) { mDeferredMessages.push_back(msg); break; } sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); sp<AMessage> asyncNotify; (void)msg->findMessage("async", &asyncNotify); // post asyncNotify if going out of scope. struct AsyncNotifyPost { AsyncNotifyPost(const sp<AMessage> &asyncNotify) : mAsyncNotify(asyncNotify) {} ~AsyncNotifyPost() { if (mAsyncNotify) { mAsyncNotify->post(); } } void clear() { mAsyncNotify.clear(); } private: sp<AMessage> mAsyncNotify; } asyncNotifyPost{asyncNotify}; // already stopped/released if (mState == UNINITIALIZED && mReleasedByResourceManager) { sp<AMessage> response = new AMessage; Loading Loading @@ -3063,12 +3137,14 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { // after this, and we'll no longer be able to reply. if (mState == FLUSHING || mState == STOPPING || mState == CONFIGURING || mState == STARTING) { (new AMessage)->postReply(mReplyID); // mReply is always set if in these states. postPendingRepliesAndDeferredMessages(); } if (mFlags & kFlagSawMediaServerDie) { // It's dead, Jim. Don't expect initiateShutdown to yield // any useful results now... // Any pending reply would have been handled at kWhatError. setState(UNINITIALIZED); if (targetState == UNINITIALIZED) { mComponentName.clear(); Loading @@ -3082,12 +3158,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { // reply now with an error to unblock the client, client can // release after the failure (instead of ANR). if (msg->what() == kWhatStop && (mFlags & kFlagStickyError)) { // Any pending reply would have been handled at kWhatError. PostReplyWithError(replyID, getStickyError()); break; } sp<AMessage> asyncNotify; if (msg->findMessage("async", &asyncNotify) && asyncNotify != nullptr) { if (asyncNotify != nullptr) { if (mSurface != NULL) { if (!mReleaseSurface) { mReleaseSurface.reset(new ReleaseSurface); Loading @@ -3107,6 +3183,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { } } if (mReplyID) { // State transition replies are handled above, so this reply // would not be related to state transition. As we are // shutting down the component, just fail the operation. postPendingRepliesAndDeferredMessages(UNKNOWN_ERROR); } mReplyID = replyID; setState(msg->what() == kWhatStop ? STOPPING : RELEASING); Loading @@ -3121,8 +3203,8 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { if (asyncNotify != nullptr) { mResourceManagerProxy->markClientForPendingRemoval(); (new AMessage)->postReply(mReplyID); mReplyID = 0; postPendingRepliesAndDeferredMessages(); asyncNotifyPost.clear(); mAsyncReleaseCompleteNotification = asyncNotify; } Loading Loading @@ -3293,17 +3375,21 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { case kWhatSignalEndOfInputStream: { sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); if (!isExecuting() || !mHaveInputSurface) { PostReplyWithError(replyID, INVALID_OPERATION); PostReplyWithError(msg, INVALID_OPERATION); break; } else if (mFlags & kFlagStickyError) { PostReplyWithError(replyID, getStickyError()); PostReplyWithError(msg, getStickyError()); break; } if (mReplyID) { mDeferredMessages.push_back(msg); break; } sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); mReplyID = replyID; mCodec->signalEndOfInputStream(); break; Loading Loading @@ -3345,16 +3431,20 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { case kWhatFlush: { sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); if (!isExecuting()) { PostReplyWithError(replyID, INVALID_OPERATION); PostReplyWithError(msg, INVALID_OPERATION); break; } else if (mFlags & kFlagStickyError) { PostReplyWithError(replyID, getStickyError()); PostReplyWithError(msg, getStickyError()); break; } if (mReplyID) { mDeferredMessages.push_back(msg); break; } sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); mReplyID = replyID; // TODO: skip flushing if already FLUSHED Loading Loading @@ -4188,6 +4278,26 @@ status_t MediaCodec::amendOutputFormatWithCodecSpecificData( return OK; } void MediaCodec::postPendingRepliesAndDeferredMessages(status_t err /* = OK */) { sp<AMessage> response{new AMessage}; if (err != OK) { response->setInt32("err", err); } postPendingRepliesAndDeferredMessages(response); } void MediaCodec::postPendingRepliesAndDeferredMessages(const sp<AMessage> &response) { CHECK(mReplyID); response->postReply(mReplyID); mReplyID.clear(); ALOGV_IF(!mDeferredMessages.empty(), "posting %zu deferred messages", mDeferredMessages.size()); for (sp<AMessage> msg : mDeferredMessages) { msg->post(); } mDeferredMessages.clear(); } std::string MediaCodec::stateString(State state) { const char *rval = NULL; char rawbuffer[16]; // room for "%d" Loading media/libstagefright/include/media/stagefright/MediaCodec.h +5 −0 Original line number Diff line number Diff line Loading @@ -366,6 +366,7 @@ private: AString mOwnerName; sp<MediaCodecInfo> mCodecInfo; sp<AReplyToken> mReplyID; std::vector<sp<AMessage>> mDeferredMessages; uint32_t mFlags; status_t mStickyError; sp<Surface> mSurface; Loading Loading @@ -435,6 +436,7 @@ private: static status_t PostAndAwaitResponse( const sp<AMessage> &msg, sp<AMessage> *response); void PostReplyWithError(const sp<AMessage> &msg, int32_t err); void PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err); status_t init(const AString &name); Loading Loading @@ -484,6 +486,9 @@ private: bool hasPendingBuffer(int portIndex); bool hasPendingBuffer(); void postPendingRepliesAndDeferredMessages(status_t err = OK); void postPendingRepliesAndDeferredMessages(const sp<AMessage> &response); /* called to get the last codec error when the sticky flag is set. * if no such codec error is found, returns UNKNOWN_ERROR. */ Loading Loading
media/libstagefright/MediaCodec.cpp +157 −47 Original line number Diff line number Diff line Loading @@ -1008,6 +1008,12 @@ status_t MediaCodec::PostAndAwaitResponse( return err; } void MediaCodec::PostReplyWithError(const sp<AMessage> &msg, int32_t err) { sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); PostReplyWithError(replyID, err); } void MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) { int32_t finalErr = err; if (mReleasedByResourceManager) { Loading Loading @@ -1511,7 +1517,6 @@ status_t MediaCodec::reset() { mStickyError = OK; // reset state not reset by setState(UNINITIALIZED) mReplyID = 0; mDequeueInputReplyID = 0; mDequeueOutputReplyID = 0; mDequeueInputTimeoutGeneration = 0; Loading Loading @@ -2159,7 +2164,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { if (mState == RELEASING) { mComponentName.clear(); } (new AMessage)->postReply(mReplyID); postPendingRepliesAndDeferredMessages(); sendErrorResponse = false; } break; Loading @@ -2185,7 +2190,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { case FLUSHED: case STARTED: { sendErrorResponse = false; sendErrorResponse = (mReplyID != nullptr); setStickyError(err); postActivityNotificationIfPossible(); Loading Loading @@ -2215,7 +2220,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { default: { sendErrorResponse = false; sendErrorResponse = (mReplyID != nullptr); setStickyError(err); postActivityNotificationIfPossible(); Loading @@ -2242,7 +2247,15 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { } if (sendErrorResponse) { PostReplyWithError(mReplyID, err); // TRICKY: replicate PostReplyWithError logic for // err code override int32_t finalErr = err; if (mReleasedByResourceManager) { // override the err code if MediaCodec has been // released by ResourceManager. finalErr = DEAD_OBJECT; } postPendingRepliesAndDeferredMessages(finalErr); } break; } Loading Loading @@ -2290,7 +2303,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { MediaResource::CodecResource(mFlags & kFlagIsSecure, mIsVideo)); } (new AMessage)->postReply(mReplyID); postPendingRepliesAndDeferredMessages(); break; } Loading Loading @@ -2329,7 +2342,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { mFlags |= kFlagUsesSoftwareRenderer; } setState(CONFIGURED); (new AMessage)->postReply(mReplyID); postPendingRepliesAndDeferredMessages(); // augment our media metrics info, now that we know more things // such as what the codec extracted from any CSD passed in. Loading Loading @@ -2374,6 +2387,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { case kWhatInputSurfaceCreated: { if (mState != CONFIGURED) { // state transitioned unexpectedly; we should have replied already. ALOGD("received kWhatInputSurfaceCreated message in state %s", stateString(mState).c_str()); break; } // response to initiateCreateInputSurface() status_t err = NO_ERROR; sp<AMessage> response = new AMessage; Loading @@ -2392,12 +2411,18 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { } else { response->setInt32("err", err); } response->postReply(mReplyID); postPendingRepliesAndDeferredMessages(response); break; } case kWhatInputSurfaceAccepted: { if (mState != CONFIGURED) { // state transitioned unexpectedly; we should have replied already. ALOGD("received kWhatInputSurfaceAccepted message in state %s", stateString(mState).c_str()); break; } // response to initiateSetInputSurface() status_t err = NO_ERROR; sp<AMessage> response = new AMessage(); Loading @@ -2408,19 +2433,25 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { } else { response->setInt32("err", err); } response->postReply(mReplyID); postPendingRepliesAndDeferredMessages(response); break; } case kWhatSignaledInputEOS: { if (!isExecuting()) { // state transitioned unexpectedly; we should have replied already. ALOGD("received kWhatSignaledInputEOS message in state %s", stateString(mState).c_str()); break; } // response to signalEndOfInputStream() sp<AMessage> response = new AMessage; status_t err; if (msg->findInt32("err", &err)) { response->setInt32("err", err); } response->postReply(mReplyID); postPendingRepliesAndDeferredMessages(response); break; } Loading @@ -2439,7 +2470,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { MediaResource::GraphicMemoryResource(getGraphicBufferSize())); } setState(STARTED); (new AMessage)->postReply(mReplyID); postPendingRepliesAndDeferredMessages(); break; } Loading Loading @@ -2669,7 +2700,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { break; } setState(INITIALIZED); (new AMessage)->postReply(mReplyID); postPendingRepliesAndDeferredMessages(); break; } Loading @@ -2693,7 +2724,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { mReleaseSurface.reset(); if (mReplyID != nullptr) { (new AMessage)->postReply(mReplyID); postPendingRepliesAndDeferredMessages(); } if (mAsyncReleaseCompleteNotification != nullptr) { flushMediametrics(); Loading @@ -2718,7 +2749,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { mCodec->signalResume(); } (new AMessage)->postReply(mReplyID); postPendingRepliesAndDeferredMessages(); break; } Loading @@ -2730,14 +2761,18 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { case kWhatInit: { sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); if (mState != UNINITIALIZED) { PostReplyWithError(replyID, INVALID_OPERATION); PostReplyWithError(msg, INVALID_OPERATION); break; } if (mReplyID) { mDeferredMessages.push_back(msg); break; } sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); mReplyID = replyID; setState(INITIALIZING); Loading Loading @@ -2799,13 +2834,17 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { case kWhatConfigure: { sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); if (mState != INITIALIZED) { PostReplyWithError(replyID, INVALID_OPERATION); PostReplyWithError(msg, INVALID_OPERATION); break; } if (mReplyID) { mDeferredMessages.push_back(msg); break; } sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); sp<RefBase> obj; CHECK(msg->findObject("surface", &obj)); Loading Loading @@ -2944,14 +2983,18 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { case kWhatCreateInputSurface: case kWhatSetInputSurface: { sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); // Must be configured, but can't have been started yet. if (mState != CONFIGURED) { PostReplyWithError(replyID, INVALID_OPERATION); PostReplyWithError(msg, INVALID_OPERATION); break; } if (mReplyID) { mDeferredMessages.push_back(msg); break; } sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); mReplyID = replyID; if (msg->what() == kWhatCreateInputSurface) { Loading @@ -2967,9 +3010,6 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { } case kWhatStart: { sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); if (mState == FLUSHED) { setState(STARTED); if (mHavePendingInputBuffers) { Loading @@ -2977,12 +3017,19 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { mHavePendingInputBuffers = false; } mCodec->signalResume(); PostReplyWithError(replyID, OK); PostReplyWithError(msg, OK); break; } else if (mState != CONFIGURED) { PostReplyWithError(replyID, INVALID_OPERATION); PostReplyWithError(msg, INVALID_OPERATION); break; } if (mReplyID) { mDeferredMessages.push_back(msg); break; } sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); mReplyID = replyID; setState(STARTING); Loading @@ -2991,15 +3038,42 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { break; } case kWhatStop: case kWhatStop: { if (mReplyID) { mDeferredMessages.push_back(msg); break; } [[fallthrough]]; } case kWhatRelease: { State targetState = (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED; if ((mState == RELEASING && targetState == UNINITIALIZED) || (mState == STOPPING && targetState == INITIALIZED)) { mDeferredMessages.push_back(msg); break; } sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); sp<AMessage> asyncNotify; (void)msg->findMessage("async", &asyncNotify); // post asyncNotify if going out of scope. struct AsyncNotifyPost { AsyncNotifyPost(const sp<AMessage> &asyncNotify) : mAsyncNotify(asyncNotify) {} ~AsyncNotifyPost() { if (mAsyncNotify) { mAsyncNotify->post(); } } void clear() { mAsyncNotify.clear(); } private: sp<AMessage> mAsyncNotify; } asyncNotifyPost{asyncNotify}; // already stopped/released if (mState == UNINITIALIZED && mReleasedByResourceManager) { sp<AMessage> response = new AMessage; Loading Loading @@ -3063,12 +3137,14 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { // after this, and we'll no longer be able to reply. if (mState == FLUSHING || mState == STOPPING || mState == CONFIGURING || mState == STARTING) { (new AMessage)->postReply(mReplyID); // mReply is always set if in these states. postPendingRepliesAndDeferredMessages(); } if (mFlags & kFlagSawMediaServerDie) { // It's dead, Jim. Don't expect initiateShutdown to yield // any useful results now... // Any pending reply would have been handled at kWhatError. setState(UNINITIALIZED); if (targetState == UNINITIALIZED) { mComponentName.clear(); Loading @@ -3082,12 +3158,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { // reply now with an error to unblock the client, client can // release after the failure (instead of ANR). if (msg->what() == kWhatStop && (mFlags & kFlagStickyError)) { // Any pending reply would have been handled at kWhatError. PostReplyWithError(replyID, getStickyError()); break; } sp<AMessage> asyncNotify; if (msg->findMessage("async", &asyncNotify) && asyncNotify != nullptr) { if (asyncNotify != nullptr) { if (mSurface != NULL) { if (!mReleaseSurface) { mReleaseSurface.reset(new ReleaseSurface); Loading @@ -3107,6 +3183,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { } } if (mReplyID) { // State transition replies are handled above, so this reply // would not be related to state transition. As we are // shutting down the component, just fail the operation. postPendingRepliesAndDeferredMessages(UNKNOWN_ERROR); } mReplyID = replyID; setState(msg->what() == kWhatStop ? STOPPING : RELEASING); Loading @@ -3121,8 +3203,8 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { if (asyncNotify != nullptr) { mResourceManagerProxy->markClientForPendingRemoval(); (new AMessage)->postReply(mReplyID); mReplyID = 0; postPendingRepliesAndDeferredMessages(); asyncNotifyPost.clear(); mAsyncReleaseCompleteNotification = asyncNotify; } Loading Loading @@ -3293,17 +3375,21 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { case kWhatSignalEndOfInputStream: { sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); if (!isExecuting() || !mHaveInputSurface) { PostReplyWithError(replyID, INVALID_OPERATION); PostReplyWithError(msg, INVALID_OPERATION); break; } else if (mFlags & kFlagStickyError) { PostReplyWithError(replyID, getStickyError()); PostReplyWithError(msg, getStickyError()); break; } if (mReplyID) { mDeferredMessages.push_back(msg); break; } sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); mReplyID = replyID; mCodec->signalEndOfInputStream(); break; Loading Loading @@ -3345,16 +3431,20 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { case kWhatFlush: { sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); if (!isExecuting()) { PostReplyWithError(replyID, INVALID_OPERATION); PostReplyWithError(msg, INVALID_OPERATION); break; } else if (mFlags & kFlagStickyError) { PostReplyWithError(replyID, getStickyError()); PostReplyWithError(msg, getStickyError()); break; } if (mReplyID) { mDeferredMessages.push_back(msg); break; } sp<AReplyToken> replyID; CHECK(msg->senderAwaitsResponse(&replyID)); mReplyID = replyID; // TODO: skip flushing if already FLUSHED Loading Loading @@ -4188,6 +4278,26 @@ status_t MediaCodec::amendOutputFormatWithCodecSpecificData( return OK; } void MediaCodec::postPendingRepliesAndDeferredMessages(status_t err /* = OK */) { sp<AMessage> response{new AMessage}; if (err != OK) { response->setInt32("err", err); } postPendingRepliesAndDeferredMessages(response); } void MediaCodec::postPendingRepliesAndDeferredMessages(const sp<AMessage> &response) { CHECK(mReplyID); response->postReply(mReplyID); mReplyID.clear(); ALOGV_IF(!mDeferredMessages.empty(), "posting %zu deferred messages", mDeferredMessages.size()); for (sp<AMessage> msg : mDeferredMessages) { msg->post(); } mDeferredMessages.clear(); } std::string MediaCodec::stateString(State state) { const char *rval = NULL; char rawbuffer[16]; // room for "%d" Loading
media/libstagefright/include/media/stagefright/MediaCodec.h +5 −0 Original line number Diff line number Diff line Loading @@ -366,6 +366,7 @@ private: AString mOwnerName; sp<MediaCodecInfo> mCodecInfo; sp<AReplyToken> mReplyID; std::vector<sp<AMessage>> mDeferredMessages; uint32_t mFlags; status_t mStickyError; sp<Surface> mSurface; Loading Loading @@ -435,6 +436,7 @@ private: static status_t PostAndAwaitResponse( const sp<AMessage> &msg, sp<AMessage> *response); void PostReplyWithError(const sp<AMessage> &msg, int32_t err); void PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err); status_t init(const AString &name); Loading Loading @@ -484,6 +486,9 @@ private: bool hasPendingBuffer(int portIndex); bool hasPendingBuffer(); void postPendingRepliesAndDeferredMessages(status_t err = OK); void postPendingRepliesAndDeferredMessages(const sp<AMessage> &response); /* called to get the last codec error when the sticky flag is set. * if no such codec error is found, returns UNKNOWN_ERROR. */ Loading