blob: d89f54be2cc0fa4f8024df211cf8431602160a5e [file] [log] [blame]
Andreas Hubere46b7be2009-07-14 16:56:47 -07001/*
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//#define LOG_NDEBUG 0
18#define LOG_TAG "OMX"
19#include <utils/Log.h>
20
Andreas Huberb0caf942009-12-03 11:39:54 -080021#include <dlfcn.h>
Andreas Huber122ff042010-03-15 09:21:46 -070022
23#include <sys/prctl.h>
Andreas Huber98b29562010-03-12 14:33:12 -080024#include <sys/resource.h>
Andreas Huberb0caf942009-12-03 11:39:54 -080025
Andreas Huber784202e2009-10-15 13:46:54 -070026#include "../include/OMX.h"
Andreas Huber1de13162009-07-31 11:52:50 -070027#include "OMXRenderer.h"
28
Andreas Huber784202e2009-10-15 13:46:54 -070029#include "../include/OMXNodeInstance.h"
Andreas Huberbd7b43b2009-10-13 10:22:55 -070030#include "../include/SoftwareRenderer.h"
Andreas Huberbd7b43b2009-10-13 10:22:55 -070031
Andreas Hubere46b7be2009-07-14 16:56:47 -070032#include <binder/IMemory.h>
Andreas Huberb5ceb9e2009-08-26 14:48:20 -070033#include <media/stagefright/MediaDebug.h>
Andreas Huber1de13162009-07-31 11:52:50 -070034#include <media/stagefright/VideoRenderer.h>
Andreas Huber98b29562010-03-12 14:33:12 -080035#include <utils/threads.h>
Andreas Hubere46b7be2009-07-14 16:56:47 -070036
Andreas Huberb0caf942009-12-03 11:39:54 -080037#include "OMXMaster.h"
38
Andreas Hubere46b7be2009-07-14 16:56:47 -070039#include <OMX_Component.h>
40
41namespace android {
42
Andreas Huberbe06d262009-08-14 14:37:10 -070043////////////////////////////////////////////////////////////////////////////////
44
45struct OMX::CallbackDispatcher : public RefBase {
James Dongc52ced02010-06-14 17:28:05 -070046 CallbackDispatcher(OMXNodeInstance *owner);
Andreas Huberbe06d262009-08-14 14:37:10 -070047
48 void post(const omx_message &msg);
49
50protected:
51 virtual ~CallbackDispatcher();
52
53private:
54 Mutex mLock;
Andreas Huber784202e2009-10-15 13:46:54 -070055
James Dongc52ced02010-06-14 17:28:05 -070056 OMXNodeInstance *mOwner;
Andreas Huberbe06d262009-08-14 14:37:10 -070057 bool mDone;
58 Condition mQueueChanged;
59 List<omx_message> mQueue;
60
61 pthread_t mThread;
62
63 void dispatch(const omx_message &msg);
64
65 static void *ThreadWrapper(void *me);
66 void threadEntry();
67
68 CallbackDispatcher(const CallbackDispatcher &);
69 CallbackDispatcher &operator=(const CallbackDispatcher &);
70};
71
James Dongc52ced02010-06-14 17:28:05 -070072OMX::CallbackDispatcher::CallbackDispatcher(OMXNodeInstance *owner)
Andreas Huber784202e2009-10-15 13:46:54 -070073 : mOwner(owner),
74 mDone(false) {
Andreas Huberbe06d262009-08-14 14:37:10 -070075 pthread_attr_t attr;
76 pthread_attr_init(&attr);
77 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
78
79 pthread_create(&mThread, &attr, ThreadWrapper, this);
80
81 pthread_attr_destroy(&attr);
82}
83
84OMX::CallbackDispatcher::~CallbackDispatcher() {
85 {
86 Mutex::Autolock autoLock(mLock);
87
88 mDone = true;
89 mQueueChanged.signal();
90 }
91
92 void *dummy;
93 pthread_join(mThread, &dummy);
94}
95
96void OMX::CallbackDispatcher::post(const omx_message &msg) {
97 Mutex::Autolock autoLock(mLock);
Andreas Huber98b29562010-03-12 14:33:12 -080098
Andreas Huberbe06d262009-08-14 14:37:10 -070099 mQueue.push_back(msg);
100 mQueueChanged.signal();
101}
102
103void OMX::CallbackDispatcher::dispatch(const omx_message &msg) {
James Dongc52ced02010-06-14 17:28:05 -0700104 if (mOwner == NULL) {
Andreas Huber3085c832009-10-26 16:11:54 -0700105 LOGV("Would have dispatched a message to a node that's already gone.");
Andreas Huber784202e2009-10-15 13:46:54 -0700106 return;
Andreas Huberbe06d262009-08-14 14:37:10 -0700107 }
James Dongc52ced02010-06-14 17:28:05 -0700108 mOwner->onMessage(msg);
Andreas Huberbe06d262009-08-14 14:37:10 -0700109}
110
111// static
112void *OMX::CallbackDispatcher::ThreadWrapper(void *me) {
113 static_cast<CallbackDispatcher *>(me)->threadEntry();
114
115 return NULL;
116}
117
118void OMX::CallbackDispatcher::threadEntry() {
Andreas Huber98b29562010-03-12 14:33:12 -0800119 setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_AUDIO);
120 prctl(PR_SET_NAME, (unsigned long)"OMXCallbackDisp", 0, 0, 0);
121
Andreas Huberbe06d262009-08-14 14:37:10 -0700122 for (;;) {
123 omx_message msg;
124
125 {
126 Mutex::Autolock autoLock(mLock);
127 while (!mDone && mQueue.empty()) {
128 mQueueChanged.wait(mLock);
129 }
130
131 if (mDone) {
132 break;
133 }
134
135 msg = *mQueue.begin();
136 mQueue.erase(mQueue.begin());
137 }
138
139 dispatch(msg);
140 }
141}
142
143////////////////////////////////////////////////////////////////////////////////
144
Andreas Huberbe06d262009-08-14 14:37:10 -0700145OMX::OMX()
Andreas Huberb0caf942009-12-03 11:39:54 -0800146 : mMaster(new OMXMaster),
Andreas Huber784202e2009-10-15 13:46:54 -0700147 mNodeCounter(0) {
Andreas Hubere46b7be2009-07-14 16:56:47 -0700148}
149
Andreas Huberb0caf942009-12-03 11:39:54 -0800150OMX::~OMX() {
151 delete mMaster;
152 mMaster = NULL;
153}
154
Andreas Huber784202e2009-10-15 13:46:54 -0700155void OMX::binderDied(const wp<IBinder> &the_late_who) {
156 OMXNodeInstance *instance;
157
158 {
159 Mutex::Autolock autoLock(mLock);
160
161 ssize_t index = mLiveNodes.indexOfKey(the_late_who);
162 CHECK(index >= 0);
163
164 instance = mLiveNodes.editValueAt(index);
165 mLiveNodes.removeItemsAt(index);
166
Andreas Huber6615def2010-07-07 08:20:49 -0700167 index = mDispatchers.indexOfKey(instance->nodeID());
168 CHECK(index >= 0);
169 mDispatchers.removeItemsAt(index);
170
Andreas Huber784202e2009-10-15 13:46:54 -0700171 invalidateNodeID_l(instance->nodeID());
172 }
173
Andreas Huberfef64352009-12-04 12:52:40 -0800174 instance->onObserverDied(mMaster);
Andreas Huber784202e2009-10-15 13:46:54 -0700175}
176
Andreas Huberf1fe0642010-01-15 15:28:19 -0800177bool OMX::livesLocally(pid_t pid) {
178 return pid == getpid();
179}
180
Andreas Huber2ea14e22009-12-16 09:30:55 -0800181status_t OMX::listNodes(List<ComponentInfo> *list) {
Andreas Hubere46b7be2009-07-14 16:56:47 -0700182 list->clear();
183
184 OMX_U32 index = 0;
185 char componentName[256];
Andreas Huberb0caf942009-12-03 11:39:54 -0800186 while (mMaster->enumerateComponents(
187 componentName, sizeof(componentName), index) == OMX_ErrorNone) {
Andreas Huber2ea14e22009-12-16 09:30:55 -0800188 list->push_back(ComponentInfo());
189 ComponentInfo &info = *--list->end();
Andreas Hubere46b7be2009-07-14 16:56:47 -0700190
Andreas Huber2ea14e22009-12-16 09:30:55 -0800191 info.mName = componentName;
192
193 Vector<String8> roles;
194 OMX_ERRORTYPE err =
195 mMaster->getRolesOfComponent(componentName, &roles);
196
197 if (err == OMX_ErrorNone) {
198 for (OMX_U32 i = 0; i < roles.size(); ++i) {
199 info.mRoles.push_back(roles[i]);
200 }
201 }
Andreas Huberc7e91ee2009-12-15 15:22:08 -0800202
Andreas Hubere46b7be2009-07-14 16:56:47 -0700203 ++index;
204 }
205
206 return OK;
207}
208
Andreas Huber784202e2009-10-15 13:46:54 -0700209status_t OMX::allocateNode(
210 const char *name, const sp<IOMXObserver> &observer, node_id *node) {
Andreas Hubere46b7be2009-07-14 16:56:47 -0700211 Mutex::Autolock autoLock(mLock);
212
213 *node = 0;
214
Andreas Huber784202e2009-10-15 13:46:54 -0700215 OMXNodeInstance *instance = new OMXNodeInstance(this, observer);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700216
Andreas Huberb0caf942009-12-03 11:39:54 -0800217 OMX_COMPONENTTYPE *handle;
218 OMX_ERRORTYPE err = mMaster->makeComponentInstance(
219 name, &OMXNodeInstance::kCallbacks,
220 instance, &handle);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700221
222 if (err != OMX_ErrorNone) {
Andreas Huber53a76bd2009-10-06 16:20:44 -0700223 LOGV("FAILED to allocate omx component '%s'", name);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700224
Andreas Huber784202e2009-10-15 13:46:54 -0700225 instance->onGetHandleFailed();
Andreas Hubere46b7be2009-07-14 16:56:47 -0700226
227 return UNKNOWN_ERROR;
228 }
229
Andreas Huber784202e2009-10-15 13:46:54 -0700230 *node = makeNodeID(instance);
James Dongc52ced02010-06-14 17:28:05 -0700231 mDispatchers.add(*node, new CallbackDispatcher(instance));
Andreas Hubere46b7be2009-07-14 16:56:47 -0700232
Andreas Huber784202e2009-10-15 13:46:54 -0700233 instance->setHandle(*node, handle);
234
235 mLiveNodes.add(observer->asBinder(), instance);
236 observer->asBinder()->linkToDeath(this);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700237
238 return OK;
239}
240
Andreas Huber784202e2009-10-15 13:46:54 -0700241status_t OMX::freeNode(node_id node) {
242 OMXNodeInstance *instance = findInstance(node);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700243
Andreas Huber784202e2009-10-15 13:46:54 -0700244 ssize_t index = mLiveNodes.indexOfKey(instance->observer()->asBinder());
245 CHECK(index >= 0);
246 mLiveNodes.removeItemsAt(index);
Andreas Huber6615def2010-07-07 08:20:49 -0700247
Andreas Huberf98197a2010-09-17 11:49:39 -0700248 instance->observer()->asBinder()->unlinkToDeath(this);
249
250 status_t err = instance->freeNode(mMaster);
251
Andreas Huber6615def2010-07-07 08:20:49 -0700252 index = mDispatchers.indexOfKey(node);
253 CHECK(index >= 0);
254 mDispatchers.removeItemsAt(index);
255
Andreas Huberf98197a2010-09-17 11:49:39 -0700256 return err;
Andreas Hubere46b7be2009-07-14 16:56:47 -0700257}
258
Andreas Huber784202e2009-10-15 13:46:54 -0700259status_t OMX::sendCommand(
Andreas Hubere46b7be2009-07-14 16:56:47 -0700260 node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) {
Andreas Huber784202e2009-10-15 13:46:54 -0700261 return findInstance(node)->sendCommand(cmd, param);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700262}
263
Andreas Huber784202e2009-10-15 13:46:54 -0700264status_t OMX::getParameter(
Andreas Hubere46b7be2009-07-14 16:56:47 -0700265 node_id node, OMX_INDEXTYPE index,
266 void *params, size_t size) {
Andreas Huber784202e2009-10-15 13:46:54 -0700267 return findInstance(node)->getParameter(
268 index, params, size);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700269}
270
Andreas Huber784202e2009-10-15 13:46:54 -0700271status_t OMX::setParameter(
Andreas Hubere46b7be2009-07-14 16:56:47 -0700272 node_id node, OMX_INDEXTYPE index,
273 const void *params, size_t size) {
Andreas Huber784202e2009-10-15 13:46:54 -0700274 return findInstance(node)->setParameter(
275 index, params, size);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700276}
277
Andreas Huber784202e2009-10-15 13:46:54 -0700278status_t OMX::getConfig(
Andreas Huberbe06d262009-08-14 14:37:10 -0700279 node_id node, OMX_INDEXTYPE index,
280 void *params, size_t size) {
Andreas Huber784202e2009-10-15 13:46:54 -0700281 return findInstance(node)->getConfig(
282 index, params, size);
Andreas Huberbe06d262009-08-14 14:37:10 -0700283}
284
Andreas Huber784202e2009-10-15 13:46:54 -0700285status_t OMX::setConfig(
Andreas Huberbe06d262009-08-14 14:37:10 -0700286 node_id node, OMX_INDEXTYPE index,
287 const void *params, size_t size) {
Andreas Huber784202e2009-10-15 13:46:54 -0700288 return findInstance(node)->setConfig(
289 index, params, size);
Andreas Huberbe06d262009-08-14 14:37:10 -0700290}
291
Jamie Gennis33a78142010-08-30 16:48:38 -0700292status_t OMX::enableGraphicBuffers(
293 node_id node, OMX_U32 port_index, OMX_BOOL enable) {
294 return findInstance(node)->enableGraphicBuffers(port_index, enable);
295}
296
Andreas Huber784202e2009-10-15 13:46:54 -0700297status_t OMX::useBuffer(
Andreas Hubere46b7be2009-07-14 16:56:47 -0700298 node_id node, OMX_U32 port_index, const sp<IMemory> &params,
299 buffer_id *buffer) {
Andreas Huber784202e2009-10-15 13:46:54 -0700300 return findInstance(node)->useBuffer(
301 port_index, params, buffer);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700302}
303
Jamie Gennis33a78142010-08-30 16:48:38 -0700304status_t OMX::useGraphicBuffer(
305 node_id node, OMX_U32 port_index,
306 const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) {
307 return findInstance(node)->useGraphicBuffer(
308 port_index, graphicBuffer, buffer);
309}
310
Andreas Huber784202e2009-10-15 13:46:54 -0700311status_t OMX::allocateBuffer(
Andreas Hubere46b7be2009-07-14 16:56:47 -0700312 node_id node, OMX_U32 port_index, size_t size,
Andreas Huberc712b9f2010-01-20 15:05:46 -0800313 buffer_id *buffer, void **buffer_data) {
Andreas Huber784202e2009-10-15 13:46:54 -0700314 return findInstance(node)->allocateBuffer(
Andreas Huberc712b9f2010-01-20 15:05:46 -0800315 port_index, size, buffer, buffer_data);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700316}
317
Andreas Huber784202e2009-10-15 13:46:54 -0700318status_t OMX::allocateBufferWithBackup(
Andreas Hubere46b7be2009-07-14 16:56:47 -0700319 node_id node, OMX_U32 port_index, const sp<IMemory> &params,
320 buffer_id *buffer) {
Andreas Huber784202e2009-10-15 13:46:54 -0700321 return findInstance(node)->allocateBufferWithBackup(
322 port_index, params, buffer);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700323}
324
Andreas Huber784202e2009-10-15 13:46:54 -0700325status_t OMX::freeBuffer(node_id node, OMX_U32 port_index, buffer_id buffer) {
326 return findInstance(node)->freeBuffer(
327 port_index, buffer);
328}
Andreas Hubere46b7be2009-07-14 16:56:47 -0700329
Andreas Huber784202e2009-10-15 13:46:54 -0700330status_t OMX::fillBuffer(node_id node, buffer_id buffer) {
331 return findInstance(node)->fillBuffer(buffer);
332}
Andreas Hubere46b7be2009-07-14 16:56:47 -0700333
Andreas Huber784202e2009-10-15 13:46:54 -0700334status_t OMX::emptyBuffer(
335 node_id node,
336 buffer_id buffer,
337 OMX_U32 range_offset, OMX_U32 range_length,
338 OMX_U32 flags, OMX_TICKS timestamp) {
339 return findInstance(node)->emptyBuffer(
340 buffer, range_offset, range_length, flags, timestamp);
341}
Andreas Hubere46b7be2009-07-14 16:56:47 -0700342
Andreas Huber784202e2009-10-15 13:46:54 -0700343status_t OMX::getExtensionIndex(
344 node_id node,
345 const char *parameter_name,
346 OMX_INDEXTYPE *index) {
347 return findInstance(node)->getExtensionIndex(
348 parameter_name, index);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700349}
350
351OMX_ERRORTYPE OMX::OnEvent(
Andreas Huber784202e2009-10-15 13:46:54 -0700352 node_id node,
Andreas Hubere46b7be2009-07-14 16:56:47 -0700353 OMX_IN OMX_EVENTTYPE eEvent,
354 OMX_IN OMX_U32 nData1,
355 OMX_IN OMX_U32 nData2,
356 OMX_IN OMX_PTR pEventData) {
357 LOGV("OnEvent(%d, %ld, %ld)", eEvent, nData1, nData2);
358
359 omx_message msg;
360 msg.type = omx_message::EVENT;
Andreas Huber784202e2009-10-15 13:46:54 -0700361 msg.node = node;
Andreas Hubere46b7be2009-07-14 16:56:47 -0700362 msg.u.event_data.event = eEvent;
363 msg.u.event_data.data1 = nData1;
364 msg.u.event_data.data2 = nData2;
365
James Dongc52ced02010-06-14 17:28:05 -0700366 findDispatcher(node)->post(msg);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700367
368 return OMX_ErrorNone;
369}
Andreas Huber784202e2009-10-15 13:46:54 -0700370
Andreas Hubere46b7be2009-07-14 16:56:47 -0700371OMX_ERRORTYPE OMX::OnEmptyBufferDone(
Andreas Huber784202e2009-10-15 13:46:54 -0700372 node_id node, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) {
Andreas Hubere46b7be2009-07-14 16:56:47 -0700373 LOGV("OnEmptyBufferDone buffer=%p", pBuffer);
374
375 omx_message msg;
376 msg.type = omx_message::EMPTY_BUFFER_DONE;
Andreas Huber784202e2009-10-15 13:46:54 -0700377 msg.node = node;
Andreas Hubere46b7be2009-07-14 16:56:47 -0700378 msg.u.buffer_data.buffer = pBuffer;
379
James Dongc52ced02010-06-14 17:28:05 -0700380 findDispatcher(node)->post(msg);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700381
382 return OMX_ErrorNone;
383}
384
385OMX_ERRORTYPE OMX::OnFillBufferDone(
Andreas Huber784202e2009-10-15 13:46:54 -0700386 node_id node, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) {
Andreas Hubere46b7be2009-07-14 16:56:47 -0700387 LOGV("OnFillBufferDone buffer=%p", pBuffer);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700388
389 omx_message msg;
390 msg.type = omx_message::FILL_BUFFER_DONE;
Andreas Huber784202e2009-10-15 13:46:54 -0700391 msg.node = node;
Andreas Hubere46b7be2009-07-14 16:56:47 -0700392 msg.u.extended_buffer_data.buffer = pBuffer;
393 msg.u.extended_buffer_data.range_offset = pBuffer->nOffset;
394 msg.u.extended_buffer_data.range_length = pBuffer->nFilledLen;
395 msg.u.extended_buffer_data.flags = pBuffer->nFlags;
396 msg.u.extended_buffer_data.timestamp = pBuffer->nTimeStamp;
397 msg.u.extended_buffer_data.platform_private = pBuffer->pPlatformPrivate;
Andreas Huber52733b82010-01-25 10:41:35 -0800398 msg.u.extended_buffer_data.data_ptr = pBuffer->pBuffer;
Andreas Hubere46b7be2009-07-14 16:56:47 -0700399
James Dongc52ced02010-06-14 17:28:05 -0700400 findDispatcher(node)->post(msg);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700401
402 return OMX_ErrorNone;
403}
404
Andreas Huber784202e2009-10-15 13:46:54 -0700405OMX::node_id OMX::makeNodeID(OMXNodeInstance *instance) {
406 // mLock is already held.
Andreas Hubere46b7be2009-07-14 16:56:47 -0700407
Andreas Huber784202e2009-10-15 13:46:54 -0700408 node_id node = (node_id)++mNodeCounter;
409 mNodeIDToInstance.add(node, instance);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700410
Andreas Huber784202e2009-10-15 13:46:54 -0700411 return node;
Andreas Hubere46b7be2009-07-14 16:56:47 -0700412}
413
Andreas Huber784202e2009-10-15 13:46:54 -0700414OMXNodeInstance *OMX::findInstance(node_id node) {
415 Mutex::Autolock autoLock(mLock);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700416
Andreas Huber784202e2009-10-15 13:46:54 -0700417 ssize_t index = mNodeIDToInstance.indexOfKey(node);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700418
Andreas Huber784202e2009-10-15 13:46:54 -0700419 return index < 0 ? NULL : mNodeIDToInstance.valueAt(index);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700420}
421
James Dongc52ced02010-06-14 17:28:05 -0700422sp<OMX::CallbackDispatcher> OMX::findDispatcher(node_id node) {
423 Mutex::Autolock autoLock(mLock);
424
425 ssize_t index = mDispatchers.indexOfKey(node);
426
427 return index < 0 ? NULL : mDispatchers.valueAt(index);
428}
429
Andreas Huber784202e2009-10-15 13:46:54 -0700430void OMX::invalidateNodeID(node_id node) {
431 Mutex::Autolock autoLock(mLock);
432 invalidateNodeID_l(node);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700433}
Andreas Hubere46b7be2009-07-14 16:56:47 -0700434
Andreas Huber784202e2009-10-15 13:46:54 -0700435void OMX::invalidateNodeID_l(node_id node) {
436 // mLock is held.
437 mNodeIDToInstance.removeItem(node);
Andreas Huberbe06d262009-08-14 14:37:10 -0700438}
439
Andreas Huber1de13162009-07-31 11:52:50 -0700440////////////////////////////////////////////////////////////////////////////////
441
Andreas Huber078f7f02010-02-22 11:24:01 -0800442struct SharedVideoRenderer : public VideoRenderer {
443 SharedVideoRenderer(void *libHandle, VideoRenderer *obj)
444 : mLibHandle(libHandle),
445 mObj(obj) {
446 }
447
448 virtual ~SharedVideoRenderer() {
449 delete mObj;
450 mObj = NULL;
451
452 dlclose(mLibHandle);
453 mLibHandle = NULL;
454 }
455
456 virtual void render(
457 const void *data, size_t size, void *platformPrivate) {
458 return mObj->render(data, size, platformPrivate);
459 }
460
461private:
462 void *mLibHandle;
463 VideoRenderer *mObj;
464
465 SharedVideoRenderer(const SharedVideoRenderer &);
466 SharedVideoRenderer &operator=(const SharedVideoRenderer &);
467};
468
Andreas Huber1de13162009-07-31 11:52:50 -0700469sp<IOMXRenderer> OMX::createRenderer(
470 const sp<ISurface> &surface,
471 const char *componentName,
472 OMX_COLOR_FORMATTYPE colorFormat,
473 size_t encodedWidth, size_t encodedHeight,
474 size_t displayWidth, size_t displayHeight) {
Andreas Huberc8d7c142009-11-11 16:33:17 -0800475 Mutex::Autolock autoLock(mLock);
476
Andreas Huber1de13162009-07-31 11:52:50 -0700477 VideoRenderer *impl = NULL;
478
Andreas Huber078f7f02010-02-22 11:24:01 -0800479 void *libHandle = dlopen("libstagefrighthw.so", RTLD_NOW);
Andreas Huberc8d7c142009-11-11 16:33:17 -0800480
481 if (libHandle) {
482 typedef VideoRenderer *(*CreateRendererFunc)(
483 const sp<ISurface> &surface,
484 const char *componentName,
485 OMX_COLOR_FORMATTYPE colorFormat,
486 size_t displayWidth, size_t displayHeight,
487 size_t decodedWidth, size_t decodedHeight);
488
489 CreateRendererFunc func =
490 (CreateRendererFunc)dlsym(
491 libHandle,
492 "_Z14createRendererRKN7android2spINS_8ISurfaceEEEPKc20"
493 "OMX_COLOR_FORMATTYPEjjjj");
494
495 if (func) {
496 impl = (*func)(surface, componentName, colorFormat,
497 displayWidth, displayHeight, encodedWidth, encodedHeight);
Andreas Huber078f7f02010-02-22 11:24:01 -0800498
499 if (impl) {
500 impl = new SharedVideoRenderer(libHandle, impl);
501 libHandle = NULL;
502 }
503 }
504
505 if (libHandle) {
506 dlclose(libHandle);
507 libHandle = NULL;
Andreas Huberc8d7c142009-11-11 16:33:17 -0800508 }
509 }
510
511 if (!impl) {
Andreas Hubere3c01832010-08-16 08:49:37 -0700512#if 0
Andreas Huber1de13162009-07-31 11:52:50 -0700513 LOGW("Using software renderer.");
514 impl = new SoftwareRenderer(
Andreas Huberc966a3c2009-09-15 14:32:59 -0700515 colorFormat,
Andreas Huber1de13162009-07-31 11:52:50 -0700516 surface,
517 displayWidth, displayHeight,
518 encodedWidth, encodedHeight);
Andreas Hubere3c01832010-08-16 08:49:37 -0700519#else
520 CHECK(!"Should not be here.");
521 return NULL;
522#endif
Andreas Huber1de13162009-07-31 11:52:50 -0700523 }
524
525 return new OMXRenderer(impl);
526}
527
528OMXRenderer::OMXRenderer(VideoRenderer *impl)
529 : mImpl(impl) {
530}
531
532OMXRenderer::~OMXRenderer() {
533 delete mImpl;
534 mImpl = NULL;
535}
536
537void OMXRenderer::render(IOMX::buffer_id buffer) {
538 OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
539
540 mImpl->render(
541 header->pBuffer + header->nOffset,
542 header->nFilledLen,
543 header->pPlatformPrivate);
544}
545
Andreas Hubere46b7be2009-07-14 16:56:47 -0700546} // namespace android