ACodec.cpp revision bc098410be55f9d96f394b3981a0c482b83859b6
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
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
40f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
44f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
46f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setPointer("node", omx_msg.node);
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer("buffer", omx_msg.u.buffer_data.buffer);
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "platform_private",
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.platform_private);
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "data_ptr",
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.data_ptr);
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs,
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate,
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr);
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
169c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
173c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
180c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
181c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
182c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
183c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
184c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
185c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
186c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
187c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
188c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
189c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
190c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
191c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
192c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
193c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
194c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
195c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
196c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
197c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
198c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
215f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
218f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
223f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
238349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
239349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
240349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
249349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
250349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
2885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
331f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
332afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
333afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber      mNode(NULL),
3345778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
335c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
3369806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
3379806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
3389806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
3399806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
3409806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMask(0) {
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
342c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
355dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
360f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
363f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
367f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3735778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
3745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
3755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
3765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
3775778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3795778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
3805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
3815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
3825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
3835778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3855778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
3865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
3875778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
389f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
3907a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
394f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
398c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
399c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
400c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
401c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = allocateOutputBuffersFromNativeWindow();
4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
4315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
4325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
434ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
435ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
437afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
438afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
439afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
440afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
4411065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
442ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) {
443ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
444ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
445ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
446ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
447ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
448ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
449ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
450ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(ptr, def.nBufferSize);
451ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
4525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
453ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
4545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
455ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
456ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
457ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
458ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
459ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
4605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4611065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
4631065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
4641065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
4655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
475eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
476eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
477eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
479eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
481eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
484eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
50929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
5153c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
5163c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
5173c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
5185ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
5193c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
5203c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
5213c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
5223c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
523bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
524bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
525bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
526bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
527bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
528bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
529bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
530bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
531bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
532bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
533bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
534bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
535bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
536bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
537bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
538bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
539bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
540bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
541bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
542bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
543bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
544bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
545bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
5483c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
55129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
555258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    int minUndequeuedBufs = 0;
556258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
557258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
558258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            &minUndequeuedBufs);
559258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
560258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
56129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
562258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
563258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
564258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
565258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
566258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
567258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // buffer counts refer to - how do they account for the renderer holding on
568258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // to buffers?
569258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (def.nBufferCountActual < def.nBufferCountMin + minUndequeuedBufs) {
570258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs;
571258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
572258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
573258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
574258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
575258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (err != OK) {
57629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
577258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    mComponentName.c_str(), newBufferCount, err);
578258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
579258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
580258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
581258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
58629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), def.nBufferCountActual, def.nBufferSize);
594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
59674006804065941841883c4b46ee785070164023fJamie Gennis    for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
5978ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
60029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
60574006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
60674006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
60774006804065941841883c4b46ee785070164023fJamie Gennis        info.mData = new ABuffer(0);
60874006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
60974006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
61074006804065941841883c4b46ee785070164023fJamie Gennis
611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
61529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
61674006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62074006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
62174006804065941841883c4b46ee785070164023fJamie Gennis
6223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
63474006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // Return the last two buffers to the native window.
637258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        cancelStart = def.nBufferCountActual - minUndequeuedBufs;
638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelEnd = def.nBufferCountActual;
639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
649f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNativeWindow.get(), info->mGraphicBuffer.get());
657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
665f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
6668ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
667c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf) != 0) {
66829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
669c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
670c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mGraphicBuffer->handle == buf->handle) {
677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
701349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
706349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        if (info->mStatus !=
707349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                BufferInfo::OWNED_BY_COMPONENT) {
708349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We shouldn't have sent out any buffers to the client at this
709349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // point.
710349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            CHECK_NE((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
711349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
719f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
739f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7585778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
7692944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
7702944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
7712944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
7722944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
779729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
780729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
781c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
782c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
783c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
784c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
7915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        { MEDIA_MIMETYPE_VIDEO_VPX,
7925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            "video_decoder.vpx", "video_encoder.vpx" },
793ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
794ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
7952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
7962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
8105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
8315ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
8335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
8375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8415778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
8435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
8445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
8455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
8465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
8515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
8535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
8545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
8555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
8572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
8582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
8592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
8605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
8615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
8625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!strncasecmp(mime, "video/", 6)) {
8645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
8655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
8665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
8675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
8685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
8695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
8705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
8715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
8725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
8735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
8745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
8775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
8785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
8795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
8805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
881aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
882ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
883ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
884ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
885aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
886aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
887aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
888ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
889ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
890aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                    encoder, numChannels, sampleRate, bitRate, aacProfile, isADTS != 0);
8915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
892729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
8935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
894729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
8955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
896729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
897729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
898729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
899729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
900729de186450f78c099637e1fce743fe531862c52Andreas Huber
901729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
9025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
9035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
9045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
9055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
9065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9072f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
9082f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
9092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
9102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
9112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
9122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
9132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
9142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
9152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
9162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                if (!msg->findInt32("flac-compression-level", &compressionLevel)) {
9172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
9182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
9192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    ALOGW("compression level %d outside [0..8] range, using 0", compressionLevel);
9202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
9212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
9222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    ALOGW("compression level %d outside [0..8] range, using 8", compressionLevel);
9232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
9242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
9252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
9262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = setupFlacCodec(encoder, numChannels, sampleRate, compressionLevel);
9272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
928ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
929ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
930ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
931ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
932ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
933ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
934ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
935ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
936ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
9375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
938729de186450f78c099637e1fce743fe531862c52Andreas Huber
9398b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
9408b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
9418b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
9429806555d3930be43e11106281dee354820ac1c88Andreas Huber
9438b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
9448b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
9458b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
9468b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
9479806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
9489806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
9499806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
9509806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
9519806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
9529806555d3930be43e11106281dee354820ac1c88Andreas Huber
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
9555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
9575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
9595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
963f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10005778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
10015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
10025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
10035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
10045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
10065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
10075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
10085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
10105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
10115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
10125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
10145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
10155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1027aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1028aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1029ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1030ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1031ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1032ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
10345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
10365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
10435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
10465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
10475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
10505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
10515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
10525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
10545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
10555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
10575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
10585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
10615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
10625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
10645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
10655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
10675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
10685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
10715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
10725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
10735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
10755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
10765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
10785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
10795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
10825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
10845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
10855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
10865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
10885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
10895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
10905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
10915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
10925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1093aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
10945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
10955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
10975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
10985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
11005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
11015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
11045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1119ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1120ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1121ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1122ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1123ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
11275778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11295778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
11305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
11315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
11325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
11335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
11345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
11355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
11365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
11375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
11385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
11395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
11405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
11415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
11425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
11435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
11445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
11455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
11465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
11475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
11485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
11515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
11525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
11535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
11545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
11555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
11565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
11575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
11585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
11595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
11605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
11625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
11645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
11665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11745778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1175729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1176729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
11775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1178729de186450f78c099637e1fce743fe531862c52Andreas Huber
1179729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1180729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1181729de186450f78c099637e1fce743fe531862c52Andreas Huber
1182729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1183729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1184729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1185729de186450f78c099637e1fce743fe531862c52Andreas Huber
1186729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
11875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
11885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
11905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1191729de186450f78c099637e1fce743fe531862c52Andreas Huber
11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
11935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
11945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1195729de186450f78c099637e1fce743fe531862c52Andreas Huber
11965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
11975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
11985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
11995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1200729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1201729de186450f78c099637e1fce743fe531862c52Andreas Huber
12025778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
12035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
12045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1205729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1206729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1207729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1208729de186450f78c099637e1fce743fe531862c52Andreas Huber
12092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
12102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
12112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
12122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
12132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
12142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
12152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
12162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
12172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
12182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
12192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
12202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
12212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
12222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
12232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
12242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
12252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
12262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
12272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
12282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
12292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
12302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
12312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
12322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
12332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
12342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
12352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
12362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1237729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1238729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1239729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1240729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1241729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1242729de186450f78c099637e1fce743fe531862c52Andreas Huber
1243729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1244729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1245729de186450f78c099637e1fce743fe531862c52Andreas Huber
1246729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1247729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1248729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1249729de186450f78c099637e1fce743fe531862c52Andreas Huber
1250729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1251729de186450f78c099637e1fce743fe531862c52Andreas Huber
1252729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1253729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1254729de186450f78c099637e1fce743fe531862c52Andreas Huber
1255729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1256729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1257729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1258729de186450f78c099637e1fce743fe531862c52Andreas Huber
1259729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1260729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1261729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1262729de186450f78c099637e1fce743fe531862c52Andreas Huber
1263729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1264729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1265729de186450f78c099637e1fce743fe531862c52Andreas Huber
1266729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1267729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1268729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1269729de186450f78c099637e1fce743fe531862c52Andreas Huber
1270729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1271729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1272729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1273729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1274729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1275729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1276729de186450f78c099637e1fce743fe531862c52Andreas Huber
1277c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1278c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1279729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1280729de186450f78c099637e1fce743fe531862c52Andreas Huber
1281729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1282729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1283729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1284729de186450f78c099637e1fce743fe531862c52Andreas Huber
1285f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1344f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
1357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber           || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
1358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber           || format.eColorFormat == OMX_COLOR_FormatCbYCrY
13591065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber           || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar
1360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber           || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar);
1361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
13685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingAVC;
1371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingMPEG4;
1373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
13745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingH263;
1375386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG2, mime)) {
13765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingMPEG2;
13775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VPX, mime)) {
13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingVPX;
1379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
13805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingUnused;
13815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
13855778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13875778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
13885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
14405778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
14415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
14465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
14645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
14735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
14775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
14895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
14945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
15065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
15615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
15655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
15665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
15695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
15735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
15755778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
15765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
15815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
15825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
16245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
16335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
16355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
16385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
16395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
16485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
16495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
16525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
16535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = configureBitrate(bitrate);
16595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
16655778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
16665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16675778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
16685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
16695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
16705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
16795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
16815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
16845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
16865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
16885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
16895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
16955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
17045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
17055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
17065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
17075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
17085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
17115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
17135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
17145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
17175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
17185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
17215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
17225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
17235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
17245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
17265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
17275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = configureBitrate(bitrate);
17335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17415778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
17425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
17435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
17445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
17455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
17465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
17495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
17505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
17515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
17525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
17535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
17555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
17585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
17595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
17635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
17725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
17897c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
17907c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
17917c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
17965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
17975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return configureBitrate(bitrate);
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureBitrate(int32_t bitrate) {
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.eControlRate = OMX_Video_ControlRateVariable;
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1907f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
1908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
1910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
1915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
1922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
1923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
1924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
1925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
1926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
1930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
1932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
1933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
1935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
1936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
1937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1945f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
1946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
1947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
1951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1954d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
1955d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
1956d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
1957d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1958d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
1959d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
1960d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
1961d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
1962d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
1963d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
1964d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
1965d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
1966d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
1967d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
1968f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
1969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
1970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
1974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
19753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
1976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
1977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
1978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
1979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
1983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1985f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
1986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
1987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
1988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1990f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
1991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
1992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
1993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1995f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
1996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
1997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
1998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
200531e2508c75018145a8238925ff1a08cbde4e799aAndreas Hubervoid ACodec::sendFormatChange() {
200631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    sp<AMessage> notify = mNotify->dup();
200731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->setInt32("what", kWhatOutputFormatChanged);
200831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
200931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
201031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
201131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    def.nPortIndex = kPortIndexOutput;
201231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
201331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
201431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
201531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
201631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
201731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
201831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
201931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
202031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
202131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
202231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
202331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
202431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
202531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("width", videoDef->nFrameWidth);
202631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("height", videoDef->nFrameHeight);
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("stride", videoDef->nStride);
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("slice-height", videoDef->nSliceHeight);
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("color-format", videoDef->eColorFormat);
203031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
203131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_CONFIG_RECTTYPE rect;
203231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            InitOMXParams(&rect);
203331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            rect.nPortIndex = kPortIndexOutput;
203431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
203531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (mOMX->getConfig(
203631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        mNode, OMX_IndexConfigCommonOutputCrop,
203731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        &rect, sizeof(rect)) != OK) {
203831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nLeft = 0;
203931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nTop = 0;
204031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nWidth = videoDef->nFrameWidth;
204131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nHeight = videoDef->nFrameHeight;
204231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
204331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
204431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nLeft, 0);
204531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nTop, 0);
204631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nWidth, 0u);
204731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nHeight, 0u);
204831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
204931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
205031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
205131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setRect(
205231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    "crop",
205331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nLeft,
205431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nTop,
205531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nLeft + rect.nWidth - 1,
205631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nTop + rect.nHeight - 1);
205731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
205831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (mNativeWindow != NULL) {
205931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                android_native_rect_t crop;
206031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                crop.left = rect.nLeft;
206131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                crop.top = rect.nTop;
206289c120e7adbe09c6283591789594c5e591aa5032Andreas Huber                crop.right = rect.nLeft + rect.nWidth;
206389c120e7adbe09c6283591789594c5e591aa5032Andreas Huber                crop.bottom = rect.nTop + rect.nHeight;
206431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
206531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                CHECK_EQ(0, native_window_set_crop(
206631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                            mNativeWindow.get(), &crop));
206731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
206831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
206931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
207031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
207131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
207231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
207331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
207431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ((int)audioDef->eEncoding, (int)OMX_AUDIO_CodingPCM);
207531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
207631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PARAM_PCMMODETYPE params;
207731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            InitOMXParams(&params);
207831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            params.nPortIndex = kPortIndexOutput;
207931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
208031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ(mOMX->getParameter(
208131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        mNode, OMX_IndexParamAudioPcm,
208231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        &params, sizeof(params)),
208331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                     (status_t)OK);
208431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
208531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK(params.nChannels == 1 || params.bInterleaved);
208631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ(params.nBitPerSample, 16u);
208731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned);
208831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear);
208931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
209031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
209131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("channel-count", params.nChannels);
209231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("sample-rate", params.nSamplingRate);
20938b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mEncoderDelay + mEncoderPadding) {
20948b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                size_t frameSize = params.nChannels * sizeof(int16_t);
20958b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                if (mSkipCutBuffer != NULL) {
20968b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    size_t prevbufsize = mSkipCutBuffer->size();
20978b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    if (prevbufsize != 0) {
20988b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                        ALOGW("Replacing SkipCutBuffer holding %d bytes", prevbufsize);
20998b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
21008b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
21018b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay * frameSize,
21028b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                                                   mEncoderPadding * frameSize);
21038b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
21049806555d3930be43e11106281dee354820ac1c88Andreas Huber
21059806555d3930be43e11106281dee354820ac1c88Andreas Huber            if (mChannelMaskPresent) {
21069806555d3930be43e11106281dee354820ac1c88Andreas Huber                notify->setInt32("channel-mask", mChannelMask);
21079806555d3930be43e11106281dee354820ac1c88Andreas Huber            }
21089806555d3930be43e11106281dee354820ac1c88Andreas Huber
210931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
211031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
211131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
211231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
211331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
211431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
211531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
211631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
211731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
211831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
211931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
212031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
21215778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2122cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
2123cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
2124cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
2126cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
2127cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
2128cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
2129bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2130bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
2131bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
2132bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
2133bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
2134bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2135bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2136bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
2137bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
2138bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
2139bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
2140bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2141bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2142bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2143bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2144bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2145bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2146bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
2147bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
2148bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2149bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2150bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2151bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2152bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2153bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2154bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2155bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
2156bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2157bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2158bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2159bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2160bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2161bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2162bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
2163bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
2164bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2165bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2166bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2167bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2168bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2169bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2170bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
2171bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2172bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2173bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2174bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
2175bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2176bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2177bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2178bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
2179bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2180bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2181bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2182bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2183bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2184bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2185bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2186bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2187bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
2188bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
2189bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
2190bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
2191bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &anb);
2192bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2193bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2194bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2195bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2196bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2197bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2198bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2199bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->lockBuffer(mNativeWindow.get(),
2200bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                buf->getNativeBuffer());
2201bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2202bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lockBuffer failed: %s (%d)",
2203bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2204bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2205bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2206bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2207bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2208bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
2209bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2210bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2211bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2212bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2213bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2214bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2215bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2216bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
2217bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2218bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
2219bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2220bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2221bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2222bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2223bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2224bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2225bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
2226bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                buf->getNativeBuffer());
2227bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2228bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2229bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2230bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2231bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2232bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2233bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
2234bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2235bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2236bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
2237bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2238bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2239bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
2240bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
2241bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb);
2242bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2243bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2244bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
2245bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2246bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
2247bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2248bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2249bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2250bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
2251bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
2252bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
2253bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2254bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2255bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2256bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2257bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2258bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2259bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2260bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
2261bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2262bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2263bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2264bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2265bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2266bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2267bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2268bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
2269bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2270bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
2271bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2274eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
2275eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2276eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2277eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
2278eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
2279eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
2280eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
2281eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2282eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2283eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
2284eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
2285eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2286eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2287eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
2288eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
2289eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2290eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2291eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
2292eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
2293eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2294eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2295eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
2296eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2297f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
2298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
2299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
2300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2302f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
2303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
2304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2306f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
2307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
2309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
2311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
2315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
2317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
2321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
2323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2332f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
2333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
2334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
2335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
2337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
2338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
2339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
2341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
2342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
2344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
2345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
2346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
2347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23480af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
23490af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
23500af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
23510af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
23520af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
23530af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
23540af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
23550af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
23560af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
23570af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
23580af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
2359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
2360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
2361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
2362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
2363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
2366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
2371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
2374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
2379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
2380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
2381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
2382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
2384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
2385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
2386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
2387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
2388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
2389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
2391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
2392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
2393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
2394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
2395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
2396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
2397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
2401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2405f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
2406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
24083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
2409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
2410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
2412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
241429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
2415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2416cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
2417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2421f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
24223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
2423349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
2424349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
2426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
2427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
2429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
2430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
2432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
2439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
2445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2452f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
2453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
2454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
2455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
2458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
2460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
2461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
2462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
24642d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
2465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
2467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
2468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
2470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
2472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
2474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2476f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
2477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
2478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
2479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24802d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
2481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
24825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
24835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24842d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
2485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
2486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] saw error %d instead of an input buffer",
24883831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber             mCodec->mComponentName.c_str(), err);
24893831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
24902d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
24915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
2493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
24965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
24975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
24985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
24995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
2502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
2503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
2505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
2507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
25115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
2512dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
2513dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
2514dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
2515dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
2516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
25225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
2523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
2524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
2527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
2529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
2530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
2531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
2532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
25345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
25355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
25365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
2538349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    if (0 && !(flags & OMX_BUFFERFLAG_CODECCONFIG)) {
25393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                        ALOGV("[%s] Needs to copy input data.",
2540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                             mCodec->mComponentName.c_str());
2541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
2542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
2544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
2545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
2546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2547078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
25483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
2549078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
25505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
25515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
25525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
2553078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
25543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
2555078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
2556078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
2557349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
2559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
2560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
2561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
2562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
2563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
2564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
2565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
2566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
2568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
25705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
25715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
25725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
25735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
25745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
25765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
25775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
2578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
2579dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
25803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
2581dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
2582dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
2583dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
25843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
2585dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
2586dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
2587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
2589349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
2590349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
2592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
2593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
2594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
2595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
2596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
2597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
2598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
2599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
2601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
2603dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
2604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
2608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2614f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
2615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
2616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
2617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
2620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
2622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
2623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
2625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
2626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
2627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
2628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
2630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
2632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
2633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
2637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
2638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
2641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2643f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
2644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
2645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
2646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
2647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
2648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *platformPrivate,
2649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *dataPtr) {
26505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
26515778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
2652349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
2654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
2655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
2656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
2658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
2660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
2662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
26695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
26705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
26715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
2672349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
26735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
26745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
26755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
2676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
26785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
26795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
268031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
26815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!mCodec->mIsEncoder && !mCodec->mSentFormat) {
26825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->sendFormatChange();
26835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
2684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mCodec->mNativeWindow == NULL) {
26865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mData->setRange(rangeOffset, rangeLength);
26875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
2688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26898b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
26908b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
26918b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
26925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
2693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
26955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
26965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
26972d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
26985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
2699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> reply =
27015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                new AMessage(kWhatOutputBufferDrained, mCodec->id());
2702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
2704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
2706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
27085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
2710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
27125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
27135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
2715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
2716dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
2717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
2718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
2720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
2729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
2730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2737f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
2738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
2739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
2740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
2742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
2743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
2744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
2745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
2747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
2748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && msg->findInt32("render", &render) && render != 0) {
2749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
2750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
27525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
2753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
27545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    info->mGraphicBuffer.get())) == OK) {
2755cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
2756cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
27575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
2758cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
2759cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
2760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
2761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
2762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
2765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
2770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
2773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
2774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
2776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
2783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
2785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
2786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
2788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
2789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2790c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
27913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
2792c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
2793349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2794c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
2795c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
2796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2797c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
2798c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
2799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
2808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
2809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2816f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
2817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
2818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2820c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
2821c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
2822c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
2823c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
2824f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
2825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
2826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
2829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
2831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
2833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
28375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
28385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
28395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
28405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
28415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
2844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2845c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
2846c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
2847c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
2848c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(!keepComponentAllocated);
2849c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
2850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
2851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
2852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
2853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
2855c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
2856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
2859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
2861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
2862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
2863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
2865c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
2866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
2870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
2873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2875f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
2876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
2877c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
2878c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
2879c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
2880c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
28815778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2883c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
28845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
28855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2886c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
28875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
2889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
2890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
2892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<String8> matchingCodecs;
2894afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    Vector<uint32_t> matchingCodecQuirks;
28955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
2897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
2899afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    uint32_t quirks;
29005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
29015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        matchingCodecs.push_back(String8(componentName.c_str()));
2902afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
2903afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        if (!OMXCodec::findCodecQuirks(componentName.c_str(), &quirks)) {
2904afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber            quirks = 0;
2905afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
2906afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        matchingCodecQuirks.push_back(quirks);
29075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
29085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
29095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
29115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
29125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
29135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
29165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
29175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
29185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
29195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
2920afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                &matchingCodecs,
2921afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                &matchingCodecQuirks);
29225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29231065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
29241065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
29251065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
29261065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
29271065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
29281065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
29291065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        componentName = matchingCodecs.itemAt(matchIndex).string();
2930afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        quirks = matchingCodecQuirks.itemAt(matchIndex);
2931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2932078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
2933078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
2934078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
29351065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
2936078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
2937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29381065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
29391065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
29401065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
29411065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
29421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
29431065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
29441065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
2945c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
29465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
29475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
29485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
29495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
29505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
29515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2952c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
2953cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
2954c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
2955c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXMessage, mCodec->id());
2958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
2959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
2961ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
2962ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2963ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
2964ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
2965ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
2966ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2967afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
2968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
2969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
2970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2971349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
2972349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
2973349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2974dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mCodec->mInputEOSResult = OK;
2975dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
29765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
29775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
29785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
29795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
29805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
29815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2982c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
2983c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
2984c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
2985c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
29865778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
29875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2988c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
2989c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
2990c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
2991c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
2992c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
2993c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
2994c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
2995c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
2996c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
2997c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
2998c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
2999c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3000c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
3001c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
3002c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3003c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
3004c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3005c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3006c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3007c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3008c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
3009c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3010c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3011c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mNativeWindow.clear();
3012c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mNode = NULL;
3013c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mOMX.clear();
3014afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        mCodec->mQuirks = 0;
3015ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags = 0;
3016c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mComponentName.clear();
3017c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3018c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
3019c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3020c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3021c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3022c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3023c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->post();
3024c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3025c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3026c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3027c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
3028c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3029c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
3030c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
3031c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3032c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
3033c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3034c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3035c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3036c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3037c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
3038c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3039c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
3040c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3041c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3042c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3043c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3044c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
3045c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3046c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3047c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3048c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3049c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3050c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
3051c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3052c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3053c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3054c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3055c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3056c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
3057c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3058c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3059c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3060c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
3061c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3062c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3063c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3064c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3065c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3066c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
3067c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
3068c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3069c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3070c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
3071c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3072c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3073c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
30745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
30755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
30765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
30785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
30805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
30815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
30835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3085c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
3086c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
3087c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
30885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
3089c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
30905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
3093386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
30945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
30951173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
30961173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
30971173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
30981173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
30991ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
31001ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
31011ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
31021ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
31075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
31085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
31095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
31105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3111c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3112c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
31135778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
31145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3115c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
31165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
31175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
31195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
3121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
3123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3127f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
3128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3131f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
31323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
3133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3134cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
3135cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
313629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
3137cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
3138cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
3139cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
31405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
314191bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
314291bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
3143cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
3144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3146f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
3147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
3148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
3154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3156f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3169f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
3170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
3176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
3179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
3182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3193f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
3194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3197f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
31983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
3199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3201f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3214f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
3215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
3221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
3223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
3224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3235f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
3236349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
3237349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
3238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3240f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
3241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
3243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3245f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::submitOutputBuffers() {
3246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
3247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
3248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
3250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
3251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
3252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
3255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            status_t err = mCodec->mNativeWindow->lockBuffer(
3258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
3259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mGraphicBuffer.get());
3260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(err, (status_t)OK);
3261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
3262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32653856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
3266349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
3267349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
3270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3275f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
3276349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
32773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
3278349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
3279349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3280349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
3281349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
3282349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
3284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
3286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
3287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
3288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
3290349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3291349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
3292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3294f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
32953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
3296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
3298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3300f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3306c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3307c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3308c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3309c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3310c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
3311c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
3312c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3313349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
3314349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
3320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
33277a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
3328d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
3329d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
3330d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
3331d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
3332d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
3333d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
3334d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3335349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
3336349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
3339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
3342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
3348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
3350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3363f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
3364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
3367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
3369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
337031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
3371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
3372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
3374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3376349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
3377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
337931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
338031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
3381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
33823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
3383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
3384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
3390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3401f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
3402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
3403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3406f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
3407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
3409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
3410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
3413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
3415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3417f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
3418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3424349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
3425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3426349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
34273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
3428349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
3429349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3443f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
34443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
3445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
3446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3448f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
3449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
3454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
3455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
3457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
3458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
3460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
3461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
3463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
3464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3466cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
3467cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
3468cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
346929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
3470cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
3471cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
3472cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
34735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
3474d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3475d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    // This is technically not correct, since we were unable
3476d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    // to allocate output buffers and therefore the output port
3477d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    // remains disabled. It is necessary however to allow us
3478d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    // to shutdown the codec properly.
3479d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->changeState(mCodec->mExecutingState);
3480cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
3481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
3483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
3484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
3485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
348631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
348731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
34883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
3489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
3490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3491349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
3492349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
3493349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
3494349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
3496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
3498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3510f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
35115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
35125778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
3513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3515f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
3522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
3523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
3530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3543f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
35443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
354531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
35465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
354731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
3548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3550f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
3551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
3557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
35595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
3561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3565349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
3566349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
3567349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
3568349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
3569349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
3570349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
3571349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
35760af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3577f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
35785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
3579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
3580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
3581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
3582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
3584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
3585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3586bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (mCodec->mFlags & kFlagIsSecure && mCodec->mNativeWindow != NULL) {
3587bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
3588bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
3589bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
3590bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
3591bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
3592bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3593bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
3595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3598f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
3599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
3601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
3603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3605f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
3606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
3608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
3610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3614f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
3615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3618f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
3619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
3625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
3633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
3634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3646f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
36473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
3648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3650f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
3651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
3657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3658c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
3659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3670f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
3671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3674f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
36753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
3676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
3678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3680f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
3681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
3693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3705f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
3706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
37077a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
3708d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
3709d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
3714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
3716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
3717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
3718e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
3719e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
3720e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
3721e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
3722e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
3723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
3724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
3725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
3726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
3727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
3729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3734349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
3735349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
3736349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
3737349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
3738349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
3739349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
3740349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
3741349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
3742349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
37433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
3744349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
3745349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3746349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
3747349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3748349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
3749349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
3750349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3758f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
3759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
3760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
3762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3764f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
3765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
3766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
3768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3770f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
3771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
3772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
3773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
3774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
3775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
3776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
3777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
3779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
3780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3781dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
3782dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
3783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
3784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
3788