blob: 12ab94100d029eb9dd396c568f4321a9f61832e5 [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>
Jamie Gennis33a78142010-08-30 16:48:38 -070027#include <media/stagefright/HardwareAPI.h>
Andreas Huber784202e2009-10-15 13:46:54 -070028#include <media/stagefright/MediaDebug.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() {
94 CHECK_EQ(mHandle, NULL);
95}
96
97void OMXNodeInstance::setHandle(OMX::node_id node_id, OMX_HANDLETYPE handle) {
98 CHECK_EQ(mHandle, NULL);
99 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 {
145 LOGV("forcing Executing->Idle");
146 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) {
153 LOGE("component failed to enter Idle state, aborting.");
154 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 {
171 LOGV("forcing Idle->Loaded");
172 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) {
182 LOGE("component failed to enter Loaded state, aborting.");
183 state = OMX_StateInvalid;
184 break;
185 }
186
Andreas Huber3085c832009-10-26 16:11:54 -0700187 LOGV("waiting for Loaded state...");
188 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
Andreas Huber06be3b12011-01-25 14:55:00 -0800204 LOGV("calling destroyComponentInstance");
Andreas Huberfef64352009-12-04 12:52:40 -0800205 OMX_ERRORTYPE err = master->destroyComponentInstance(
206 static_cast<OMX_COMPONENTTYPE *>(mHandle));
Andreas Huber06be3b12011-01-25 14:55:00 -0800207 LOGV("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) {
212 LOGE("FreeHandle FAILED with error 0x%08x.", err);
213 }
214
215 mOwner->invalidateNodeID(mNodeID);
216 mNodeID = NULL;
217
Andreas Huberad285432009-10-22 09:44:00 -0700218 LOGV("OMXNodeInstance going away.");
219 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 Gennis33a78142010-08-30 16:48:38 -0700269status_t OMXNodeInstance::enableGraphicBuffers(
270 OMX_U32 portIndex, OMX_BOOL enable) {
271 Mutex::Autolock autoLock(mLock);
272
273 OMX_INDEXTYPE index;
274 OMX_ERRORTYPE err = OMX_GetExtensionIndex(
275 mHandle,
276 const_cast<OMX_STRING>("OMX.google.android.index.enableAndroidNativeBuffers"),
277 &index);
278
279 if (err != OMX_ErrorNone) {
280 LOGE("OMX_GetExtensionIndex failed");
281
282 return StatusFromOMXError(err);
283 }
284
285 OMX_VERSIONTYPE ver;
286 ver.s.nVersionMajor = 1;
287 ver.s.nVersionMinor = 0;
288 ver.s.nRevision = 0;
289 ver.s.nStep = 0;
290 EnableAndroidNativeBuffersParams params = {
291 sizeof(EnableAndroidNativeBuffersParams), ver, portIndex, enable,
292 };
293
294 err = OMX_SetParameter(mHandle, index, &params);
295
296 if (err != OMX_ErrorNone) {
297 LOGE("OMX_EnableAndroidNativeBuffers failed with error %d (0x%08x)",
298 err, err);
299
300 return UNKNOWN_ERROR;
301 }
302
303 return OK;
304}
305
Jamie Gennise6befb82011-02-23 19:01:28 -0800306status_t OMXNodeInstance::getGraphicBufferUsage(
307 OMX_U32 portIndex, OMX_U32* usage) {
308 Mutex::Autolock autoLock(mLock);
309
310 OMX_INDEXTYPE index;
311 OMX_ERRORTYPE err = OMX_GetExtensionIndex(
312 mHandle,
313 const_cast<OMX_STRING>(
314 "OMX.google.android.index.getAndroidNativeBufferUsage"),
315 &index);
316
317 if (err != OMX_ErrorNone) {
318 LOGE("OMX_GetExtensionIndex failed");
319
320 return StatusFromOMXError(err);
321 }
322
323 OMX_VERSIONTYPE ver;
324 ver.s.nVersionMajor = 1;
325 ver.s.nVersionMinor = 0;
326 ver.s.nRevision = 0;
327 ver.s.nStep = 0;
328 GetAndroidNativeBufferUsageParams params = {
329 sizeof(GetAndroidNativeBufferUsageParams), ver, portIndex, 0,
330 };
331
332 err = OMX_GetParameter(mHandle, index, &params);
333
334 if (err != OMX_ErrorNone) {
335 LOGE("OMX_GetAndroidNativeBufferUsage failed with error %d (0x%08x)",
336 err, err);
337 return UNKNOWN_ERROR;
338 }
339
340 *usage = params.nUsage;
341
342 return OK;
343}
344
James Dong387e38d2010-10-20 17:38:41 -0700345status_t OMXNodeInstance::storeMetaDataInBuffers(
346 OMX_U32 portIndex,
347 OMX_BOOL enable) {
348 Mutex::Autolock autolock(mLock);
349
350 OMX_INDEXTYPE index;
351 OMX_STRING name = const_cast<OMX_STRING>(
352 "OMX.google.android.index.storeMetaDataInBuffers");
353
354 OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
355 if (err != OMX_ErrorNone) {
356 LOGE("OMX_GetExtensionIndex %s failed", name);
357 return StatusFromOMXError(err);
358 }
359
360 StoreMetaDataInBuffersParams params;
361 memset(&params, 0, sizeof(params));
362 params.nSize = sizeof(params);
363
364 // Version: 1.0.0.0
365 params.nVersion.s.nVersionMajor = 1;
366
367 params.nPortIndex = portIndex;
368 params.bStoreMetaData = enable;
369 if ((err = OMX_SetParameter(mHandle, index, &params)) != OMX_ErrorNone) {
370 LOGE("OMX_SetParameter() failed for StoreMetaDataInBuffers: 0x%08x", err);
371 return UNKNOWN_ERROR;
372 }
373 return err;
374}
375
Andreas Huber784202e2009-10-15 13:46:54 -0700376status_t OMXNodeInstance::useBuffer(
377 OMX_U32 portIndex, const sp<IMemory> &params,
378 OMX::buffer_id *buffer) {
379 Mutex::Autolock autoLock(mLock);
380
381 BufferMeta *buffer_meta = new BufferMeta(params);
382
383 OMX_BUFFERHEADERTYPE *header;
384
385 OMX_ERRORTYPE err = OMX_UseBuffer(
386 mHandle, &header, portIndex, buffer_meta,
387 params->size(), static_cast<OMX_U8 *>(params->pointer()));
388
389 if (err != OMX_ErrorNone) {
390 LOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err);
391
392 delete buffer_meta;
393 buffer_meta = NULL;
394
395 *buffer = 0;
396
397 return UNKNOWN_ERROR;
398 }
399
Andreas Huber71c27d92010-03-19 11:43:15 -0700400 CHECK_EQ(header->pAppPrivate, buffer_meta);
401
Andreas Huber784202e2009-10-15 13:46:54 -0700402 *buffer = header;
403
Andreas Huber3085c832009-10-26 16:11:54 -0700404 addActiveBuffer(portIndex, *buffer);
405
Andreas Huber784202e2009-10-15 13:46:54 -0700406 return OK;
407}
408
Anu Sundararajan3db9f382011-06-22 10:49:21 -0500409status_t OMXNodeInstance::useGraphicBuffer2_l(
410 OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
411 OMX::buffer_id *buffer) {
412
413 // port definition
414 OMX_PARAM_PORTDEFINITIONTYPE def;
415 def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
416 def.nVersion.s.nVersionMajor = 1;
417 def.nVersion.s.nVersionMinor = 0;
418 def.nVersion.s.nRevision = 0;
419 def.nVersion.s.nStep = 0;
420 def.nPortIndex = portIndex;
421 OMX_ERRORTYPE err = OMX_GetParameter(mHandle, OMX_IndexParamPortDefinition, &def);
422 if (err != OK)
423 {
424 LOGE("%s::%d:Error getting OMX_IndexParamPortDefinition", __FUNCTION__, __LINE__);
425 return err;
426 }
427
428 BufferMeta *bufferMeta = new BufferMeta(graphicBuffer);
429
430 OMX_BUFFERHEADERTYPE *header = NULL;
431 OMX_U8* bufferHandle = const_cast<OMX_U8*>(
432 reinterpret_cast<const OMX_U8*>(graphicBuffer->handle));
433
434 err = OMX_UseBuffer(
435 mHandle,
436 &header,
437 portIndex,
438 bufferMeta,
439 def.nBufferSize,
440 bufferHandle);
441
442 if (err != OMX_ErrorNone) {
443 LOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err);
444 delete bufferMeta;
445 bufferMeta = NULL;
446 *buffer = 0;
447 return UNKNOWN_ERROR;
448 }
449
450 CHECK_EQ(header->pBuffer, bufferHandle);
451 CHECK_EQ(header->pAppPrivate, bufferMeta);
452
453 *buffer = header;
454
455 addActiveBuffer(portIndex, *buffer);
456
457 return OK;
458}
459
460// XXX: This function is here for backwards compatibility. Once the OMX
461// implementations have been updated this can be removed and useGraphicBuffer2
462// can be renamed to useGraphicBuffer.
Jamie Gennis33a78142010-08-30 16:48:38 -0700463status_t OMXNodeInstance::useGraphicBuffer(
464 OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
465 OMX::buffer_id *buffer) {
466 Mutex::Autolock autoLock(mLock);
467
Anu Sundararajan3db9f382011-06-22 10:49:21 -0500468 // See if the newer version of the extension is present.
Jamie Gennis33a78142010-08-30 16:48:38 -0700469 OMX_INDEXTYPE index;
Anu Sundararajan3db9f382011-06-22 10:49:21 -0500470 if (OMX_GetExtensionIndex(
471 mHandle,
472 const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer2"),
473 &index) == OMX_ErrorNone) {
474 return useGraphicBuffer2_l(portIndex, graphicBuffer, buffer);
475 }
476
477 LOGW("Falling back to the deprecated useAndroidNativeBuffer support. You "
478 "should switch to the useAndroidNativeBuffer2 extension.");
479
Jamie Gennis33a78142010-08-30 16:48:38 -0700480 OMX_ERRORTYPE err = OMX_GetExtensionIndex(
481 mHandle,
482 const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer"),
483 &index);
484
485 if (err != OMX_ErrorNone) {
486 LOGE("OMX_GetExtensionIndex failed");
487
488 return StatusFromOMXError(err);
489 }
490
491 BufferMeta *bufferMeta = new BufferMeta(graphicBuffer);
492
493 OMX_BUFFERHEADERTYPE *header;
494
495 OMX_VERSIONTYPE ver;
496 ver.s.nVersionMajor = 1;
497 ver.s.nVersionMinor = 0;
498 ver.s.nRevision = 0;
499 ver.s.nStep = 0;
500 UseAndroidNativeBufferParams params = {
501 sizeof(UseAndroidNativeBufferParams), ver, portIndex, bufferMeta,
502 &header, graphicBuffer,
503 };
504
505 err = OMX_SetParameter(mHandle, index, &params);
506
507 if (err != OMX_ErrorNone) {
508 LOGE("OMX_UseAndroidNativeBuffer failed with error %d (0x%08x)", err,
509 err);
510
511 delete bufferMeta;
512 bufferMeta = NULL;
513
514 *buffer = 0;
515
516 return UNKNOWN_ERROR;
517 }
518
519 CHECK_EQ(header->pAppPrivate, bufferMeta);
520
521 *buffer = header;
522
523 addActiveBuffer(portIndex, *buffer);
524
525 return OK;
526}
527
Andreas Huber784202e2009-10-15 13:46:54 -0700528status_t OMXNodeInstance::allocateBuffer(
Andreas Huberc712b9f2010-01-20 15:05:46 -0800529 OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer,
530 void **buffer_data) {
Andreas Huber784202e2009-10-15 13:46:54 -0700531 Mutex::Autolock autoLock(mLock);
532
533 BufferMeta *buffer_meta = new BufferMeta(size);
534
535 OMX_BUFFERHEADERTYPE *header;
536
537 OMX_ERRORTYPE err = OMX_AllocateBuffer(
538 mHandle, &header, portIndex, buffer_meta, size);
539
540 if (err != OMX_ErrorNone) {
541 LOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err);
542
543 delete buffer_meta;
544 buffer_meta = NULL;
545
546 *buffer = 0;
547
548 return UNKNOWN_ERROR;
549 }
550
Andreas Huber71c27d92010-03-19 11:43:15 -0700551 CHECK_EQ(header->pAppPrivate, buffer_meta);
552
Andreas Huber784202e2009-10-15 13:46:54 -0700553 *buffer = header;
Andreas Huberc712b9f2010-01-20 15:05:46 -0800554 *buffer_data = header->pBuffer;
Andreas Huber784202e2009-10-15 13:46:54 -0700555
Andreas Huber3085c832009-10-26 16:11:54 -0700556 addActiveBuffer(portIndex, *buffer);
557
Andreas Huber784202e2009-10-15 13:46:54 -0700558 return OK;
559}
560
561status_t OMXNodeInstance::allocateBufferWithBackup(
562 OMX_U32 portIndex, const sp<IMemory> &params,
563 OMX::buffer_id *buffer) {
564 Mutex::Autolock autoLock(mLock);
565
566 BufferMeta *buffer_meta = new BufferMeta(params, true);
567
568 OMX_BUFFERHEADERTYPE *header;
569
570 OMX_ERRORTYPE err = OMX_AllocateBuffer(
571 mHandle, &header, portIndex, buffer_meta, params->size());
572
573 if (err != OMX_ErrorNone) {
574 LOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err);
575
576 delete buffer_meta;
577 buffer_meta = NULL;
578
579 *buffer = 0;
580
581 return UNKNOWN_ERROR;
582 }
583
Andreas Huber71c27d92010-03-19 11:43:15 -0700584 CHECK_EQ(header->pAppPrivate, buffer_meta);
585
Andreas Huber784202e2009-10-15 13:46:54 -0700586 *buffer = header;
587
Andreas Huber3085c832009-10-26 16:11:54 -0700588 addActiveBuffer(portIndex, *buffer);
589
Andreas Huber784202e2009-10-15 13:46:54 -0700590 return OK;
591}
592
593status_t OMXNodeInstance::freeBuffer(
594 OMX_U32 portIndex, OMX::buffer_id buffer) {
595 Mutex::Autolock autoLock(mLock);
596
Andreas Huber3085c832009-10-26 16:11:54 -0700597 removeActiveBuffer(portIndex, buffer);
598
Andreas Huber784202e2009-10-15 13:46:54 -0700599 OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
600 BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate);
601
602 OMX_ERRORTYPE err = OMX_FreeBuffer(mHandle, portIndex, header);
603
604 delete buffer_meta;
605 buffer_meta = NULL;
606
607 return StatusFromOMXError(err);
608}
609
610status_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer) {
611 Mutex::Autolock autoLock(mLock);
612
613 OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
614 header->nFilledLen = 0;
615 header->nOffset = 0;
616 header->nFlags = 0;
617
618 OMX_ERRORTYPE err = OMX_FillThisBuffer(mHandle, header);
619
620 return StatusFromOMXError(err);
621}
622
623status_t OMXNodeInstance::emptyBuffer(
624 OMX::buffer_id buffer,
625 OMX_U32 rangeOffset, OMX_U32 rangeLength,
626 OMX_U32 flags, OMX_TICKS timestamp) {
627 Mutex::Autolock autoLock(mLock);
628
629 OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
630 header->nFilledLen = rangeLength;
631 header->nOffset = rangeOffset;
632 header->nFlags = flags;
633 header->nTimeStamp = timestamp;
634
635 BufferMeta *buffer_meta =
636 static_cast<BufferMeta *>(header->pAppPrivate);
637 buffer_meta->CopyToOMX(header);
638
639 OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header);
640
641 return StatusFromOMXError(err);
642}
643
644status_t OMXNodeInstance::getExtensionIndex(
645 const char *parameterName, OMX_INDEXTYPE *index) {
646 Mutex::Autolock autoLock(mLock);
647
648 OMX_ERRORTYPE err = OMX_GetExtensionIndex(
649 mHandle, const_cast<char *>(parameterName), index);
650
651 return StatusFromOMXError(err);
652}
653
654void OMXNodeInstance::onMessage(const omx_message &msg) {
655 if (msg.type == omx_message::FILL_BUFFER_DONE) {
656 OMX_BUFFERHEADERTYPE *buffer =
657 static_cast<OMX_BUFFERHEADERTYPE *>(
658 msg.u.extended_buffer_data.buffer);
659
660 BufferMeta *buffer_meta =
661 static_cast<BufferMeta *>(buffer->pAppPrivate);
662
663 buffer_meta->CopyFromOMX(buffer);
664 }
665
666 mObserver->onMessage(msg);
667}
668
Andreas Huberfef64352009-12-04 12:52:40 -0800669void OMXNodeInstance::onObserverDied(OMXMaster *master) {
Andreas Huber784202e2009-10-15 13:46:54 -0700670 LOGE("!!! Observer died. Quickly, do something, ... anything...");
671
672 // Try to force shutdown of the node and hope for the best.
Andreas Huberfef64352009-12-04 12:52:40 -0800673 freeNode(master);
Andreas Huber784202e2009-10-15 13:46:54 -0700674}
675
676void OMXNodeInstance::onGetHandleFailed() {
677 delete this;
678}
679
680// static
681OMX_ERRORTYPE OMXNodeInstance::OnEvent(
682 OMX_IN OMX_HANDLETYPE hComponent,
683 OMX_IN OMX_PTR pAppData,
684 OMX_IN OMX_EVENTTYPE eEvent,
685 OMX_IN OMX_U32 nData1,
686 OMX_IN OMX_U32 nData2,
687 OMX_IN OMX_PTR pEventData) {
688 OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
Andreas Huber2ea14e22009-12-16 09:30:55 -0800689 if (instance->mDying) {
690 return OMX_ErrorNone;
691 }
Andreas Huber784202e2009-10-15 13:46:54 -0700692 return instance->owner()->OnEvent(
693 instance->nodeID(), eEvent, nData1, nData2, pEventData);
694}
695
696// static
697OMX_ERRORTYPE OMXNodeInstance::OnEmptyBufferDone(
698 OMX_IN OMX_HANDLETYPE hComponent,
699 OMX_IN OMX_PTR pAppData,
700 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
701 OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
Andreas Huber2ea14e22009-12-16 09:30:55 -0800702 if (instance->mDying) {
703 return OMX_ErrorNone;
704 }
Andreas Huber784202e2009-10-15 13:46:54 -0700705 return instance->owner()->OnEmptyBufferDone(instance->nodeID(), pBuffer);
706}
707
708// static
709OMX_ERRORTYPE OMXNodeInstance::OnFillBufferDone(
710 OMX_IN OMX_HANDLETYPE hComponent,
711 OMX_IN OMX_PTR pAppData,
712 OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
713 OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
Andreas Huber2ea14e22009-12-16 09:30:55 -0800714 if (instance->mDying) {
715 return OMX_ErrorNone;
716 }
Andreas Huber784202e2009-10-15 13:46:54 -0700717 return instance->owner()->OnFillBufferDone(instance->nodeID(), pBuffer);
718}
719
Andreas Huber3085c832009-10-26 16:11:54 -0700720void OMXNodeInstance::addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id) {
721 ActiveBuffer active;
722 active.mPortIndex = portIndex;
723 active.mID = id;
724 mActiveBuffers.push(active);
725}
726
727void OMXNodeInstance::removeActiveBuffer(
728 OMX_U32 portIndex, OMX::buffer_id id) {
729 bool found = false;
730 for (size_t i = 0; i < mActiveBuffers.size(); ++i) {
731 if (mActiveBuffers[i].mPortIndex == portIndex
732 && mActiveBuffers[i].mID == id) {
733 found = true;
734 mActiveBuffers.removeItemsAt(i);
735 break;
736 }
737 }
738
739 if (!found) {
740 LOGW("Attempt to remove an active buffer we know nothing about...");
741 }
742}
743
744void OMXNodeInstance::freeActiveBuffers() {
745 // Make sure to count down here, as freeBuffer will in turn remove
746 // the active buffer from the vector...
747 for (size_t i = mActiveBuffers.size(); i--;) {
748 freeBuffer(mActiveBuffers[i].mPortIndex, mActiveBuffers[i].mID);
749 }
750}
751
Andreas Huber784202e2009-10-15 13:46:54 -0700752} // namespace android