OMXNodeInstance.cpp revision e870772a78ffe08b1c14a791e368f1499f1be0f3
1318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber/*
2318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber * Copyright (C) 2009 The Android Open Source Project
3318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber *
4318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber * you may not use this file except in compliance with the License.
6318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber * You may obtain a copy of the License at
7318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber *
8318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber *
10318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber * Unless required by applicable law or agreed to in writing, software
11318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber * See the License for the specific language governing permissions and
14318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber * limitations under the License.
15318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber */
16318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
17318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber//#define LOG_NDEBUG 0
18318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber#define LOG_TAG "OMXNodeInstance"
19318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber#include <utils/Log.h>
20318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
21318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber#include "../include/OMXNodeInstance.h"
22f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber#include "OMXMaster.h"
23318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
24e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#include <OMX_Component.h>
25318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
26318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber#include <binder/IMemory.h>
2783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis#include <media/stagefright/HardwareAPI.h>
28318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber#include <media/stagefright/MediaDebug.h>
292a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber#include <media/stagefright/MediaErrors.h>
30318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
31318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Hubernamespace android {
32318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
33318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstruct BufferMeta {
34318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta(const sp<IMemory> &mem, bool is_backup = false)
35318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        : mMem(mem),
36318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber          mIsBackup(is_backup) {
37318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
38318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
39318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta(size_t size)
40318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        : mSize(size),
41318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber          mIsBackup(false) {
42318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
43318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
4483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    BufferMeta(const sp<GraphicBuffer> &graphicBuffer)
4583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        : mGraphicBuffer(graphicBuffer),
4683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis          mIsBackup(false) {
4783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    }
4883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
49318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    void CopyFromOMX(const OMX_BUFFERHEADERTYPE *header) {
50318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        if (!mIsBackup) {
51318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            return;
52318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        }
53318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
54318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        memcpy((OMX_U8 *)mMem->pointer() + header->nOffset,
55318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber               header->pBuffer + header->nOffset,
56318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber               header->nFilledLen);
57318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
58318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
59318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    void CopyToOMX(const OMX_BUFFERHEADERTYPE *header) {
60318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        if (!mIsBackup) {
61318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            return;
62318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        }
63318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
64318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        memcpy(header->pBuffer + header->nOffset,
65318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber               (const OMX_U8 *)mMem->pointer() + header->nOffset,
66318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber               header->nFilledLen);
67318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
68318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
69318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberprivate:
7083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    sp<GraphicBuffer> mGraphicBuffer;
71318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    sp<IMemory> mMem;
72318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    size_t mSize;
73318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    bool mIsBackup;
74318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
75318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta(const BufferMeta &);
76318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta &operator=(const BufferMeta &);
77318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber};
78318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
79318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber// static
80318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMX_CALLBACKTYPE OMXNodeInstance::kCallbacks = {
81318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    &OnEvent, &OnEmptyBufferDone, &OnFillBufferDone
82318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber};
83318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
84318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMXNodeInstance::OMXNodeInstance(
85318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX *owner, const sp<IOMXObserver> &observer)
86318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    : mOwner(owner),
87318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber      mNodeID(NULL),
88318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber      mHandle(NULL),
89134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber      mObserver(observer),
90134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber      mDying(false) {
91318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
92318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
93318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMXNodeInstance::~OMXNodeInstance() {
94318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    CHECK_EQ(mHandle, NULL);
95318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
96318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
97318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Hubervoid OMXNodeInstance::setHandle(OMX::node_id node_id, OMX_HANDLETYPE handle) {
98318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    CHECK_EQ(mHandle, NULL);
99318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    mNodeID = node_id;
100318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    mHandle = handle;
101318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
102318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
103318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMX *OMXNodeInstance::owner() {
104318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return mOwner;
105318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
106318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
107318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Hubersp<IOMXObserver> OMXNodeInstance::observer() {
108318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return mObserver;
109318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
110318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
111318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMX::node_id OMXNodeInstance::nodeID() {
112318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return mNodeID;
113318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
114318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
115318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatic status_t StatusFromOMXError(OMX_ERRORTYPE err) {
1162a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber    switch (err) {
1172a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        case OMX_ErrorNone:
1182a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber            return OK;
1192a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        case OMX_ErrorUnsupportedSetting:
1202a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber            return ERROR_UNSUPPORTED;
1212a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        default:
1222a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber            return UNKNOWN_ERROR;
1232a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber    }
124318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
125318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
126f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huberstatus_t OMXNodeInstance::freeNode(OMXMaster *master) {
127d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // Transition the node from its current state all the way down
128d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // to "Loaded".
129d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // This ensures that all active buffers are properly freed even
130d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // for components that don't do this themselves on a call to
131d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // "FreeHandle".
132d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
133134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    // The code below may trigger some more events to be dispatched
134134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    // by the OMX component - we want to ignore them as our client
135134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    // does not expect them.
136134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    mDying = true;
137134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber
138d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    OMX_STATETYPE state;
139d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    CHECK_EQ(OMX_GetState(mHandle, &state), OMX_ErrorNone);
140d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    switch (state) {
141d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        case OMX_StateExecuting:
142d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        {
143d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            LOGV("forcing Executing->Idle");
144d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            sendCommand(OMX_CommandStateSet, OMX_StateIdle);
145d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            OMX_ERRORTYPE err;
146d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone
1470d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber                   && state != OMX_StateIdle
1480d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber                   && state != OMX_StateInvalid) {
149d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber                usleep(100000);
150d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            }
151d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            CHECK_EQ(err, OMX_ErrorNone);
152d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
1530d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber            if (state == OMX_StateInvalid) {
1540d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber                break;
1550d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber            }
1560d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber
157d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            // fall through
158d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        }
159d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
160d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        case OMX_StateIdle:
161d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        {
162d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            LOGV("forcing Idle->Loaded");
163d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            sendCommand(OMX_CommandStateSet, OMX_StateLoaded);
164d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
165d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            freeActiveBuffers();
166d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
167d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            OMX_ERRORTYPE err;
168d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone
1690d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber                   && state != OMX_StateLoaded
1700d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber                   && state != OMX_StateInvalid) {
171d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber                LOGV("waiting for Loaded state...");
172d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber                usleep(100000);
173d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            }
174d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            CHECK_EQ(err, OMX_ErrorNone);
175d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
176d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            // fall through
177d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        }
178d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
179d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        case OMX_StateLoaded:
180fa70cad40b01627ac1c22e04cdd548ece9c2654fAndreas Huber        case OMX_StateInvalid:
181d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            break;
182d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
183d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        default:
184d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            CHECK(!"should not be here, unknown state.");
185d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            break;
186d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    }
187d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
188f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    OMX_ERRORTYPE err = master->destroyComponentInstance(
189f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber            static_cast<OMX_COMPONENTTYPE *>(mHandle));
190f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber
191318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    mHandle = NULL;
192318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
193318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    if (err != OMX_ErrorNone) {
194318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        LOGE("FreeHandle FAILED with error 0x%08x.", err);
195318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
196318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
197318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    mOwner->invalidateNodeID(mNodeID);
198318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    mNodeID = NULL;
199318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
20047bed1a7755ed58fa5d4c0d35b20468deb83bd60Andreas Huber    LOGV("OMXNodeInstance going away.");
20147bed1a7755ed58fa5d4c0d35b20468deb83bd60Andreas Huber    delete this;
202318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
203318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
204318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
205318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
206318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::sendCommand(
207318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_COMMANDTYPE cmd, OMX_S32 param) {
208318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
209318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
210318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_SendCommand(mHandle, cmd, param, NULL);
211318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
212318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
213318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
214318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::getParameter(
215318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_INDEXTYPE index, void *params, size_t size) {
216318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
217318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
218318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_GetParameter(mHandle, index, params);
219318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
220318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
221318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
222318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::setParameter(
223318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_INDEXTYPE index, const void *params, size_t size) {
224318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
225318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
226318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_SetParameter(
227318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, index, const_cast<void *>(params));
228318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
229318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
230318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
231318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
232318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::getConfig(
233318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_INDEXTYPE index, void *params, size_t size) {
234318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
235318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
236318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_GetConfig(mHandle, index, params);
237318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
238318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
239318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
240318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::setConfig(
241318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_INDEXTYPE index, const void *params, size_t size) {
242318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
243318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
244318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_SetConfig(
245318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, index, const_cast<void *>(params));
246318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
247318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
248318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
249318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
25083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennisstatus_t OMXNodeInstance::enableGraphicBuffers(
25183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        OMX_U32 portIndex, OMX_BOOL enable) {
25283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    Mutex::Autolock autoLock(mLock);
25383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
25483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    OMX_INDEXTYPE index;
25583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    OMX_ERRORTYPE err = OMX_GetExtensionIndex(
25683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis            mHandle,
25783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis            const_cast<OMX_STRING>("OMX.google.android.index.enableAndroidNativeBuffers"),
25883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis            &index);
25983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
26083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    if (err != OMX_ErrorNone) {
26183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        LOGE("OMX_GetExtensionIndex failed");
26283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
26383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        return StatusFromOMXError(err);
26483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    }
26583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
26683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    OMX_VERSIONTYPE ver;
26783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nVersionMajor = 1;
26883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nVersionMinor = 0;
26983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nRevision = 0;
27083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nStep = 0;
27183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    EnableAndroidNativeBuffersParams params = {
27283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        sizeof(EnableAndroidNativeBuffersParams), ver, portIndex, enable,
27383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    };
27483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
27583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    err = OMX_SetParameter(mHandle, index, &params);
27683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
27783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    if (err != OMX_ErrorNone) {
27883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        LOGE("OMX_EnableAndroidNativeBuffers failed with error %d (0x%08x)",
27983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis                err, err);
28083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
28183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        return UNKNOWN_ERROR;
28283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    }
28383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
28483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    return OK;
28583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis}
28683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
287e870772a78ffe08b1c14a791e368f1499f1be0f3James Dongstatus_t OMXNodeInstance::storeMetaDataInBuffers(
288e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong        OMX_U32 portIndex,
289e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong        OMX_BOOL enable) {
290e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    Mutex::Autolock autolock(mLock);
291e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
292e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    OMX_INDEXTYPE index;
293e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    OMX_STRING name = const_cast<OMX_STRING>(
294e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong            "OMX.google.android.index.storeMetaDataInBuffers");
295e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
296e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
297e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    if (err != OMX_ErrorNone) {
298e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong        LOGE("OMX_GetExtensionIndex %s failed", name);
299e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong        return StatusFromOMXError(err);
300e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    }
301e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
302e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    StoreMetaDataInBuffersParams params;
303e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    memset(&params, 0, sizeof(params));
304e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    params.nSize = sizeof(params);
305e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
306e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    // Version: 1.0.0.0
307e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    params.nVersion.s.nVersionMajor = 1;
308e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
309e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    params.nPortIndex = portIndex;
310e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    params.bStoreMetaData = enable;
311e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    if ((err = OMX_SetParameter(mHandle, index, &params)) != OMX_ErrorNone) {
312e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong        LOGE("OMX_SetParameter() failed for StoreMetaDataInBuffers: 0x%08x", err);
313e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong        return UNKNOWN_ERROR;
314e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    }
315e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    return err;
316e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong}
317e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
318318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::useBuffer(
319318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_U32 portIndex, const sp<IMemory> &params,
320318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX::buffer_id *buffer) {
321318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
322318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
323318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta *buffer_meta = new BufferMeta(params);
324318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
325318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_BUFFERHEADERTYPE *header;
326318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
327318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_UseBuffer(
328318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, &header, portIndex, buffer_meta,
329318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            params->size(), static_cast<OMX_U8 *>(params->pointer()));
330318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
331318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    if (err != OMX_ErrorNone) {
332318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        LOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err);
333318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
334318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        delete buffer_meta;
335318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        buffer_meta = NULL;
336318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
337318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        *buffer = 0;
338318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
339318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        return UNKNOWN_ERROR;
340318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
341318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
34203b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber    CHECK_EQ(header->pAppPrivate, buffer_meta);
34303b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber
344318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    *buffer = header;
345318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
346d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    addActiveBuffer(portIndex, *buffer);
347d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
348318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return OK;
349318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
350318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
35183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennisstatus_t OMXNodeInstance::useGraphicBuffer(
35283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
35383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        OMX::buffer_id *buffer) {
35483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    Mutex::Autolock autoLock(mLock);
35583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
35683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    OMX_INDEXTYPE index;
35783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    OMX_ERRORTYPE err = OMX_GetExtensionIndex(
35883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis            mHandle,
35983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis            const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer"),
36083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis            &index);
36183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
36283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    if (err != OMX_ErrorNone) {
36383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        LOGE("OMX_GetExtensionIndex failed");
36483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
36583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        return StatusFromOMXError(err);
36683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    }
36783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
36883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    BufferMeta *bufferMeta = new BufferMeta(graphicBuffer);
36983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
37083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    OMX_BUFFERHEADERTYPE *header;
37183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
37283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    OMX_VERSIONTYPE ver;
37383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nVersionMajor = 1;
37483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nVersionMinor = 0;
37583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nRevision = 0;
37683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nStep = 0;
37783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    UseAndroidNativeBufferParams params = {
37883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        sizeof(UseAndroidNativeBufferParams), ver, portIndex, bufferMeta,
37983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        &header, graphicBuffer,
38083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    };
38183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
38283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    err = OMX_SetParameter(mHandle, index, &params);
38383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
38483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    if (err != OMX_ErrorNone) {
38583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        LOGE("OMX_UseAndroidNativeBuffer failed with error %d (0x%08x)", err,
38683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis                err);
38783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
38883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        delete bufferMeta;
38983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        bufferMeta = NULL;
39083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
39183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        *buffer = 0;
39283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
39383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        return UNKNOWN_ERROR;
39483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    }
39583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
39683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    CHECK_EQ(header->pAppPrivate, bufferMeta);
39783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
39883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    *buffer = header;
39983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
40083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    addActiveBuffer(portIndex, *buffer);
40183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
40283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    return OK;
40383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis}
40483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
405318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::allocateBuffer(
406570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber        OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer,
407570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber        void **buffer_data) {
408318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
409318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
410318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta *buffer_meta = new BufferMeta(size);
411318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
412318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_BUFFERHEADERTYPE *header;
413318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
414318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_AllocateBuffer(
415318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, &header, portIndex, buffer_meta, size);
416318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
417318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    if (err != OMX_ErrorNone) {
418318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        LOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err);
419318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
420318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        delete buffer_meta;
421318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        buffer_meta = NULL;
422318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
423318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        *buffer = 0;
424318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
425318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        return UNKNOWN_ERROR;
426318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
427318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
42803b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber    CHECK_EQ(header->pAppPrivate, buffer_meta);
42903b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber
430318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    *buffer = header;
431570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber    *buffer_data = header->pBuffer;
432318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
433d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    addActiveBuffer(portIndex, *buffer);
434d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
435318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return OK;
436318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
437318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
438318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::allocateBufferWithBackup(
439318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_U32 portIndex, const sp<IMemory> &params,
440318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX::buffer_id *buffer) {
441318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
442318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
443318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta *buffer_meta = new BufferMeta(params, true);
444318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
445318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_BUFFERHEADERTYPE *header;
446318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
447318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_AllocateBuffer(
448318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, &header, portIndex, buffer_meta, params->size());
449318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
450318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    if (err != OMX_ErrorNone) {
451318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        LOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err);
452318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
453318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        delete buffer_meta;
454318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        buffer_meta = NULL;
455318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
456318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        *buffer = 0;
457318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
458318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        return UNKNOWN_ERROR;
459318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
460318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
46103b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber    CHECK_EQ(header->pAppPrivate, buffer_meta);
46203b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber
463318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    *buffer = header;
464318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
465d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    addActiveBuffer(portIndex, *buffer);
466d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
467318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return OK;
468318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
469318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
470318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::freeBuffer(
471318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_U32 portIndex, OMX::buffer_id buffer) {
472318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
473318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
474d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    removeActiveBuffer(portIndex, buffer);
475d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
476318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
477318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate);
478318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
479318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_FreeBuffer(mHandle, portIndex, header);
480318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
481318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    delete buffer_meta;
482318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    buffer_meta = NULL;
483318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
484318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
485318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
486318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
487318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer) {
488318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
489318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
490318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
491318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nFilledLen = 0;
492318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nOffset = 0;
493318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nFlags = 0;
494318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
495318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_FillThisBuffer(mHandle, header);
496318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
497318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
498318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
499318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
500318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::emptyBuffer(
501318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX::buffer_id buffer,
502318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_U32 rangeOffset, OMX_U32 rangeLength,
503318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_U32 flags, OMX_TICKS timestamp) {
504318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
505318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
506318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
507318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nFilledLen = rangeLength;
508318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nOffset = rangeOffset;
509318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nFlags = flags;
510318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nTimeStamp = timestamp;
511318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
512318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta *buffer_meta =
513318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        static_cast<BufferMeta *>(header->pAppPrivate);
514318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    buffer_meta->CopyToOMX(header);
515318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
516318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header);
517318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
518318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
519318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
520318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
521318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::getExtensionIndex(
522318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        const char *parameterName, OMX_INDEXTYPE *index) {
523318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
524318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
525318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_GetExtensionIndex(
526318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, const_cast<char *>(parameterName), index);
527318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
528318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
529318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
530318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
531318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Hubervoid OMXNodeInstance::onMessage(const omx_message &msg) {
532318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    if (msg.type == omx_message::FILL_BUFFER_DONE) {
533318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_BUFFERHEADERTYPE *buffer =
534318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            static_cast<OMX_BUFFERHEADERTYPE *>(
535318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                    msg.u.extended_buffer_data.buffer);
536318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
537318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        BufferMeta *buffer_meta =
538318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            static_cast<BufferMeta *>(buffer->pAppPrivate);
539318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
540318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        buffer_meta->CopyFromOMX(buffer);
541318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
542318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
543318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    mObserver->onMessage(msg);
544318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
545318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
546f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Hubervoid OMXNodeInstance::onObserverDied(OMXMaster *master) {
547318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    LOGE("!!! Observer died. Quickly, do something, ... anything...");
548318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
549318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    // Try to force shutdown of the node and hope for the best.
550f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    freeNode(master);
551318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
552318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
553318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Hubervoid OMXNodeInstance::onGetHandleFailed() {
554318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    delete this;
555318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
556318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
557318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber// static
558318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMX_ERRORTYPE OMXNodeInstance::OnEvent(
559318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_HANDLETYPE hComponent,
560318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_PTR pAppData,
561318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_EVENTTYPE eEvent,
562318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_U32 nData1,
563318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_U32 nData2,
564318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_PTR pEventData) {
565318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
566134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    if (instance->mDying) {
567134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber        return OMX_ErrorNone;
568134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    }
569318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return instance->owner()->OnEvent(
570318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            instance->nodeID(), eEvent, nData1, nData2, pEventData);
571318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
572318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
573318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber// static
574318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMX_ERRORTYPE OMXNodeInstance::OnEmptyBufferDone(
575318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_HANDLETYPE hComponent,
576318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_PTR pAppData,
577318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
578318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
579134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    if (instance->mDying) {
580134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber        return OMX_ErrorNone;
581134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    }
582318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return instance->owner()->OnEmptyBufferDone(instance->nodeID(), pBuffer);
583318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
584318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
585318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber// static
586318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMX_ERRORTYPE OMXNodeInstance::OnFillBufferDone(
587318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_HANDLETYPE hComponent,
588318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_PTR pAppData,
589318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
590318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
591134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    if (instance->mDying) {
592134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber        return OMX_ErrorNone;
593134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    }
594318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return instance->owner()->OnFillBufferDone(instance->nodeID(), pBuffer);
595318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
596318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
597d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Hubervoid OMXNodeInstance::addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id) {
598d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    ActiveBuffer active;
599d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    active.mPortIndex = portIndex;
600d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    active.mID = id;
601d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    mActiveBuffers.push(active);
602d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber}
603d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
604d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Hubervoid OMXNodeInstance::removeActiveBuffer(
605d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        OMX_U32 portIndex, OMX::buffer_id id) {
606d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    bool found = false;
607d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    for (size_t i = 0; i < mActiveBuffers.size(); ++i) {
608d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        if (mActiveBuffers[i].mPortIndex == portIndex
609d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            && mActiveBuffers[i].mID == id) {
610d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            found = true;
611d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            mActiveBuffers.removeItemsAt(i);
612d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            break;
613d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        }
614d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    }
615d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
616d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    if (!found) {
617d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        LOGW("Attempt to remove an active buffer we know nothing about...");
618d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    }
619d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber}
620d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
621d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Hubervoid OMXNodeInstance::freeActiveBuffers() {
622d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // Make sure to count down here, as freeBuffer will in turn remove
623d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // the active buffer from the vector...
624d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    for (size_t i = mActiveBuffers.size(); i--;) {
625d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        freeBuffer(mActiveBuffers[i].mPortIndex, mActiveBuffers[i].mID);
626d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    }
627d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber}
628d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
629318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}  // namespace android
630