blob: bff3def81ff3a75ca1326652f19db607ad0d29d0 [file] [log] [blame]
Andreas Huber784202e2009-10-15 13:46:54 -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
Andreas Huber3a28b022011-03-28 14:48:28 -070017//#define LOG_NDEBUG 0
Andreas Huber784202e2009-10-15 13:46:54 -070018#define LOG_TAG "OMXNodeInstance"
19#include <utils/Log.h>
20
21#include "../include/OMXNodeInstance.h"
Andreas Huberfef64352009-12-04 12:52:40 -080022#include "OMXMaster.h"
Andreas Huber784202e2009-10-15 13:46:54 -070023
Andreas Huberb0caf942009-12-03 11:39:54 -080024#include <OMX_Component.h>
Andreas Huber784202e2009-10-15 13:46:54 -070025
26#include <binder/IMemory.h>
James Donge1dea482012-03-12 14:37:53 -070027#include <HardwareAPI.h>
James Dong8e9d67a2012-02-06 23:46:37 -080028#include <media/stagefright/foundation/ADebug.h>
Andreas Huber2a09c7e2010-03-16 11:44:07 -070029#include <media/stagefright/MediaErrors.h>
Andreas Huber784202e2009-10-15 13:46:54 -070030
31namespace android {
32
33struct BufferMeta {
34 BufferMeta(const sp<IMemory> &mem, bool is_backup = false)
35 : mMem(mem),
36 mIsBackup(is_backup) {
37 }
38
39 BufferMeta(size_t size)
40 : mSize(size),
41 mIsBackup(false) {
42 }
43
Jamie Gennis33a78142010-08-30 16:48:38 -070044 BufferMeta(const sp<GraphicBuffer> &graphicBuffer)
45 : mGraphicBuffer(graphicBuffer),
46 mIsBackup(false) {
47 }
48
Andreas Huber784202e2009-10-15 13:46:54 -070049 void CopyFromOMX(const OMX_BUFFERHEADERTYPE *header) {
50 if (!mIsBackup) {
51 return;
52 }
53
54 memcpy((OMX_U8 *)mMem->pointer() + header->nOffset,
55 header->pBuffer + header->nOffset,
56 header->nFilledLen);
57 }
58
59 void CopyToOMX(const OMX_BUFFERHEADERTYPE *header) {
60 if (!mIsBackup) {
61 return;
62 }
63
64 memcpy(header->pBuffer + header->nOffset,
65 (const OMX_U8 *)mMem->pointer() + header->nOffset,
66 header->nFilledLen);
67 }
68
69private:
Jamie Gennis33a78142010-08-30 16:48:38 -070070 sp<GraphicBuffer> mGraphicBuffer;
Andreas Huber784202e2009-10-15 13:46:54 -070071 sp<IMemory> mMem;
72 size_t mSize;
73 bool mIsBackup;
74
75 BufferMeta(const BufferMeta &);
76 BufferMeta &operator=(const BufferMeta &);
77};
78
79// static
80OMX_CALLBACKTYPE OMXNodeInstance::kCallbacks = {
81 &OnEvent, &OnEmptyBufferDone, &OnFillBufferDone
82};
83
84OMXNodeInstance::OMXNodeInstance(
85 OMX *owner, const sp<IOMXObserver> &observer)
86 : mOwner(owner),
87 mNodeID(NULL),
88 mHandle(NULL),
Andreas Huber2ea14e22009-12-16 09:30:55 -080089 mObserver(observer),
90 mDying(false) {
Andreas Huber784202e2009-10-15 13:46:54 -070091}
92
93OMXNodeInstance::~OMXNodeInstance() {
James Dong8e9d67a2012-02-06 23:46:37 -080094 CHECK(mHandle == NULL);
Andreas Huber784202e2009-10-15 13:46:54 -070095}
96
97void OMXNodeInstance::setHandle(OMX::node_id node_id, OMX_HANDLETYPE handle) {
James Dong8e9d67a2012-02-06 23:46:37 -080098 CHECK(mHandle == NULL);
Andreas Huber784202e2009-10-15 13:46:54 -070099 mNodeID = node_id;
100 mHandle = handle;
101}
102
103OMX *OMXNodeInstance::owner() {
104 return mOwner;
105}
106
107sp<IOMXObserver> OMXNodeInstance::observer() {
108 return mObserver;
109}
110
111OMX::node_id OMXNodeInstance::nodeID() {
112 return mNodeID;
113}
114
115static status_t StatusFromOMXError(OMX_ERRORTYPE err) {
Andreas Huber2a09c7e2010-03-16 11:44:07 -0700116 switch (err) {
117 case OMX_ErrorNone:
118 return OK;
119 case OMX_ErrorUnsupportedSetting:
120 return ERROR_UNSUPPORTED;
121 default:
122 return UNKNOWN_ERROR;
123 }
Andreas Huber784202e2009-10-15 13:46:54 -0700124}
125
Andreas Huberfef64352009-12-04 12:52:40 -0800126status_t OMXNodeInstance::freeNode(OMXMaster *master) {
Andreas Huber06be3b12011-01-25 14:55:00 -0800127 static int32_t kMaxNumIterations = 10;
128
Andreas Huber3085c832009-10-26 16:11:54 -0700129 // Transition the node from its current state all the way down
130 // to "Loaded".
131 // This ensures that all active buffers are properly freed even
132 // for components that don't do this themselves on a call to
133 // "FreeHandle".
134
Andreas Huber2ea14e22009-12-16 09:30:55 -0800135 // The code below may trigger some more events to be dispatched
136 // by the OMX component - we want to ignore them as our client
137 // does not expect them.
138 mDying = true;
139
Andreas Huber3085c832009-10-26 16:11:54 -0700140 OMX_STATETYPE state;
141 CHECK_EQ(OMX_GetState(mHandle, &state), OMX_ErrorNone);
142 switch (state) {
143 case OMX_StateExecuting:
144 {
Steve Block71f2cf12011-10-20 11:56:00 +0100145 ALOGV("forcing Executing->Idle");
Andreas Huber3085c832009-10-26 16:11:54 -0700146 sendCommand(OMX_CommandStateSet, OMX_StateIdle);
147 OMX_ERRORTYPE err;
Andreas Huber06be3b12011-01-25 14:55:00 -0800148 int32_t iteration = 0;
Andreas Huber3085c832009-10-26 16:11:54 -0700149 while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone
Andreas Huber9f4557e2010-02-08 12:54:40 -0800150 && state != OMX_StateIdle
151 && state != OMX_StateInvalid) {
Andreas Huber06be3b12011-01-25 14:55:00 -0800152 if (++iteration > kMaxNumIterations) {
Steve Block3762c312012-01-06 19:20:56 +0000153 ALOGE("component failed to enter Idle state, aborting.");
Andreas Huber06be3b12011-01-25 14:55:00 -0800154 state = OMX_StateInvalid;
155 break;
156 }
157
Andreas Huber3085c832009-10-26 16:11:54 -0700158 usleep(100000);
159 }
160 CHECK_EQ(err, OMX_ErrorNone);
161
Andreas Huber9f4557e2010-02-08 12:54:40 -0800162 if (state == OMX_StateInvalid) {
163 break;
164 }
165
Andreas Huber3085c832009-10-26 16:11:54 -0700166 // fall through
167 }
168
169 case OMX_StateIdle:
170 {
Steve Block71f2cf12011-10-20 11:56:00 +0100171 ALOGV("forcing Idle->Loaded");
Andreas Huber3085c832009-10-26 16:11:54 -0700172 sendCommand(OMX_CommandStateSet, OMX_StateLoaded);
173
174 freeActiveBuffers();
175
176 OMX_ERRORTYPE err;
Andreas Huber06be3b12011-01-25 14:55:00 -0800177 int32_t iteration = 0;
Andreas Huber3085c832009-10-26 16:11:54 -0700178 while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone
Andreas Huber9f4557e2010-02-08 12:54:40 -0800179 && state != OMX_StateLoaded
180 && state != OMX_StateInvalid) {
Andreas Huber06be3b12011-01-25 14:55:00 -0800181 if (++iteration > kMaxNumIterations) {
Steve Block3762c312012-01-06 19:20:56 +0000182 ALOGE("component failed to enter Loaded state, aborting.");
Andreas Huber06be3b12011-01-25 14:55:00 -0800183 state = OMX_StateInvalid;
184 break;
185 }
186
Steve Block71f2cf12011-10-20 11:56:00 +0100187 ALOGV("waiting for Loaded state...");
Andreas Huber3085c832009-10-26 16:11:54 -0700188 usleep(100000);
189 }
190 CHECK_EQ(err, OMX_ErrorNone);
191
192 // fall through
193 }
194
195 case OMX_StateLoaded:
Andreas Huber9a50fdf2009-11-06 08:40:09 -0800196 case OMX_StateInvalid:
Andreas Huber3085c832009-10-26 16:11:54 -0700197 break;
198
199 default:
200 CHECK(!"should not be here, unknown state.");
201 break;
202 }
203
Steve Block71f2cf12011-10-20 11:56:00 +0100204 ALOGV("calling destroyComponentInstance");
Andreas Huberfef64352009-12-04 12:52:40 -0800205 OMX_ERRORTYPE err = master->destroyComponentInstance(
206 static_cast<OMX_COMPONENTTYPE *>(mHandle));
Steve Block71f2cf12011-10-20 11:56:00 +0100207 ALOGV("destroyComponentInstance returned err %d", err);
Andreas Huberfef64352009-12-04 12:52:40 -0800208
Andreas Huber784202e2009-10-15 13:46:54 -0700209 mHandle = NULL;
210
211 if (err != OMX_ErrorNone) {
Steve Block3762c312012-01-06 19:20:56 +0000212 ALOGE("FreeHandle FAILED with error 0x%08x.", err);
Andreas Huber784202e2009-10-15 13:46:54 -0700213 }
214
215 mOwner->invalidateNodeID(mNodeID);
216 mNodeID = NULL;
217
Steve Block71f2cf12011-10-20 11:56:00 +0100218 ALOGV("OMXNodeInstance going away.");
Andreas Huberad285432009-10-22 09:44:00 -0700219 delete this;
Andreas Huber784202e2009-10-15 13:46:54 -0700220
221 return StatusFromOMXError(err);
222}
223
224status_t OMXNodeInstance::sendCommand(
225 OMX_COMMANDTYPE cmd, OMX_S32 param) {
226 Mutex::Autolock autoLock(mLock);
227
228 OMX_ERRORTYPE err = OMX_SendCommand(mHandle, cmd, param, NULL);
229 return StatusFromOMXError(err);
230}
231
232status_t OMXNodeInstance::getParameter(
233 OMX_INDEXTYPE index, void *params, size_t size) {
234 Mutex::Autolock autoLock(mLock);
235
236 OMX_ERRORTYPE err = OMX_GetParameter(mHandle, index, params);
Andreas Huber4b3913a2011-05-11 14:13:42 -0700237
Andreas Huber784202e2009-10-15 13:46:54 -0700238 return StatusFromOMXError(err);
239}
240
241status_t OMXNodeInstance::setParameter(
242 OMX_INDEXTYPE index, const void *params, size_t size) {
243 Mutex::Autolock autoLock(mLock);
244
245 OMX_ERRORTYPE err = OMX_SetParameter(
246 mHandle, index, const_cast<void *>(params));
247
248 return StatusFromOMXError(err);
249}
250
251status_t OMXNodeInstance::getConfig(
252 OMX_INDEXTYPE index, void *params, size_t size) {
253 Mutex::Autolock autoLock(mLock);
254
255 OMX_ERRORTYPE err = OMX_GetConfig(mHandle, index, params);
256 return StatusFromOMXError(err);
257}
258
259status_t OMXNodeInstance::setConfig(
260 OMX_INDEXTYPE index, const void *params, size_t size) {
261 Mutex::Autolock autoLock(mLock);
262
263 OMX_ERRORTYPE err = OMX_SetConfig(
264 mHandle, index, const_cast<void *>(params));
265
266 return StatusFromOMXError(err);
267}
268
Jamie Gennis6607b392011-10-19 21:14:13 -0700269status_t OMXNodeInstance::getState(OMX_STATETYPE* state) {
270 Mutex::Autolock autoLock(mLock);
271
272 OMX_ERRORTYPE err = OMX_GetState(mHandle, state);
273
274 return StatusFromOMXError(err);
275}
276
Jamie Gennis33a78142010-08-30 16:48:38 -0700277status_t OMXNodeInstance::enableGraphicBuffers(
278 OMX_U32 portIndex, OMX_BOOL enable) {
279 Mutex::Autolock autoLock(mLock);
280
281 OMX_INDEXTYPE index;
282 OMX_ERRORTYPE err = OMX_GetExtensionIndex(
283 mHandle,
284 const_cast<OMX_STRING>("OMX.google.android.index.enableAndroidNativeBuffers"),
285 &index);
286
287 if (err != OMX_ErrorNone) {
Steve Block3762c312012-01-06 19:20:56 +0000288 ALOGE("OMX_GetExtensionIndex failed");
Jamie Gennis33a78142010-08-30 16:48:38 -0700289
290 return StatusFromOMXError(err);
291 }
292
293 OMX_VERSIONTYPE ver;
294 ver.s.nVersionMajor = 1;
295 ver.s.nVersionMinor = 0;
296 ver.s.nRevision = 0;
297 ver.s.nStep = 0;
298 EnableAndroidNativeBuffersParams params = {
299 sizeof(EnableAndroidNativeBuffersParams), ver, portIndex, enable,
300 };
301
302 err = OMX_SetParameter(mHandle, index, &params);
303
304 if (err != OMX_ErrorNone) {
Steve Block3762c312012-01-06 19:20:56 +0000305 ALOGE("OMX_EnableAndroidNativeBuffers failed with error %d (0x%08x)",
Jamie Gennis33a78142010-08-30 16:48:38 -0700306 err, err);
307
308 return UNKNOWN_ERROR;
309 }
310
311 return OK;
312}
313
Jamie Gennise6befb82011-02-23 19:01:28 -0800314status_t OMXNodeInstance::getGraphicBufferUsage(
315 OMX_U32 portIndex, OMX_U32* usage) {
316 Mutex::Autolock autoLock(mLock);
317
318 OMX_INDEXTYPE index;
319 OMX_ERRORTYPE err = OMX_GetExtensionIndex(
320 mHandle,
321 const_cast<OMX_STRING>(
322 "OMX.google.android.index.getAndroidNativeBufferUsage"),
323 &index);
324
325 if (err != OMX_ErrorNone) {
Steve Block3762c312012-01-06 19:20:56 +0000326 ALOGE("OMX_GetExtensionIndex failed");
Jamie Gennise6befb82011-02-23 19:01:28 -0800327
328 return StatusFromOMXError(err);
329 }
330
331 OMX_VERSIONTYPE ver;
332 ver.s.nVersionMajor = 1;
333 ver.s.nVersionMinor = 0;
334 ver.s.nRevision = 0;
335 ver.s.nStep = 0;
336 GetAndroidNativeBufferUsageParams params = {
337 sizeof(GetAndroidNativeBufferUsageParams), ver, portIndex, 0,
338 };
339
340 err = OMX_GetParameter(mHandle, index, &params);
341
342 if (err != OMX_ErrorNone) {
Steve Block3762c312012-01-06 19:20:56 +0000343 ALOGE("OMX_GetAndroidNativeBufferUsage failed with error %d (0x%08x)",
Jamie Gennise6befb82011-02-23 19:01:28 -0800344 err, err);
345 return UNKNOWN_ERROR;
346 }
347
348 *usage = params.nUsage;
349
350 return OK;
351}
352
James Dong387e38d2010-10-20 17:38:41 -0700353status_t OMXNodeInstance::storeMetaDataInBuffers(
354 OMX_U32 portIndex,
355 OMX_BOOL enable) {
356 Mutex::Autolock autolock(mLock);
357
358 OMX_INDEXTYPE index;
359 OMX_STRING name = const_cast<OMX_STRING>(
360 "OMX.google.android.index.storeMetaDataInBuffers");
361
362 OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
363 if (err != OMX_ErrorNone) {
Steve Block3762c312012-01-06 19:20:56 +0000364 ALOGE("OMX_GetExtensionIndex %s failed", name);
James Dong387e38d2010-10-20 17:38:41 -0700365 return StatusFromOMXError(err);
366 }
367
368 StoreMetaDataInBuffersParams params;
369 memset(&params, 0, sizeof(params));
370 params.nSize = sizeof(params);
371
372 // Version: 1.0.0.0
373 params.nVersion.s.nVersionMajor = 1;
374
375 params.nPortIndex = portIndex;
376 params.bStoreMetaData = enable;
377 if ((err = OMX_SetParameter(mHandle, index, &params)) != OMX_ErrorNone) {
Steve Block3762c312012-01-06 19:20:56 +0000378 ALOGE("OMX_SetParameter() failed for StoreMetaDataInBuffers: 0x%08x", err);
James Dong387e38d2010-10-20 17:38:41 -0700379 return UNKNOWN_ERROR;
380 }
381 return err;
382}
383
Andreas Huber784202e2009-10-15 13:46:54 -0700384status_t OMXNodeInstance::useBuffer(
385 OMX_U32 portIndex, const sp<IMemory> &params,
386 OMX::buffer_id *buffer) {
387 Mutex::Autolock autoLock(mLock);
388
389 BufferMeta *buffer_meta = new BufferMeta(params);
390
391 OMX_BUFFERHEADERTYPE *header;
392
393 OMX_ERRORTYPE err = OMX_UseBuffer(
394 mHandle, &header, portIndex, buffer_meta,
395 params->size(), static_cast<OMX_U8 *>(params->pointer()));
396
397 if (err != OMX_ErrorNone) {
Steve Block3762c312012-01-06 19:20:56 +0000398 ALOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err);
Andreas Huber784202e2009-10-15 13:46:54 -0700399
400 delete buffer_meta;
401 buffer_meta = NULL;
402
403 *buffer = 0;
404
405 return UNKNOWN_ERROR;
406 }
407
Andreas Huber71c27d92010-03-19 11:43:15 -0700408 CHECK_EQ(header->pAppPrivate, buffer_meta);
409
Andreas Huber784202e2009-10-15 13:46:54 -0700410 *buffer = header;
411
Andreas Huber3085c832009-10-26 16:11:54 -0700412 addActiveBuffer(portIndex, *buffer);
413
Andreas Huber784202e2009-10-15 13:46:54 -0700414 return OK;
415}
416
Anu Sundararajan3db9f382011-06-22 10:49:21 -0500417status_t OMXNodeInstance::useGraphicBuffer2_l(
418 OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
419 OMX::buffer_id *buffer) {
420
421 // port definition
422 OMX_PARAM_PORTDEFINITIONTYPE def;
423 def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
424 def.nVersion.s.nVersionMajor = 1;
425 def.nVersion.s.nVersionMinor = 0;
426 def.nVersion.s.nRevision = 0;
427 def.nVersion.s.nStep = 0;
428 def.nPortIndex = portIndex;
429 OMX_ERRORTYPE err = OMX_GetParameter(mHandle, OMX_IndexParamPortDefinition, &def);
Jamie Gennis35c6ec22011-08-11 17:59:24 -0700430 if (err != OMX_ErrorNone)
Anu Sundararajan3db9f382011-06-22 10:49:21 -0500431 {
Steve Block3762c312012-01-06 19:20:56 +0000432 ALOGE("%s::%d:Error getting OMX_IndexParamPortDefinition", __FUNCTION__, __LINE__);
Anu Sundararajan3db9f382011-06-22 10:49:21 -0500433 return err;
434 }
435
436 BufferMeta *bufferMeta = new BufferMeta(graphicBuffer);
437
438 OMX_BUFFERHEADERTYPE *header = NULL;
439 OMX_U8* bufferHandle = const_cast<OMX_U8*>(
440 reinterpret_cast<const OMX_U8*>(graphicBuffer->handle));
441
442 err = OMX_UseBuffer(
443 mHandle,
444 &header,
445 portIndex,
446 bufferMeta,
447 def.nBufferSize,
448 bufferHandle);
449
450 if (err != OMX_ErrorNone) {
Steve Block3762c312012-01-06 19:20:56 +0000451 ALOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err);
Anu Sundararajan3db9f382011-06-22 10:49:21 -0500452 delete bufferMeta;
453 bufferMeta = NULL;
454 *buffer = 0;
455 return UNKNOWN_ERROR;
456 }
457
458 CHECK_EQ(header->pBuffer, bufferHandle);
459 CHECK_EQ(header->pAppPrivate, bufferMeta);
460
461 *buffer = header;
462
463 addActiveBuffer(portIndex, *buffer);
464
465 return OK;
466}
467
468// XXX: This function is here for backwards compatibility. Once the OMX
469// implementations have been updated this can be removed and useGraphicBuffer2
470// can be renamed to useGraphicBuffer.
Jamie Gennis33a78142010-08-30 16:48:38 -0700471status_t OMXNodeInstance::useGraphicBuffer(
472 OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
473 OMX::buffer_id *buffer) {
474 Mutex::Autolock autoLock(mLock);
475
Anu Sundararajan3db9f382011-06-22 10:49:21 -0500476 // See if the newer version of the extension is present.
Jamie Gennis33a78142010-08-30 16:48:38 -0700477 OMX_INDEXTYPE index;
Anu Sundararajan3db9f382011-06-22 10:49:21 -0500478 if (OMX_GetExtensionIndex(
479 mHandle,
480 const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer2"),
481 &index) == OMX_ErrorNone) {
482 return useGraphicBuffer2_l(portIndex, graphicBuffer, buffer);
483 }
484
Jamie Gennis33a78142010-08-30 16:48:38 -0700485 OMX_ERRORTYPE err = OMX_GetExtensionIndex(
486 mHandle,
487 const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer"),
488 &index);
489
490 if (err != OMX_ErrorNone) {
Steve Block3762c312012-01-06 19:20:56 +0000491 ALOGE("OMX_GetExtensionIndex failed");
Jamie Gennis33a78142010-08-30 16:48:38 -0700492
493 return StatusFromOMXError(err);
494 }
495
496 BufferMeta *bufferMeta = new BufferMeta(graphicBuffer);
497
498 OMX_BUFFERHEADERTYPE *header;
499
500 OMX_VERSIONTYPE ver;
501 ver.s.nVersionMajor = 1;
502 ver.s.nVersionMinor = 0;
503 ver.s.nRevision = 0;
504 ver.s.nStep = 0;
505 UseAndroidNativeBufferParams params = {
506 sizeof(UseAndroidNativeBufferParams), ver, portIndex, bufferMeta,
507 &header, graphicBuffer,
508 };
509
510 err = OMX_SetParameter(mHandle, index, &params);
511
512 if (err != OMX_ErrorNone) {
Steve Block3762c312012-01-06 19:20:56 +0000513 ALOGE("OMX_UseAndroidNativeBuffer failed with error %d (0x%08x)", err,
Jamie Gennis33a78142010-08-30 16:48:38 -0700514 err);
515
516 delete bufferMeta;
517 bufferMeta = NULL;
518
519 *buffer = 0;
520
521 return UNKNOWN_ERROR;
522 }
523
524 CHECK_EQ(header->pAppPrivate, bufferMeta);
525
526 *buffer = header;
527
528 addActiveBuffer(portIndex, *buffer);
529
530 return OK;
531}
532
Andreas Huber784202e2009-10-15 13:46:54 -0700533status_t OMXNodeInstance::allocateBuffer(
Andreas Huberc712b9f2010-01-20 15:05:46 -0800534 OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer,
535 void **buffer_data) {
Andreas Huber784202e2009-10-15 13:46:54 -0700536 Mutex::Autolock autoLock(mLock);
537
538 BufferMeta *buffer_meta = new BufferMeta(size);
539
540 OMX_BUFFERHEADERTYPE *header;
541
542 OMX_ERRORTYPE err = OMX_AllocateBuffer(
543 mHandle, &header, portIndex, buffer_meta, size);
544
545 if (err != OMX_ErrorNone) {
Steve Block3762c312012-01-06 19:20:56 +0000546 ALOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err);
Andreas Huber784202e2009-10-15 13:46:54 -0700547
548 delete buffer_meta;
549 buffer_meta = NULL;
550
551 *buffer = 0;
552
553 return UNKNOWN_ERROR;
554 }
555
Andreas Huber71c27d92010-03-19 11:43:15 -0700556 CHECK_EQ(header->pAppPrivate, buffer_meta);
557
Andreas Huber784202e2009-10-15 13:46:54 -0700558 *buffer = header;
Andreas Huberc712b9f2010-01-20 15:05:46 -0800559 *buffer_data = header->pBuffer;
Andreas Huber784202e2009-10-15 13:46:54 -0700560
Andreas Huber3085c832009-10-26 16:11:54 -0700561 addActiveBuffer(portIndex, *buffer);
562
Andreas Huber784202e2009-10-15 13:46:54 -0700563 return OK;
564}
565
566status_t OMXNodeInstance::allocateBufferWithBackup(
567 OMX_U32 portIndex, const sp<IMemory> &params,
568 OMX::buffer_id *buffer) {
569 Mutex::Autolock autoLock(mLock);
570
571 BufferMeta *buffer_meta = new BufferMeta(params, true);
572
573 OMX_BUFFERHEADERTYPE *header;
574
575 OMX_ERRORTYPE err = OMX_AllocateBuffer(
576 mHandle, &header, portIndex, buffer_meta, params->size());
577
578 if (err != OMX_ErrorNone) {
Steve Block3762c312012-01-06 19:20:56 +0000579 ALOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err);
Andreas Huber784202e2009-10-15 13:46:54 -0700580
581 delete buffer_meta;
582 buffer_meta = NULL;
583
584 *buffer = 0;
585
586 return UNKNOWN_ERROR;
587 }
588
Andreas Huber71c27d92010-03-19 11:43:15 -0700589 CHECK_EQ(header->pAppPrivate, buffer_meta);
590
Andreas Huber784202e2009-10-15 13:46:54 -0700591 *buffer = header;
592
Andreas Huber3085c832009-10-26 16:11:54 -0700593 addActiveBuffer(portIndex, *buffer);
594
Andreas Huber784202e2009-10-15 13:46:54 -0700595 return OK;
596}
597
598status_t OMXNodeInstance::freeBuffer(
599 OMX_U32 portIndex, OMX::buffer_id buffer) {
600 Mutex::Autolock autoLock(mLock);
601
Andreas Huber3085c832009-10-26 16:11:54 -0700602 removeActiveBuffer(portIndex, buffer);
603
Andreas Huber784202e2009-10-15 13:46:54 -0700604 OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
605 BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate);
606
607 OMX_ERRORTYPE err = OMX_FreeBuffer(mHandle, portIndex, header);
608
609 delete buffer_meta;
610 buffer_meta = NULL;
611
612 return StatusFromOMXError(err);
613}
614
615status_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer) {
616 Mutex::Autolock autoLock(mLock);
617
618 OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
619 header->nFilledLen = 0;
620 header->nOffset = 0;
621 header->nFlags = 0;
622
623 OMX_ERRORTYPE err = OMX_FillThisBuffer(mHandle, header);
624
625 return StatusFromOMXError(err);
626}
627
628status_t OMXNodeInstance::emptyBuffer(
629 OMX::buffer_id buffer,
630 OMX_U32 rangeOffset, OMX_U32 rangeLength,
631 OMX_U32 flags, OMX_TICKS timestamp) {
632 Mutex::Autolock autoLock(mLock);
633
634 OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
635 header->nFilledLen = rangeLength;
636 header->nOffset = rangeOffset;
637 header->nFlags = flags;
638 header->nTimeStamp = timestamp;
639
640 BufferMeta *buffer_meta =
641 static_cast<BufferMeta *>(header->pAppPrivate);
642 buffer_meta->CopyToOMX(header);
643
644 OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header);
645
646 return StatusFromOMXError(err);
647}
648
649status_t OMXNodeInstance::getExtensionIndex(
650 const char *parameterName, OMX_INDEXTYPE *index) {
651 Mutex::Autolock autoLock(mLock);
652
653 OMX_ERRORTYPE err = OMX_GetExtensionIndex(
654 mHandle, const_cast<char *>(parameterName), index);
655
656 return StatusFromOMXError(err);
657}
658
659void OMXNodeInstance::onMessage(const omx_message &msg) {
660 if (msg.type == omx_message::FILL_BUFFER_DONE) {
661 OMX_BUFFERHEADERTYPE *buffer =
662 static_cast<OMX_BUFFERHEADERTYPE *>(
663 msg.u.extended_buffer_data.buffer);
664
665 BufferMeta *buffer_meta =
666 static_cast<BufferMeta *>(buffer->pAppPrivate);
667
668 buffer_meta->CopyFromOMX(buffer);
669 }
670
671 mObserver->onMessage(msg);
672}
673
Andreas Huberfef64352009-12-04 12:52:40 -0800674void OMXNodeInstance::onObserverDied(OMXMaster *master) {
Steve Block3762c312012-01-06 19:20:56 +0000675 ALOGE("!!! Observer died. Quickly, do something, ... anything...");
Andreas Huber784202e2009-10-15 13:46:54 -0700676
677 // Try to force shutdown of the node and hope for the best.
Andreas Huberfef64352009-12-04 12:52:40 -0800678 freeNode(master);
Andreas Huber784202e2009-10-15 13:46:54 -0700679}
680
681void OMXNodeInstance::onGetHandleFailed() {
682 delete this;
683}
684
685// static
686OMX_ERRORTYPE OMXNodeInstance::OnEvent(
687 OMX_IN OMX_HANDLETYPE hComponent,
688 OMX_IN OMX_PTR pAppData,
689 OMX_IN OMX_EVENTTYPE eEvent,
690 OMX_IN OMX_U32 nData1,
691 OMX_IN OMX_U32 nData2,
692 OMX_IN OMX_PTR pEventData) {
693 OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
Andreas Huber2ea14e22009-12-16 09:30:55 -0800694 if (instance->mDying) {
695 return OMX_ErrorNone;
696 }
Andreas Huber784202e2009-10-15 13:46:54 -0700697 return instance->owner()->OnEvent(
698 instance->nodeID(), eEvent, nData1, nData2, pEventData);
699}
700
701// static
702OMX_ERRORTYPE OMXNodeInstance::OnEmptyBufferDone(
703 OMX_IN OMX_HANDLETYPE hComponent,
704 OMX_IN OMX_PTR pAppData,
705 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
706 OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
Andreas Huber2ea14e22009-12-16 09:30:55 -0800707 if (instance->mDying) {
708 return OMX_ErrorNone;
709 }
Andreas Huber784202e2009-10-15 13:46:54 -0700710 return instance->owner()->OnEmptyBufferDone(instance->nodeID(), pBuffer);
711}
712
713// static
714OMX_ERRORTYPE OMXNodeInstance::OnFillBufferDone(
715 OMX_IN OMX_HANDLETYPE hComponent,
716 OMX_IN OMX_PTR pAppData,
717 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
718 OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
Andreas Huber2ea14e22009-12-16 09:30:55 -0800719 if (instance->mDying) {
720 return OMX_ErrorNone;
721 }
Andreas Huber784202e2009-10-15 13:46:54 -0700722 return instance->owner()->OnFillBufferDone(instance->nodeID(), pBuffer);
723}
724
Andreas Huber3085c832009-10-26 16:11:54 -0700725void OMXNodeInstance::addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id) {
726 ActiveBuffer active;
727 active.mPortIndex = portIndex;
728 active.mID = id;
729 mActiveBuffers.push(active);
730}
731
732void OMXNodeInstance::removeActiveBuffer(
733 OMX_U32 portIndex, OMX::buffer_id id) {
734 bool found = false;
735 for (size_t i = 0; i < mActiveBuffers.size(); ++i) {
736 if (mActiveBuffers[i].mPortIndex == portIndex
737 && mActiveBuffers[i].mID == id) {
738 found = true;
739 mActiveBuffers.removeItemsAt(i);
740 break;
741 }
742 }
743
744 if (!found) {
Steve Block8564c8d2012-01-05 23:22:43 +0000745 ALOGW("Attempt to remove an active buffer we know nothing about...");
Andreas Huber3085c832009-10-26 16:11:54 -0700746 }
747}
748
749void OMXNodeInstance::freeActiveBuffers() {
750 // Make sure to count down here, as freeBuffer will in turn remove
751 // the active buffer from the vector...
752 for (size_t i = mActiveBuffers.size(); i--;) {
753 freeBuffer(mActiveBuffers[i].mPortIndex, mActiveBuffers[i].mID);
754 }
755}
756
Andreas Huber784202e2009-10-15 13:46:54 -0700757} // namespace android