Loading include/media/stagefright/MediaCodec.h +15 −2 Original line number Diff line number Diff line Loading @@ -55,10 +55,10 @@ struct MediaCodec : public AHandler { struct BatteryNotifier; static sp<MediaCodec> CreateByType( const sp<ALooper> &looper, const char *mime, bool encoder); const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err = NULL); static sp<MediaCodec> CreateByComponentName( const sp<ALooper> &looper, const char *name); const sp<ALooper> &looper, const char *name, status_t *err = NULL); status_t configure( const sp<AMessage> &format, Loading Loading @@ -223,6 +223,7 @@ private: AString mComponentName; uint32_t mReplyID; uint32_t mFlags; status_t mStickyError; sp<Surface> mNativeWindow; SoftwareRenderer *mSoftRenderer; sp<AMessage> mOutputFormat; Loading Loading @@ -304,6 +305,18 @@ private: void updateBatteryStat(); bool isExecuting() const; /* called to get the last codec error when the sticky flag is set. * if no such codec error is found, returns UNKNOWN_ERROR. */ inline status_t getStickyError() const { return mStickyError != 0 ? mStickyError : UNKNOWN_ERROR; } inline void setStickyError(status_t err) { mFlags |= kFlagStickyError; mStickyError = err; } DISALLOW_EVIL_CONSTRUCTORS(MediaCodec); }; Loading include/media/stagefright/MediaErrors.h +38 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,18 @@ namespace android { enum { // status_t map for errors in the media framework // OK or NO_ERROR or 0 represents no error. // See system/core/include/utils/Errors.h // System standard errors from -1 through (possibly) -133 // // Errors with special meanings and side effects. // INVALID_OPERATION: Operation attempted in an illegal state (will try to signal to app). // DEAD_OBJECT: Signal from CodecBase to MediaCodec that MediaServer has died. // NAME_NOT_FOUND: Signal from CodecBase to MediaCodec that the component was not found. // Media errors MEDIA_ERROR_BASE = -1000, ERROR_ALREADY_CONNECTED = MEDIA_ERROR_BASE, Loading Loading @@ -64,8 +76,34 @@ enum { // Heartbeat Error Codes HEARTBEAT_ERROR_BASE = -3000, ERROR_HEARTBEAT_TERMINATE_REQUESTED = HEARTBEAT_ERROR_BASE, // NDK Error codes // frameworks/av/include/ndk/NdkMediaError.h // from -10000 (0xFFFFD8F0 - 0xFFFFD8EC) // from -20000 (0xFFFFB1E0 - 0xFFFFB1D7) // Codec errors are permitted from 0x80001000 through 0x9000FFFF ERROR_CODEC_MAX = (signed)0x9000FFFF, ERROR_CODEC_MIN = (signed)0x80001000, // System unknown errors from 0x80000000 - 0x80000007 (INT32_MIN + 7) // See system/core/include/utils/Errors.h }; // action codes for MediaCodecs that tell the upper layer and application // the severity of any error. enum ActionCode { ACTION_CODE_FATAL, ACTION_CODE_TRANSIENT, ACTION_CODE_RECOVERABLE, }; // returns true if err is a recognized DRM error code static inline bool isCryptoError(status_t err) { return (ERROR_DRM_RESOURCE_BUSY <= err && err <= ERROR_DRM_UNKNOWN) || (ERROR_DRM_VENDOR_MIN <= err && err <= ERROR_DRM_VENDOR_MAX); } } // namespace android #endif // MEDIA_ERRORS_H_ media/libstagefright/ACodec.cpp +66 −6 Original line number Diff line number Diff line Loading @@ -51,6 +51,48 @@ namespace android { // OMX errors are directly mapped into status_t range if // there is no corresponding MediaError status code. // Use the statusFromOMXError(int32_t omxError) function. // // Currently this is a direct map. // See frameworks/native/include/media/openmax/OMX_Core.h // // Vendor OMX errors from 0x90000000 - 0x9000FFFF // Extension OMX errors from 0x8F000000 - 0x90000000 // Standard OMX errors from 0x80001000 - 0x80001024 (0x80001024 current) // // returns true if err is a recognized OMX error code. // as OMX error is OMX_S32, this is an int32_t type static inline bool isOMXError(int32_t err) { return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX); } // converts an OMX error to a status_t static inline status_t statusFromOMXError(int32_t omxError) { switch (omxError) { case OMX_ErrorInvalidComponentName: case OMX_ErrorComponentNotFound: return NAME_NOT_FOUND; // can trigger illegal argument error for provided names. default: return isOMXError(omxError) ? omxError : 0; // no translation required } } // checks and converts status_t to a non-side-effect status_t static inline status_t makeNoSideEffectStatus(status_t err) { switch (err) { // the following errors have side effects and may come // from other code modules. Remap for safety reasons. case INVALID_OPERATION: case DEAD_OBJECT: return UNKNOWN_ERROR; default: return err; } } template<class T> static void InitOMXParams(T *params) { params->nSize = sizeof(T); Loading Loading @@ -3287,8 +3329,18 @@ void ACodec::sendFormatChange(const sp<AMessage> &reply) { void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) { sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", CodecBase::kWhatError); notify->setInt32("omx-error", error); ALOGE("signalError(omxError %#x, internalError %d)", error, internalError); if (internalError == UNKNOWN_ERROR) { // find better error code const status_t omxStatus = statusFromOMXError(error); if (omxStatus != 0) { internalError = omxStatus; } else { ALOGW("Invalid OMX error %#x", error); } } notify->setInt32("err", internalError); notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error. notify->post(); } Loading Loading @@ -3512,6 +3564,7 @@ bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) { case ACodec::kWhatCreateInputSurface: case ACodec::kWhatSignalEndOfInputStream: { // This may result in an app illegal state exception. ALOGE("Message 0x%x was not handled", msg->what()); mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION); return true; Loading @@ -3519,6 +3572,7 @@ bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) { case ACodec::kWhatOMXDied: { // This will result in kFlagSawMediaServerDie handling in MediaCodec. ALOGE("OMX/mediaserver died, signalling error!"); mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT); break; Loading Loading @@ -3617,7 +3671,13 @@ bool ACodec::BaseState::onOMXEvent( ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1); mCodec->signalError((OMX_ERRORTYPE)data1); // verify OMX component sends back an error we expect. OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1; if (!isOMXError(omxError)) { ALOGW("Invalid OMX error %#x", omxError); omxError = OMX_ErrorUndefined; } mCodec->signalError(omxError); return true; } Loading Loading @@ -4060,7 +4120,7 @@ void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) { info->mGraphicBuffer.get(), -1)) == OK) { info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; } else { mCodec->signalError(OMX_ErrorUndefined, err); mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); info->mStatus = BufferInfo::OWNED_BY_US; } } else { Loading Loading @@ -4432,7 +4492,7 @@ bool ACodec::LoadedState::onConfigureComponent( ALOGE("[%s] configureCodec returning error %d", mCodec->mComponentName.c_str(), err); mCodec->signalError(OMX_ErrorUndefined, err); mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); return false; } Loading Loading @@ -4579,7 +4639,7 @@ void ACodec::LoadedToIdleState::stateEntered() { "(error 0x%08x)", err); mCodec->signalError(OMX_ErrorUndefined, err); mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); mCodec->changeState(mCodec->mLoadedState); } Loading Loading @@ -5107,7 +5167,7 @@ bool ACodec::OutputPortSettingsChangedState::onOMXEvent( "port reconfiguration (error 0x%08x)", err); mCodec->signalError(OMX_ErrorUndefined, err); mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); // This is technically not correct, but appears to be // the only way to free the component instance. Loading media/libstagefright/MediaCodec.cpp +78 −36 Original line number Diff line number Diff line Loading @@ -113,24 +113,26 @@ void MediaCodec::BatteryNotifier::noteStopAudio() { } // static sp<MediaCodec> MediaCodec::CreateByType( const sp<ALooper> &looper, const char *mime, bool encoder) { const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err) { sp<MediaCodec> codec = new MediaCodec(looper); if (codec->init(mime, true /* nameIsType */, encoder) != OK) { return NULL; } return codec; const status_t ret = codec->init(mime, true /* nameIsType */, encoder); if (err != NULL) { *err = ret; } return ret == OK ? codec : NULL; // NULL deallocates codec. } // static sp<MediaCodec> MediaCodec::CreateByComponentName( const sp<ALooper> &looper, const char *name) { const sp<ALooper> &looper, const char *name, status_t *err) { sp<MediaCodec> codec = new MediaCodec(looper); if (codec->init(name, false /* nameIsType */, false /* encoder */) != OK) { return NULL; } return codec; const status_t ret = codec->init(name, false /* nameIsType */, false /* encoder */); if (err != NULL) { *err = ret; } return ret == OK ? codec : NULL; // NULL deallocates codec. } MediaCodec::MediaCodec(const sp<ALooper> &looper) Loading @@ -139,6 +141,7 @@ MediaCodec::MediaCodec(const sp<ALooper> &looper) mCodec(NULL), mReplyID(0), mFlags(0), mStickyError(OK), mSoftRenderer(NULL), mBatteryStatNotified(false), mIsVideo(false), Loading Loading @@ -330,6 +333,7 @@ status_t MediaCodec::reset() { mLooper->unregisterHandler(id()); mFlags = 0; // clear all flags mStickyError = OK; // reset state not reset by setState(UNINITIALIZED) mReplyID = 0; Loading Loading @@ -620,10 +624,12 @@ void MediaCodec::cancelPendingDequeueOperations() { bool MediaCodec::handleDequeueInputBuffer(uint32_t replyID, bool newRequest) { if (!isExecuting() || (mFlags & kFlagIsAsync) || (mFlags & kFlagStickyError) || (newRequest && (mFlags & kFlagDequeueInputPending))) { PostReplyWithError(replyID, INVALID_OPERATION); return true; } else if (mFlags & kFlagStickyError) { PostReplyWithError(replyID, getStickyError()); return true; } ssize_t index = dequeuePortBuffer(kPortIndexInput); Loading @@ -644,9 +650,10 @@ bool MediaCodec::handleDequeueOutputBuffer(uint32_t replyID, bool newRequest) { sp<AMessage> response = new AMessage; if (!isExecuting() || (mFlags & kFlagIsAsync) || (mFlags & kFlagStickyError) || (newRequest && (mFlags & kFlagDequeueOutputPending))) { response->setInt32("err", INVALID_OPERATION); } else if (mFlags & kFlagStickyError) { response->setInt32("err", getStickyError()); } else if (mFlags & kFlagOutputBuffersChanged) { response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED); mFlags &= ~kFlagOutputBuffersChanged; Loading Loading @@ -705,16 +712,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { switch (what) { case CodecBase::kWhatError: { int32_t omxError, internalError; CHECK(msg->findInt32("omx-error", &omxError)); CHECK(msg->findInt32("err", &internalError)); ALOGE("Codec reported an error. " "(omx error 0x%08x, internalError %d)", omxError, internalError); int32_t err, actionCode; CHECK(msg->findInt32("err", &err)); CHECK(msg->findInt32("actionCode", &actionCode)); if (omxError == OMX_ErrorResourcesLost && internalError == DEAD_OBJECT) { ALOGE("Codec reported err %#x, actionCode %d", err, actionCode); if (err == DEAD_OBJECT) { mFlags |= kFlagSawMediaServerDie; } Loading Loading @@ -774,35 +777,57 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { { sendErrorReponse = false; mFlags |= kFlagStickyError; setStickyError(err); postActivityNotificationIfPossible(); cancelPendingDequeueOperations(); if (mFlags & kFlagIsAsync) { onError(omxError, 0); onError(err, actionCode); } switch (actionCode) { case ACTION_CODE_TRANSIENT: break; case ACTION_CODE_RECOVERABLE: setState(INITIALIZED); break; default: setState(UNINITIALIZED); break; } break; } default: { sendErrorReponse = false; mFlags |= kFlagStickyError; setStickyError(err); postActivityNotificationIfPossible(); // actionCode in an uninitialized state is always fatal. if (mState == UNINITIALIZED) { actionCode = ACTION_CODE_FATAL; } if (mFlags & kFlagIsAsync) { onError(omxError, 0); onError(err, actionCode); } switch (actionCode) { case ACTION_CODE_TRANSIENT: break; case ACTION_CODE_RECOVERABLE: setState(INITIALIZED); break; default: setState(UNINITIALIZED); break; } break; } } if (sendErrorReponse) { PostReplyWithError(mReplyID, UNKNOWN_ERROR); PostReplyWithError(mReplyID, err); } break; } Loading Loading @@ -1009,7 +1034,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { ALOGE("queueCSDInputBuffer failed w/ error %d", err); mFlags |= kFlagStickyError; setStickyError(err); postActivityNotificationIfPossible(); cancelPendingDequeueOperations(); Loading Loading @@ -1401,9 +1426,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { uint32_t replyID; CHECK(msg->senderAwaitsResponse(&replyID)); if (!isExecuting() || (mFlags & kFlagStickyError)) { if (!isExecuting()) { PostReplyWithError(replyID, INVALID_OPERATION); break; } else if (mFlags & kFlagStickyError) { PostReplyWithError(replyID, getStickyError()); break; } status_t err = onQueueInputBuffer(msg); Loading Loading @@ -1472,9 +1500,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { uint32_t replyID; CHECK(msg->senderAwaitsResponse(&replyID)); if (!isExecuting() || (mFlags & kFlagStickyError)) { if (!isExecuting()) { PostReplyWithError(replyID, INVALID_OPERATION); break; } else if (mFlags & kFlagStickyError) { PostReplyWithError(replyID, getStickyError()); break; } status_t err = onReleaseOutputBuffer(msg); Loading @@ -1488,9 +1519,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { uint32_t replyID; CHECK(msg->senderAwaitsResponse(&replyID)); if (!isExecuting() || (mFlags & kFlagStickyError)) { if (!isExecuting()) { PostReplyWithError(replyID, INVALID_OPERATION); break; } else if (mFlags & kFlagStickyError) { PostReplyWithError(replyID, getStickyError()); break; } mReplyID = replyID; Loading @@ -1503,10 +1537,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { uint32_t replyID; CHECK(msg->senderAwaitsResponse(&replyID)); if (!isExecuting() || (mFlags & kFlagIsAsync) || (mFlags & kFlagStickyError)) { if (!isExecuting() || (mFlags & kFlagIsAsync)) { PostReplyWithError(replyID, INVALID_OPERATION); break; } else if (mFlags & kFlagStickyError) { PostReplyWithError(replyID, getStickyError()); break; } int32_t portIndex; Loading Loading @@ -1535,9 +1571,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { uint32_t replyID; CHECK(msg->senderAwaitsResponse(&replyID)); if (!isExecuting() || (mFlags & kFlagStickyError)) { if (!isExecuting()) { PostReplyWithError(replyID, INVALID_OPERATION); break; } else if (mFlags & kFlagStickyError) { PostReplyWithError(replyID, getStickyError()); break; } mReplyID = replyID; Loading @@ -1561,10 +1600,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { if ((mState != CONFIGURED && mState != STARTING && mState != STARTED && mState != FLUSHING && mState != FLUSHED) || (mFlags & kFlagStickyError) || format == NULL) { PostReplyWithError(replyID, INVALID_OPERATION); break; } else if (mFlags & kFlagStickyError) { PostReplyWithError(replyID, getStickyError()); break; } sp<AMessage> response = new AMessage; Loading Loading @@ -1687,6 +1728,7 @@ void MediaCodec::setState(State newState) { mFlags &= ~kFlagIsEncoder; mFlags &= ~kFlagGatherCodecSpecificData; mFlags &= ~kFlagIsAsync; mStickyError = OK; mActivityNotify.clear(); mCallback.clear(); Loading Loading
include/media/stagefright/MediaCodec.h +15 −2 Original line number Diff line number Diff line Loading @@ -55,10 +55,10 @@ struct MediaCodec : public AHandler { struct BatteryNotifier; static sp<MediaCodec> CreateByType( const sp<ALooper> &looper, const char *mime, bool encoder); const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err = NULL); static sp<MediaCodec> CreateByComponentName( const sp<ALooper> &looper, const char *name); const sp<ALooper> &looper, const char *name, status_t *err = NULL); status_t configure( const sp<AMessage> &format, Loading Loading @@ -223,6 +223,7 @@ private: AString mComponentName; uint32_t mReplyID; uint32_t mFlags; status_t mStickyError; sp<Surface> mNativeWindow; SoftwareRenderer *mSoftRenderer; sp<AMessage> mOutputFormat; Loading Loading @@ -304,6 +305,18 @@ private: void updateBatteryStat(); bool isExecuting() const; /* called to get the last codec error when the sticky flag is set. * if no such codec error is found, returns UNKNOWN_ERROR. */ inline status_t getStickyError() const { return mStickyError != 0 ? mStickyError : UNKNOWN_ERROR; } inline void setStickyError(status_t err) { mFlags |= kFlagStickyError; mStickyError = err; } DISALLOW_EVIL_CONSTRUCTORS(MediaCodec); }; Loading
include/media/stagefright/MediaErrors.h +38 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,18 @@ namespace android { enum { // status_t map for errors in the media framework // OK or NO_ERROR or 0 represents no error. // See system/core/include/utils/Errors.h // System standard errors from -1 through (possibly) -133 // // Errors with special meanings and side effects. // INVALID_OPERATION: Operation attempted in an illegal state (will try to signal to app). // DEAD_OBJECT: Signal from CodecBase to MediaCodec that MediaServer has died. // NAME_NOT_FOUND: Signal from CodecBase to MediaCodec that the component was not found. // Media errors MEDIA_ERROR_BASE = -1000, ERROR_ALREADY_CONNECTED = MEDIA_ERROR_BASE, Loading Loading @@ -64,8 +76,34 @@ enum { // Heartbeat Error Codes HEARTBEAT_ERROR_BASE = -3000, ERROR_HEARTBEAT_TERMINATE_REQUESTED = HEARTBEAT_ERROR_BASE, // NDK Error codes // frameworks/av/include/ndk/NdkMediaError.h // from -10000 (0xFFFFD8F0 - 0xFFFFD8EC) // from -20000 (0xFFFFB1E0 - 0xFFFFB1D7) // Codec errors are permitted from 0x80001000 through 0x9000FFFF ERROR_CODEC_MAX = (signed)0x9000FFFF, ERROR_CODEC_MIN = (signed)0x80001000, // System unknown errors from 0x80000000 - 0x80000007 (INT32_MIN + 7) // See system/core/include/utils/Errors.h }; // action codes for MediaCodecs that tell the upper layer and application // the severity of any error. enum ActionCode { ACTION_CODE_FATAL, ACTION_CODE_TRANSIENT, ACTION_CODE_RECOVERABLE, }; // returns true if err is a recognized DRM error code static inline bool isCryptoError(status_t err) { return (ERROR_DRM_RESOURCE_BUSY <= err && err <= ERROR_DRM_UNKNOWN) || (ERROR_DRM_VENDOR_MIN <= err && err <= ERROR_DRM_VENDOR_MAX); } } // namespace android #endif // MEDIA_ERRORS_H_
media/libstagefright/ACodec.cpp +66 −6 Original line number Diff line number Diff line Loading @@ -51,6 +51,48 @@ namespace android { // OMX errors are directly mapped into status_t range if // there is no corresponding MediaError status code. // Use the statusFromOMXError(int32_t omxError) function. // // Currently this is a direct map. // See frameworks/native/include/media/openmax/OMX_Core.h // // Vendor OMX errors from 0x90000000 - 0x9000FFFF // Extension OMX errors from 0x8F000000 - 0x90000000 // Standard OMX errors from 0x80001000 - 0x80001024 (0x80001024 current) // // returns true if err is a recognized OMX error code. // as OMX error is OMX_S32, this is an int32_t type static inline bool isOMXError(int32_t err) { return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX); } // converts an OMX error to a status_t static inline status_t statusFromOMXError(int32_t omxError) { switch (omxError) { case OMX_ErrorInvalidComponentName: case OMX_ErrorComponentNotFound: return NAME_NOT_FOUND; // can trigger illegal argument error for provided names. default: return isOMXError(omxError) ? omxError : 0; // no translation required } } // checks and converts status_t to a non-side-effect status_t static inline status_t makeNoSideEffectStatus(status_t err) { switch (err) { // the following errors have side effects and may come // from other code modules. Remap for safety reasons. case INVALID_OPERATION: case DEAD_OBJECT: return UNKNOWN_ERROR; default: return err; } } template<class T> static void InitOMXParams(T *params) { params->nSize = sizeof(T); Loading Loading @@ -3287,8 +3329,18 @@ void ACodec::sendFormatChange(const sp<AMessage> &reply) { void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) { sp<AMessage> notify = mNotify->dup(); notify->setInt32("what", CodecBase::kWhatError); notify->setInt32("omx-error", error); ALOGE("signalError(omxError %#x, internalError %d)", error, internalError); if (internalError == UNKNOWN_ERROR) { // find better error code const status_t omxStatus = statusFromOMXError(error); if (omxStatus != 0) { internalError = omxStatus; } else { ALOGW("Invalid OMX error %#x", error); } } notify->setInt32("err", internalError); notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error. notify->post(); } Loading Loading @@ -3512,6 +3564,7 @@ bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) { case ACodec::kWhatCreateInputSurface: case ACodec::kWhatSignalEndOfInputStream: { // This may result in an app illegal state exception. ALOGE("Message 0x%x was not handled", msg->what()); mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION); return true; Loading @@ -3519,6 +3572,7 @@ bool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) { case ACodec::kWhatOMXDied: { // This will result in kFlagSawMediaServerDie handling in MediaCodec. ALOGE("OMX/mediaserver died, signalling error!"); mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT); break; Loading Loading @@ -3617,7 +3671,13 @@ bool ACodec::BaseState::onOMXEvent( ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1); mCodec->signalError((OMX_ERRORTYPE)data1); // verify OMX component sends back an error we expect. OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1; if (!isOMXError(omxError)) { ALOGW("Invalid OMX error %#x", omxError); omxError = OMX_ErrorUndefined; } mCodec->signalError(omxError); return true; } Loading Loading @@ -4060,7 +4120,7 @@ void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) { info->mGraphicBuffer.get(), -1)) == OK) { info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW; } else { mCodec->signalError(OMX_ErrorUndefined, err); mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); info->mStatus = BufferInfo::OWNED_BY_US; } } else { Loading Loading @@ -4432,7 +4492,7 @@ bool ACodec::LoadedState::onConfigureComponent( ALOGE("[%s] configureCodec returning error %d", mCodec->mComponentName.c_str(), err); mCodec->signalError(OMX_ErrorUndefined, err); mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); return false; } Loading Loading @@ -4579,7 +4639,7 @@ void ACodec::LoadedToIdleState::stateEntered() { "(error 0x%08x)", err); mCodec->signalError(OMX_ErrorUndefined, err); mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); mCodec->changeState(mCodec->mLoadedState); } Loading Loading @@ -5107,7 +5167,7 @@ bool ACodec::OutputPortSettingsChangedState::onOMXEvent( "port reconfiguration (error 0x%08x)", err); mCodec->signalError(OMX_ErrorUndefined, err); mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err)); // This is technically not correct, but appears to be // the only way to free the component instance. Loading
media/libstagefright/MediaCodec.cpp +78 −36 Original line number Diff line number Diff line Loading @@ -113,24 +113,26 @@ void MediaCodec::BatteryNotifier::noteStopAudio() { } // static sp<MediaCodec> MediaCodec::CreateByType( const sp<ALooper> &looper, const char *mime, bool encoder) { const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err) { sp<MediaCodec> codec = new MediaCodec(looper); if (codec->init(mime, true /* nameIsType */, encoder) != OK) { return NULL; } return codec; const status_t ret = codec->init(mime, true /* nameIsType */, encoder); if (err != NULL) { *err = ret; } return ret == OK ? codec : NULL; // NULL deallocates codec. } // static sp<MediaCodec> MediaCodec::CreateByComponentName( const sp<ALooper> &looper, const char *name) { const sp<ALooper> &looper, const char *name, status_t *err) { sp<MediaCodec> codec = new MediaCodec(looper); if (codec->init(name, false /* nameIsType */, false /* encoder */) != OK) { return NULL; } return codec; const status_t ret = codec->init(name, false /* nameIsType */, false /* encoder */); if (err != NULL) { *err = ret; } return ret == OK ? codec : NULL; // NULL deallocates codec. } MediaCodec::MediaCodec(const sp<ALooper> &looper) Loading @@ -139,6 +141,7 @@ MediaCodec::MediaCodec(const sp<ALooper> &looper) mCodec(NULL), mReplyID(0), mFlags(0), mStickyError(OK), mSoftRenderer(NULL), mBatteryStatNotified(false), mIsVideo(false), Loading Loading @@ -330,6 +333,7 @@ status_t MediaCodec::reset() { mLooper->unregisterHandler(id()); mFlags = 0; // clear all flags mStickyError = OK; // reset state not reset by setState(UNINITIALIZED) mReplyID = 0; Loading Loading @@ -620,10 +624,12 @@ void MediaCodec::cancelPendingDequeueOperations() { bool MediaCodec::handleDequeueInputBuffer(uint32_t replyID, bool newRequest) { if (!isExecuting() || (mFlags & kFlagIsAsync) || (mFlags & kFlagStickyError) || (newRequest && (mFlags & kFlagDequeueInputPending))) { PostReplyWithError(replyID, INVALID_OPERATION); return true; } else if (mFlags & kFlagStickyError) { PostReplyWithError(replyID, getStickyError()); return true; } ssize_t index = dequeuePortBuffer(kPortIndexInput); Loading @@ -644,9 +650,10 @@ bool MediaCodec::handleDequeueOutputBuffer(uint32_t replyID, bool newRequest) { sp<AMessage> response = new AMessage; if (!isExecuting() || (mFlags & kFlagIsAsync) || (mFlags & kFlagStickyError) || (newRequest && (mFlags & kFlagDequeueOutputPending))) { response->setInt32("err", INVALID_OPERATION); } else if (mFlags & kFlagStickyError) { response->setInt32("err", getStickyError()); } else if (mFlags & kFlagOutputBuffersChanged) { response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED); mFlags &= ~kFlagOutputBuffersChanged; Loading Loading @@ -705,16 +712,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { switch (what) { case CodecBase::kWhatError: { int32_t omxError, internalError; CHECK(msg->findInt32("omx-error", &omxError)); CHECK(msg->findInt32("err", &internalError)); ALOGE("Codec reported an error. " "(omx error 0x%08x, internalError %d)", omxError, internalError); int32_t err, actionCode; CHECK(msg->findInt32("err", &err)); CHECK(msg->findInt32("actionCode", &actionCode)); if (omxError == OMX_ErrorResourcesLost && internalError == DEAD_OBJECT) { ALOGE("Codec reported err %#x, actionCode %d", err, actionCode); if (err == DEAD_OBJECT) { mFlags |= kFlagSawMediaServerDie; } Loading Loading @@ -774,35 +777,57 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { { sendErrorReponse = false; mFlags |= kFlagStickyError; setStickyError(err); postActivityNotificationIfPossible(); cancelPendingDequeueOperations(); if (mFlags & kFlagIsAsync) { onError(omxError, 0); onError(err, actionCode); } switch (actionCode) { case ACTION_CODE_TRANSIENT: break; case ACTION_CODE_RECOVERABLE: setState(INITIALIZED); break; default: setState(UNINITIALIZED); break; } break; } default: { sendErrorReponse = false; mFlags |= kFlagStickyError; setStickyError(err); postActivityNotificationIfPossible(); // actionCode in an uninitialized state is always fatal. if (mState == UNINITIALIZED) { actionCode = ACTION_CODE_FATAL; } if (mFlags & kFlagIsAsync) { onError(omxError, 0); onError(err, actionCode); } switch (actionCode) { case ACTION_CODE_TRANSIENT: break; case ACTION_CODE_RECOVERABLE: setState(INITIALIZED); break; default: setState(UNINITIALIZED); break; } break; } } if (sendErrorReponse) { PostReplyWithError(mReplyID, UNKNOWN_ERROR); PostReplyWithError(mReplyID, err); } break; } Loading Loading @@ -1009,7 +1034,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { ALOGE("queueCSDInputBuffer failed w/ error %d", err); mFlags |= kFlagStickyError; setStickyError(err); postActivityNotificationIfPossible(); cancelPendingDequeueOperations(); Loading Loading @@ -1401,9 +1426,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { uint32_t replyID; CHECK(msg->senderAwaitsResponse(&replyID)); if (!isExecuting() || (mFlags & kFlagStickyError)) { if (!isExecuting()) { PostReplyWithError(replyID, INVALID_OPERATION); break; } else if (mFlags & kFlagStickyError) { PostReplyWithError(replyID, getStickyError()); break; } status_t err = onQueueInputBuffer(msg); Loading Loading @@ -1472,9 +1500,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { uint32_t replyID; CHECK(msg->senderAwaitsResponse(&replyID)); if (!isExecuting() || (mFlags & kFlagStickyError)) { if (!isExecuting()) { PostReplyWithError(replyID, INVALID_OPERATION); break; } else if (mFlags & kFlagStickyError) { PostReplyWithError(replyID, getStickyError()); break; } status_t err = onReleaseOutputBuffer(msg); Loading @@ -1488,9 +1519,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { uint32_t replyID; CHECK(msg->senderAwaitsResponse(&replyID)); if (!isExecuting() || (mFlags & kFlagStickyError)) { if (!isExecuting()) { PostReplyWithError(replyID, INVALID_OPERATION); break; } else if (mFlags & kFlagStickyError) { PostReplyWithError(replyID, getStickyError()); break; } mReplyID = replyID; Loading @@ -1503,10 +1537,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { uint32_t replyID; CHECK(msg->senderAwaitsResponse(&replyID)); if (!isExecuting() || (mFlags & kFlagIsAsync) || (mFlags & kFlagStickyError)) { if (!isExecuting() || (mFlags & kFlagIsAsync)) { PostReplyWithError(replyID, INVALID_OPERATION); break; } else if (mFlags & kFlagStickyError) { PostReplyWithError(replyID, getStickyError()); break; } int32_t portIndex; Loading Loading @@ -1535,9 +1571,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { uint32_t replyID; CHECK(msg->senderAwaitsResponse(&replyID)); if (!isExecuting() || (mFlags & kFlagStickyError)) { if (!isExecuting()) { PostReplyWithError(replyID, INVALID_OPERATION); break; } else if (mFlags & kFlagStickyError) { PostReplyWithError(replyID, getStickyError()); break; } mReplyID = replyID; Loading @@ -1561,10 +1600,12 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { if ((mState != CONFIGURED && mState != STARTING && mState != STARTED && mState != FLUSHING && mState != FLUSHED) || (mFlags & kFlagStickyError) || format == NULL) { PostReplyWithError(replyID, INVALID_OPERATION); break; } else if (mFlags & kFlagStickyError) { PostReplyWithError(replyID, getStickyError()); break; } sp<AMessage> response = new AMessage; Loading Loading @@ -1687,6 +1728,7 @@ void MediaCodec::setState(State newState) { mFlags &= ~kFlagIsEncoder; mFlags &= ~kFlagGatherCodecSpecificData; mFlags &= ~kFlagIsAsync; mStickyError = OK; mActivityNotify.clear(); mCallback.clear(); Loading