Enable proper cleanup of OMX nodes managed through stagefright.

This commit is contained in:
Andreas Huber
2009-12-04 12:52:40 -08:00
parent 8280c2b15f
commit fef6435a06
10 changed files with 65 additions and 20 deletions

View File

@ -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,

View File

@ -26,6 +26,7 @@
namespace android {
class IOMXObserver;
struct OMXMaster;
struct OMXNodeInstance {
OMXNodeInstance(
@ -37,7 +38,7 @@ struct OMXNodeInstance {
sp<IOMXObserver> 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;

View File

@ -205,7 +205,7 @@ void OMX::binderDied(const wp<IBinder> &the_late_who) {
invalidateNodeID_l(instance->nodeID());
}
instance->onObserverDied();
instance->onObserverDied(mMaster);
}
status_t OMX::listNodes(List<String8> *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(

View File

@ -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(

View File

@ -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<OMXPluginBase *> mPlugins;
KeyedVector<String8, OMXPluginBase *> mPluginByComponentName;
KeyedVector<OMX_COMPONENTTYPE *, OMXPluginBase *> mPluginByInstance;
void *mVendorLibHandle;
void addVendorPlugin();

View File

@ -19,6 +19,7 @@
#include <utils/Log.h>
#include "../include/OMXNodeInstance.h"
#include "OMXMaster.h"
#include <OMX_Component.h>
@ -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<OMX_COMPONENTTYPE *>(mHandle)->ComponentDeInit)(mHandle);
OMX_ERRORTYPE err = master->destroyComponentInstance(
static_cast<OMX_COMPONENTTYPE *>(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() {

View File

@ -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<OMX_HANDLETYPE *>(component),
const_cast<char *>(name),
appData,
const_cast<OMX_CALLBACKTYPE *>(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(

View File

@ -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,

View File

@ -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,

View File

@ -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,