OMX.cpp revision d59b97223424a3974d2ac31cff998d02eecf2eed
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <inttypes.h> 18 19//#define LOG_NDEBUG 0 20#define LOG_TAG "OMX" 21#include <utils/Log.h> 22 23#include <dlfcn.h> 24 25#include "../include/OMX.h" 26 27#include "../include/OMXNodeInstance.h" 28 29#include <media/stagefright/foundation/ADebug.h> 30 31#include "OMXMaster.h" 32#include "OMXUtils.h" 33 34namespace android { 35 36// node ids are created by concatenating the pid with a 16-bit counter 37static size_t kMaxNodeInstances = (1 << 16); 38 39OMX::OMX() 40 : mMaster(new OMXMaster) { 41} 42 43OMX::~OMX() { 44 delete mMaster; 45 mMaster = NULL; 46} 47 48void OMX::binderDied(const wp<IBinder> &the_late_who) { 49 sp<OMXNodeInstance> instance; 50 51 { 52 Mutex::Autolock autoLock(mLock); 53 54 ssize_t index = mLiveNodes.indexOfKey(the_late_who); 55 56 if (index < 0) { 57 ALOGE("b/27597103, nonexistent observer on binderDied"); 58 android_errorWriteLog(0x534e4554, "27597103"); 59 return; 60 } 61 62 instance = mLiveNodes.editValueAt(index); 63 mLiveNodes.removeItemsAt(index); 64 } 65 66 instance->onObserverDied(); 67} 68 69status_t OMX::listNodes(List<ComponentInfo> *list) { 70 list->clear(); 71 72 OMX_U32 index = 0; 73 char componentName[256]; 74 while (mMaster->enumerateComponents( 75 componentName, sizeof(componentName), index) == OMX_ErrorNone) { 76 list->push_back(ComponentInfo()); 77 ComponentInfo &info = *--list->end(); 78 79 info.mName = componentName; 80 81 Vector<String8> roles; 82 OMX_ERRORTYPE err = 83 mMaster->getRolesOfComponent(componentName, &roles); 84 85 if (err == OMX_ErrorNone) { 86 for (OMX_U32 i = 0; i < roles.size(); ++i) { 87 info.mRoles.push_back(roles[i]); 88 } 89 } 90 91 ++index; 92 } 93 94 return OK; 95} 96 97status_t OMX::allocateNode( 98 const char *name, const sp<IOMXObserver> &observer, 99 sp<IBinder> *nodeBinder, sp<IOMXNode> *omxNode) { 100 Mutex::Autolock autoLock(mLock); 101 102 omxNode->clear(); 103 if (nodeBinder != NULL) { 104 *nodeBinder = NULL; 105 } 106 107 if (mLiveNodes.size() == kMaxNodeInstances) { 108 return NO_MEMORY; 109 } 110 111 sp<OMXNodeInstance> instance = new OMXNodeInstance(this, observer, name); 112 113 OMX_COMPONENTTYPE *handle; 114 OMX_ERRORTYPE err = mMaster->makeComponentInstance( 115 name, &OMXNodeInstance::kCallbacks, 116 instance.get(), &handle); 117 118 if (err != OMX_ErrorNone) { 119 ALOGE("FAILED to allocate omx component '%s' err=%s(%#x)", name, asString(err), err); 120 121 return StatusFromOMXError(err); 122 } 123 instance->setHandle(handle); 124 125 mLiveNodes.add(IInterface::asBinder(observer), instance); 126 IInterface::asBinder(observer)->linkToDeath(this); 127 128 *omxNode = instance; 129 130 return OK; 131} 132 133status_t OMX::freeNode(const sp<OMXNodeInstance> &instance) { 134 if (instance == NULL) { 135 return OK; 136 } 137 138 { 139 Mutex::Autolock autoLock(mLock); 140 ssize_t index = mLiveNodes.indexOfKey(IInterface::asBinder(instance->observer())); 141 if (index < 0) { 142 // This could conceivably happen if the observer dies at roughly the 143 // same time that a client attempts to free the node explicitly. 144 return OK; 145 } 146 mLiveNodes.removeItemsAt(index); 147 } 148 149 IInterface::asBinder(instance->observer())->unlinkToDeath(this); 150 151 OMX_ERRORTYPE err = OMX_ErrorNone; 152 if (instance->handle() != NULL) { 153 err = mMaster->destroyComponentInstance( 154 static_cast<OMX_COMPONENTTYPE *>(instance->handle())); 155 } 156 157 return StatusFromOMXError(err); 158} 159 160status_t OMX::createPersistentInputSurface( 161 sp<IGraphicBufferProducer> *bufferProducer, 162 sp<IGraphicBufferConsumer> *bufferConsumer) { 163 return OMXNodeInstance::createPersistentInputSurface( 164 bufferProducer, bufferConsumer); 165} 166 167} // namespace android 168