OMXNodeInstance.cpp revision ad3b7e8d40bf1c97347f1538d30bba78ca371f67
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),
95318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber      mNodeID(NULL),
96318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber      mHandle(NULL),
97134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber      mObserver(observer),
98134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber      mDying(false) {
99318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
100318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
101318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMXNodeInstance::~OMXNodeInstance() {
102f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong    CHECK(mHandle == NULL);
103318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
104318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
105318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Hubervoid OMXNodeInstance::setHandle(OMX::node_id node_id, OMX_HANDLETYPE handle) {
106f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong    CHECK(mHandle == NULL);
107318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    mNodeID = node_id;
108318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    mHandle = handle;
109318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
110318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
111f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddensp<GraphicBufferSource> OMXNodeInstance::getGraphicBufferSource() {
112f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mGraphicBufferSourceLock);
113f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    return mGraphicBufferSource;
114f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
115f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
116f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid OMXNodeInstance::setGraphicBufferSource(
117f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        const sp<GraphicBufferSource>& bufferSource) {
118f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mGraphicBufferSourceLock);
119f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    mGraphicBufferSource = bufferSource;
120f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
121f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
122318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMX *OMXNodeInstance::owner() {
123318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return mOwner;
124318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
125318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
126318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Hubersp<IOMXObserver> OMXNodeInstance::observer() {
127318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return mObserver;
128318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
129318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
130318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMX::node_id OMXNodeInstance::nodeID() {
131318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return mNodeID;
132318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
133318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
134318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatic status_t StatusFromOMXError(OMX_ERRORTYPE err) {
1352a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber    switch (err) {
1362a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        case OMX_ErrorNone:
1372a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber            return OK;
1382a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        case OMX_ErrorUnsupportedSetting:
1392a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber            return ERROR_UNSUPPORTED;
1402a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber        default:
1412a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber            return UNKNOWN_ERROR;
1422a3847ee1cbdaa8a65eee397a0173bb02211c459Andreas Huber    }
143318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
144318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
145f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huberstatus_t OMXNodeInstance::freeNode(OMXMaster *master) {
14643e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber    static int32_t kMaxNumIterations = 10;
14743e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber
148d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // Transition the node from its current state all the way down
149d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // to "Loaded".
150d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // This ensures that all active buffers are properly freed even
151d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // for components that don't do this themselves on a call to
152d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // "FreeHandle".
153d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
154134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    // The code below may trigger some more events to be dispatched
155134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    // by the OMX component - we want to ignore them as our client
156134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    // does not expect them.
157134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    mDying = true;
158134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber
159d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    OMX_STATETYPE state;
160d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    CHECK_EQ(OMX_GetState(mHandle, &state), OMX_ErrorNone);
161d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    switch (state) {
162d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        case OMX_StateExecuting:
163d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        {
1643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("forcing Executing->Idle");
165d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            sendCommand(OMX_CommandStateSet, OMX_StateIdle);
166d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            OMX_ERRORTYPE err;
16743e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber            int32_t iteration = 0;
168d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone
1690d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber                   && state != OMX_StateIdle
1700d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber                   && state != OMX_StateInvalid) {
17143e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                if (++iteration > kMaxNumIterations) {
17229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("component failed to enter Idle state, aborting.");
17343e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                    state = OMX_StateInvalid;
17443e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                    break;
17543e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                }
17643e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber
177d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber                usleep(100000);
178d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            }
179d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            CHECK_EQ(err, OMX_ErrorNone);
180d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
1810d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber            if (state == OMX_StateInvalid) {
1820d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber                break;
1830d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber            }
1840d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber
185d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            // fall through
186d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        }
187d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
188d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        case OMX_StateIdle:
189d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        {
1903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("forcing Idle->Loaded");
191d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            sendCommand(OMX_CommandStateSet, OMX_StateLoaded);
192d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
193d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            freeActiveBuffers();
194d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
195d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            OMX_ERRORTYPE err;
19643e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber            int32_t iteration = 0;
197d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            while ((err = OMX_GetState(mHandle, &state)) == OMX_ErrorNone
1980d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber                   && state != OMX_StateLoaded
1990d681df3b0ded2c1e335b6b5785439da4ce2c238Andreas Huber                   && state != OMX_StateInvalid) {
20043e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                if (++iteration > kMaxNumIterations) {
20129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("component failed to enter Loaded state, aborting.");
20243e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                    state = OMX_StateInvalid;
20343e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                    break;
20443e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber                }
20543e5eca7048a3b7b3ee0223b7f3cbd837ed10ae5Andreas Huber
2063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("waiting for Loaded state...");
207d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber                usleep(100000);
208d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            }
209d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            CHECK_EQ(err, OMX_ErrorNone);
210d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
211d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            // fall through
212d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        }
213d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
214d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        case OMX_StateLoaded:
215fa70cad40b01627ac1c22e04cdd548ece9c2654fAndreas Huber        case OMX_StateInvalid:
216d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            break;
217d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
218d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        default:
219d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            CHECK(!"should not be here, unknown state.");
220d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            break;
221d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    }
222d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
2233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("calling destroyComponentInstance");
224f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    OMX_ERRORTYPE err = master->destroyComponentInstance(
225f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber            static_cast<OMX_COMPONENTTYPE *>(mHandle));
2263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("destroyComponentInstance returned err %d", err);
227f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber
228318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    mHandle = NULL;
229318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
230318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    if (err != OMX_ErrorNone) {
23129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("FreeHandle FAILED with error 0x%08x.", err);
232318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
233318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
234318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    mOwner->invalidateNodeID(mNodeID);
235318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    mNodeID = NULL;
236318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
2373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("OMXNodeInstance going away.");
23847bed1a7755ed58fa5d4c0d35b20468deb83bd60Andreas Huber    delete this;
239318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
240318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
241318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
242318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
243318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::sendCommand(
244318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_COMMANDTYPE cmd, OMX_S32 param) {
245e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource());
246ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber    if (bufferSource != NULL && cmd == OMX_CommandStateSet) {
247ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber        if (param == OMX_StateIdle) {
248ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            // Initiating transition from Executing -> Idle
249ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            // ACodec is waiting for all buffers to be returned, do NOT
250ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            // submit any more buffers to the codec.
251ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            bufferSource->omxIdle();
252ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber        } else if (param == OMX_StateLoaded) {
253ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            // Initiating transition from Idle/Executing -> Loaded
254ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            // Buffers are about to be freed.
255ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            bufferSource->omxLoaded();
256ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber            setGraphicBufferSource(NULL);
257ad3b7e8d40bf1c97347f1538d30bba78ca371f67Andreas Huber        }
258e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
259e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        // fall through
260e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
261e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
262318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
263318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
264318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_SendCommand(mHandle, cmd, param, NULL);
265318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
266318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
267318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
268318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::getParameter(
269318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_INDEXTYPE index, void *params, size_t size) {
270318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
271318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
272318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_GetParameter(mHandle, index, params);
273bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
274318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
275318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
276318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
277318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::setParameter(
278318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_INDEXTYPE index, const void *params, size_t size) {
279318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
280318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
281318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_SetParameter(
282318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, index, const_cast<void *>(params));
283318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
284318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
285318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
286318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
287318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::getConfig(
288318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_INDEXTYPE index, void *params, size_t size) {
289318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
290318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
291318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_GetConfig(mHandle, index, params);
292318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
293318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
294318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
295318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::setConfig(
296318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_INDEXTYPE index, const void *params, size_t size) {
297318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
298318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
299318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_SetConfig(
300318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, index, const_cast<void *>(params));
301318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
302318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
303b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennis}
304b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennis
305b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennisstatus_t OMXNodeInstance::getState(OMX_STATETYPE* state) {
306b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennis    Mutex::Autolock autoLock(mLock);
307b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennis
308b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennis    OMX_ERRORTYPE err = OMX_GetState(mHandle, state);
309b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennis
310b1d666f5cb555d135eb69e005e88a03330bbb54cJamie Gennis    return StatusFromOMXError(err);
311318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
312318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
31383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennisstatus_t OMXNodeInstance::enableGraphicBuffers(
31483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        OMX_U32 portIndex, OMX_BOOL enable) {
31583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    Mutex::Autolock autoLock(mLock);
316ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis    OMX_STRING name = const_cast<OMX_STRING>(
317ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis            "OMX.google.android.index.enableAndroidNativeBuffers");
31883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
31983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    OMX_INDEXTYPE index;
320ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis    OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
32183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
32283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    if (err != OMX_ErrorNone) {
323d8754298b576aca4e85a059ea7b7e8f7a9502226Jamie Gennis        if (enable) {
324d8754298b576aca4e85a059ea7b7e8f7a9502226Jamie Gennis            ALOGE("OMX_GetExtensionIndex %s failed", name);
325d8754298b576aca4e85a059ea7b7e8f7a9502226Jamie Gennis        }
32683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
32783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        return StatusFromOMXError(err);
32883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    }
32983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
33083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    OMX_VERSIONTYPE ver;
33183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nVersionMajor = 1;
33283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nVersionMinor = 0;
33383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nRevision = 0;
33483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nStep = 0;
33583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    EnableAndroidNativeBuffersParams params = {
33683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        sizeof(EnableAndroidNativeBuffersParams), ver, portIndex, enable,
33783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    };
33883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
33983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    err = OMX_SetParameter(mHandle, index, &params);
34083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
34183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    if (err != OMX_ErrorNone) {
34229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_EnableAndroidNativeBuffers failed with error %d (0x%08x)",
34383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis                err, err);
34483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
34583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        return UNKNOWN_ERROR;
34683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    }
34783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
34883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    return OK;
34983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis}
35083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
351e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennisstatus_t OMXNodeInstance::getGraphicBufferUsage(
352e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis        OMX_U32 portIndex, OMX_U32* usage) {
353e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    Mutex::Autolock autoLock(mLock);
354e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
355e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    OMX_INDEXTYPE index;
356ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis    OMX_STRING name = const_cast<OMX_STRING>(
357ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis            "OMX.google.android.index.getAndroidNativeBufferUsage");
358ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis    OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
359e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
360e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    if (err != OMX_ErrorNone) {
361ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis        ALOGE("OMX_GetExtensionIndex %s failed", name);
362e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
363e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis        return StatusFromOMXError(err);
364e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    }
365e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
366e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    OMX_VERSIONTYPE ver;
367e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    ver.s.nVersionMajor = 1;
368e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    ver.s.nVersionMinor = 0;
369e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    ver.s.nRevision = 0;
370e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    ver.s.nStep = 0;
371e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    GetAndroidNativeBufferUsageParams params = {
372e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis        sizeof(GetAndroidNativeBufferUsageParams), ver, portIndex, 0,
373e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    };
374e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
375e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    err = OMX_GetParameter(mHandle, index, &params);
376e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
377e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    if (err != OMX_ErrorNone) {
37829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_GetAndroidNativeBufferUsage failed with error %d (0x%08x)",
379e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis                err, err);
380e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis        return UNKNOWN_ERROR;
381e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    }
382e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
383e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    *usage = params.nUsage;
384e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
385e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis    return OK;
386e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis}
387e2ce6458659c6e1bad420357b61dc10cd8bbe2abJamie Gennis
388e870772a78ffe08b1c14a791e368f1499f1be0f3James Dongstatus_t OMXNodeInstance::storeMetaDataInBuffers(
389e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong        OMX_U32 portIndex,
390e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong        OMX_BOOL enable) {
391e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    Mutex::Autolock autolock(mLock);
392f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    return storeMetaDataInBuffers_l(portIndex, enable);
393f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
394e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
395f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenstatus_t OMXNodeInstance::storeMetaDataInBuffers_l(
396f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        OMX_U32 portIndex,
397f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        OMX_BOOL enable) {
398e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    OMX_INDEXTYPE index;
399e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    OMX_STRING name = const_cast<OMX_STRING>(
400e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong            "OMX.google.android.index.storeMetaDataInBuffers");
401e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
402e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
403e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    if (err != OMX_ErrorNone) {
404d8754298b576aca4e85a059ea7b7e8f7a9502226Jamie Gennis        ALOGE("OMX_GetExtensionIndex %s failed", name);
405d8754298b576aca4e85a059ea7b7e8f7a9502226Jamie Gennis
406e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong        return StatusFromOMXError(err);
407e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    }
408e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
409e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    StoreMetaDataInBuffersParams params;
410e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    memset(&params, 0, sizeof(params));
411e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    params.nSize = sizeof(params);
412e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
413e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    // Version: 1.0.0.0
414e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    params.nVersion.s.nVersionMajor = 1;
415e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
416e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    params.nPortIndex = portIndex;
417e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    params.bStoreMetaData = enable;
418e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    if ((err = OMX_SetParameter(mHandle, index, &params)) != OMX_ErrorNone) {
41929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_SetParameter() failed for StoreMetaDataInBuffers: 0x%08x", err);
420e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong        return UNKNOWN_ERROR;
421e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    }
422e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong    return err;
423e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong}
424e870772a78ffe08b1c14a791e368f1499f1be0f3James Dong
42556ce726019f700a95ce5b45beebceadae4836e30Lajos Molnarstatus_t OMXNodeInstance::prepareForAdaptivePlayback(
42656ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar        OMX_U32 portIndex, OMX_BOOL enable, OMX_U32 maxFrameWidth,
42756ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar        OMX_U32 maxFrameHeight) {
42856ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    Mutex::Autolock autolock(mLock);
42956ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar
43056ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    OMX_INDEXTYPE index;
43156ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    OMX_STRING name = const_cast<OMX_STRING>(
43256ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar            "OMX.google.android.index.prepareForAdaptivePlayback");
43356ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar
43456ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
43556ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    if (err != OMX_ErrorNone) {
43656ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar        ALOGW_IF(enable, "OMX_GetExtensionIndex %s failed", name);
43756ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar        return StatusFromOMXError(err);
43856ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    }
43956ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar
44056ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    PrepareForAdaptivePlaybackParams params;
44156ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nSize = sizeof(params);
44256ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nVersion.s.nVersionMajor = 1;
44356ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nVersion.s.nVersionMinor = 0;
44456ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nVersion.s.nRevision = 0;
44556ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nVersion.s.nStep = 0;
44656ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar
44756ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nPortIndex = portIndex;
44856ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.bEnable = enable;
44956ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nMaxFrameWidth = maxFrameWidth;
45056ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    params.nMaxFrameHeight = maxFrameHeight;
45156ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    if ((err = OMX_SetParameter(mHandle, index, &params)) != OMX_ErrorNone) {
45256ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar        ALOGW("OMX_SetParameter failed for PrepareForAdaptivePlayback "
45356ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar              "with error %d (0x%08x)", err, err);
45456ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar        return UNKNOWN_ERROR;
45556ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    }
45656ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar    return err;
45756ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar}
45856ce726019f700a95ce5b45beebceadae4836e30Lajos Molnar
459318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::useBuffer(
460318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_U32 portIndex, const sp<IMemory> &params,
461318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX::buffer_id *buffer) {
462318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
463318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
464318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta *buffer_meta = new BufferMeta(params);
465318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
466318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_BUFFERHEADERTYPE *header;
467318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
468318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_UseBuffer(
469318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, &header, portIndex, buffer_meta,
470318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            params->size(), static_cast<OMX_U8 *>(params->pointer()));
471318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
472318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    if (err != OMX_ErrorNone) {
47329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err);
474318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
475318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        delete buffer_meta;
476318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        buffer_meta = NULL;
477318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
478318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        *buffer = 0;
479318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
480318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        return UNKNOWN_ERROR;
481318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
482318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
48303b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber    CHECK_EQ(header->pAppPrivate, buffer_meta);
48403b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber
485318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    *buffer = header;
486318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
487d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    addActiveBuffer(portIndex, *buffer);
488d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
489f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
490f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (bufferSource != NULL && portIndex == kPortIndexInput) {
491f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        bufferSource->addCodecBuffer(header);
492f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
493f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
494318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return OK;
495318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
496318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
497c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajanstatus_t OMXNodeInstance::useGraphicBuffer2_l(
498c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
499c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        OMX::buffer_id *buffer) {
500c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
501c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    // port definition
502c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    OMX_PARAM_PORTDEFINITIONTYPE def;
503c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
504c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    def.nVersion.s.nVersionMajor = 1;
505c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    def.nVersion.s.nVersionMinor = 0;
506c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    def.nVersion.s.nRevision = 0;
507c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    def.nVersion.s.nStep = 0;
508c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    def.nPortIndex = portIndex;
509c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    OMX_ERRORTYPE err = OMX_GetParameter(mHandle, OMX_IndexParamPortDefinition, &def);
510a0dac9e24ae7520cb7d7f0505bf0936bffbcd047Jamie Gennis    if (err != OMX_ErrorNone)
511c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    {
51229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("%s::%d:Error getting OMX_IndexParamPortDefinition", __FUNCTION__, __LINE__);
513c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        return err;
514c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    }
515c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
516c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    BufferMeta *bufferMeta = new BufferMeta(graphicBuffer);
517c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
518c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    OMX_BUFFERHEADERTYPE *header = NULL;
519c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    OMX_U8* bufferHandle = const_cast<OMX_U8*>(
520c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            reinterpret_cast<const OMX_U8*>(graphicBuffer->handle));
521c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
522c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    err = OMX_UseBuffer(
523c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            mHandle,
524c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            &header,
525c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            portIndex,
526c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            bufferMeta,
527c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            def.nBufferSize,
528c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            bufferHandle);
529c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
530c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    if (err != OMX_ErrorNone) {
53129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_UseBuffer failed with error %d (0x%08x)", err, err);
532c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        delete bufferMeta;
533c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        bufferMeta = NULL;
534c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        *buffer = 0;
535c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        return UNKNOWN_ERROR;
536c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    }
537c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
538c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    CHECK_EQ(header->pBuffer, bufferHandle);
539c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    CHECK_EQ(header->pAppPrivate, bufferMeta);
540c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
541c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    *buffer = header;
542c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
543c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    addActiveBuffer(portIndex, *buffer);
544c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
545c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    return OK;
546c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan}
547c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
548c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan// XXX: This function is here for backwards compatibility.  Once the OMX
549c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan// implementations have been updated this can be removed and useGraphicBuffer2
550c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan// can be renamed to useGraphicBuffer.
55183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennisstatus_t OMXNodeInstance::useGraphicBuffer(
55283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
55383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        OMX::buffer_id *buffer) {
55483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    Mutex::Autolock autoLock(mLock);
55583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
556c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    // See if the newer version of the extension is present.
55783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    OMX_INDEXTYPE index;
558c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    if (OMX_GetExtensionIndex(
559c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            mHandle,
560c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer2"),
561c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan            &index) == OMX_ErrorNone) {
562c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan        return useGraphicBuffer2_l(portIndex, graphicBuffer, buffer);
563c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan    }
564c5a57efb706ec79032fc09c43b16d11ed0876604Anu Sundararajan
565ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis    OMX_STRING name = const_cast<OMX_STRING>(
566ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis        "OMX.google.android.index.useAndroidNativeBuffer");
567ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis    OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
56883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
56983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    if (err != OMX_ErrorNone) {
570ce18d7d85a78ac6642624fef1b5831eff4c72d56Jamie Gennis        ALOGE("OMX_GetExtensionIndex %s failed", name);
57183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
57283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        return StatusFromOMXError(err);
57383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    }
57483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
57583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    BufferMeta *bufferMeta = new BufferMeta(graphicBuffer);
57683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
57783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    OMX_BUFFERHEADERTYPE *header;
57883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
57983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    OMX_VERSIONTYPE ver;
58083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nVersionMajor = 1;
58183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nVersionMinor = 0;
58283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nRevision = 0;
58383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    ver.s.nStep = 0;
58483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    UseAndroidNativeBufferParams params = {
58583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        sizeof(UseAndroidNativeBufferParams), ver, portIndex, bufferMeta,
58683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        &header, graphicBuffer,
58783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    };
58883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
58983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    err = OMX_SetParameter(mHandle, index, &params);
59083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
59183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    if (err != OMX_ErrorNone) {
59229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_UseAndroidNativeBuffer failed with error %d (0x%08x)", err,
59383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis                err);
59483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
59583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        delete bufferMeta;
59683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        bufferMeta = NULL;
59783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
59883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        *buffer = 0;
59983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
60083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis        return UNKNOWN_ERROR;
60183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    }
60283750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
60383750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    CHECK_EQ(header->pAppPrivate, bufferMeta);
60483750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
60583750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    *buffer = header;
60683750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
60783750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    addActiveBuffer(portIndex, *buffer);
60883750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
60983750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis    return OK;
61083750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis}
61183750eaf5a3f38c243a9e7eb81d4b2421e3a0d88Jamie Gennis
612d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnarstatus_t OMXNodeInstance::updateGraphicBufferInMeta(
613d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
614d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        OMX::buffer_id buffer) {
615d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    Mutex::Autolock autoLock(mLock);
616d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
617d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)(buffer);
618d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    VideoDecoderOutputMetaData *metadata =
619d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        (VideoDecoderOutputMetaData *)(header->pBuffer);
620d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    BufferMeta *bufferMeta = (BufferMeta *)(header->pAppPrivate);
621d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    bufferMeta->setGraphicBuffer(graphicBuffer);
622d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    metadata->eType = kMetadataBufferTypeGrallocSource;
623d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    metadata->pHandle = graphicBuffer->handle;
624d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
625d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar    return OK;
626d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar}
627d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
628f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenstatus_t OMXNodeInstance::createInputSurface(
629f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        OMX_U32 portIndex, sp<IGraphicBufferProducer> *bufferProducer) {
630f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autolock(mLock);
631f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    status_t err;
632f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
633f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    const sp<GraphicBufferSource>& surfaceCheck = getGraphicBufferSource();
634f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (surfaceCheck != NULL) {
635f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return ALREADY_EXISTS;
636f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
637f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
638f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Input buffers will hold meta-data (gralloc references).
639f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    err = storeMetaDataInBuffers_l(portIndex, OMX_TRUE);
640f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (err != OK) {
641f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return err;
642f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
643f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
644f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // Retrieve the width and height of the graphic buffer, set when the
645f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // codec was configured.
646f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    OMX_PARAM_PORTDEFINITIONTYPE def;
647f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    def.nSize = sizeof(def);
648f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    def.nVersion.s.nVersionMajor = 1;
649f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    def.nVersion.s.nVersionMinor = 0;
650f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    def.nVersion.s.nRevision = 0;
651f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    def.nVersion.s.nStep = 0;
652f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    def.nPortIndex = portIndex;
653f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    OMX_ERRORTYPE oerr = OMX_GetParameter(
654f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden            mHandle, OMX_IndexParamPortDefinition, &def);
655f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    CHECK(oerr == OMX_ErrorNone);
656f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
657ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden    if (def.format.video.eColorFormat != OMX_COLOR_FormatAndroidOpaque) {
65892cb8f928dc9e237c356c942d10b5c0c1e04b2aeAndy McFadden        ALOGE("createInputSurface requires COLOR_FormatSurface "
65992cb8f928dc9e237c356c942d10b5c0c1e04b2aeAndy McFadden              "(AndroidOpaque) color format");
660ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden        return INVALID_OPERATION;
661ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden    }
662ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden
663f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    GraphicBufferSource* bufferSource = new GraphicBufferSource(
6640c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden            this, def.format.video.nFrameWidth, def.format.video.nFrameHeight,
6650c37f9d1320bb87fd242f9425c67dacd6ce20112Andy McFadden            def.nBufferCountActual);
666f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if ((err = bufferSource->initCheck()) != OK) {
667f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        delete bufferSource;
668f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return err;
669f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
670f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    setGraphicBufferSource(bufferSource);
671f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
672f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    *bufferProducer = bufferSource->getIGraphicBufferProducer();
673f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    return OK;
674f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
675f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
676f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenstatus_t OMXNodeInstance::signalEndOfInputStream() {
677f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // For non-Surface input, the MediaCodec should convert the call to a
678f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // pair of requests (dequeue input buffer, queue input buffer with EOS
679f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    // flag set).  Seems easier than doing the equivalent from here.
680f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
681f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (bufferSource == NULL) {
682ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden        ALOGW("signalEndOfInputStream can only be used with Surface input");
683f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        return INVALID_OPERATION;
684f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    };
685ba6218eae3dbcf3f962b3561b26374a214dbf5e2Andy McFadden    return bufferSource->signalEndOfInputStream();
686f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
687f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
688318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::allocateBuffer(
689570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber        OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer,
690570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber        void **buffer_data) {
691318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
692318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
693318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta *buffer_meta = new BufferMeta(size);
694318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
695318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_BUFFERHEADERTYPE *header;
696318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
697318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_AllocateBuffer(
698318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, &header, portIndex, buffer_meta, size);
699318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
700318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    if (err != OMX_ErrorNone) {
70129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err);
702318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
703318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        delete buffer_meta;
704318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        buffer_meta = NULL;
705318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
706318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        *buffer = 0;
707318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
708318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        return UNKNOWN_ERROR;
709318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
710318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
71103b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber    CHECK_EQ(header->pAppPrivate, buffer_meta);
71203b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber
713318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    *buffer = header;
714570a3cb7582daa030cb38eedc5eb6a06f86ecc7fAndreas Huber    *buffer_data = header->pBuffer;
715318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
716d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    addActiveBuffer(portIndex, *buffer);
717d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
718f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
719f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (bufferSource != NULL && portIndex == kPortIndexInput) {
720f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        bufferSource->addCodecBuffer(header);
721f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
722f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
723318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return OK;
724318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
725318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
726318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::allocateBufferWithBackup(
727318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_U32 portIndex, const sp<IMemory> &params,
728318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX::buffer_id *buffer) {
729318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
730318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
731318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta *buffer_meta = new BufferMeta(params, true);
732318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
733318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_BUFFERHEADERTYPE *header;
734318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
735318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_AllocateBuffer(
736318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, &header, portIndex, buffer_meta, params->size());
737318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
738318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    if (err != OMX_ErrorNone) {
73929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("OMX_AllocateBuffer failed with error %d (0x%08x)", err, err);
740318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
741318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        delete buffer_meta;
742318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        buffer_meta = NULL;
743318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
744318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        *buffer = 0;
745318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
746318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        return UNKNOWN_ERROR;
747318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
748318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
74903b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber    CHECK_EQ(header->pAppPrivate, buffer_meta);
75003b268eac37ca2589bfff0bf58daf79d29cc14f4Andreas Huber
751318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    *buffer = header;
752318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
753d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    addActiveBuffer(portIndex, *buffer);
754d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
755f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
756f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (bufferSource != NULL && portIndex == kPortIndexInput) {
757f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        bufferSource->addCodecBuffer(header);
758f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
759f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
760318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return OK;
761318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
762318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
763318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::freeBuffer(
764318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_U32 portIndex, OMX::buffer_id buffer) {
765318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
766318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
767d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    removeActiveBuffer(portIndex, buffer);
768d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
769318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
770318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate);
771318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
772318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_FreeBuffer(mHandle, portIndex, header);
773318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
774318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    delete buffer_meta;
775318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    buffer_meta = NULL;
776318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
777318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
778318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
779318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
780318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer) {
781318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
782318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
783318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
784318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nFilledLen = 0;
785318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nOffset = 0;
786318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nFlags = 0;
787318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
788318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_FillThisBuffer(mHandle, header);
789318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
790318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
791318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
792318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
793318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::emptyBuffer(
794318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX::buffer_id buffer,
795318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_U32 rangeOffset, OMX_U32 rangeLength,
796318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_U32 flags, OMX_TICKS timestamp) {
797318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
798318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
799318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
800318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nFilledLen = rangeLength;
801318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nOffset = rangeOffset;
802318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nFlags = flags;
803318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    header->nTimeStamp = timestamp;
804318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
805318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    BufferMeta *buffer_meta =
806318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        static_cast<BufferMeta *>(header->pAppPrivate);
807318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    buffer_meta->CopyToOMX(header);
808318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
809318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header);
810318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
811318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
812318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
813318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
814f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// like emptyBuffer, but the data is already in header->pBuffer
815f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenstatus_t OMXNodeInstance::emptyDirectBuffer(
816f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        OMX_BUFFERHEADERTYPE *header,
817f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        OMX_U32 rangeOffset, OMX_U32 rangeLength,
818f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        OMX_U32 flags, OMX_TICKS timestamp) {
819f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    Mutex::Autolock autoLock(mLock);
820f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
821f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    header->nFilledLen = rangeLength;
822f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    header->nOffset = rangeOffset;
823f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    header->nFlags = flags;
824f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    header->nTimeStamp = timestamp;
825f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
826f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    OMX_ERRORTYPE err = OMX_EmptyThisBuffer(mHandle, header);
827f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    if (err != OMX_ErrorNone) {
828f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        ALOGW("emptyDirectBuffer failed, OMX err=0x%x", err);
829f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
830f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
831f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    return StatusFromOMXError(err);
832f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
833f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
834318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huberstatus_t OMXNodeInstance::getExtensionIndex(
835318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        const char *parameterName, OMX_INDEXTYPE *index) {
836318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
837318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
838318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMX_ERRORTYPE err = OMX_GetExtensionIndex(
839318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            mHandle, const_cast<char *>(parameterName), index);
840318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
841318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return StatusFromOMXError(err);
842318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
843318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
844e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huberstatus_t OMXNodeInstance::setInternalOption(
845e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        OMX_U32 portIndex,
846e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        IOMX::InternalOptionType type,
847e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        const void *data,
848e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        size_t size) {
849e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    switch (type) {
850e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        case IOMX::INTERNAL_OPTION_SUSPEND:
851a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        case IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY:
852e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        {
853e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            const sp<GraphicBufferSource> &bufferSource =
854e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                getGraphicBufferSource();
855e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
856e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            if (bufferSource == NULL || portIndex != kPortIndexInput) {
857e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                return ERROR_UNSUPPORTED;
858e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            }
859e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
860a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            if (type == IOMX::INTERNAL_OPTION_SUSPEND) {
861a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                if (size != sizeof(bool)) {
862a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    return INVALID_OPERATION;
863a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                }
864a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
865a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                bool suspend = *(bool *)data;
866a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                bufferSource->suspend(suspend);
867a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            } else {
868a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                if (size != sizeof(int64_t)) {
869a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    return INVALID_OPERATION;
870a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                }
871a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
872a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                int64_t delayUs = *(int64_t *)data;
873e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
874a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                return bufferSource->setRepeatPreviousFrameDelayUs(delayUs);
875a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            }
876e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
877e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            return OK;
878e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        }
879e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
880e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        default:
881e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            return ERROR_UNSUPPORTED;
882e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
883e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber}
884e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
885318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Hubervoid OMXNodeInstance::onMessage(const omx_message &msg) {
886318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    if (msg.type == omx_message::FILL_BUFFER_DONE) {
887318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_BUFFERHEADERTYPE *buffer =
888318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            static_cast<OMX_BUFFERHEADERTYPE *>(
889318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber                    msg.u.extended_buffer_data.buffer);
890318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
891318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        BufferMeta *buffer_meta =
892318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            static_cast<BufferMeta *>(buffer->pAppPrivate);
893318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
894318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        buffer_meta->CopyFromOMX(buffer);
8951b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber    } else if (msg.type == omx_message::EMPTY_BUFFER_DONE) {
8961b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber        const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource());
8971b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber
8981b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber        if (bufferSource != NULL) {
8991b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            // This is one of the buffers used exclusively by
9001b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            // GraphicBufferSource.
9011b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            // Don't dispatch a message back to ACodec, since it doesn't
9021b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            // know that anyone asked to have the buffer emptied and will
9031b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            // be very confused.
9041b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber
9051b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            OMX_BUFFERHEADERTYPE *buffer =
9061b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber                static_cast<OMX_BUFFERHEADERTYPE *>(
9071b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber                        msg.u.buffer_data.buffer);
9081b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber
9091b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            bufferSource->codecBufferEmptied(buffer);
9101b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber            return;
9111b4ca5cebd7f42a8f8842e45bfabe19001e9a435Andreas Huber        }
912318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
913318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
914318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    mObserver->onMessage(msg);
915318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
916318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
917f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Hubervoid OMXNodeInstance::onObserverDied(OMXMaster *master) {
91829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("!!! Observer died. Quickly, do something, ... anything...");
919318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
920318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    // Try to force shutdown of the node and hope for the best.
921f0fb96c352f30b812a4903a1d783a715e1e817bdAndreas Huber    freeNode(master);
922318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
923318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
924318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Hubervoid OMXNodeInstance::onGetHandleFailed() {
925318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    delete this;
926318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
927318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
928f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// OMXNodeInstance::OnEvent calls OMX::OnEvent, which then calls here.
929f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden// Don't try to acquire mLock here -- in rare circumstances this will hang.
930f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFaddenvoid OMXNodeInstance::onEvent(
931f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden        OMX_EVENTTYPE event, OMX_U32 arg1, OMX_U32 arg2) {
932f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource());
933f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
934e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (bufferSource != NULL
935e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            && event == OMX_EventCmdComplete
936e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            && arg1 == OMX_CommandStateSet
937e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber            && arg2 == OMX_StateExecuting) {
938e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bufferSource->omxExecuting();
939f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden    }
940f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden}
941f779bb50d9746d9526541c3e6dcdf619cac941b7Andy McFadden
942318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber// static
943318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMX_ERRORTYPE OMXNodeInstance::OnEvent(
944318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_HANDLETYPE hComponent,
945318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_PTR pAppData,
946318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_EVENTTYPE eEvent,
947318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_U32 nData1,
948318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_U32 nData2,
949318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_PTR pEventData) {
950318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
951134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    if (instance->mDying) {
952134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber        return OMX_ErrorNone;
953134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    }
954318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return instance->owner()->OnEvent(
955318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber            instance->nodeID(), eEvent, nData1, nData2, pEventData);
956318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
957318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
958318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber// static
959318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMX_ERRORTYPE OMXNodeInstance::OnEmptyBufferDone(
960318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_HANDLETYPE hComponent,
961318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_PTR pAppData,
962318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
963318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
964134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    if (instance->mDying) {
965134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber        return OMX_ErrorNone;
966134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    }
967318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return instance->owner()->OnEmptyBufferDone(instance->nodeID(), pBuffer);
968318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
969318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
970318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber// static
971318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas HuberOMX_ERRORTYPE OMXNodeInstance::OnFillBufferDone(
972318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_HANDLETYPE hComponent,
973318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_PTR pAppData,
974318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
975318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
976134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    if (instance->mDying) {
977134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber        return OMX_ErrorNone;
978134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber    }
979318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return instance->owner()->OnFillBufferDone(instance->nodeID(), pBuffer);
980318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}
981318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
982d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Hubervoid OMXNodeInstance::addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id) {
983d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    ActiveBuffer active;
984d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    active.mPortIndex = portIndex;
985d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    active.mID = id;
986d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    mActiveBuffers.push(active);
987d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber}
988d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
989d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Hubervoid OMXNodeInstance::removeActiveBuffer(
990d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        OMX_U32 portIndex, OMX::buffer_id id) {
991d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    bool found = false;
992d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    for (size_t i = 0; i < mActiveBuffers.size(); ++i) {
993d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        if (mActiveBuffers[i].mPortIndex == portIndex
994d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            && mActiveBuffers[i].mID == id) {
995d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            found = true;
996d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            mActiveBuffers.removeItemsAt(i);
997d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber            break;
998d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        }
999d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    }
1000d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
1001d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    if (!found) {
10025ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Attempt to remove an active buffer we know nothing about...");
1003d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    }
1004d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber}
1005d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
1006d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Hubervoid OMXNodeInstance::freeActiveBuffers() {
1007d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // Make sure to count down here, as freeBuffer will in turn remove
1008d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    // the active buffer from the vector...
1009d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    for (size_t i = mActiveBuffers.size(); i--;) {
1010d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber        freeBuffer(mActiveBuffers[i].mPortIndex, mActiveBuffers[i].mID);
1011d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber    }
1012d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber}
1013d6703ab22c85b43fdb2deb78a37e51465c902a5fAndreas Huber
1014318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber}  // namespace android
1015