ACodec.cpp revision 5778822d86b0337407514b9372562b86edfa91cd
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
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
301173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/NativeWindowWrapper.h>
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
321065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <surfaceflinger/Surface.h>
351173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <gui/SurfaceTextureClient.h>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
40f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
44f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
46f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setPointer("node", omx_msg.node);
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer("buffer", omx_msg.u.buffer_data.buffer);
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "platform_private",
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.platform_private);
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "data_ptr",
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.data_ptr);
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs,
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate,
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr);
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
1745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    void onAllocateComponent(const sp<AMessage> &msg);
1755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    void onConfigureComponent(const sp<AMessage> &msg);
1765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    void onStart();
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
186f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(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    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
222349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
223349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
224349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
233349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
234349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
268f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
2725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
315f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
31631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    : mNode(NULL),
3175778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mIsEncoder(false) {
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
332dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
337f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
340f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
344f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3505778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
3515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
3525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
3535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
3545778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3565778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
3575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
3585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
3595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
3605778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3625778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
3635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
366f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
3677a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
371f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
375f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateShutdown() {
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatShutdown, id()))->post();
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
3875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = allocateOutputBuffersFromNativeWindow();
3885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
3895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
3905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
3915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
3945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
3975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
3985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
3995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
4035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
4065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
4075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                IOMX::buffer_id buffer;
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!strncasecmp(
4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mComponentName.c_str(), "OMX.TI.DUCATI1.VIDEO.", 21)) {
4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (portIndex == kPortIndexInput && i == 0) {
4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        // Only log this warning once per allocation round.
415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ALOGW("OMX.TI.DUCATI1.VIDEO.* require the use of "
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                             "OMX_AllocateBuffer instead of the preferred "
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                             "OMX_UseBuffer. Vendor must fix this.");
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
4201065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mNode, portIndex, mem, &buffer);
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4261065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                BufferInfo info;
4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info.mBufferID = buffer;
4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
4305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
4315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
4321065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
4331065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
4385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
4415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
4425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
4445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
4455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        AString name = StringPrintf("buffer-id_%d", i);
4465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setPointer(name.c_str(), mBuffers[portIndex][i].mBufferID);
4475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        name = StringPrintf("data_%d", i);
4495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setObject(name.c_str(), mBuffers[portIndex][i].mData);
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
4535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4699bc7af17974f448291a44912566ec7472a0d798bMathias Agopian    err = native_window_set_scaling_mode(mNativeWindow.get(),
4709bc7af17974f448291a44912566ec7472a0d798bMathias Agopian            NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
4719bc7af17974f448291a44912566ec7472a0d798bMathias Agopian
4729bc7af17974f448291a44912566ec7472a0d798bMathias Agopian    if (err != OK) {
4739bc7af17974f448291a44912566ec7472a0d798bMathias Agopian        return err;
4749bc7af17974f448291a44912566ec7472a0d798bMathias Agopian    }
4759bc7af17974f448291a44912566ec7472a0d798bMathias Agopian
476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
48329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
4893c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
4903c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
4913c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
4925ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
4933c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
4943c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
4953c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
4963c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
4993c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
50229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
506258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    int minUndequeuedBufs = 0;
507258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
508258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
509258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            &minUndequeuedBufs);
510258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
511258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
51229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
513258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
514258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
515258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
516258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
517258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
518258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // buffer counts refer to - how do they account for the renderer holding on
519258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // to buffers?
520258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (def.nBufferCountActual < def.nBufferCountMin + minUndequeuedBufs) {
521258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs;
522258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
523258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
524258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
525258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
526258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (err != OK) {
52729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
528258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    mComponentName.c_str(), newBufferCount, err);
529258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
530258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
531258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
532258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
53729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5423856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), def.nBufferCountActual, def.nBufferSize);
545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
54774006804065941841883c4b46ee785070164023fJamie Gennis    for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
5488ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
55129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
55674006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
55774006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
55874006804065941841883c4b46ee785070164023fJamie Gennis        info.mData = new ABuffer(0);
55974006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
56074006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
56174006804065941841883c4b46ee785070164023fJamie Gennis
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
56629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
56774006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57174006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
57274006804065941841883c4b46ee785070164023fJamie Gennis
5733856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
58574006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // Return the last two buffers to the native window.
588258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        cancelStart = def.nBufferCountActual - minUndequeuedBufs;
589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelEnd = def.nBufferCountActual;
590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
600f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNativeWindow.get(), info->mGraphicBuffer.get());
608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
616f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
6178ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
618c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf) != 0) {
61929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
620c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
621c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mGraphicBuffer->handle == buf->handle) {
628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
642f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
652349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
657349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        if (info->mStatus !=
658349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                BufferInfo::OWNED_BY_COMPONENT) {
659349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We shouldn't have sent out any buffers to the client at this
660349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // point.
661349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            CHECK_NE((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
662349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
670f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
690f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7095778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
7202944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
7212944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
7222944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
7232944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
730729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
731729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
7385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        { MEDIA_MIMETYPE_VIDEO_VPX,
7395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            "video_decoder.vpx", "video_encoder.vpx" },
740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
7535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
7745ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
7765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7845778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
7865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
7875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
7885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
7895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
7945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
7965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
7975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
7985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
8005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder && !msg->findInt32("bitrate", &bitRate)) {
8015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
8025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
8035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!strncasecmp(mime, "video/", 6)) {
8055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
8065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
8075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
8085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
8095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
8105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
8115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
8125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
8135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
8145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
8155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
8185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
8195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
8205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
8215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
8225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAACCodec(encoder, numChannels, sampleRate, bitRate);
8235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
824729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
8255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
826729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
8275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
828729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
829729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
830729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
831729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
832729de186450f78c099637e1fce743fe531862c52Andreas Huber
833729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
8345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
8355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
8365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
8375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
8385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
8395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
840729de186450f78c099637e1fce743fe531862c52Andreas Huber
8415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
8425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
8475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
8495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
8515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8925778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
8935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
8945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
8955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
8965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
8985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
8995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
9005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
9025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
9035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
9045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
9065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
9075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
9105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
9115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
9155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
9165778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9185778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
9195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool encoder,
9205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t numChannels, int32_t sampleRate, int32_t bitRate) {
9215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
9225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
9235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
9245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
9255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
9275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
9285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
9315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
9325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
9345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
9355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
9385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
9395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
9405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
9425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
9435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
9455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
9465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
9495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
9505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
9525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
9535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
9555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
9565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
9595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
9605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
9615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
9635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
9645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
9665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
9675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
9705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
9725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
9735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
9745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
9765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
9775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
9785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
9795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
9805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
9815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACProfile = OMX_AUDIO_AACObjectLC;
9825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
9835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
9855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
9865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
9885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
9895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
9925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
10115778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10135778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
10145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
10155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
10285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
10305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
10315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
10325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
10365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
10385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
10395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
10415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
10425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
10435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
10455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
10465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
10475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
10485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
10495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
10505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
10515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
10545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
10555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10585778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1059729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1060729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
10615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1062729de186450f78c099637e1fce743fe531862c52Andreas Huber
1063729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1064729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1065729de186450f78c099637e1fce743fe531862c52Andreas Huber
1066729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1067729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1068729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1069729de186450f78c099637e1fce743fe531862c52Andreas Huber
1070729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
10715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
10725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
10745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1075729de186450f78c099637e1fce743fe531862c52Andreas Huber
10765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1079729de186450f78c099637e1fce743fe531862c52Andreas Huber
10805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
10815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
10825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
10835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1084729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1085729de186450f78c099637e1fce743fe531862c52Andreas Huber
10865778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
10875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
10885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1089729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1090729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1091729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1092729de186450f78c099637e1fce743fe531862c52Andreas Huber
1093729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1094729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1095729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1096729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1097729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1098729de186450f78c099637e1fce743fe531862c52Andreas Huber
1099729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1100729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1101729de186450f78c099637e1fce743fe531862c52Andreas Huber
1102729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1103729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1104729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1105729de186450f78c099637e1fce743fe531862c52Andreas Huber
1106729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1107729de186450f78c099637e1fce743fe531862c52Andreas Huber
1108729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1109729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1110729de186450f78c099637e1fce743fe531862c52Andreas Huber
1111729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1112729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1113729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1114729de186450f78c099637e1fce743fe531862c52Andreas Huber
1115729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1116729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1117729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1118729de186450f78c099637e1fce743fe531862c52Andreas Huber
1119729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1120729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1121729de186450f78c099637e1fce743fe531862c52Andreas Huber
1122729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1123729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1124729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1125729de186450f78c099637e1fce743fe531862c52Andreas Huber
1126729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1127729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1128729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1129729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1130729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1131729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1132729de186450f78c099637e1fce743fe531862c52Andreas Huber
1133729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (numChannels == 1) {
1134729de186450f78c099637e1fce743fe531862c52Andreas Huber        pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelCF;
1135729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else {
1136729de186450f78c099637e1fce743fe531862c52Andreas Huber        CHECK_EQ(numChannels, 2);
1137729de186450f78c099637e1fce743fe531862c52Andreas Huber
1138729de186450f78c099637e1fce743fe531862c52Andreas Huber        pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
1139729de186450f78c099637e1fce743fe531862c52Andreas Huber        pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
1140729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1141729de186450f78c099637e1fce743fe531862c52Andreas Huber
1142729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1143729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1144729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1145729de186450f78c099637e1fce743fe531862c52Andreas Huber
1146f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1205f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
1218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber           || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
1219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber           || format.eColorFormat == OMX_COLOR_FormatCbYCrY
12201065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber           || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar
1221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber           || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar);
1222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12285778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
12295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
12315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingAVC;
1232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
12335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingMPEG4;
1234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
12355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingH263;
1236386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG2, mime)) {
12375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingMPEG2;
12385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VPX, mime)) {
12395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingVPX;
1240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
12415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingUnused;
12425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
12465778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
12475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12485778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
12495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
12505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
12515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
12525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
12545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
12555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
12565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12875778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
12885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
12895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
12905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
12915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
12925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
12945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
12955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
12975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
12985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
13005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
13015778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
13025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
13075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
13095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
13105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
13125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
13145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
13165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
13175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
13195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
13235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
13245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
13255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
13265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
13275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
13305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
13315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
13335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
13345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
13355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
13385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
13405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
13415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
13425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
13455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
13475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
13495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
13505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
13515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
13525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
13535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
13555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
13585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
13595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
13605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
13745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
13755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
13775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
13815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
13825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
13845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
13855778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
13965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
14395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
14405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
14415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
14455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
14465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
14505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
14525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
14595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
14775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
14895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
14935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
14945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
15035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
15105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = configureBitrate(bitrate);
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
15605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
15615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
15635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
15655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
15665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
15675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
15695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
15725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
15825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = configureBitrate(bitrate);
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
16245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
16335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
16355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
16505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!strncmp(mComponentName.c_str(), "OMX.TI.DUCATI1", 14)) {
16515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
16525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
16555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
16565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
16575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
16585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
16595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
16605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
16615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
16625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
16645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
16655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
16665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
16675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
16685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
16695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
16705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
16745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
16795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
16805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
16815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
16825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
16835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
16845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!strcasecmp("OMX.Nvidia.h264.encoder", mComponentName.c_str())) {
16865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = OMX_VIDEO_AVCLevelMax;
16875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
16905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
16915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return configureBitrate(bitrate);
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
17015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
17035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
17045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
17065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
17075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
17085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
17095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
17105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
17115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
17135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
17145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
17175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
17185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
17205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
17215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17235778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17255778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureBitrate(int32_t bitrate) {
17265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
17275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
17285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
17295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
17325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
17335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.eControlRate = OMX_Video_ControlRateVariable;
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
17405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
17425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
17435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
17445778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17465778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
17475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
17495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
17505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
17525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
17535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
17545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
17575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
17615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
17635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1770f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
1771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
1773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
1778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
1785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
1786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
1787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
1788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
1789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
1793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
1795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
1796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
1798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
1799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
1800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1808f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
1809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
1810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
1814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1817d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
1818d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
1819d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
1820d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1821d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
1822d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
1823d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
1824d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
1825d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
1826d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
1827d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
1828d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
1829d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
1830d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
1831f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
1832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
1833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
1837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
18383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
1839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
1840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
1841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
1842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
1846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1848f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
1849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
1850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
1851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1853f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
1854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
1855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
1856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1858f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
1859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
1860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
1861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
1863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
1864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
1865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
186831e2508c75018145a8238925ff1a08cbde4e799aAndreas Hubervoid ACodec::sendFormatChange() {
186931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    sp<AMessage> notify = mNotify->dup();
187031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->setInt32("what", kWhatOutputFormatChanged);
187131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
187231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
187331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
187431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    def.nPortIndex = kPortIndexOutput;
187531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
187631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
187731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
187831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
187931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
188031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
188131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
188231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
188331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
188431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
188531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
188631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
188731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
188831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("width", videoDef->nFrameWidth);
188931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("height", videoDef->nFrameHeight);
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("stride", videoDef->nStride);
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("slice-height", videoDef->nSliceHeight);
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("color-format", videoDef->eColorFormat);
189331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
189431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_CONFIG_RECTTYPE rect;
189531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            InitOMXParams(&rect);
189631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            rect.nPortIndex = kPortIndexOutput;
189731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
189831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (mOMX->getConfig(
189931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        mNode, OMX_IndexConfigCommonOutputCrop,
190031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        &rect, sizeof(rect)) != OK) {
190131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nLeft = 0;
190231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nTop = 0;
190331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nWidth = videoDef->nFrameWidth;
190431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nHeight = videoDef->nFrameHeight;
190531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
190631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
190731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nLeft, 0);
190831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nTop, 0);
190931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nWidth, 0u);
191031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nHeight, 0u);
191131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
191231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
191331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
191431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setRect(
191531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    "crop",
191631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nLeft,
191731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nTop,
191831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nLeft + rect.nWidth - 1,
191931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nTop + rect.nHeight - 1);
192031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
192131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (mNativeWindow != NULL) {
192231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                android_native_rect_t crop;
192331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                crop.left = rect.nLeft;
192431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                crop.top = rect.nTop;
192589c120e7adbe09c6283591789594c5e591aa5032Andreas Huber                crop.right = rect.nLeft + rect.nWidth;
192689c120e7adbe09c6283591789594c5e591aa5032Andreas Huber                crop.bottom = rect.nTop + rect.nHeight;
192731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
192831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                CHECK_EQ(0, native_window_set_crop(
192931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                            mNativeWindow.get(), &crop));
193031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
193131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
193231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
193331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
193431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
193531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
193631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
193731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ((int)audioDef->eEncoding, (int)OMX_AUDIO_CodingPCM);
193831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
193931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PARAM_PCMMODETYPE params;
194031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            InitOMXParams(&params);
194131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            params.nPortIndex = kPortIndexOutput;
194231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
194331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ(mOMX->getParameter(
194431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        mNode, OMX_IndexParamAudioPcm,
194531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        &params, sizeof(params)),
194631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                     (status_t)OK);
194731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
194831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK(params.nChannels == 1 || params.bInterleaved);
194931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ(params.nBitPerSample, 16u);
195031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned);
195131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear);
195231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
195331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
195431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("channel-count", params.nChannels);
195531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("sample-rate", params.nSamplingRate);
195631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
195731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
195831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
195931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
196031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
196131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
196231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
196331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
196431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
196531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
196631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
196731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
19685778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
1969cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
1970cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
1971cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
1973cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
1974cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
1975cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
1976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
1977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1978f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
1979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
1980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
1981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1983f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
1984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
1985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1987f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
1988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
1989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
1990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
1992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
1996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
1998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
2002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
2004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2013f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
2014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
2015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
2016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
2018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
2019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
2020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
2022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
2023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
2025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
2026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
2027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
2028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20290af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
20300af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
20310af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
20320af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
20330af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
20340af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
20350af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
20360af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
20370af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
20380af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
20390af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
2040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
2041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
2042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
2043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
2044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
2047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
2052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
2055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
2060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
2061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
2062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
2063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
2065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
2066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
2067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
2068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
2069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
2070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
2072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
2073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
2074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
2075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
2076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
2077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
2078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
2082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2086f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
2087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
20893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
2090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
2091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
2093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
209529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
2096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2097cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
2098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2102f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
21033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
2104349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
2105349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
2107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
2108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
2110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
2111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
2113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
2120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
2126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2133f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
2134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
2135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
2136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
2139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
2141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
2142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
2143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
2145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setObject("buffer", info->mData);
2146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
2148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
2149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
2151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
2153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
2155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2157f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
2158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
2159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
2160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
2162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!msg->findObject("buffer", &obj)) {
2166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
2167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] saw error %d instead of an input buffer",
21693831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber             mCodec->mComponentName.c_str(), err);
21703831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
2171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        obj.clear();
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
2174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
2177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
2185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
2186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
2188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
2190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
2195dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
2196dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
2197dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
2198dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
2199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
2206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
2207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
2210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
2212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
2213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
2214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
2215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
2221349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    if (0 && !(flags & OMX_BUFFERFLAG_CODECCONFIG)) {
22223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                        ALOGV("[%s] Needs to copy input data.",
2223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                             mCodec->mComponentName.c_str());
2224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
2225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
2227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
2228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
2229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2230078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
22313856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
2232078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
2236078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
22373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
2238078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
2239078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
2240349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
2242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
2243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
2244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
2245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
2246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
2247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
2248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
2249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
2251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
2261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
2262dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
22633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
2264dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
2265dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
2266dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
22673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
2268dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
2269dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
2270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
2272349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
2273349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
2275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
2276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
2277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
2278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
2279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
2280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
2281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
2282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
2284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
2286dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
2287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
2291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2297f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
2298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
2299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
2300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
2303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
2305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
2306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
2308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
2309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
2310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
2311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
2313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
2315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
2316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
2320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
2321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
2324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2326f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
2327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
2328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
2329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
2330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
2331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *platformPrivate,
2332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *dataPtr) {
23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
2335349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
2337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
2338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
2339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
2341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
2343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
2345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
2355349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
2359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
23615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
23625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
236331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!mCodec->mIsEncoder && !mCodec->mSentFormat) {
23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->sendFormatChange();
23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
2367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mCodec->mNativeWindow == NULL) {
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mData->setRange(rangeOffset, rangeLength);
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
2371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
2373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
23755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setObject("buffer", info->mData);
23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
2379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> reply =
23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                new AMessage(kWhatOutputBufferDrained, mCodec->id());
2382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
2384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
2386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
23885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
2390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
23925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
2395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
2396dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
2397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
2398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
2400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
2409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
2410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2417f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
2418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
2419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
2420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
2422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
2423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
2424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
2425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
2427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
2428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && msg->findInt32("render", &render) && render != 0) {
2429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
2430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
24325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
2433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
24345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    info->mGraphicBuffer.get())) == OK) {
2435cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
2436cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
24375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
2438cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
2439cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
2440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
2441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
2442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
2445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
2450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
2453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
2454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
2456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
2463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
2465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
2466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
2468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
2469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2470c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
24713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
2472c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
2473349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2474c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
2475c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
2476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2477c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
2478c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
2479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
2488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
2489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2496f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
2497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
2498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2500f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
2501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
2502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
2505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
2507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
2509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
25135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
25145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
25155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
25165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
25175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatConfigureComponent:
25205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
25215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onConfigureComponent(msg);
25225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
25235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
25245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatStart:
25275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
25285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onStart();
25295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
25305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
25315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
2534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
2536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
2537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
2538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
2540c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
2541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
2544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
2546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
2547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
2548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
2550c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
2551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
2555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
2558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2560f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
2561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
25625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    onAllocateComponent(msg);
25635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    onConfigureComponent(msg);
25645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    onStart();
25655778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25675778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
25685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
25695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mCodec->mNode != NULL) {
25715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
25725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->mNativeWindow.clear();
25745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->mNode = NULL;
25755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->mOMX.clear();
25765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->mComponentName.clear();
25775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
2580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
2581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
2583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<String8> matchingCodecs;
25855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
2587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
25895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
25905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        matchingCodecs.push_back(String8(componentName.c_str()));
25915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
25925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
25935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
25955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
25965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
25975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
26005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
26015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
26025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
26035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
26045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &matchingCodecs);
26055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26061065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
26071065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
26081065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
26091065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
26101065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
26111065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
26121065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        componentName = matchingCodecs.itemAt(matchIndex).string();
2613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2614078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
2615078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
2616078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
26171065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
2618078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
2619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26201065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
26211065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
26221065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
26231065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
26241065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
26251065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
26261065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
2627c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
26285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
26295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
26305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
26315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
26325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
26335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2634c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
2635cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
2636c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return;
2637c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
2638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXMessage, mCodec->id());
2640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
2641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
2643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
2644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
2645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2646349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
2647349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
2648349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2649dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mCodec->mInputEOSResult = OK;
2650dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
26515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
26525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
26535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
26545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
26555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
26565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26575778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26595778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::UninitializedState::onConfigureComponent(
26605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
26615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
26625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
26645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
26665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
26675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
26695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
26725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return;
26735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
2676386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
26775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
26781173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
26791173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
26801173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
26811173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
2682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
2684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
26865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
26875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
26885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
26895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26905778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26925778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::UninitializedState::onStart() {
26935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
26945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
26965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
2697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
2698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
2700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2704f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
2705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
2706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2708f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
27093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
2710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2711cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
2712cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
271329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
2714cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
2715cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
2716cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
27175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
2718cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
2719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2721f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
2722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
2723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
2729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2731f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
2732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
2734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
2736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
2737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
2741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2744f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
2745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
2747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
2748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
2750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
2751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
2753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
2754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
2755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
2757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
2759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
2763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2768f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
2769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
2770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2772f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
27733856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
2774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2776f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
2777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
2779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
2781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
2782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
2786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2789f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
2790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
2792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
2793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
2795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
2796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
2798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
2799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
2801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
2805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2810f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
2811349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
2812349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
2813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2815f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
2816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
2818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2820f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::submitOutputBuffers() {
2821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
2822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
2823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
2825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
2826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
2827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
2830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            status_t err = mCodec->mNativeWindow->lockBuffer(
2833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
2834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mGraphicBuffer.get());
2835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(err, (status_t)OK);
2836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
2837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
2838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
2841349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
2842349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
2844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
2845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
2847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2850f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
2851349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
28523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
2853349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
2854349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2855349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
2856349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
2857349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
2859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
2861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
2862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
2863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
2865349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2866349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
2867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2869f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
28703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
2871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
2873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2875f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
2876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
2877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
2880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2881349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
2882349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
2884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
2885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
2886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
2888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
2890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
2894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
28957a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
2896d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
2897d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
2898d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
2899d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
2900d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
2901d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
2902d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2903349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
2904349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
2906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
2907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
2908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
2910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
2912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
2916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
2918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
2920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
2925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
2929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2931f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
2932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
2934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
2935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
2937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
293831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
2939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
2940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
2941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
2942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
2943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2944349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
2945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
294731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
294831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
2949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
29503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
2951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
2952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
2955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
2958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
2960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
2964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2969f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
2970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
2971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
2972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2974f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
2975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
2977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
2978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2985f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
2986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
2988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
2991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
2992349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
2993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2994349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
29953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
2996349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
2997349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
2999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3011f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
30123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
3013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
3014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3016f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
3017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
3022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
3023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
3025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
3026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
3028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
3029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
3031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
3032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3034cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
3035cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
3036cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
303729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
3038cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
3039cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
3040cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
30415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
3042d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3043d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    // This is technically not correct, since we were unable
3044d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    // to allocate output buffers and therefore the output port
3045d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    // remains disabled. It is necessary however to allow us
3046d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    // to shutdown the codec properly.
3047d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->changeState(mCodec->mExecutingState);
3048cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
3049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
3051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
3052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
3053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
305431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
305531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
30563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
3057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
3058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3059349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
3060349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
3061349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
3062349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
3064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
3066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3078f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
30795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
30805778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
3081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3083f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
3090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
3091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
3098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3111f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
31123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
311331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
31145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
311531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
3116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3118f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
3119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
3125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
31275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
3129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3133349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
3134349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
3135349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
3136349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
3137349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
3138349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
3139349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
31440af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3145f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
31465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
3147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
3148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
3149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
3150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
3152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
3153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
3155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3158f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
3159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
3161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
3163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3165f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
3166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
3168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
3170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3174f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
3175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3178f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
3179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
3185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
3193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
3194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3206f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
32073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
3208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3210f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
3211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
3217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mNativeWindow.clear();
3223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mNode = NULL;
3224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mOMX.clear();
3225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mComponentName.clear();
3226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mUninitializedState);
3228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3243f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
3244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3247f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
32483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
3249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
3251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3253f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
3254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
3266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3278f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
3279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
32807a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
3281d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
3282d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
3287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
3289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
3290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
3291e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
3292e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
3293e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
3294e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
3295e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
3296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
3297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
3298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
3299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
3300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
3302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3307349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
3308349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
3309349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
3310349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
3311349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
3312349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
3313349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
3314349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
3315349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
33163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
3317349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
3318349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3319349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
3320349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3321349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
3322349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
3323349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3331f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
3332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
3333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
3335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3337f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
3338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
3339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
3341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3343f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
3344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
3345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
3346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
3347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
3348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
3349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
3350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
3352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
3353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3354dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
3355dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
3356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
3357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
3361