diff --git a/include/media/stagefright/OMXPluginBase.h b/include/media/stagefright/OMXPluginBase.h index 9643c5fb1d47c..61cc50a54acb1 100644 --- a/include/media/stagefright/OMXPluginBase.h +++ b/include/media/stagefright/OMXPluginBase.h @@ -36,6 +36,9 @@ struct OMXPluginBase { OMX_PTR appData, OMX_COMPONENTTYPE **component) = 0; + virtual OMX_ERRORTYPE destroyComponentInstance( + OMX_COMPONENTTYPE *component) = 0; + virtual OMX_ERRORTYPE enumerateComponents( OMX_STRING name, size_t size, diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h index 09a88169c0402..19d39409cdafe 100644 --- a/media/libstagefright/include/OMXNodeInstance.h +++ b/media/libstagefright/include/OMXNodeInstance.h @@ -26,6 +26,7 @@ namespace android { class IOMXObserver; +struct OMXMaster; struct OMXNodeInstance { OMXNodeInstance( @@ -37,7 +38,7 @@ struct OMXNodeInstance { sp observer(); OMX::node_id nodeID(); - status_t freeNode(); + status_t freeNode(OMXMaster *master); status_t sendCommand(OMX_COMMANDTYPE cmd, OMX_S32 param); status_t getParameter(OMX_INDEXTYPE index, void *params, size_t size); @@ -72,7 +73,7 @@ struct OMXNodeInstance { const char *parameterName, OMX_INDEXTYPE *index); void onMessage(const omx_message &msg); - void onObserverDied(); + void onObserverDied(OMXMaster *master); void onGetHandleFailed(); static OMX_CALLBACKTYPE kCallbacks; diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp index 9f93c31cec5b2..61be8f769480f 100644 --- a/media/libstagefright/omx/OMX.cpp +++ b/media/libstagefright/omx/OMX.cpp @@ -205,7 +205,7 @@ void OMX::binderDied(const wp &the_late_who) { invalidateNodeID_l(instance->nodeID()); } - instance->onObserverDied(); + instance->onObserverDied(mMaster); } status_t OMX::listNodes(List *list) { @@ -262,7 +262,7 @@ status_t OMX::freeNode(node_id node) { mLiveNodes.removeItemsAt(index); instance->observer()->asBinder()->unlinkToDeath(this); - return instance->freeNode(); + return instance->freeNode(mMaster); } status_t OMX::sendCommand( diff --git a/media/libstagefright/omx/OMXMaster.cpp b/media/libstagefright/omx/OMXMaster.cpp index 838a9f7fb477b..12302f30174d9 100644 --- a/media/libstagefright/omx/OMXMaster.cpp +++ b/media/libstagefright/omx/OMXMaster.cpp @@ -60,7 +60,9 @@ void OMXMaster::addVendorPlugin() { (CreateOMXPluginFunc)dlsym( mVendorLibHandle, "_ZN7android15createOMXPluginEv"); - addPlugin((*createOMXPlugin)()); + if (createOMXPlugin) { + addPlugin((*createOMXPlugin)()); + } } void OMXMaster::addPlugin(OMXPluginBase *plugin) { @@ -118,7 +120,32 @@ OMX_ERRORTYPE OMXMaster::makeComponentInstance( } OMXPluginBase *plugin = mPluginByComponentName.valueAt(index); - return plugin->makeComponentInstance(name, callbacks, appData, component); + OMX_ERRORTYPE err = + plugin->makeComponentInstance(name, callbacks, appData, component); + + if (err != OMX_ErrorNone) { + return err; + } + + mPluginByInstance.add(*component, plugin); + + return err; +} + +OMX_ERRORTYPE OMXMaster::destroyComponentInstance( + OMX_COMPONENTTYPE *component) { + Mutex::Autolock autoLock(mLock); + + ssize_t index = mPluginByInstance.indexOfKey(component); + + if (index < 0) { + return OMX_ErrorBadParameter; + } + + OMXPluginBase *plugin = mPluginByInstance.valueAt(index); + mPluginByInstance.removeItemsAt(index); + + return plugin->destroyComponentInstance(component); } OMX_ERRORTYPE OMXMaster::enumerateComponents( diff --git a/media/libstagefright/omx/OMXMaster.h b/media/libstagefright/omx/OMXMaster.h index 63cd664f361e7..e944c4a72cabc 100644 --- a/media/libstagefright/omx/OMXMaster.h +++ b/media/libstagefright/omx/OMXMaster.h @@ -37,6 +37,9 @@ struct OMXMaster : public OMXPluginBase { OMX_PTR appData, OMX_COMPONENTTYPE **component); + virtual OMX_ERRORTYPE destroyComponentInstance( + OMX_COMPONENTTYPE *component); + virtual OMX_ERRORTYPE enumerateComponents( OMX_STRING name, size_t size, @@ -46,6 +49,8 @@ private: Mutex mLock; List mPlugins; KeyedVector mPluginByComponentName; + KeyedVector mPluginByInstance; + void *mVendorLibHandle; void addVendorPlugin(); diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp index 099139aa46e68..288710eabdd4f 100644 --- a/media/libstagefright/omx/OMXNodeInstance.cpp +++ b/media/libstagefright/omx/OMXNodeInstance.cpp @@ -19,6 +19,7 @@ #include #include "../include/OMXNodeInstance.h" +#include "OMXMaster.h" #include @@ -106,7 +107,7 @@ static status_t StatusFromOMXError(OMX_ERRORTYPE err) { return (err == OMX_ErrorNone) ? OK : UNKNOWN_ERROR; } -status_t OMXNodeInstance::freeNode() { +status_t OMXNodeInstance::freeNode(OMXMaster *master) { // Transition the node from its current state all the way down // to "Loaded". // This ensures that all active buffers are properly freed even @@ -157,8 +158,9 @@ status_t OMXNodeInstance::freeNode() { break; } - OMX_ERRORTYPE err = - (*static_cast(mHandle)->ComponentDeInit)(mHandle); + OMX_ERRORTYPE err = master->destroyComponentInstance( + static_cast(mHandle)); + mHandle = NULL; if (err != OMX_ErrorNone) { @@ -384,11 +386,11 @@ void OMXNodeInstance::onMessage(const omx_message &msg) { mObserver->onMessage(msg); } -void OMXNodeInstance::onObserverDied() { +void OMXNodeInstance::onObserverDied(OMXMaster *master) { LOGE("!!! Observer died. Quickly, do something, ... anything..."); // Try to force shutdown of the node and hope for the best. - freeNode(); + freeNode(master); } void OMXNodeInstance::onGetHandleFailed() { diff --git a/media/libstagefright/omx/OMXPVCodecsPlugin.cpp b/media/libstagefright/omx/OMXPVCodecsPlugin.cpp index 3957901e23af3..2bd80947defe7 100644 --- a/media/libstagefright/omx/OMXPVCodecsPlugin.cpp +++ b/media/libstagefright/omx/OMXPVCodecsPlugin.cpp @@ -35,20 +35,16 @@ OMX_ERRORTYPE OMXPVCodecsPlugin::makeComponentInstance( const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData, OMX_COMPONENTTYPE **component) { - OMX_ERRORTYPE err = OMX_MasterGetHandle( + return OMX_MasterGetHandle( reinterpret_cast(component), const_cast(name), appData, const_cast(callbacks)); +} - if (err != OMX_ErrorNone) { - return err; - } - - // PV is not even filling this in... - (*component)->ComponentDeInit = &OMX_MasterFreeHandle; - - return OMX_ErrorNone; +OMX_ERRORTYPE OMXPVCodecsPlugin::destroyComponentInstance( + OMX_COMPONENTTYPE *component) { + return OMX_MasterFreeHandle(component); } OMX_ERRORTYPE OMXPVCodecsPlugin::enumerateComponents( diff --git a/media/libstagefright/omx/OMXPVCodecsPlugin.h b/media/libstagefright/omx/OMXPVCodecsPlugin.h index 55ca87ab60677..f32eede607697 100644 --- a/media/libstagefright/omx/OMXPVCodecsPlugin.h +++ b/media/libstagefright/omx/OMXPVCodecsPlugin.h @@ -32,6 +32,9 @@ struct OMXPVCodecsPlugin : public OMXPluginBase { OMX_PTR appData, OMX_COMPONENTTYPE **component); + virtual OMX_ERRORTYPE destroyComponentInstance( + OMX_COMPONENTTYPE *component); + virtual OMX_ERRORTYPE enumerateComponents( OMX_STRING name, size_t size, diff --git a/media/libstagefright/omx/OMXSoftwareCodecsPlugin.cpp b/media/libstagefright/omx/OMXSoftwareCodecsPlugin.cpp index 22f58cc41ac4d..45610dfb5a3be 100644 --- a/media/libstagefright/omx/OMXSoftwareCodecsPlugin.cpp +++ b/media/libstagefright/omx/OMXSoftwareCodecsPlugin.cpp @@ -63,6 +63,11 @@ OMX_ERRORTYPE OMXSoftwareCodecsPlugin::makeComponentInstance( return OMX_ErrorInvalidComponentName; } +OMX_ERRORTYPE OMXSoftwareCodecsPlugin::destroyComponentInstance( + OMX_COMPONENTTYPE *component) { + return (*component->ComponentDeInit)(component); +} + OMX_ERRORTYPE OMXSoftwareCodecsPlugin::enumerateComponents( OMX_STRING name, size_t size, diff --git a/media/libstagefright/omx/OMXSoftwareCodecsPlugin.h b/media/libstagefright/omx/OMXSoftwareCodecsPlugin.h index dcb5b193ad308..5beeb262fd08a 100644 --- a/media/libstagefright/omx/OMXSoftwareCodecsPlugin.h +++ b/media/libstagefright/omx/OMXSoftwareCodecsPlugin.h @@ -31,6 +31,9 @@ struct OMXSoftwareCodecsPlugin : public OMXPluginBase { OMX_PTR appData, OMX_COMPONENTTYPE **component); + virtual OMX_ERRORTYPE destroyComponentInstance( + OMX_COMPONENTTYPE *component); + virtual OMX_ERRORTYPE enumerateComponents( OMX_STRING name, size_t size,