127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "ACodec"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
311173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/NativeWindowWrapper.h>
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
331065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
353a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
363a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
37f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
40496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
41f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
44f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
46f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setPointer("node", omx_msg.node);
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer("buffer", omx_msg.u.buffer_data.buffer);
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "platform_private",
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.platform_private);
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "data_ptr",
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.data_ptr);
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs,
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate,
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr);
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
173c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
175f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
177c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
184c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
185c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
186c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
187c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
188c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
189c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
190c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
191c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
192c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
193c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
194c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
195c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
196c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
197c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
198c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
199c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
200c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
201c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
202c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
219f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
222f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
242349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
243349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
244349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
253349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
254349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
2925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
335f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
336afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
337afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber      mNode(NULL),
3385778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
339c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
3409806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
3419806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
3429806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
3439806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
3449806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMask(0) {
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
346c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
359dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
364f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
367f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
371f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3775778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
3785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
3795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
3805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
3815778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3835778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
3845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
3855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
3865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
3875778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3895778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
3905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
3915778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
393f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
3947a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
398f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
402c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
403c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
404c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
405c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
408496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
409496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
410496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
411496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
412f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = allocateOutputBuffersFromNativeWindow();
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
4305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
4315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
4395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
4405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
442ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
443ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
445afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
446afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
447afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
448afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
4491065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
450ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) {
451ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
452ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
453ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
454ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
455ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
456ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
457ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
458ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(ptr, def.nBufferSize);
459ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
4605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
461ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
4625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
463ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
464ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
465ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
466ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
467ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4691065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
4711065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
4721065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
483eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
484eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
485eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
487eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
489eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
492eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
4935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
4945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
498f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
51729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
5233c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
5243c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
5253c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
5265ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
5273c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
5283c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
5293c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
5303c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
531bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
532bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
533bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
534bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
535bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
536bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
537bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
538bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
539bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
540bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
541bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
542bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
543bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
544bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
545bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
546bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
547bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
548bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
549bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
550bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
551bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
552bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
553bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
5563c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
55929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
563258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    int minUndequeuedBufs = 0;
564258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
565258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
566258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            &minUndequeuedBufs);
567258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
568258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
56929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
570258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
571258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
572258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
573258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
574258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
575258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // buffer counts refer to - how do they account for the renderer holding on
576258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // to buffers?
577258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (def.nBufferCountActual < def.nBufferCountMin + minUndequeuedBufs) {
578258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs;
579258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
580258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
581258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
582258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
583258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (err != OK) {
58429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
585258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    mComponentName.c_str(), newBufferCount, err);
586258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
587258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
588258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
589258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
59429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), def.nBufferCountActual, def.nBufferSize);
602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
60474006804065941841883c4b46ee785070164023fJamie Gennis    for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
6058ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
6061e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
60829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
61374006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
61474006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
61574006804065941841883c4b46ee785070164023fJamie Gennis        info.mData = new ABuffer(0);
61674006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
61774006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
61874006804065941841883c4b46ee785070164023fJamie Gennis
619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
62329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
62474006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62874006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
62974006804065941841883c4b46ee785070164023fJamie Gennis
6303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
64274006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // Return the last two buffers to the native window.
645258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        cancelStart = def.nBufferCountActual - minUndequeuedBufs;
646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelEnd = def.nBufferCountActual;
647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
657f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
6641e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
673f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
6748ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
6751e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
6761e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
67729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
678c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
679c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mGraphicBuffer->handle == buf->handle) {
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
710349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
715349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        if (info->mStatus !=
716349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                BufferInfo::OWNED_BY_COMPONENT) {
717349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We shouldn't have sent out any buffers to the client at this
718349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // point.
719349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            CHECK_NE((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
720349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
728f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
748f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7675778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
7782944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
7792944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
7802944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
7812944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
788729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
789729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
790c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
791c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
792c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
793c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
8005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        { MEDIA_MIMETYPE_VIDEO_VPX,
8015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            "video_decoder.vpx", "video_encoder.vpx" },
802ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
803ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
8042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
8052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
8195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
8405ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
8425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
8465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8505778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
8525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
8535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
8545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
8555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
8605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
8625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
8635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
8645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
8662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
8672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
8682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
8695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
8705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
8715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
872d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
873d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
874d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
875d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
876d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
877d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
878d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
879d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
880d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                  mComponentName.c_str(), err);
881d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
882d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            return err;
883d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
884d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
885d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
8863a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    int32_t prependSPSPPS;
8873a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
8883a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
8893a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
8903a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
8913a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
8923a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
8933a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
8943a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
8953a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
8963a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
8973a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
8983a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
8993a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
9003a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
9013a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
9023a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
9033a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
9043a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
9053a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
9063a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
9073a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
9083a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
9093a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
9103a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
9113a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
9123a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
9135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!strncasecmp(mime, "video/", 6)) {
9145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
9155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
9165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
9175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
9185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
9195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
9205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
9215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
9225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
9235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
9245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
9275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
9285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
9295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
9305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
931aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
932ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
933ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
934ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
935aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
936aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
937aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
938ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
939ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
940aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                    encoder, numChannels, sampleRate, bitRate, aacProfile, isADTS != 0);
9415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
942729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
9435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
944729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
9455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
946729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
947729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
948729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
949729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
950729de186450f78c099637e1fce743fe531862c52Andreas Huber
951729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
9525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
9535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
9545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
9555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
9565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
9582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
9592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
9602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
9612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
9622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
9632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
9642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
9652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
9662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                if (!msg->findInt32("flac-compression-level", &compressionLevel)) {
9672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
9682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
9692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    ALOGW("compression level %d outside [0..8] range, using 0", compressionLevel);
9702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
9712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
9722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    ALOGW("compression level %d outside [0..8] range, using 8", compressionLevel);
9732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
9742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
9752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
9762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = setupFlacCodec(encoder, numChannels, sampleRate, compressionLevel);
9772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
978ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
979ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
980ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
981ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
982ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
983ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
984ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
985ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
986ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
9875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
988729de186450f78c099637e1fce743fe531862c52Andreas Huber
9898b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
9908b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
9918b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
9929806555d3930be43e11106281dee354820ac1c88Andreas Huber
9938b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
9948b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
9958b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
9968b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
9979806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
9989806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
9999806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
10009806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
10019806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
10029806555d3930be43e11106281dee354820ac1c88Andreas Huber
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
10055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
10075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10505778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t