OMXNodeInstance.cpp revision 512e979284de984427e5b2f73b9054ae1b5e2b0a
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
152d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // Transition the node from its current state all the way down
153d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // to "Loaded".
154d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // This ensures that all active buffers are properly freed even
155d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // for components that don't do this themselves on a call to
156d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // "FreeHandle".
157d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
158134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    // The code below may trigger some more events to be dispatched
159134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    // by the OMX component - we want to ignore them as our client
160134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    // does not expect them.
161134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    mDying = true;
162134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber
163d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    OMX_STATETYPE state;
164d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    CHECK_EQ(OMX_GetState(mHandle, &state), OMX_ErrorNone);
165d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    switch (state) {
166d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        case OMX_StateExecuting:
167d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        {
1683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("forcing Executing->Idle");
169d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            sendCommand(OMX_CommandStateSet, OMX_StateIdle);
170d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            OMX_ERRORTYPE err;
17143e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber            int32_t iteration = 0;
172d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone
1730d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber                   && state != OMX_StateIdle
1740d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber                   && state != OMX_StateInvalid) {
17543e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                if (++iteration > kMaxNumIterations) {
17629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("component failed to enter Idle state, aborting.");
17743e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                    state = OMX_StateInvalid;
17843e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                    break;
17943e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                }
18043e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber
181d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber                usleep(100000);
182d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            }
183d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            CHECK_EQ(err, OMX_ErrorNone);
184d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
1850d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber            if (state == OMX_StateInvalid) {
1860d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber                break;
1870d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber            }
1880d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber
189d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            // fall through
190d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        }
191d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
192d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        case OMX_StateIdle:
193d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        {
1943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("forcing Idle->Loaded");
195d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            sendCommand(OMX_CommandStateSet, OMX_StateLoaded);
196d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
197d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            freeActiveBuffers();
198d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
199d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            OMX_ERRORTYPE err;
20043e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber            int32_t iteration = 0;
201d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone
2020d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber                   && state != OMX_StateLoaded
2030d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber                   && state != OMX_StateInvalid) {
20443e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                if (++iteration > kMaxNumIterations) {
20529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("component failed to enter Loaded state, aborting.");
20643e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                    state = OMX_StateInvalid;
20743e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                    break;
20843e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                }
20943e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber
2103856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("waiting for Loaded state...");
211d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber                usleep(100000);
212d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            }
213d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            CHECK_EQ(err, OMX_ErrorNone);
214d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
215d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            // fall through
216d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        }
217d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
218d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        case OMX_StateLoaded:
219fa70cad40b01627ac1c22e04cdd548ece9c2654fAndreas Huber        case OMX_StateInvalid:
220d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            break;
221d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
222d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        default:
223d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            CHECK(!"should not be here, unknown state.");
224d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            break;
225d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    }
226d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
2273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("calling destroyComponentInstance");
228f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    OMX_ERRORTYPE err = master->destroyComponentInstance(
229f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber            static_cast<OMX_COMPONENTTYPE *>(mHandle));
2303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("destroyComponentInstance returned err %d", err);
231f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber
232318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    mHandle = NULL;
233318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
234318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    if (err != OMX_ErrorNone) {
23529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("FreeHandle FAILED with error 0x%08x.", err);
236318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
237318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
238318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    mOwner->invalidateNodeID(mNodeID);
239609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    mNodeID = 0;
240318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
2413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("OMXNodeInstance going away.");
24247bed1a7755ed58fa5d4c0d35b20468deb83bd60Andreas Huber    delete this;
243318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
244318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
245318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
246318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
247318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::sendCommand(
248318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_COMMANDTYPE cmd, OMX_S32 param) {
249e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource());
250ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber    if (bufferSource != NULL && cmd == OMX_CommandStateSet) {
251ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber        if (param == OMX_StateIdle) {
252ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            // Initiating transition from Executing -> Idle
253ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            // ACodec is waiting for all buffers to be returned, do NOT
254ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            // submit any more buffers to the codec.
255ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            bufferSource->omxIdle();
256ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber        } else if (param == OMX_StateLoaded) {
257ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            // Initiating transition from Idle/Executing -> Loaded
258ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            // Buffers are about to be freed.
259ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            bufferSource->omxLoaded();
260ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            setGraphicBufferSource(NULL);
261ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber        }
262e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
263e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        // fall through
264e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
265e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
266318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
267318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
268318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_SendCommand(mHandle, cmd, param, NULL);
269318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
270318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
271318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
272318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::getParameter(
27384333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        OMX_INDEXTYPE index, void *params, size_t /* size */) {
274318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
275318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
276318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_GetParameter(mHandle, index, params);
277609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGE_IF(err != OMX_ErrorNone, "getParameter(%d) ERROR: %#x", index, err);
278318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
279318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
280318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
281318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::setParameter(
28284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        OMX_INDEXTYPE index, const void *params, size_t /* size */) {
283318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
284318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
285318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_SetParameter(
286318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, index, const_cast<void *>(params));
287609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGE_IF(err != OMX_ErrorNone, "setParameter(%d) ERROR: %#x", index, err);
288318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
289318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
290318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
291318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::getConfig(
29284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        OMX_INDEXTYPE index, void *params, size_t /* size */) {
293318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
294318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
295318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_GetConfig(mHandle, index, params);
296318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
297318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
298318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
299318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::setConfig(
30084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        OMX_INDEXTYPE index, const void *params, size_t /* size */) {
301318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
302318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
303318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_SetConfig(
304318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, index, const_cast<void *>(params));
305318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
306318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
307b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennis}
308b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennis
309b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennisstatus_t OMXNodeInstance::getState(OMX_STATETYPE* state) {
310b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennis    Mutex::Autolock autoLock(mLock);
311b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennis
312b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennis    OMX_ERRORTYPE err = OMX_GetState(mHandle, state);
313b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennis
314b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennis    return StatusFromOMXError(err);
315318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
316318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
31783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennisstatus_t OMXNodeInstance::enableGraphicBuffers(
31883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        OMX_U32 portIndex, OMX_BOOL enable) {
31983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    Mutex::Autolock autoLock(mLock);
320ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis    OMX_STRING name = const_cast<OMX_STRING>(
321ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis            "OMX.google.android.index.enableAndroidNativeBuffers");
32283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
32383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    OMX_INDEXTYPE index;
324ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis    OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
32583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
32683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    if (err != OMX_ErrorNone) {
327d8754298b576aca4e85a059ea7b7e8f7a9502226Jamie Gennis        if (enable) {
328d8754298b576aca4e85a059ea7b7e8f7a9502226Jamie Gennis            ALOGE("OMX_GetExtensionIndex %s failed", name);
329d8754298b576aca4e85a059ea7b7e8f7a9502226Jamie Gennis        }
33083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
33183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        return StatusFromOMXError(err);
33283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    }
33383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
33483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    OMX_VERSIONTYPE ver;
33583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nVersionMajor = 1;
33683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nVersionMinor = 0;
33783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nRevision = 0;
33883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nStep = 0;
33983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    EnableAndroidNativeBuffersParams params = {
34083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        sizeof(EnableAndroidNativeBuffersParams), ver, portIndex, enable,
34183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    };
34283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
34383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    err = OMX_SetParameter(mHandle, index, &params);
34483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
34583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    if (err != OMX_ErrorNone) {
34629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_EnableAndroidNativeBuffers failed with error %d (0x%08x)",
34783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis                err, err);
34883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
34983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        return UNKNOWN_ERROR;
35083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    }
35183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
35283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    return OK;
35383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis}
35483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
355e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennisstatus_t OMXNodeInstance::getGraphicBufferUsage(
356e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis        OMX_U32 portIndex, OMX_U32* usage) {
357e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    Mutex::Autolock autoLock(mLock);
358e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
359e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    OMX_INDEXTYPE index;
360ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis    OMX_STRING name = const_cast<OMX_STRING>(
361ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis            "OMX.google.android.index.getAndroidNativeBufferUsage");
362ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis    OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
363e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
364e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    if (err != OMX_ErrorNone) {
365ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis        ALOGE("OMX_GetExtensionIndex %s failed", name);
366e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
367e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis        return StatusFromOMXError(err);
368e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    }
369e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
370e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    OMX_VERSIONTYPE ver;
371e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    ver.s.nVersionMajor = 1;
372e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    ver.s.nVersionMinor = 0;
373e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    ver.s.nRevision = 0;
374e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    ver.s.nStep = 0;
375e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    GetAndroidNativeBufferUsageParams params = {
376e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis        sizeof(GetAndroidNativeBufferUsageParams), ver, portIndex, 0,
377e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    };
378e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
379e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    err = OMX_GetParameter(mHandle, index, &params);
380e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
381e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    if (err != OMX_ErrorNone) {
38229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_GetAndroidNativeBufferUsage failed with error %d (0x%08x)",
383e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis                err, err);
384e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis        return UNKNOWN_ERROR;
385e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    }
386e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
387e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    *usage = params.nUsage;
388e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
389e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    return OK;
390e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis}
391e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
392e870772a78ffe08b1c14a791e368f1499f1be0f3James Dongstatus_t OMXNodeInstance::storeMetaDataInBuffers(
393e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong        OMX_U32 portIndex,
394e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong        OMX_BOOL enable) {
395e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    Mutex::Autolock autolock(mLock);
396512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar    return storeMetaDataInBuffers_l(
397512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar            portIndex, enable,
398512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar            OMX_FALSE /* useGraphicBuffer */, NULL /* usingGraphicBufferInMetadata */);
399f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
400e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
401f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenstatus_t OMXNodeInstance::storeMetaDataInBuffers_l(
402f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        OMX_U32 portIndex,
403512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar        OMX_BOOL enable,
404512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar        OMX_BOOL useGraphicBuffer,
405512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar        OMX_BOOL *usingGraphicBufferInMetadata) {
406e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    OMX_INDEXTYPE index;
407e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    OMX_STRING name = const_cast<OMX_STRING>(
408e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong            "OMX.google.android.index.storeMetaDataInBuffers");
409e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
410512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar    OMX_STRING graphicBufferName = const_cast<OMX_STRING>(
411512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar            "OMX.google.android.index.storeGraphicBufferInMetaData");
412512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar    if (usingGraphicBufferInMetadata == NULL) {
413512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar        usingGraphicBufferInMetadata = &useGraphicBuffer;
414512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar    }
415512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar
416512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar    OMX_ERRORTYPE err =
417512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar        (useGraphicBuffer && portIndex == kPortIndexInput)
418512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar                ? OMX_GetExtensionIndex(mHandle, graphicBufferName, &index)
419512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar                : OMX_ErrorBadParameter;
420512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar    if (err == OMX_ErrorNone) {
421512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar        *usingGraphicBufferInMetadata = OMX_TRUE;
422512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar    } else {
423512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar        *usingGraphicBufferInMetadata = OMX_FALSE;
424512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar        err = OMX_GetExtensionIndex(mHandle, name, &index);
425512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar    }
426512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar
427e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    if (err != OMX_ErrorNone) {
428d8754298b576aca4e85a059ea7b7e8f7a9502226Jamie Gennis        ALOGE("OMX_GetExtensionIndex %s failed", name);
429e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong        return StatusFromOMXError(err);
430e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    }
431e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
432e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    StoreMetaDataInBuffersParams params;
433e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    memset(&params, 0, sizeof(params));
434e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    params.nSize = sizeof(params);
435e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
436e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    // Version: 1.0.0.0
437e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    params.nVersion.s.nVersionMajor = 1;
438e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
439e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    params.nPortIndex = portIndex;
440e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    params.bStoreMetaData = enable;
441e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    if ((err = OMX_SetParameter(mHandle, index, &params)) != OMX_ErrorNone) {
44229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_SetParameter() failed for StoreMetaDataInBuffers: 0x%08x", err);
443512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar        *usingGraphicBufferInMetadata = OMX_FALSE;
444e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong        return UNKNOWN_ERROR;
445e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    }
446e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    return err;
447e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong}
448e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
44956ce726019f700a95ce5b45beebceadae4836e30Lajos Molnarstatus_t OMXNodeInstance::prepareForAdaptivePlayback(
45056ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar        OMX_U32 portIndex, OMX_BOOL enable, OMX_U32 maxFrameWidth,
45156ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar        OMX_U32 maxFrameHeight) {
45256ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    Mutex::Autolock autolock(mLock);
45356ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar
45456ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    OMX_INDEXTYPE index;
45556ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    OMX_STRING name = const_cast<OMX_STRING>(
45656ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar            "OMX.google.android.index.prepareForAdaptivePlayback");
45756ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar
45856ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
45956ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    if (err != OMX_ErrorNone) {
46056ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar        ALOGW_IF(enable, "OMX_GetExtensionIndex %s failed", name);
46156ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar        return StatusFromOMXError(err);
46256ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    }
46356ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar
46456ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    PrepareForAdaptivePlaybackParams params;
46556ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nSize = sizeof(params);
46656ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nVersion.s.nVersionMajor = 1;
46756ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nVersion.s.nVersionMinor = 0;
46856ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nVersion.s.nRevision = 0;
46956ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nVersion.s.nStep = 0;
47056ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar
47156ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nPortIndex = portIndex;
47256ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.bEnable = enable;
47356ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nMaxFrameWidth = maxFrameWidth;
47456ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nMaxFrameHeight = maxFrameHeight;
47556ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    if ((err = OMX_SetParameter(mHandle, index, &params)) != OMX_ErrorNone) {
47656ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar        ALOGW("OMX_SetParameter failed for PrepareForAdaptivePlayback "
47756ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar              "with error %d (0x%08x)", err, err);
47856ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar        return UNKNOWN_ERROR;
47956ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    }
48056ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    return err;
48156ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar}
48256ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar
4835a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t OMXNodeInstance::configureVideoTunnelMode(
4845a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        OMX_U32 portIndex, OMX_BOOL tunneled, OMX_U32 audioHwSync,
4855a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        native_handle_t **sidebandHandle) {
4865a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    Mutex::Autolock autolock(mLock);
4875a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
4885a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    OMX_INDEXTYPE index;
4895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    OMX_STRING name = const_cast<OMX_STRING>(
4905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            "OMX.google.android.index.configureVideoTunnelMode");
4915a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
4925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
4935a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OMX_ErrorNone) {
4945a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode extension is missing!");
4955a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return StatusFromOMXError(err);
4965a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
4975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
4985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    ConfigureVideoTunnelModeParams tunnelParams;
4995a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    tunnelParams.nSize = sizeof(tunnelParams);
5005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    tunnelParams.nVersion.s.nVersionMajor = 1;
5015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    tunnelParams.nVersion.s.nVersionMinor = 0;
5025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    tunnelParams.nVersion.s.nRevision = 0;
5035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    tunnelParams.nVersion.s.nStep = 0;
5045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
5055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    tunnelParams.nPortIndex = portIndex;
5065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    tunnelParams.bTunneled = tunneled;
5075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    tunnelParams.nAudioHwSync = audioHwSync;
5085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = OMX_SetParameter(mHandle, index, &tunnelParams);
5095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OMX_ErrorNone) {
5105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
5115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return UNKNOWN_ERROR;
5125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
5135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
5145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = OMX_GetParameter(mHandle, index, &tunnelParams);
5155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OMX_ErrorNone) {
5165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("GetVideoTunnelWindow failed! (err %d).", err);
5175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return UNKNOWN_ERROR;
5185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
5195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (sidebandHandle) {
5205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        *sidebandHandle = (native_handle_t*)tunnelParams.pSidebandWindow;
5215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
5225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
5235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return err;
5245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
5255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
526318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::useBuffer(
527318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_U32 portIndex, const sp<IMemory> &params,
528318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX::buffer_id *buffer) {
529318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
530318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
531318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta *buffer_meta = new BufferMeta(params);
532318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
533318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_BUFFERHEADERTYPE *header;
534318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
535318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_UseBuffer(
536318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, &header, portIndex, buffer_meta,
537318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            params->size(), static_cast<OMX_U8 *>(params->pointer()));
538318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
539318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    if (err != OMX_ErrorNone) {
54029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err);
541318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
542318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        delete buffer_meta;
543318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        buffer_meta = NULL;
544318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
545318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        *buffer = 0;
546318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
547318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        return UNKNOWN_ERROR;
548318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
549318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
55003b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber    CHECK_EQ(header->pAppPrivate, buffer_meta);
55103b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber
552609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    *buffer = makeBufferID(header);
553318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
554d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    addActiveBuffer(portIndex, *buffer);
555d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
556f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
557f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (bufferSource != NULL && portIndex == kPortIndexInput) {
558f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        bufferSource->addCodecBuffer(header);
559f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
560f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
561318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return OK;
562318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
563318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
564c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajanstatus_t OMXNodeInstance::useGraphicBuffer2_l(
565c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
566c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        OMX::buffer_id *buffer) {
567c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
568c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    // port definition
569c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    OMX_PARAM_PORTDEFINITIONTYPE def;
570c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
571c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    def.nVersion.s.nVersionMajor = 1;
572c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    def.nVersion.s.nVersionMinor = 0;
573c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    def.nVersion.s.nRevision = 0;
574c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    def.nVersion.s.nStep = 0;
575c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    def.nPortIndex = portIndex;
576c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    OMX_ERRORTYPE err = OMX_GetParameter(mHandle, OMX_IndexParamPortDefinition, &def);
577a0dac9e24ae7520cb7d7f0505bf0936bffbcd047Jamie Gennis    if (err != OMX_ErrorNone)
578c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    {
57929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("%s::%d:Error getting OMX_IndexParamPortDefinition", __FUNCTION__, __LINE__);
580c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        return err;
581c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    }
582c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
583c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    BufferMeta *bufferMeta = new BufferMeta(graphicBuffer);
584c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
585c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    OMX_BUFFERHEADERTYPE *header = NULL;
586c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    OMX_U8* bufferHandle = const_cast<OMX_U8*>(
587c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            reinterpret_cast<const OMX_U8*>(graphicBuffer->handle));
588c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
589c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    err = OMX_UseBuffer(
590c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            mHandle,
591c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            &header,
592c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            portIndex,
593c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            bufferMeta,
594c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            def.nBufferSize,
595c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            bufferHandle);
596c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
597c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    if (err != OMX_ErrorNone) {
59829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err);
599c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        delete bufferMeta;
600c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        bufferMeta = NULL;
601c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        *buffer = 0;
602c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        return UNKNOWN_ERROR;
603c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    }
604c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
605c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    CHECK_EQ(header->pBuffer, bufferHandle);
606c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    CHECK_EQ(header->pAppPrivate, bufferMeta);
607c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
608609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    *buffer = makeBufferID(header);
609c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
610c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    addActiveBuffer(portIndex, *buffer);
611c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
612c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    return OK;
613c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan}
614c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
615c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan// XXX: This function is here for backwards compatibility.  Once the OMX
616c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan// implementations have been updated this can be removed and useGraphicBuffer2
617c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan// can be renamed to useGraphicBuffer.
61883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennisstatus_t OMXNodeInstance::useGraphicBuffer(
61983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
62083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        OMX::buffer_id *buffer) {
62183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    Mutex::Autolock autoLock(mLock);
62283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
623c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    // See if the newer version of the extension is present.
62483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    OMX_INDEXTYPE index;
625c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    if (OMX_GetExtensionIndex(
626c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            mHandle,
627c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer2"),
628c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            &index) == OMX_ErrorNone) {
629c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        return useGraphicBuffer2_l(portIndex, graphicBuffer, buffer);
630c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    }
631c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
632ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis    OMX_STRING name = const_cast<OMX_STRING>(
633ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis        "OMX.google.android.index.useAndroidNativeBuffer");
634ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis    OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
63583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
63683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    if (err != OMX_ErrorNone) {
637ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis        ALOGE("OMX_GetExtensionIndex %s failed", name);
63883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
63983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        return StatusFromOMXError(err);
64083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    }
64183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
64283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    BufferMeta *bufferMeta = new BufferMeta(graphicBuffer);
64383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
64483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    OMX_BUFFERHEADERTYPE *header;
64583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
64683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    OMX_VERSIONTYPE ver;
64783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nVersionMajor = 1;
64883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nVersionMinor = 0;
64983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nRevision = 0;
65083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nStep = 0;
65183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    UseAndroidNativeBufferParams params = {
65283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        sizeof(UseAndroidNativeBufferParams), ver, portIndex, bufferMeta,
65383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        &header, graphicBuffer,
65483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    };
65583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
65683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    err = OMX_SetParameter(mHandle, index, &params);
65783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
65883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    if (err != OMX_ErrorNone) {
65929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_UseAndroidNativeBuffer failed with error %d (0x%08x)", err,
66083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis                err);
66183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
66283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        delete bufferMeta;
66383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        bufferMeta = NULL;
66483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
66583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        *buffer = 0;
66683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
66783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        return UNKNOWN_ERROR;
66883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    }
66983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
67083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    CHECK_EQ(header->pAppPrivate, bufferMeta);
67183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
672609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    *buffer = makeBufferID(header);
67383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
67483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    addActiveBuffer(portIndex, *buffer);
67583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
67683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    return OK;
67783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis}
67883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
679d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnarstatus_t OMXNodeInstance::updateGraphicBufferInMeta(
68084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        OMX_U32 /* portIndex */, const sp<GraphicBuffer>& graphicBuffer,
681d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        OMX::buffer_id buffer) {
682d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    Mutex::Autolock autoLock(mLock);
683d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
684609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer);
685d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    VideoDecoderOutputMetaData *metadata =
686d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        (VideoDecoderOutputMetaData *)(header->pBuffer);
687d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    BufferMeta *bufferMeta = (BufferMeta *)(header->pAppPrivate);
688d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    bufferMeta->setGraphicBuffer(graphicBuffer);
689d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    metadata->eType = kMetadataBufferTypeGrallocSource;
690d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    metadata->pHandle = graphicBuffer->handle;
691d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
692d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    return OK;
693d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar}
694d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
695f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenstatus_t OMXNodeInstance::createInputSurface(
696f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        OMX_U32 portIndex, sp<IGraphicBufferProducer> *bufferProducer) {
697f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autolock(mLock);
698f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    status_t err;
699f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
700f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    const sp<GraphicBufferSource>& surfaceCheck = getGraphicBufferSource();
701f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (surfaceCheck != NULL) {
702f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return ALREADY_EXISTS;
703f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
704f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
705f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Input buffers will hold meta-data (gralloc references).
706512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar    OMX_BOOL usingGraphicBuffer = OMX_FALSE;
707512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar    err = storeMetaDataInBuffers_l(
708512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar            portIndex, OMX_TRUE,
709512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar            OMX_TRUE /* useGraphicBuffer */, &usingGraphicBuffer);
710f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (err != OK) {
711f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return err;
712f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
713f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
714f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Retrieve the width and height of the graphic buffer, set when the
715f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // codec was configured.
716f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    OMX_PARAM_PORTDEFINITIONTYPE def;
717f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    def.nSize = sizeof(def);
718f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    def.nVersion.s.nVersionMajor = 1;
719f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    def.nVersion.s.nVersionMinor = 0;
720f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    def.nVersion.s.nRevision = 0;
721f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    def.nVersion.s.nStep = 0;
722f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    def.nPortIndex = portIndex;
723f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    OMX_ERRORTYPE oerr = OMX_GetParameter(
724f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            mHandle, OMX_IndexParamPortDefinition, &def);
725f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CHECK(oerr == OMX_ErrorNone);
726f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
727ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden    if (def.format.video.eColorFormat != OMX_COLOR_FormatAndroidOpaque) {
72892cb8f928dc9e237c356c942d10b5c0c1e04b2aeAndy McFadden        ALOGE("createInputSurface requires COLOR_FormatSurface "
72992cb8f928dc9e237c356c942d10b5c0c1e04b2aeAndy McFadden              "(AndroidOpaque) color format");
730ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden        return INVALID_OPERATION;
731ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden    }
732ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden
733f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    GraphicBufferSource* bufferSource = new GraphicBufferSource(
7340c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden            this, def.format.video.nFrameWidth, def.format.video.nFrameHeight,
735512e979284de984427e5b2f73b9054ae1b5e2b0aLajos Molnar            def.nBufferCountActual, usingGraphicBuffer);
736f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if ((err = bufferSource->initCheck()) != OK) {
737f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        delete bufferSource;
738f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return err;
739f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
740f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    setGraphicBufferSource(bufferSource);
741f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
742f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    *bufferProducer = bufferSource->getIGraphicBufferProducer();
743f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    return OK;
744f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
745f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
746f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenstatus_t OMXNodeInstance::signalEndOfInputStream() {
747f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // For non-Surface input, the MediaCodec should convert the call to a
748f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // pair of requests (dequeue input buffer, queue input buffer with EOS
749f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // flag set).  Seems easier than doing the equivalent from here.
750f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
751f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (bufferSource == NULL) {
752ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden        ALOGW("signalEndOfInputStream can only be used with Surface input");
753f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return INVALID_OPERATION;
754f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    };
755ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden    return bufferSource->signalEndOfInputStream();
756f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
757f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
758318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::allocateBuffer(
759570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber        OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer,
760570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber        void **buffer_data) {
761318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
762318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
763318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta *buffer_meta = new BufferMeta(size);
764318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
765318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_BUFFERHEADERTYPE *header;
766318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
767318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_AllocateBuffer(
768318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, &header, portIndex, buffer_meta, size);
769318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
770318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    if (err != OMX_ErrorNone) {
77129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err);
772318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
773318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        delete buffer_meta;
774318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        buffer_meta = NULL;
775318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
776318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        *buffer = 0;
777318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
778318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        return UNKNOWN_ERROR;
779318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
780318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
78103b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber    CHECK_EQ(header->pAppPrivate, buffer_meta);
78203b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber
783609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    *buffer = makeBufferID(header);
784570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber    *buffer_data = header->pBuffer;
785318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
786d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    addActiveBuffer(portIndex, *buffer);
787d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
788f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
789f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (bufferSource != NULL && portIndex == kPortIndexInput) {
790f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        bufferSource->addCodecBuffer(header);
791f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
792f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
793318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return OK;
794318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
795318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
796318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::allocateBufferWithBackup(
797318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_U32 portIndex, const sp<IMemory> &params,
798318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX::buffer_id *buffer) {
799318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
800318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
801318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta *buffer_meta = new BufferMeta(params, true);
802318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
803318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_BUFFERHEADERTYPE *header;
804318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
805318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_AllocateBuffer(
806318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, &header, portIndex, buffer_meta, params->size());
807318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
808318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    if (err != OMX_ErrorNone) {
80929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err);
810318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
811318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        delete buffer_meta;
812318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        buffer_meta = NULL;
813318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
814318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        *buffer = 0;
815318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
816318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        return UNKNOWN_ERROR;
817318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
818318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
81903b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber    CHECK_EQ(header->pAppPrivate, buffer_meta);
82003b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber
821609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    *buffer = makeBufferID(header);
822318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
823d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    addActiveBuffer(portIndex, *buffer);
824d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
825f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
826f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (bufferSource != NULL && portIndex == kPortIndexInput) {
827f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        bufferSource->addCodecBuffer(header);
828f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
829f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
830318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return OK;
831318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
832318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
833318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::freeBuffer(
834318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_U32 portIndex, OMX::buffer_id buffer) {
835318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
836318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
837d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    removeActiveBuffer(portIndex, buffer);
838d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
839609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer);
840318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate);
841318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
842318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_FreeBuffer(mHandle, portIndex, header);
843318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
844318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    delete buffer_meta;
845318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    buffer_meta = NULL;
846609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    invalidateBufferID(buffer);
847318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
848318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
849318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
850318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
851318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer) {
852318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
853318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
854609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer);
855318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nFilledLen = 0;
856318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nOffset = 0;
857318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nFlags = 0;
858318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
859318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_FillThisBuffer(mHandle, header);
860318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
861318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
862318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
863318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
864318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::emptyBuffer(
865318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX::buffer_id buffer,
866318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_U32 rangeOffset, OMX_U32 rangeLength,
867318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_U32 flags, OMX_TICKS timestamp) {
868318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
869318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
870609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer);
871318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nFilledLen = rangeLength;
872318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nOffset = rangeOffset;
873318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nFlags = flags;
874318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nTimeStamp = timestamp;
875318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
876318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta *buffer_meta =
877318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        static_cast<BufferMeta *>(header->pAppPrivate);
878318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    buffer_meta->CopyToOMX(header);
879318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
880318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header);
881318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
882318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
883318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
884318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
885f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// like emptyBuffer, but the data is already in header->pBuffer
886f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenstatus_t OMXNodeInstance::emptyDirectBuffer(
887f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        OMX_BUFFERHEADERTYPE *header,
888f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        OMX_U32 rangeOffset, OMX_U32 rangeLength,
889f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        OMX_U32 flags, OMX_TICKS timestamp) {
890f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mLock);
891f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
892f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    header->nFilledLen = rangeLength;
893f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    header->nOffset = rangeOffset;
894f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    header->nFlags = flags;
895f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    header->nTimeStamp = timestamp;
896f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
897f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header);
898f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (err != OMX_ErrorNone) {
899f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGW("emptyDirectBuffer failed, OMX err=0x%x", err);
900f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
901f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
902f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    return StatusFromOMXError(err);
903f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
904f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
905318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::getExtensionIndex(
906318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        const char *parameterName, OMX_INDEXTYPE *index) {
907318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
908318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
909318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_GetExtensionIndex(
910318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, const_cast<char *>(parameterName), index);
911318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
912318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
913318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
914318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
915e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huberstatus_t OMXNodeInstance::setInternalOption(
916e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        OMX_U32 portIndex,
917e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        IOMX::InternalOptionType type,
918e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        const void *data,
919e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        size_t size) {
920e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    switch (type) {
921e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        case IOMX::INTERNAL_OPTION_SUSPEND:
922a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        case IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY:
92394ee4b708acfa941581160b267afb79192b1d816Chong Zhang        case IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP:
92472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case IOMX::INTERNAL_OPTION_START_TIME:
9252c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        case IOMX::INTERNAL_OPTION_TIME_LAPSE:
926e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        {
927e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            const sp<GraphicBufferSource> &bufferSource =
928e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                getGraphicBufferSource();
929e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
930e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            if (bufferSource == NULL || portIndex != kPortIndexInput) {
931e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                return ERROR_UNSUPPORTED;
932e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            }
933e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
934a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            if (type == IOMX::INTERNAL_OPTION_SUSPEND) {
935a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                if (size != sizeof(bool)) {
936a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    return INVALID_OPERATION;
937a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                }
938a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
939a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                bool suspend = *(bool *)data;
940a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                bufferSource->suspend(suspend);
94194ee4b708acfa941581160b267afb79192b1d816Chong Zhang            } else if (type ==
94294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                    IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY){
943a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                if (size != sizeof(int64_t)) {
944a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    return INVALID_OPERATION;
945a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                }
946a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
947a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                int64_t delayUs = *(int64_t *)data;
948e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
949a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                return bufferSource->setRepeatPreviousFrameDelayUs(delayUs);
95072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            } else if (type ==
95172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP){
95294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                if (size != sizeof(int64_t)) {
95394ee4b708acfa941581160b267afb79192b1d816Chong Zhang                    return INVALID_OPERATION;
95494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                }
95594ee4b708acfa941581160b267afb79192b1d816Chong Zhang
95694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                int64_t maxGapUs = *(int64_t *)data;
95794ee4b708acfa941581160b267afb79192b1d816Chong Zhang
95894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                return bufferSource->setMaxTimestampGapUs(maxGapUs);
9592c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            } else if (type == IOMX::INTERNAL_OPTION_START_TIME) {
96072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                if (size != sizeof(int64_t)) {
96172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    return INVALID_OPERATION;
96272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                }
96372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
96472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                int64_t skipFramesBeforeUs = *(int64_t *)data;
96572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
96672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                bufferSource->setSkipFramesBeforeUs(skipFramesBeforeUs);
9672c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            } else { // IOMX::INTERNAL_OPTION_TIME_LAPSE
9682c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                if (size != sizeof(int64_t) * 2) {
9692c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    return INVALID_OPERATION;
9702c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                }
9712c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
9722c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                bufferSource->setTimeLapseUs((int64_t *)data);
973a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            }
974e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
975e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            return OK;
976e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        }
977e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
978e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        default:
979e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            return ERROR_UNSUPPORTED;
980e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
981e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber}
982e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
983318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Hubervoid OMXNodeInstance::onMessage(const omx_message &msg) {
98494ee4b708acfa941581160b267afb79192b1d816Chong Zhang    const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource());
98594ee4b708acfa941581160b267afb79192b1d816Chong Zhang
986318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    if (msg.type == omx_message::FILL_BUFFER_DONE) {
987318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_BUFFERHEADERTYPE *buffer =
988609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            findBufferHeader(msg.u.extended_buffer_data.buffer);
989318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
990318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        BufferMeta *buffer_meta =
991318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            static_cast<BufferMeta *>(buffer->pAppPrivate);
992318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
993318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        buffer_meta->CopyFromOMX(buffer);
9941b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber
9951b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber        if (bufferSource != NULL) {
99694ee4b708acfa941581160b267afb79192b1d816Chong Zhang            // fix up the buffer info (especially timestamp) if needed
99794ee4b708acfa941581160b267afb79192b1d816Chong Zhang            bufferSource->codecBufferFilled(buffer);
99894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
99994ee4b708acfa941581160b267afb79192b1d816Chong Zhang            omx_message newMsg = msg;
100094ee4b708acfa941581160b267afb79192b1d816Chong Zhang            newMsg.u.extended_buffer_data.timestamp = buffer->nTimeStamp;
100194ee4b708acfa941581160b267afb79192b1d816Chong Zhang            mObserver->onMessage(newMsg);
100294ee4b708acfa941581160b267afb79192b1d816Chong Zhang            return;
100394ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
100494ee4b708acfa941581160b267afb79192b1d816Chong Zhang    } else if (msg.type == omx_message::EMPTY_BUFFER_DONE) {
100594ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (bufferSource != NULL) {
10061b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            // This is one of the buffers used exclusively by
10071b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            // GraphicBufferSource.
10081b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            // Don't dispatch a message back to ACodec, since it doesn't
10091b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            // know that anyone asked to have the buffer emptied and will
10101b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            // be very confused.
10111b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber
10121b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            OMX_BUFFERHEADERTYPE *buffer =
1013609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                findBufferHeader(msg.u.buffer_data.buffer);
10141b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber
10151b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            bufferSource->codecBufferEmptied(buffer);
10161b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            return;
10171b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber        }
1018318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
1019318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
1020318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    mObserver->onMessage(msg);
1021318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
1022318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
1023f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Hubervoid OMXNodeInstance::onObserverDied(OMXMaster *master) {
102429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("!!! Observer died. Quickly, do something, ... anything...");
1025318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
1026318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    // Try to force shutdown of the node and hope for the best.
1027f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    freeNode(master);
1028318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
1029318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
1030318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Hubervoid OMXNodeInstance::onGetHandleFailed() {
1031318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    delete this;
1032318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
1033318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
1034f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// OMXNodeInstance::OnEvent calls OMX::OnEvent, which then calls here.
1035f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// Don't try to acquire mLock here -- in rare circumstances this will hang.
1036f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid OMXNodeInstance::onEvent(
1037f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        OMX_EVENTTYPE event, OMX_U32 arg1, OMX_U32 arg2) {
1038f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource());
1039f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
1040e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (bufferSource != NULL
1041e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            && event == OMX_EventCmdComplete
1042e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            && arg1 == OMX_CommandStateSet
1043e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            && arg2 == OMX_StateExecuting) {
1044e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bufferSource->omxExecuting();
1045f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
1046f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
1047f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
1048318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber// static
1049318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMX_ERRORTYPE OMXNodeInstance::OnEvent(
105084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        OMX_IN OMX_HANDLETYPE /* hComponent */,
1051318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_PTR pAppData,
1052318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_EVENTTYPE eEvent,
1053318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_U32 nData1,
1054318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_U32 nData2,
1055318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_PTR pEventData) {
1056318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
1057134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    if (instance->mDying) {
1058134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber        return OMX_ErrorNone;
1059134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    }
1060318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return instance->owner()->OnEvent(
1061318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            instance->nodeID(), eEvent, nData1, nData2, pEventData);
1062318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
1063318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
1064318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber// static
1065318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMX_ERRORTYPE OMXNodeInstance::OnEmptyBufferDone(
106684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        OMX_IN OMX_HANDLETYPE /* hComponent */,
1067318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_PTR pAppData,
1068318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
1069318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
1070134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    if (instance->mDying) {
1071134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber        return OMX_ErrorNone;
1072134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    }
1073609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    return instance->owner()->OnEmptyBufferDone(instance->nodeID(),
1074609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            instance->findBufferID(pBuffer), pBuffer);
1075318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
1076318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
1077318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber// static
1078318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMX_ERRORTYPE OMXNodeInstance::OnFillBufferDone(
107984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        OMX_IN OMX_HANDLETYPE /* hComponent */,
1080318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_PTR pAppData,
1081318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
1082318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
1083134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    if (instance->mDying) {
1084134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber        return OMX_ErrorNone;
1085134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    }
1086609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    return instance->owner()->OnFillBufferDone(instance->nodeID(),
1087609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            instance->findBufferID(pBuffer), pBuffer);
1088318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
1089318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
1090d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Hubervoid OMXNodeInstance::addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id) {
1091d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    ActiveBuffer active;
1092d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    active.mPortIndex = portIndex;
1093d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    active.mID = id;
1094d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    mActiveBuffers.push(active);
1095d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber}
1096d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
1097d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Hubervoid OMXNodeInstance::removeActiveBuffer(
1098d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        OMX_U32 portIndex, OMX::buffer_id id) {
1099d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    bool found = false;
1100d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    for (size_t i = 0; i < mActiveBuffers.size(); ++i) {
1101d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        if (mActiveBuffers[i].mPortIndex == portIndex
1102d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            && mActiveBuffers[i].mID == id) {
1103d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            found = true;
1104d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            mActiveBuffers.removeItemsAt(i);
1105d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            break;
1106d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        }
1107d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    }
1108d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
1109d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    if (!found) {
11105ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Attempt to remove an active buffer we know nothing about...");
1111d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    }
1112d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber}
1113d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
1114d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Hubervoid OMXNodeInstance::freeActiveBuffers() {
1115d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // Make sure to count down here, as freeBuffer will in turn remove
1116d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // the active buffer from the vector...
1117d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    for (size_t i = mActiveBuffers.size(); i--;) {
1118d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        freeBuffer(mActiveBuffers[i].mPortIndex, mActiveBuffers[i].mID);
1119d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    }
1120d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber}
1121d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
1122609b815a3131d22da38b2f452faa9f89daad4039Andy Hung#ifdef __LP64__
1123609b815a3131d22da38b2f452faa9f89daad4039Andy Hung
1124609b815a3131d22da38b2f452faa9f89daad4039Andy HungOMX::buffer_id OMXNodeInstance::makeBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) {
1125609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    if (bufferHeader == NULL) {
1126609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        return 0;
1127609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    }
1128609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    Mutex::Autolock autoLock(mBufferIDLock);
1129609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    OMX::buffer_id buffer;
1130609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    do { // handle the very unlikely case of ID overflow
1131609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        if (++mBufferIDCount == 0) {
1132609b815a3131d22da38b2f452faa9f89daad4039Andy Hung           ++mBufferIDCount;
1133609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        }
1134609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        buffer = (OMX::buffer_id)mBufferIDCount;
1135609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    } while (mBufferIDToBufferHeader.indexOfKey(buffer) >= 0);
1136609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    mBufferIDToBufferHeader.add(buffer, bufferHeader);
1137609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    mBufferHeaderToBufferID.add(bufferHeader, buffer);
1138609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    return buffer;
1139609b815a3131d22da38b2f452faa9f89daad4039Andy Hung}
1140609b815a3131d22da38b2f452faa9f89daad4039Andy Hung
1141609b815a3131d22da38b2f452faa9f89daad4039Andy HungOMX_BUFFERHEADERTYPE *OMXNodeInstance::findBufferHeader(OMX::buffer_id buffer) {
1142609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    if (buffer == 0) {
1143609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        return NULL;
1144609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    }
1145609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    Mutex::Autolock autoLock(mBufferIDLock);
1146609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    return mBufferIDToBufferHeader.valueFor(buffer);
1147609b815a3131d22da38b2f452faa9f89daad4039Andy Hung}
1148609b815a3131d22da38b2f452faa9f89daad4039Andy Hung
1149609b815a3131d22da38b2f452faa9f89daad4039Andy HungOMX::buffer_id OMXNodeInstance::findBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) {
1150609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    if (bufferHeader == NULL) {
1151609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        return 0;
1152609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    }
1153609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    Mutex::Autolock autoLock(mBufferIDLock);
1154609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    return mBufferHeaderToBufferID.valueFor(bufferHeader);
1155609b815a3131d22da38b2f452faa9f89daad4039Andy Hung}
1156609b815a3131d22da38b2f452faa9f89daad4039Andy Hung
1157609b815a3131d22da38b2f452faa9f89daad4039Andy Hungvoid OMXNodeInstance::invalidateBufferID(OMX::buffer_id buffer) {
1158609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    if (buffer == 0) {
1159609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        return;
1160609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    }
1161609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    Mutex::Autolock autoLock(mBufferIDLock);
1162609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    mBufferHeaderToBufferID.removeItem(mBufferIDToBufferHeader.valueFor(buffer));
1163609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    mBufferIDToBufferHeader.removeItem(buffer);
1164609b815a3131d22da38b2f452faa9f89daad4039Andy Hung}
1165609b815a3131d22da38b2f452faa9f89daad4039Andy Hung
1166609b815a3131d22da38b2f452faa9f89daad4039Andy Hung#else
1167609b815a3131d22da38b2f452faa9f89daad4039Andy Hung
1168609b815a3131d22da38b2f452faa9f89daad4039Andy HungOMX::buffer_id OMXNodeInstance::makeBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) {
1169609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    return (OMX::buffer_id)bufferHeader;
1170609b815a3131d22da38b2f452faa9f89daad4039Andy Hung}
1171609b815a3131d22da38b2f452faa9f89daad4039Andy Hung
1172609b815a3131d22da38b2f452faa9f89daad4039Andy HungOMX_BUFFERHEADERTYPE *OMXNodeInstance::findBufferHeader(OMX::buffer_id buffer) {
1173609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    return (OMX_BUFFERHEADERTYPE *)buffer;
1174609b815a3131d22da38b2f452faa9f89daad4039Andy Hung}
1175609b815a3131d22da38b2f452faa9f89daad4039Andy Hung
1176609b815a3131d22da38b2f452faa9f89daad4039Andy HungOMX::buffer_id OMXNodeInstance::findBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) {
1177609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    return (OMX::buffer_id)bufferHeader;
1178609b815a3131d22da38b2f452faa9f89daad4039Andy Hung}
1179609b815a3131d22da38b2f452faa9f89daad4039Andy Hung
1180609b815a3131d22da38b2f452faa9f89daad4039Andy Hungvoid OMXNodeInstance::invalidateBufferID(OMX::buffer_id buffer __unused) {
1181609b815a3131d22da38b2f452faa9f89daad4039Andy Hung}
1182609b815a3131d22da38b2f452faa9f89daad4039Andy Hung
1183609b815a3131d22da38b2f452faa9f89daad4039Andy Hung#endif
1184609b815a3131d22da38b2f452faa9f89daad4039Andy Hung
1185318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}  // namespace android
1186