OMXNodeInstance.cpp revision 30358faf33fb9b638257b017fadb4c5f7352d903
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
170c03d5c7c2fa4d17f7f5159e3fddd2adf6bfc923Andreas 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"
23f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include "GraphicBufferSource.h"
24318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
25e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber#include <OMX_Component.h>
26318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
27318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber#include <binder/IMemory.h>
28f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden#include <gui/BufferQueue.h>
296c6b4d0d2b98a7ceee8b697daaf611f8df3254fbJames Dong#include <HardwareAPI.h>
30f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h>
312a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber#include <media/stagefright/MediaErrors.h>
32318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
33f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenstatic const OMX_U32 kPortIndexInput = 0;
34f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
35318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Hubernamespace android {
36318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
37318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstruct BufferMeta {
38318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta(const sp<IMemory> &mem, bool is_backup = false)
39318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        : mMem(mem),
40318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber          mIsBackup(is_backup) {
41318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
42318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
43318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta(size_t size)
44318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        : mSize(size),
45318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber          mIsBackup(false) {
46318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
47318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
4883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    BufferMeta(const sp<GraphicBuffer> &graphicBuffer)
4983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        : mGraphicBuffer(graphicBuffer),
5083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis          mIsBackup(false) {
5183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    }
5283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
53318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    void CopyFromOMX(const OMX_BUFFERHEADERTYPE *header) {
54318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        if (!mIsBackup) {
55318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            return;
56318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        }
57318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
58318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        memcpy((OMX_U8 *)mMem->pointer() + header->nOffset,
59318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber               header->pBuffer + header->nOffset,
60318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber               header->nFilledLen);
61318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
62318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
63318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    void CopyToOMX(const OMX_BUFFERHEADERTYPE *header) {
64318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        if (!mIsBackup) {
65318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            return;
66318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        }
67318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
68318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        memcpy(header->pBuffer + header->nOffset,
69318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber               (const OMX_U8 *)mMem->pointer() + header->nOffset,
70318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber               header->nFilledLen);
71318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
72318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
73d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    void setGraphicBuffer(const sp<GraphicBuffer> &graphicBuffer) {
74d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mGraphicBuffer = graphicBuffer;
75d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    }
76d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
77318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberprivate:
7883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    sp<GraphicBuffer> mGraphicBuffer;
79318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    sp<IMemory> mMem;
80318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    size_t mSize;
81318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    bool mIsBackup;
82318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
83318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta(const BufferMeta &);
84318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta &operator=(const BufferMeta &);
85318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber};
86318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
87318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber// static
88318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMX_CALLBACKTYPE OMXNodeInstance::kCallbacks = {
89318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    &OnEvent, &OnEmptyBufferDone, &OnFillBufferDone
90318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber};
91318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
92318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMXNodeInstance::OMXNodeInstance(
93318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX *owner, const sp<IOMXObserver> &observer)
94318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    : mOwner(owner),
95609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mNodeID(0),
96318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber      mHandle(NULL),
97134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber      mObserver(observer),
98609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mDying(false)
99609b815a3131d22da38b2f452faa9f89daad4039Andy Hung#ifdef __LP64__
100609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      , mBufferIDCount(0)
101609b815a3131d22da38b2f452faa9f89daad4039Andy Hung#endif
102609b815a3131d22da38b2f452faa9f89daad4039Andy Hung{
103318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
104318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
105318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMXNodeInstance::~OMXNodeInstance() {
106f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong    CHECK(mHandle == NULL);
107318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
108318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
109318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Hubervoid OMXNodeInstance::setHandle(OMX::node_id node_id, OMX_HANDLETYPE handle) {
110f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong    CHECK(mHandle == NULL);
111318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    mNodeID = node_id;
112318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    mHandle = handle;
113318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
114318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
115f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddensp<GraphicBufferSource> OMXNodeInstance::getGraphicBufferSource() {
116f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mGraphicBufferSourceLock);
117f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    return mGraphicBufferSource;
118f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
119f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
120f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid OMXNodeInstance::setGraphicBufferSource(
121f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        const sp<GraphicBufferSource>& bufferSource) {
122f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mGraphicBufferSourceLock);
123f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mGraphicBufferSource = bufferSource;
124f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
125f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
126318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMX *OMXNodeInstance::owner() {
127318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return mOwner;
128318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
129318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
130318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Hubersp<IOMXObserver> OMXNodeInstance::observer() {
131318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return mObserver;
132318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
133318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
134318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMX::node_id OMXNodeInstance::nodeID() {
135318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return mNodeID;
136318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
137318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
138318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatic status_t StatusFromOMXError(OMX_ERRORTYPE err) {
1392a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber    switch (err) {
1402a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        case OMX_ErrorNone:
1412a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber            return OK;
1422a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        case OMX_ErrorUnsupportedSetting:
1432a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber            return ERROR_UNSUPPORTED;
1442a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        default:
1452a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber            return UNKNOWN_ERROR;
1462a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber    }
147318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
148318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
149f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huberstatus_t OMXNodeInstance::freeNode(OMXMaster *master) {
15043e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber    static int32_t kMaxNumIterations = 10;
15143e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber
15230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    // exit if we have already freed the node
15330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (mHandle == NULL) {
15430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        return OK;
15530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
15630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
157d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // Transition the node from its current state all the way down
158d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // to "Loaded".
159d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // This ensures that all active buffers are properly freed even
160d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // for components that don't do this themselves on a call to
161d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // "FreeHandle".
162d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
163134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    // The code below may trigger some more events to be dispatched
164134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    // by the OMX component - we want to ignore them as our client
165134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    // does not expect them.
166134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    mDying = true;
167134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber
168d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    OMX_STATETYPE state;
169d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    CHECK_EQ(OMX_GetState(mHandle, &state), OMX_ErrorNone);
170d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    switch (state) {
171d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        case OMX_StateExecuting:
172d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        {
1733856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("forcing Executing->Idle");
174d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            sendCommand(OMX_CommandStateSet, OMX_StateIdle);
175d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            OMX_ERRORTYPE err;
17643e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber            int32_t iteration = 0;
177d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone
1780d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber                   && state != OMX_StateIdle
1790d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber                   && state != OMX_StateInvalid) {
18043e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                if (++iteration > kMaxNumIterations) {
18129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("component failed to enter Idle state, aborting.");
18243e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                    state = OMX_StateInvalid;
18343e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                    break;
18443e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                }
18543e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber
186d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber                usleep(100000);
187d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            }
188d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            CHECK_EQ(err, OMX_ErrorNone);
189d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
1900d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber            if (state == OMX_StateInvalid) {
1910d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber                break;
1920d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber            }
1930d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber
194d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            // fall through
195d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        }
196d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
197d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        case OMX_StateIdle:
198d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        {
1993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("forcing Idle->Loaded");
200d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            sendCommand(OMX_CommandStateSet, OMX_StateLoaded);
201d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
202d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            freeActiveBuffers();
203d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
204d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            OMX_ERRORTYPE err;
20543e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber            int32_t iteration = 0;
206d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone
2070d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber                   && state != OMX_StateLoaded
2080d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber                   && state != OMX_StateInvalid) {
20943e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                if (++iteration > kMaxNumIterations) {
21029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("component failed to enter Loaded state, aborting.");
21143e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                    state = OMX_StateInvalid;
21243e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                    break;
21343e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                }
21443e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber
2153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("waiting for Loaded state...");
216d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber                usleep(100000);
217d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            }
218d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            CHECK_EQ(err, OMX_ErrorNone);
219d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
220d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            // fall through
221d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        }
222d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
223d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        case OMX_StateLoaded:
224fa70cad40b01627ac1c22e04cdd548ece9c2654fAndreas Huber        case OMX_StateInvalid:
225d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            break;
226d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
227d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        default:
228d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            CHECK(!"should not be here, unknown state.");
229d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            break;
230d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    }
231d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
2323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("calling destroyComponentInstance");
233f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    OMX_ERRORTYPE err = master->destroyComponentInstance(
234f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber            static_cast<OMX_COMPONENTTYPE *>(mHandle));
2353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("destroyComponentInstance returned err %d", err);
236f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber
237318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    mHandle = NULL;
238318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
239318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    if (err != OMX_ErrorNone) {
24029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("FreeHandle FAILED with error 0x%08x.", err);
241318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
242318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
243318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    mOwner->invalidateNodeID(mNodeID);
244609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    mNodeID = 0;
245318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
2463856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("OMXNodeInstance going away.");
24747bed1a7755ed58fa5d4c0d35b20468deb83bd60Andreas Huber    delete this;
248318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
249318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
250318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
251318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
252318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::sendCommand(
253318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_COMMANDTYPE cmd, OMX_S32 param) {
254e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource());
255ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber    if (bufferSource != NULL && cmd == OMX_CommandStateSet) {
256ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber        if (param == OMX_StateIdle) {
257ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            // Initiating transition from Executing -> Idle
258ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            // ACodec is waiting for all buffers to be returned, do NOT
259ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            // submit any more buffers to the codec.
260ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            bufferSource->omxIdle();
261ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber        } else if (param == OMX_StateLoaded) {
262ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            // Initiating transition from Idle/Executing -> Loaded
263ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            // Buffers are about to be freed.
264ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            bufferSource->omxLoaded();
265ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            setGraphicBufferSource(NULL);
266ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber        }
267e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
268e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        // fall through
269e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
270e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
271318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
272318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
273318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_SendCommand(mHandle, cmd, param, NULL);
274318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
275318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
276318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
277318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::getParameter(
27884333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        OMX_INDEXTYPE index, void *params, size_t /* size */) {
279318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
280318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
281318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_GetParameter(mHandle, index, params);
282609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGE_IF(err != OMX_ErrorNone, "getParameter(%d) ERROR: %#x", index, err);
283318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
284318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
285318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
286318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::setParameter(
28784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        OMX_INDEXTYPE index, const void *params, size_t /* size */) {
288318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
289318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
290318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_SetParameter(
291318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, index, const_cast<void *>(params));
292609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGE_IF(err != OMX_ErrorNone, "setParameter(%d) ERROR: %#x", index, err);
293318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
294318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
295318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
296318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::getConfig(
29784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        OMX_INDEXTYPE index, void *params, size_t /* size */) {
298318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
299318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
300318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_GetConfig(mHandle, index, params);
301318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
302318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
303318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
304318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::setConfig(
30584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        OMX_INDEXTYPE index, const void *params, size_t /* size */) {
306318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
307318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
308318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_SetConfig(
309318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, index, const_cast<void *>(params));
310318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
311318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
312b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennis}
313b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennis
314b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennisstatus_t OMXNodeInstance::getState(OMX_STATETYPE* state) {
315b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennis    Mutex::Autolock autoLock(mLock);
316b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennis
317b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennis    OMX_ERRORTYPE err = OMX_GetState(mHandle, state);
318b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennis
319b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennis    return StatusFromOMXError(err);
320318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
321318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
32283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennisstatus_t OMXNodeInstance::enableGraphicBuffers(
32383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        OMX_U32 portIndex, OMX_BOOL enable) {
32483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    Mutex::Autolock autoLock(mLock);
325ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis    OMX_STRING name = const_cast<OMX_STRING>(
326ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis            "OMX.google.android.index.enableAndroidNativeBuffers");
32783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
32883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    OMX_INDEXTYPE index;
329ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis    OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
33083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
33183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    if (err != OMX_ErrorNone) {
332d8754298b576aca4e85a059ea7b7e8f7a9502226Jamie Gennis        if (enable) {
333d8754298b576aca4e85a059ea7b7e8f7a9502226Jamie Gennis            ALOGE("OMX_GetExtensionIndex %s failed", name);
334d8754298b576aca4e85a059ea7b7e8f7a9502226Jamie Gennis        }
33583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
33683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        return StatusFromOMXError(err);
33783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    }
33883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
33983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    OMX_VERSIONTYPE ver;
34083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nVersionMajor = 1;
34183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nVersionMinor = 0;
34283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nRevision = 0;
34383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nStep = 0;
34483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    EnableAndroidNativeBuffersParams params = {
34583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        sizeof(EnableAndroidNativeBuffersParams), ver, portIndex, enable,
34683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    };
34783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
34883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    err = OMX_SetParameter(mHandle, index, &params);
34983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
35083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    if (err != OMX_ErrorNone) {
35129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_EnableAndroidNativeBuffers failed with error %d (0x%08x)",
35283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis                err, err);
35383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
35483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        return UNKNOWN_ERROR;
35583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    }
35683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
35783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    return OK;
35883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis}
35983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
360e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennisstatus_t OMXNodeInstance::getGraphicBufferUsage(
361e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis        OMX_U32 portIndex, OMX_U32* usage) {
362e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    Mutex::Autolock autoLock(mLock);
363e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
364e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    OMX_INDEXTYPE index;
365ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis    OMX_STRING name = const_cast<OMX_STRING>(
366ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis            "OMX.google.android.index.getAndroidNativeBufferUsage");
367ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis    OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
368e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
369e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    if (err != OMX_ErrorNone) {
370ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis        ALOGE("OMX_GetExtensionIndex %s failed", name);
371e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
372e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis        return StatusFromOMXError(err);
373e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    }
374e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
375e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    OMX_VERSIONTYPE ver;
376e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    ver.s.nVersionMajor = 1;
377e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    ver.s.nVersionMinor = 0;
378e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    ver.s.nRevision = 0;
379e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    ver.s.nStep = 0;
380e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    GetAndroidNativeBufferUsageParams params = {
381e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis        sizeof(GetAndroidNativeBufferUsageParams), ver, portIndex, 0,
382e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    };
383e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
384e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    err = OMX_GetParameter(mHandle, index, &params);
385e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
386e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    if (err != OMX_ErrorNone) {
38729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_GetAndroidNativeBufferUsage failed with error %d (0x%08x)",
388e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis                err, err);
389e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis        return UNKNOWN_ERROR;
390e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    }
391e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
392e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    *usage = params.nUsage;
393e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
394e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    return OK;
395e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis}
396e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
397e870772a78ffe08b1c14a791e368f1499f1be0f3James Dongstatus_t OMXNodeInstance::storeMetaDataInBuffers(
398e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong        OMX_U32 portIndex,
399e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong        OMX_BOOL enable) {
400e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    Mutex::Autolock autolock(mLock);
401512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar    return storeMetaDataInBuffers_l(
402512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar            portIndex, enable,
403512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar            OMX_FALSE /* useGraphicBuffer */, NULL /* usingGraphicBufferInMetadata */);
404f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
405e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
406f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenstatus_t OMXNodeInstance::storeMetaDataInBuffers_l(
407f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        OMX_U32 portIndex,
408512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar        OMX_BOOL enable,
409512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar        OMX_BOOL useGraphicBuffer,
410512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar        OMX_BOOL *usingGraphicBufferInMetadata) {
411e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    OMX_INDEXTYPE index;
412e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    OMX_STRING name = const_cast<OMX_STRING>(
413e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong            "OMX.google.android.index.storeMetaDataInBuffers");
414e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
415512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar    OMX_STRING graphicBufferName = const_cast<OMX_STRING>(
416512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar            "OMX.google.android.index.storeGraphicBufferInMetaData");
417512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar    if (usingGraphicBufferInMetadata == NULL) {
418512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar        usingGraphicBufferInMetadata = &useGraphicBuffer;
419512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar    }
420512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar
421512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar    OMX_ERRORTYPE err =
422512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar        (useGraphicBuffer && portIndex == kPortIndexInput)
423512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar                ? OMX_GetExtensionIndex(mHandle, graphicBufferName, &index)
424512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar                : OMX_ErrorBadParameter;
425512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar    if (err == OMX_ErrorNone) {
426512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar        *usingGraphicBufferInMetadata = OMX_TRUE;
427512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar    } else {
428512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar        *usingGraphicBufferInMetadata = OMX_FALSE;
429512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar        err = OMX_GetExtensionIndex(mHandle, name, &index);
430512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar    }
431512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar
432e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    if (err != OMX_ErrorNone) {
433d8754298b576aca4e85a059ea7b7e8f7a9502226Jamie Gennis        ALOGE("OMX_GetExtensionIndex %s failed", name);
434e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong        return StatusFromOMXError(err);
435e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    }
436e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
437e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    StoreMetaDataInBuffersParams params;
438e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    memset(&params, 0, sizeof(params));
439e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    params.nSize = sizeof(params);
440e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
441e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    // Version: 1.0.0.0
442e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    params.nVersion.s.nVersionMajor = 1;
443e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
444e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    params.nPortIndex = portIndex;
445e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    params.bStoreMetaData = enable;
446e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    if ((err = OMX_SetParameter(mHandle, index, &params)) != OMX_ErrorNone) {
44729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_SetParameter() failed for StoreMetaDataInBuffers: 0x%08x", err);
448512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar        *usingGraphicBufferInMetadata = OMX_FALSE;
449e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong        return UNKNOWN_ERROR;
450e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    }
451e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    return err;
452e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong}
453e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
45456ce726019f700a95ce5b45beebceadae4836e30Lajos Molnarstatus_t OMXNodeInstance::prepareForAdaptivePlayback(
45556ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar        OMX_U32 portIndex, OMX_BOOL enable, OMX_U32 maxFrameWidth,
45656ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar        OMX_U32 maxFrameHeight) {
45756ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    Mutex::Autolock autolock(mLock);
45856ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar
45956ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    OMX_INDEXTYPE index;
46056ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    OMX_STRING name = const_cast<OMX_STRING>(
46156ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar            "OMX.google.android.index.prepareForAdaptivePlayback");
46256ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar
46356ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
46456ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    if (err != OMX_ErrorNone) {
46556ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar        ALOGW_IF(enable, "OMX_GetExtensionIndex %s failed", name);
46656ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar        return StatusFromOMXError(err);
46756ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    }
46856ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar
46956ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    PrepareForAdaptivePlaybackParams params;
47056ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nSize = sizeof(params);
47156ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nVersion.s.nVersionMajor = 1;
47256ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nVersion.s.nVersionMinor = 0;
47356ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nVersion.s.nRevision = 0;
47456ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nVersion.s.nStep = 0;
47556ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar
47656ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nPortIndex = portIndex;
47756ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.bEnable = enable;
47856ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nMaxFrameWidth = maxFrameWidth;
47956ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nMaxFrameHeight = maxFrameHeight;
48056ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    if ((err = OMX_SetParameter(mHandle, index, &params)) != OMX_ErrorNone) {
48156ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar        ALOGW("OMX_SetParameter failed for PrepareForAdaptivePlayback "
48256ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar              "with error %d (0x%08x)", err, err);
48356ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar        return UNKNOWN_ERROR;
48456ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    }
48556ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    return err;
48656ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar}
48756ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar
4885a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t OMXNodeInstance::configureVideoTunnelMode(
4895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        OMX_U32 portIndex, OMX_BOOL tunneled, OMX_U32 audioHwSync,
4905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        native_handle_t **sidebandHandle) {
4915a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    Mutex::Autolock autolock(mLock);
4925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
4935a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    OMX_INDEXTYPE index;
4945a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    OMX_STRING name = const_cast<OMX_STRING>(
4955a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            "OMX.google.android.index.configureVideoTunnelMode");
4965a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
4975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
4985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OMX_ErrorNone) {
4995a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode extension is missing!");
5005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return StatusFromOMXError(err);
5015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
5025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
5035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    ConfigureVideoTunnelModeParams tunnelParams;
5045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    tunnelParams.nSize = sizeof(tunnelParams);
5055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    tunnelParams.nVersion.s.nVersionMajor = 1;
5065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    tunnelParams.nVersion.s.nVersionMinor = 0;
5075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    tunnelParams.nVersion.s.nRevision = 0;
5085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    tunnelParams.nVersion.s.nStep = 0;
5095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
5105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    tunnelParams.nPortIndex = portIndex;
5115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    tunnelParams.bTunneled = tunneled;
5125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    tunnelParams.nAudioHwSync = audioHwSync;
5135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = OMX_SetParameter(mHandle, index, &tunnelParams);
5145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OMX_ErrorNone) {
5155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
5165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return UNKNOWN_ERROR;
5175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
5185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
5195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = OMX_GetParameter(mHandle, index, &tunnelParams);
5205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OMX_ErrorNone) {
5215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("GetVideoTunnelWindow failed! (err %d).", err);
5225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return UNKNOWN_ERROR;
5235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
5245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (sidebandHandle) {
5255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        *sidebandHandle = (native_handle_t*)tunnelParams.pSidebandWindow;
5265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
5275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
5285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return err;
5295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
5305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
531318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::useBuffer(
532318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_U32 portIndex, const sp<IMemory> &params,
533318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX::buffer_id *buffer) {
534318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
535318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
536318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta *buffer_meta = new BufferMeta(params);
537318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
538318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_BUFFERHEADERTYPE *header;
539318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
540318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_UseBuffer(
541318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, &header, portIndex, buffer_meta,
542318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            params->size(), static_cast<OMX_U8 *>(params->pointer()));
543318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
544318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    if (err != OMX_ErrorNone) {
54529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err);
546318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
547318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        delete buffer_meta;
548318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        buffer_meta = NULL;
549318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
550318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        *buffer = 0;
551318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
552318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        return UNKNOWN_ERROR;
553318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
554318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
55503b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber    CHECK_EQ(header->pAppPrivate, buffer_meta);
55603b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber
557609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    *buffer = makeBufferID(header);
558318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
559d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    addActiveBuffer(portIndex, *buffer);
560d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
561f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
562f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (bufferSource != NULL && portIndex == kPortIndexInput) {
563f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        bufferSource->addCodecBuffer(header);
564f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
565f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
566318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return OK;
567318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
568318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
569c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajanstatus_t OMXNodeInstance::useGraphicBuffer2_l(
570c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
571c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        OMX::buffer_id *buffer) {
572c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
573c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    // port definition
574c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    OMX_PARAM_PORTDEFINITIONTYPE def;
575c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
576c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    def.nVersion.s.nVersionMajor = 1;
577c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    def.nVersion.s.nVersionMinor = 0;
578c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    def.nVersion.s.nRevision = 0;
579c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    def.nVersion.s.nStep = 0;
580c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    def.nPortIndex = portIndex;
581c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    OMX_ERRORTYPE err = OMX_GetParameter(mHandle, OMX_IndexParamPortDefinition, &def);
582a0dac9e24ae7520cb7d7f0505bf0936bffbcd047Jamie Gennis    if (err != OMX_ErrorNone)
583c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    {
58429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("%s::%d:Error getting OMX_IndexParamPortDefinition", __FUNCTION__, __LINE__);
585c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        return err;
586c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    }
587c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
588c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    BufferMeta *bufferMeta = new BufferMeta(graphicBuffer);
589c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
590c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    OMX_BUFFERHEADERTYPE *header = NULL;
591c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    OMX_U8* bufferHandle = const_cast<OMX_U8*>(
592c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            reinterpret_cast<const OMX_U8*>(graphicBuffer->handle));
593c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
594c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    err = OMX_UseBuffer(
595c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            mHandle,
596c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            &header,
597c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            portIndex,
598c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            bufferMeta,
599c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            def.nBufferSize,
600c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            bufferHandle);
601c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
602c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    if (err != OMX_ErrorNone) {
60329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err);
604c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        delete bufferMeta;
605c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        bufferMeta = NULL;
606c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        *buffer = 0;
607c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        return UNKNOWN_ERROR;
608c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    }
609c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
610c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    CHECK_EQ(header->pBuffer, bufferHandle);
611c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    CHECK_EQ(header->pAppPrivate, bufferMeta);
612c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
613609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    *buffer = makeBufferID(header);
614c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
615c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    addActiveBuffer(portIndex, *buffer);
616c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
617c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    return OK;
618c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan}
619c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
620c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan// XXX: This function is here for backwards compatibility.  Once the OMX
621c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan// implementations have been updated this can be removed and useGraphicBuffer2
622c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan// can be renamed to useGraphicBuffer.
62383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennisstatus_t OMXNodeInstance::useGraphicBuffer(
62483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
62583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        OMX::buffer_id *buffer) {
62683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    Mutex::Autolock autoLock(mLock);
62783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
628c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    // See if the newer version of the extension is present.
62983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    OMX_INDEXTYPE index;
630c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    if (OMX_GetExtensionIndex(
631c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            mHandle,
632c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer2"),
633c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            &index) == OMX_ErrorNone) {
634c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        return useGraphicBuffer2_l(portIndex, graphicBuffer, buffer);
635c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    }
636c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
637ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis    OMX_STRING name = const_cast<OMX_STRING>(
638ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis        "OMX.google.android.index.useAndroidNativeBuffer");
639ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis    OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
64083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
64183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    if (err != OMX_ErrorNone) {
642ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis        ALOGE("OMX_GetExtensionIndex %s failed", name);
64383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
64483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        return StatusFromOMXError(err);
64583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    }
64683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
64783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    BufferMeta *bufferMeta = new BufferMeta(graphicBuffer);
64883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
64983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    OMX_BUFFERHEADERTYPE *header;
65083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
65183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    OMX_VERSIONTYPE ver;
65283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nVersionMajor = 1;
65383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nVersionMinor = 0;
65483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nRevision = 0;
65583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nStep = 0;
65683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    UseAndroidNativeBufferParams params = {
65783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        sizeof(UseAndroidNativeBufferParams), ver, portIndex, bufferMeta,
65883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        &header, graphicBuffer,
65983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    };
66083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
66183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    err = OMX_SetParameter(mHandle, index, &params);
66283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
66383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    if (err != OMX_ErrorNone) {
66429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_UseAndroidNativeBuffer failed with error %d (0x%08x)", err,
66583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis                err);
66683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
66783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        delete bufferMeta;
66883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        bufferMeta = NULL;
66983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
67083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        *buffer = 0;
67183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
67283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        return UNKNOWN_ERROR;
67383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    }
67483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
67583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    CHECK_EQ(header->pAppPrivate, bufferMeta);
67683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
677609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    *buffer = makeBufferID(header);
67883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
67983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    addActiveBuffer(portIndex, *buffer);
68083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
68183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    return OK;
68283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis}
68383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
684d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnarstatus_t OMXNodeInstance::updateGraphicBufferInMeta(
68584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        OMX_U32 /* portIndex */, const sp<GraphicBuffer>& graphicBuffer,
686d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        OMX::buffer_id buffer) {
687d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    Mutex::Autolock autoLock(mLock);
688d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
689609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer);
690d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    VideoDecoderOutputMetaData *metadata =
691d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        (VideoDecoderOutputMetaData *)(header->pBuffer);
692d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    BufferMeta *bufferMeta = (BufferMeta *)(header->pAppPrivate);
693d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    bufferMeta->setGraphicBuffer(graphicBuffer);
694d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    metadata->eType = kMetadataBufferTypeGrallocSource;
695d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    metadata->pHandle = graphicBuffer->handle;
696d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
697d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    return OK;
698d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar}
699d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
700f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenstatus_t OMXNodeInstance::createInputSurface(
701f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        OMX_U32 portIndex, sp<IGraphicBufferProducer> *bufferProducer) {
702f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autolock(mLock);
703f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    status_t err;
704f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
705f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    const sp<GraphicBufferSource>& surfaceCheck = getGraphicBufferSource();
706f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (surfaceCheck != NULL) {
707f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return ALREADY_EXISTS;
708f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
709f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
710f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Input buffers will hold meta-data (gralloc references).
711512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar    OMX_BOOL usingGraphicBuffer = OMX_FALSE;
712512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar    err = storeMetaDataInBuffers_l(
713512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar            portIndex, OMX_TRUE,
714512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar            OMX_TRUE /* useGraphicBuffer */, &usingGraphicBuffer);
715f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (err != OK) {
716f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return err;
717f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
718f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
719f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Retrieve the width and height of the graphic buffer, set when the
720f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // codec was configured.
721f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    OMX_PARAM_PORTDEFINITIONTYPE def;
722f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    def.nSize = sizeof(def);
723f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    def.nVersion.s.nVersionMajor = 1;
724f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    def.nVersion.s.nVersionMinor = 0;
725f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    def.nVersion.s.nRevision = 0;
726f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    def.nVersion.s.nStep = 0;
727f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    def.nPortIndex = portIndex;
728f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    OMX_ERRORTYPE oerr = OMX_GetParameter(
729f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            mHandle, OMX_IndexParamPortDefinition, &def);
730f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CHECK(oerr == OMX_ErrorNone);
731f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
732ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden    if (def.format.video.eColorFormat != OMX_COLOR_FormatAndroidOpaque) {
73392cb8f928dc9e237c356c942d10b5c0c1e04b2aeAndy McFadden        ALOGE("createInputSurface requires COLOR_FormatSurface "
73492cb8f928dc9e237c356c942d10b5c0c1e04b2aeAndy McFadden              "(AndroidOpaque) color format");
735ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden        return INVALID_OPERATION;
736ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden    }
737ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden
738f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    GraphicBufferSource* bufferSource = new GraphicBufferSource(
7390c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden            this, def.format.video.nFrameWidth, def.format.video.nFrameHeight,
740512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar            def.nBufferCountActual, usingGraphicBuffer);
741f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if ((err = bufferSource->initCheck()) != OK) {
742f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        delete bufferSource;
743f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return err;
744f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
745f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    setGraphicBufferSource(bufferSource);
746f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
747f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    *bufferProducer = bufferSource->getIGraphicBufferProducer();
748f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    return OK;
749f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
750f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
751f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenstatus_t OMXNodeInstance::signalEndOfInputStream() {
752f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // For non-Surface input, the MediaCodec should convert the call to a
753f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // pair of requests (dequeue input buffer, queue input buffer with EOS
754f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // flag set).  Seems easier than doing the equivalent from here.
755f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
756f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (bufferSource == NULL) {
757ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden        ALOGW("signalEndOfInputStream can only be used with Surface input");
758f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return INVALID_OPERATION;
759f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    };
760ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden    return bufferSource->signalEndOfInputStream();
761f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
762f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
763318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::allocateBuffer(
764570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber        OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer,
765570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber        void **buffer_data) {
766318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
767318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
768318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta *buffer_meta = new BufferMeta(size);
769318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
770318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_BUFFERHEADERTYPE *header;
771318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
772318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_AllocateBuffer(
773318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, &header, portIndex, buffer_meta, size);
774318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
775318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    if (err != OMX_ErrorNone) {
77629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err);
777318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
778318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        delete buffer_meta;
779318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        buffer_meta = NULL;
780318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
781318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        *buffer = 0;
782318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
783318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        return UNKNOWN_ERROR;
784318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
785318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
78603b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber    CHECK_EQ(header->pAppPrivate, buffer_meta);
78703b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber
788609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    *buffer = makeBufferID(header);
789570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber    *buffer_data = header->pBuffer;
790318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
791d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    addActiveBuffer(portIndex, *buffer);
792d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
793f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
794f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (bufferSource != NULL && portIndex == kPortIndexInput) {
795f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        bufferSource->addCodecBuffer(header);
796f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
797f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
798318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return OK;
799318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
800318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
801318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::allocateBufferWithBackup(
802318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_U32 portIndex, const sp<IMemory> &params,
803318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX::buffer_id *buffer) {
804318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
805318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
806318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta *buffer_meta = new BufferMeta(params, true);
807318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
808318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_BUFFERHEADERTYPE *header;
809318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
810318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_AllocateBuffer(
811318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, &header, portIndex, buffer_meta, params->size());
812318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
813318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    if (err != OMX_ErrorNone) {
81429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err);
815318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
816318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        delete buffer_meta;
817318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        buffer_meta = NULL;
818318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
819318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        *buffer = 0;
820318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
821318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        return UNKNOWN_ERROR;
822318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
823318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
82403b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber    CHECK_EQ(header->pAppPrivate, buffer_meta);
82503b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber
826609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    *buffer = makeBufferID(header);
827318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
828d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    addActiveBuffer(portIndex, *buffer);
829d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
830f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
831f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (bufferSource != NULL && portIndex == kPortIndexInput) {
832f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        bufferSource->addCodecBuffer(header);
833f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
834f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
835318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return OK;
836318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
837318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
838318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::freeBuffer(
839318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_U32 portIndex, OMX::buffer_id buffer) {
840318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
841318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
842d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    removeActiveBuffer(portIndex, buffer);
843d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
844609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer);
845318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate);
846318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
847318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_FreeBuffer(mHandle, portIndex, header);
848318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
849318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    delete buffer_meta;
850318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    buffer_meta = NULL;
851609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    invalidateBufferID(buffer);
852318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
853318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
854318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
855318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
856318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer) {
857318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
858318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
859609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer);
860318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nFilledLen = 0;
861318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nOffset = 0;
862318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nFlags = 0;
863318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
864318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_FillThisBuffer(mHandle, header);
865318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
866318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
867318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
868318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
869318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::emptyBuffer(
870318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX::buffer_id buffer,
871318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_U32 rangeOffset, OMX_U32 rangeLength,
872318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_U32 flags, OMX_TICKS timestamp) {
873318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
874318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
875609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer);
876318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nFilledLen = rangeLength;
877318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nOffset = rangeOffset;
878318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nFlags = flags;
879318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nTimeStamp = timestamp;
880318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
881318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta *buffer_meta =
882318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        static_cast<BufferMeta *>(header->pAppPrivate);
883318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    buffer_meta->CopyToOMX(header);
884318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
885318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header);
886318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
887318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
888318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
889318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
890f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// like emptyBuffer, but the data is already in header->pBuffer
891f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenstatus_t OMXNodeInstance::emptyDirectBuffer(
892f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        OMX_BUFFERHEADERTYPE *header,
893f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        OMX_U32 rangeOffset, OMX_U32 rangeLength,
894f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        OMX_U32 flags, OMX_TICKS timestamp) {
895f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mLock);
896f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
897f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    header->nFilledLen = rangeLength;
898f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    header->nOffset = rangeOffset;
899f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    header->nFlags = flags;
900f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    header->nTimeStamp = timestamp;
901f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
902f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header);
903f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (err != OMX_ErrorNone) {
904f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGW("emptyDirectBuffer failed, OMX err=0x%x", err);
905f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
906f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
907f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    return StatusFromOMXError(err);
908f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
909f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
910318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::getExtensionIndex(
911318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        const char *parameterName, OMX_INDEXTYPE *index) {
912318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
913318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
914318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_GetExtensionIndex(
915318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, const_cast<char *>(parameterName), index);
916318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
917318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
918318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
919318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
920e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huberstatus_t OMXNodeInstance::setInternalOption(
921e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        OMX_U32 portIndex,
922e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        IOMX::InternalOptionType type,
923e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        const void *data,
924e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        size_t size) {
925e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    switch (type) {
926e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        case IOMX::INTERNAL_OPTION_SUSPEND:
927a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        case IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY:
92894ee4b708acfa941581160b267afb79192b1d816Chong Zhang        case IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP:
92972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case IOMX::INTERNAL_OPTION_START_TIME:
9302c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        case IOMX::INTERNAL_OPTION_TIME_LAPSE:
931e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        {
932e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            const sp<GraphicBufferSource> &bufferSource =
933e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                getGraphicBufferSource();
934e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
935e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            if (bufferSource == NULL || portIndex != kPortIndexInput) {
936e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                return ERROR_UNSUPPORTED;
937e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            }
938e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
939a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            if (type == IOMX::INTERNAL_OPTION_SUSPEND) {
940a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                if (size != sizeof(bool)) {
941a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    return INVALID_OPERATION;
942a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                }
943a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
944a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                bool suspend = *(bool *)data;
945a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                bufferSource->suspend(suspend);
94694ee4b708acfa941581160b267afb79192b1d816Chong Zhang            } else if (type ==
94794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                    IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY){
948a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                if (size != sizeof(int64_t)) {
949a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    return INVALID_OPERATION;
950a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                }
951a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
952a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                int64_t delayUs = *(int64_t *)data;
953e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
954a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                return bufferSource->setRepeatPreviousFrameDelayUs(delayUs);
95572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            } else if (type ==
95672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP){
95794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                if (size != sizeof(int64_t)) {
95894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                    return INVALID_OPERATION;
95994ee4b708acfa941581160b267afb79192b1d816Chong Zhang                }
96094ee4b708acfa941581160b267afb79192b1d816Chong Zhang
96194ee4b708acfa941581160b267afb79192b1d816Chong Zhang                int64_t maxGapUs = *(int64_t *)data;
96294ee4b708acfa941581160b267afb79192b1d816Chong Zhang
96394ee4b708acfa941581160b267afb79192b1d816Chong Zhang                return bufferSource->setMaxTimestampGapUs(maxGapUs);
9642c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            } else if (type == IOMX::INTERNAL_OPTION_START_TIME) {
96572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                if (size != sizeof(int64_t)) {
96672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    return INVALID_OPERATION;
96772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                }
96872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
96972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                int64_t skipFramesBeforeUs = *(int64_t *)data;
97072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
97172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                bufferSource->setSkipFramesBeforeUs(skipFramesBeforeUs);
9722c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            } else { // IOMX::INTERNAL_OPTION_TIME_LAPSE
9732c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                if (size != sizeof(int64_t) * 2) {
9742c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    return INVALID_OPERATION;
9752c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                }
9762c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
9772c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                bufferSource->setTimeLapseUs((int64_t *)data);
978a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            }
979e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
980e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            return OK;
981e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        }
982e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
983e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        default:
984e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            return ERROR_UNSUPPORTED;
985e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
986e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber}
987e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
988318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Hubervoid OMXNodeInstance::onMessage(const omx_message &msg) {
98994ee4b708acfa941581160b267afb79192b1d816Chong Zhang    const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource());
99094ee4b708acfa941581160b267afb79192b1d816Chong Zhang
991318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    if (msg.type == omx_message::FILL_BUFFER_DONE) {
992318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_BUFFERHEADERTYPE *buffer =
993609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            findBufferHeader(msg.u.extended_buffer_data.buffer);
994318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
995318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        BufferMeta *buffer_meta =
996318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            static_cast<BufferMeta *>(buffer->pAppPrivate);
997318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
998318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        buffer_meta->CopyFromOMX(buffer);
9991b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber
10001b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber        if (bufferSource != NULL) {
100194ee4b708acfa941581160b267afb79192b1d816Chong Zhang            // fix up the buffer info (especially timestamp) if needed
100294ee4b708acfa941581160b267afb79192b1d816Chong Zhang            bufferSource->codecBufferFilled(buffer);
100394ee4b708acfa941581160b267afb79192b1d816Chong Zhang
100494ee4b708acfa941581160b267afb79192b1d816Chong Zhang            omx_message newMsg = msg;
100594ee4b708acfa941581160b267afb79192b1d816Chong Zhang            newMsg.u.extended_buffer_data.timestamp = buffer->nTimeStamp;
100694ee4b708acfa941581160b267afb79192b1d816Chong Zhang            mObserver->onMessage(newMsg);
100794ee4b708acfa941581160b267afb79192b1d816Chong Zhang            return;
100894ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
100994ee4b708acfa941581160b267afb79192b1d816Chong Zhang    } else if (msg.type == omx_message::EMPTY_BUFFER_DONE) {
101094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (bufferSource != NULL) {
10111b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            // This is one of the buffers used exclusively by
10121b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            // GraphicBufferSource.
10131b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            // Don't dispatch a message back to ACodec, since it doesn't
10141b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            // know that anyone asked to have the buffer emptied and will
10151b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            // be very confused.
10161b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber
10171b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            OMX_BUFFERHEADERTYPE *buffer =
1018609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                findBufferHeader(msg.u.buffer_data.buffer);
10191b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber
10201b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            bufferSource->codecBufferEmptied(buffer);
10211b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            return;
10221b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber        }
1023318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
1024318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
1025318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    mObserver->onMessage(msg);
1026318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
1027318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
1028f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Hubervoid OMXNodeInstance::onObserverDied(OMXMaster *master) {
102929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("!!! Observer died. Quickly, do something, ... anything...");
1030318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
1031318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    // Try to force shutdown of the node and hope for the best.
1032f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    freeNode(master);
1033318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
1034318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
1035318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Hubervoid OMXNodeInstance::onGetHandleFailed() {
1036318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    delete this;
1037318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
1038318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
1039f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// OMXNodeInstance::OnEvent calls OMX::OnEvent, which then calls here.
1040f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// Don't try to acquire mLock here -- in rare circumstances this will hang.
1041f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid OMXNodeInstance::onEvent(
1042f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        OMX_EVENTTYPE event, OMX_U32 arg1, OMX_U32 arg2) {
1043f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource());
1044f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
1045e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (bufferSource != NULL
1046e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            && event == OMX_EventCmdComplete
1047e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            && arg1 == OMX_CommandStateSet
1048e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            && arg2 == OMX_StateExecuting) {
1049e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bufferSource->omxExecuting();
1050f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
1051f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
1052f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
1053318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber// static
1054318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMX_ERRORTYPE OMXNodeInstance::OnEvent(
105584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        OMX_IN OMX_HANDLETYPE /* hComponent */,
1056318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_PTR pAppData,
1057318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_EVENTTYPE eEvent,
1058318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_U32 nData1,
1059318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_U32 nData2,
1060318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_PTR pEventData) {
1061318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
1062134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    if (instance->mDying) {
1063134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber        return OMX_ErrorNone;
1064134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    }
1065318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return instance->owner()->OnEvent(
1066318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            instance->nodeID(), eEvent, nData1, nData2, pEventData);
1067318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
1068318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
1069318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber// static
1070318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMX_ERRORTYPE OMXNodeInstance::OnEmptyBufferDone(
107184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        OMX_IN OMX_HANDLETYPE /* hComponent */,
1072318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_PTR pAppData,
1073318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
1074318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
1075134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    if (instance->mDying) {
1076134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber        return OMX_ErrorNone;
1077134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    }
1078609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    return instance->owner()->OnEmptyBufferDone(instance->nodeID(),
1079609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            instance->findBufferID(pBuffer), pBuffer);
1080318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
1081318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
1082318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber// static
1083318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMX_ERRORTYPE OMXNodeInstance::OnFillBufferDone(
108484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        OMX_IN OMX_HANDLETYPE /* hComponent */,
1085318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_PTR pAppData,
1086318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
1087318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
1088134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    if (instance->mDying) {
1089134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber        return OMX_ErrorNone;
1090134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    }
1091609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    return instance->owner()->OnFillBufferDone(instance->nodeID(),
1092609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            instance->findBufferID(pBuffer), pBuffer);
1093318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
1094318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
1095d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Hubervoid OMXNodeInstance::addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id) {
1096d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    ActiveBuffer active;
1097d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    active.mPortIndex = portIndex;
1098d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    active.mID = id;
1099d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    mActiveBuffers.push(active);
1100d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber}
1101d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
1102d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Hubervoid OMXNodeInstance::removeActiveBuffer(
1103d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        OMX_U32 portIndex, OMX::buffer_id id) {
1104d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    bool found = false;
1105d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    for (size_t i = 0; i < mActiveBuffers.size(); ++i) {
1106d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        if (mActiveBuffers[i].mPortIndex == portIndex
1107d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            && mActiveBuffers[i].mID == id) {
1108d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            found = true;
1109d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            mActiveBuffers.removeItemsAt(i);
1110d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            break;
1111d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        }
1112d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    }
1113d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
1114d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    if (!found) {
11155ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Attempt to remove an active buffer we know nothing about...");
1116d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    }
1117d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber}
1118d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
1119d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Hubervoid OMXNodeInstance::freeActiveBuffers() {
1120d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // Make sure to count down here, as freeBuffer will in turn remove
1121d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // the active buffer from the vector...
1122d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    for (size_t i = mActiveBuffers.size(); i--;) {
1123d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        freeBuffer(mActiveBuffers[i].mPortIndex, mActiveBuffers[i].mID);
1124d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    }
1125d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber}
1126d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
1127609b815a3131d22da38b2f452faa9f89daad4039Andy Hung#ifdef __LP64__
1128609b815a3131d22da38b2f452faa9f89daad4039Andy Hung
1129609b815a3131d22da38b2f452faa9f89daad4039Andy HungOMX::buffer_id OMXNodeInstance::makeBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) {
1130609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    if (bufferHeader == NULL) {
1131609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        return 0;
1132609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    }
1133609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    Mutex::Autolock autoLock(mBufferIDLock);
1134609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    OMX::buffer_id buffer;
1135609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    do { // handle the very unlikely case of ID overflow
1136609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        if (++mBufferIDCount == 0) {
1137609b815a3131d22da38b2f452faa9f89daad4039Andy Hung           ++mBufferIDCount;
1138609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        }
1139609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        buffer = (OMX::buffer_id)mBufferIDCount;
1140609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    } while (mBufferIDToBufferHeader.indexOfKey(buffer) >= 0);
1141609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    mBufferIDToBufferHeader.add(buffer, bufferHeader);
1142609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    mBufferHeaderToBufferID.add(bufferHeader, buffer);
1143609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    return buffer;
1144609b815a3131d22da38b2f452faa9f89daad4039Andy Hung}
1145609b815a3131d22da38b2f452faa9f89daad4039Andy Hung
1146609b815a3131d22da38b2f452faa9f89daad4039Andy HungOMX_BUFFERHEADERTYPE *OMXNodeInstance::findBufferHeader(OMX::buffer_id buffer) {
1147609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    if (buffer == 0) {
1148609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        return NULL;
1149609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    }
1150609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    Mutex::Autolock autoLock(mBufferIDLock);
1151609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    return mBufferIDToBufferHeader.valueFor(buffer);
1152609b815a3131d22da38b2f452faa9f89daad4039Andy Hung}
1153609b815a3131d22da38b2f452faa9f89daad4039Andy Hung
1154609b815a3131d22da38b2f452faa9f89daad4039Andy HungOMX::buffer_id OMXNodeInstance::findBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) {
1155609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    if (bufferHeader == NULL) {
1156609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        return 0;
1157609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    }
1158609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    Mutex::Autolock autoLock(mBufferIDLock);
1159609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    return mBufferHeaderToBufferID.valueFor(bufferHeader);
1160609b815a3131d22da38b2f452faa9f89daad4039Andy Hung}
1161609b815a3131d22da38b2f452faa9f89daad4039Andy Hung
1162609b815a3131d22da38b2f452faa9f89daad4039Andy Hungvoid OMXNodeInstance::invalidateBufferID(OMX::buffer_id buffer) {
1163609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    if (buffer == 0) {
1164609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        return;
1165609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    }
1166609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    Mutex::Autolock autoLock(mBufferIDLock);
1167609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    mBufferHeaderToBufferID.removeItem(mBufferIDToBufferHeader.valueFor(buffer));
1168609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    mBufferIDToBufferHeader.removeItem(buffer);
1169609b815a3131d22da38b2f452faa9f89daad4039Andy Hung}
1170609b815a3131d22da38b2f452faa9f89daad4039Andy Hung
1171609b815a3131d22da38b2f452faa9f89daad4039Andy Hung#else
1172609b815a3131d22da38b2f452faa9f89daad4039Andy Hung
1173609b815a3131d22da38b2f452faa9f89daad4039Andy HungOMX::buffer_id OMXNodeInstance::makeBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) {
1174609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    return (OMX::buffer_id)bufferHeader;
1175609b815a3131d22da38b2f452faa9f89daad4039Andy Hung}
1176609b815a3131d22da38b2f452faa9f89daad4039Andy Hung
1177609b815a3131d22da38b2f452faa9f89daad4039Andy HungOMX_BUFFERHEADERTYPE *OMXNodeInstance::findBufferHeader(OMX::buffer_id buffer) {
1178609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    return (OMX_BUFFERHEADERTYPE *)buffer;
1179609b815a3131d22da38b2f452faa9f89daad4039Andy Hung}
1180609b815a3131d22da38b2f452faa9f89daad4039Andy Hung
1181609b815a3131d22da38b2f452faa9f89daad4039Andy HungOMX::buffer_id OMXNodeInstance::findBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) {
1182609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    return (OMX::buffer_id)bufferHeader;
1183609b815a3131d22da38b2f452faa9f89daad4039Andy Hung}
1184609b815a3131d22da38b2f452faa9f89daad4039Andy Hung
1185609b815a3131d22da38b2f452faa9f89daad4039Andy Hungvoid OMXNodeInstance::invalidateBufferID(OMX::buffer_id buffer __unused) {
1186609b815a3131d22da38b2f452faa9f89daad4039Andy Hung}
1187609b815a3131d22da38b2f452faa9f89daad4039Andy Hung
1188609b815a3131d22da38b2f452faa9f89daad4039Andy Hung#endif
1189609b815a3131d22da38b2f452faa9f89daad4039Andy Hung
1190318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}  // namespace android
1191