ACodec.cpp revision 7a3a2b2f9bb9421dcf83fbd47276e57917078aef
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);
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
219349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
220349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
221349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
222f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
230349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
231349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
310f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
31131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    : mNode(NULL),
31231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber      mSentFormat(false) {
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
326dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
331f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
334f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
338f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
344f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
3457a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
349f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
353f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateShutdown() {
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatShutdown, id()))->post();
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return allocateOutputBuffersFromNativeWindow();
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mComponentName.c_str(),
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferCountActual, def.nBufferSize,
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            portIndex == kPortIndexInput ? "input" : "output");
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t totalSize = def.nBufferCountActual * def.nBufferSize;
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex] = new MemoryDealer(totalSize, "OMXCodec");
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(mem.get() != NULL);
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id buffer;
3911065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3921065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (!strcasecmp(
3931065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber                    mComponentName.c_str(), "OMX.TI.DUCATI1.VIDEO.DECODER")) {
3941065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            if (portIndex == kPortIndexInput && i == 0) {
3951065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber                // Only log this warning once per allocation round.
3961065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3971065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber                LOGW("OMX.TI.DUCATI1.VIDEO.DECODER requires the use of "
3981065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber                     "OMX_AllocateBuffer instead of the preferred "
3991065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber                     "OMX_UseBuffer. Vendor must fix this.");
4001065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
4011065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4021065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            err = mOMX->allocateBufferWithBackup(
4031065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber                    mNode, portIndex, mem, &buffer);
4041065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        } else {
4051065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
4061065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo info;
413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info.mBufferID = buffer;
414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info.mStatus = BufferInfo::OWNED_BY_US;
415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mBuffers[portIndex].push(info);
417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
422f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4349bc7af17974f448291a44912566ec7472a0d798bMathias Agopian    err = native_window_set_scaling_mode(mNativeWindow.get(),
4359bc7af17974f448291a44912566ec7472a0d798bMathias Agopian            NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
4369bc7af17974f448291a44912566ec7472a0d798bMathias Agopian
4379bc7af17974f448291a44912566ec7472a0d798bMathias Agopian    if (err != OK) {
4389bc7af17974f448291a44912566ec7472a0d798bMathias Agopian        return err;
4399bc7af17974f448291a44912566ec7472a0d798bMathias Agopian    }
4409bc7af17974f448291a44912566ec7472a0d798bMathias Agopian
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        LOGE("native_window_set_buffers_geometry failed: %s (%d)",
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
4543c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
4553c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
4563c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
4573c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        LOGW("querying usage flags from OMX IL component failed: %d", err);
4583c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
4593c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
4603c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
4613c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
4643c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        LOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
471258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    int minUndequeuedBufs = 0;
472258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
473258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
474258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            &minUndequeuedBufs);
475258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
476258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
477258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        LOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
478258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
479258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
480258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
481258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
482258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
483258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // buffer counts refer to - how do they account for the renderer holding on
484258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // to buffers?
485258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (def.nBufferCountActual < def.nBufferCountMin + minUndequeuedBufs) {
486258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs;
487258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
488258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
489258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
490258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
491258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (err != OK) {
492258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            LOGE("[%s] setting nBufferCountActual to %lu failed: %d",
493258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    mComponentName.c_str(), newBufferCount, err);
494258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
495258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
496258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
497258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        LOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), def.nBufferCountActual, def.nBufferSize);
510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
51274006804065941841883c4b46ee785070164023fJamie Gennis    for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
5138ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            LOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
52174006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
52274006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
52374006804065941841883c4b46ee785070164023fJamie Gennis        info.mData = new ABuffer(0);
52474006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
52574006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
52674006804065941841883c4b46ee785070164023fJamie Gennis
527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
53174006804065941841883c4b46ee785070164023fJamie Gennis            LOGE("registering GraphicBuffer %lu with OMX IL component failed: "
53274006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53674006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
53774006804065941841883c4b46ee785070164023fJamie Gennis
5383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
55074006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // Return the last two buffers to the native window.
553258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        cancelStart = def.nBufferCountActual - minUndequeuedBufs;
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelEnd = def.nBufferCountActual;
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
565f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNativeWindow.get(), info->mGraphicBuffer.get());
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
581f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
5828ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
583c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf) != 0) {
584c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        LOGE("dequeueBuffer failed.");
585c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
586c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mGraphicBuffer->handle == buf->handle) {
593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
607f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
617349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
622349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        if (info->mStatus !=
623349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                BufferInfo::OWNED_BY_COMPONENT) {
624349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We shouldn't have sent out any buffers to the client at this
625349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // point.
626349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            CHECK_NE((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
627349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
635f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
655f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
674f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setComponentRole(
675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
6852944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
6862944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
6872944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
6882944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
695729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
696729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            LOGW("[%s] Failed to set standard component role '%s'.",
738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
743f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::configureCodec(
744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    setComponentRole(false /* isEncoder */, mime);
746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!strncasecmp(mime, "video/", 6)) {
748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, height;
749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("width", &width));
750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("height", &height));
751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(setupVideoDecoder(mime, width, height),
753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("channel-count", &numChannels));
757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("sample-rate", &sampleRate));
758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(setupAACDecoder(numChannels, sampleRate), (status_t)OK);
760729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
761729de186450f78c099637e1fce743fe531862c52Andreas Huber        CHECK_EQ(setupAMRDecoder(false /* isWAMR */), (status_t)OK);
762729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
763729de186450f78c099637e1fce743fe531862c52Andreas Huber        CHECK_EQ(setupAMRDecoder(true /* isWAMR */), (status_t)OK);
764729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
765729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
766729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
767729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
768729de186450f78c099637e1fce743fe531862c52Andreas Huber
769729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
770729de186450f78c099637e1fce743fe531862c52Andreas Huber        CHECK(msg->findInt32("channel-count", &numChannels));
771729de186450f78c099637e1fce743fe531862c52Andreas Huber
772729de186450f78c099637e1fce743fe531862c52Andreas Huber        CHECK_EQ(setupG711Decoder(numChannels), (status_t)OK);
773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(setMinBufferSize(kPortIndexInput, (size_t)maxInputSize),
778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(setMinBufferSize(kPortIndexInput, 8192),  // XXX
781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
785f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setupAACDecoder(int32_t numChannels, int32_t sampleRate) {
823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
844729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupAMRDecoder(bool isWAMR) {
845729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
846729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
847729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = kPortIndexInput;
848729de186450f78c099637e1fce743fe531862c52Andreas Huber
849729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
850729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
851729de186450f78c099637e1fce743fe531862c52Andreas Huber
852729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
853729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
854729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
855729de186450f78c099637e1fce743fe531862c52Andreas Huber
856729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
857729de186450f78c099637e1fce743fe531862c52Andreas Huber
858729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRBandMode =
859729de186450f78c099637e1fce743fe531862c52Andreas Huber        isWAMR ? OMX_AUDIO_AMRBandModeWB0 : OMX_AUDIO_AMRBandModeNB0;
860729de186450f78c099637e1fce743fe531862c52Andreas Huber
861729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
862729de186450f78c099637e1fce743fe531862c52Andreas Huber}
863729de186450f78c099637e1fce743fe531862c52Andreas Huber
864729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupG711Decoder(int32_t numChannels) {
865729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
866729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
867729de186450f78c099637e1fce743fe531862c52Andreas Huber}
868729de186450f78c099637e1fce743fe531862c52Andreas Huber
869729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
870729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
871729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
872729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
873729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
874729de186450f78c099637e1fce743fe531862c52Andreas Huber
875729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
876729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
877729de186450f78c099637e1fce743fe531862c52Andreas Huber
878729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
879729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
880729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
881729de186450f78c099637e1fce743fe531862c52Andreas Huber
882729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
883729de186450f78c099637e1fce743fe531862c52Andreas Huber
884729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
885729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
886729de186450f78c099637e1fce743fe531862c52Andreas Huber
887729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
888729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
889729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
890729de186450f78c099637e1fce743fe531862c52Andreas Huber
891729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
892729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
893729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
894729de186450f78c099637e1fce743fe531862c52Andreas Huber
895729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
896729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
897729de186450f78c099637e1fce743fe531862c52Andreas Huber
898729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
899729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
900729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
901729de186450f78c099637e1fce743fe531862c52Andreas Huber
902729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
903729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
904729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
905729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
906729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
907729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
908729de186450f78c099637e1fce743fe531862c52Andreas Huber
909729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (numChannels == 1) {
910729de186450f78c099637e1fce743fe531862c52Andreas Huber        pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelCF;
911729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else {
912729de186450f78c099637e1fce743fe531862c52Andreas Huber        CHECK_EQ(numChannels, 2);
913729de186450f78c099637e1fce743fe531862c52Andreas Huber
914729de186450f78c099637e1fce743fe531862c52Andreas Huber        pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
915729de186450f78c099637e1fce743fe531862c52Andreas Huber        pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
916729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
917729de186450f78c099637e1fce743fe531862c52Andreas Huber
918729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
919729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
920729de186450f78c099637e1fce743fe531862c52Andreas Huber}
921729de186450f78c099637e1fce743fe531862c52Andreas Huber
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
981f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber           || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber           || format.eColorFormat == OMX_COLOR_FormatCbYCrY
9961065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber           || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber           || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar);
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setupVideoDecoder(
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, int32_t width, int32_t height) {
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        compressionFormat = OMX_VIDEO_CodingAVC;
1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        compressionFormat = OMX_VIDEO_CodingMPEG4;
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        compressionFormat = OMX_VIDEO_CodingH263;
1013386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG2, mime)) {
1014386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber        compressionFormat = OMX_VIDEO_CodingMPEG2;
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        TRESPASS();
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = setVideoPortFormatType(
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1049f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
1050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
1052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
1057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
1064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
1065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
1066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
1067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
1068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
1072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
1074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
1075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
1077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
1078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
1079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1087f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
1088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
1089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
1093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1096d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
1097d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
1098d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
1099d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1100d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
1101d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
1102d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
1103d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
1104d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
1105d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
1106d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
1107d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
1108d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
1109d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
1110f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
1111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
1112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
1116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
11173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
1118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
1119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
1120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
1121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
1125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1127f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
1128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
1129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
1130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1132f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
1133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
1134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
1135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1137f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
1138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
1139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
1140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
1142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
1143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
1144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
114731e2508c75018145a8238925ff1a08cbde4e799aAndreas Hubervoid ACodec::sendFormatChange() {
114831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    sp<AMessage> notify = mNotify->dup();
114931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->setInt32("what", kWhatOutputFormatChanged);
115031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
115131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
115231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
115331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    def.nPortIndex = kPortIndexOutput;
115431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
115531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
115631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
115731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
115831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
115931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
116031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
116131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
116231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
116331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
116431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
116531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
116631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
116731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("width", videoDef->nFrameWidth);
116831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("height", videoDef->nFrameHeight);
116931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
117031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_CONFIG_RECTTYPE rect;
117131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            InitOMXParams(&rect);
117231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            rect.nPortIndex = kPortIndexOutput;
117331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
117431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (mOMX->getConfig(
117531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        mNode, OMX_IndexConfigCommonOutputCrop,
117631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        &rect, sizeof(rect)) != OK) {
117731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nLeft = 0;
117831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nTop = 0;
117931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nWidth = videoDef->nFrameWidth;
118031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nHeight = videoDef->nFrameHeight;
118131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
118231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
118331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nLeft, 0);
118431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nTop, 0);
118531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nWidth, 0u);
118631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nHeight, 0u);
118731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
118831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
118931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
119031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setRect(
119131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    "crop",
119231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nLeft,
119331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nTop,
119431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nLeft + rect.nWidth - 1,
119531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nTop + rect.nHeight - 1);
119631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
119731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (mNativeWindow != NULL) {
119831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                android_native_rect_t crop;
119931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                crop.left = rect.nLeft;
120031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                crop.top = rect.nTop;
120189c120e7adbe09c6283591789594c5e591aa5032Andreas Huber                crop.right = rect.nLeft + rect.nWidth;
120289c120e7adbe09c6283591789594c5e591aa5032Andreas Huber                crop.bottom = rect.nTop + rect.nHeight;
120331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
120431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                CHECK_EQ(0, native_window_set_crop(
120531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                            mNativeWindow.get(), &crop));
120631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
120731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
120831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
120931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
121031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
121131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
121231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
121331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ((int)audioDef->eEncoding, (int)OMX_AUDIO_CodingPCM);
121431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
121531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PARAM_PCMMODETYPE params;
121631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            InitOMXParams(&params);
121731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            params.nPortIndex = kPortIndexOutput;
121831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
121931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ(mOMX->getParameter(
122031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        mNode, OMX_IndexParamAudioPcm,
122131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        &params, sizeof(params)),
122231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                     (status_t)OK);
122331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
122431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK(params.nChannels == 1 || params.bInterleaved);
122531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ(params.nBitPerSample, 16u);
122631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned);
122731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear);
122831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
122931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
123031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("channel-count", params.nChannels);
123131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("sample-rate", params.nSamplingRate);
123231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
123331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
123431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
123531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
123631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
123731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
123831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
123931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
124031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
124131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
124231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
124331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
1244cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error) {
1245cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
1246cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
1247cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
1248cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
1249cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
1250cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
1251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
1252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1253f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
1254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
1255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
1256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1258f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
1259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
1260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1262f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
1263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
1264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
1265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
1267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
1271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
1273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
1277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
1279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
1282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
1283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
1286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1288f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
1289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
1290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
1291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
1293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
1294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
1295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
1297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
1298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
1300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
1301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
1302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
1303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13040af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
13050af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
13060af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
13070af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
13080af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
13090af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
13100af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
13110af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
13120af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
13130af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
13140af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
1315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
1316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
1317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
1318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
1319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
1324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
1330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
1332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
1333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
1335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
1336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
1337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
1338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
1340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
1341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
1342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
1343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
1344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
1345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
1347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
1348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
1349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
1350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
1351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
1352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
1353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
1356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
1357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1361f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
1362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
1363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
13643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
1365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
1366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
1368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1370c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    LOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
1371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1372cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
1373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
1375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1377f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
13783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
1379349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
1380349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
1381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
1382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
1383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
1385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
1386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
1388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
1390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
1391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
1394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
1395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
1398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
1400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
1401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
1406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1408f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
1409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
1410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
1411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
1414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
1416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
1417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
1418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
1420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setObject("buffer", info->mData);
1421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
1423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
1424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
1426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
1428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
1430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1432f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
1433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
1434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
1435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
1437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
1438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!msg->findObject("buffer", &obj)) {
1439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
1440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] saw error %d instead of an input buffer",
14423831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber             mCodec->mComponentName.c_str(), err);
14433831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
1444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        obj.clear();
1445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
1448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
1450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
1451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
1453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
1455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
1457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
1458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (buffer == NULL) {
1460dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
1461dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
1462dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
1463dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
1464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
1469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (buffer != NULL) {
1471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mCodec->mPortEOS[kPortIndexInput]);
1472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
1474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
1475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
1477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
1479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
1480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
1481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
1482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
1484349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    if (0 && !(flags & OMX_BUFFERFLAG_CODECCONFIG)) {
14853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                        ALOGV("[%s] Needs to copy input data.",
1486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                             mCodec->mComponentName.c_str());
1487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    }
1488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
1490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
1491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
1492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1493078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
14943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
1495078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
1496078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
14973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
1498078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
1499078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
1500349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
1501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
1502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
1503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
1504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
1505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
1506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
1507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
1508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
1509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
1511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                getMoreInputDataIfPossible();
1513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
1514dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
15153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
1516dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
1517dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
1518dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
15193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
1520dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
1521dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
1522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
1524349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
1525349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
1526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
1527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
1528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
1529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
1530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
1531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
1532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
1533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
1534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
1536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
1538dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
1539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
1543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ((int)mode, (int)FREE_BUFFERS);
1544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1549f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
1550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
1551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
1552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
1555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
1557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
1558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
1560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
1561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
1562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
1563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
1565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
1567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
1568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
1572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
1573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
1576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1578f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
1579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
1580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
1581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
1582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
1583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *platformPrivate,
1584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *dataPtr) {
15853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXFillBufferDone %p time %lld us",
1586078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs);
1587349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
1588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
1589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
1590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
1591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
1593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
1595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
1597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
1599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
1600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
1603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (rangeLength == 0) {
1605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (!(flags & OMX_BUFFERFLAG_EOS)) {
16063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
1607349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
1608349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
1609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(
1610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                                mCodec->mNode, info->mBufferID),
1611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                             (status_t)OK);
1612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
1614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
1615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
161631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                if (!mCodec->mSentFormat) {
161731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    mCodec->sendFormatChange();
161831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                }
161931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
1620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (mCodec->mNativeWindow == NULL) {
1621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mData->setRange(rangeOffset, rangeLength);
1622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
1623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mData->meta()->setInt64("timeUs", timeUs);
1625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
1627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
1628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setPointer("buffer-id", info->mBufferID);
1629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setObject("buffer", info->mData);
1630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> reply =
1632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    new AMessage(kWhatOutputBufferDrained, mCodec->id());
1633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                reply->setPointer("buffer-id", info->mBufferID);
1635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setMessage("reply", reply);
1637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
1639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
1641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
1644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
1645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
1646dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
1647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
1648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
1650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
1655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
1657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
1659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
1660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
1665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1667f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
1668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
1669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
1670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
1672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
1673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
1674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
1675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
1677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
1678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && msg->findInt32("render", &render) && render != 0) {
1679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
1680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1681cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        if (mCodec->mNativeWindow->queueBuffer(
1682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
1683cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber                    info->mGraphicBuffer.get()) == OK) {
1684cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1685cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
1686cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            mCodec->signalError();
1687cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
1688cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
1689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
1690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
1691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
1694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
1696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
1697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
1699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
1701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
1702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
1703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
1705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
1710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
1712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
1713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
1714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
1715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
1717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
1718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1719c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
17203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
1721c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
1722349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
1723c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
1724c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
1725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1726c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
1727c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
1728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
1733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
1735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
1737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
1738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
1744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1745f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
1746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
1747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1749f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
1750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
1751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
1753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
1754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
1756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
1758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
1762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
1764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
1765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
1766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
1768c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
1769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
1772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
1774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
1775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
1776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
1778c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
1779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
1782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
1783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
1786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1788f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
1789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
1790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
1791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
1792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
1794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
1796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findString("mime", &mime));
1797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17981065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    Vector<String8> matchingCodecs;
17991065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    OMXCodec::findMatchingCodecs(
18001065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            mime.c_str(),
18011065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            false, // createEncoder
18021065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            NULL,  // matchComponentName
18031065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            0,     // flags
18041065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            &matchingCodecs);
18051065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
18061065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
18071065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
18081065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
1809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString componentName;
1810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18111065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
18121065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
18131065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        componentName = matchingCodecs.itemAt(matchIndex).string();
1814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1815078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
1816078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
1817078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
18181065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
1819078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
1820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18211065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
18221065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
18231065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
18241065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
18251065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
18261065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
18271065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
1828c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
1829c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        LOGE("Unable to instantiate a decoder for type '%s'.", mime.c_str());
1830c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
1831cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
1832c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return;
1833c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
1834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXMessage, mCodec->id());
1836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
1837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
1839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
1840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
1841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1842349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
1843349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
1844349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
1845dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mCodec->mInputEOSResult = OK;
1846dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
1847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->configureCodec(mime.c_str(), msg);
1848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
1850386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
1851386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber            && strncmp("OMX.google.", componentName.c_str(), 11)) {
18521173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
18531173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
18541173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
18551173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
1856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
1859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(omx->sendCommand(node, OMX_CommandStateSet, OMX_StateIdle),
1861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
1862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
1864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
1867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1868f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
1869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
1870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1872f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
18733856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
1874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1875cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
1876cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
1877cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber        LOGE("Failed to allocate buffers after transitioning to IDLE state "
1878cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
1879cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
1880cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
1881cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError();
1882cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
1883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1885f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
1886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
1887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
1893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1895f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
1896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
1897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
1898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
1900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
1901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
1904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
1905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1908f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
1909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
1910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
1911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
1912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
1914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
1915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
1917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
1918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
1919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
1921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
1923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
1926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
1927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
1931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1932f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
1933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
1934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1936f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
19373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
1938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1940f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
1941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
1942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
1943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
1945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
1946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
1949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
1950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1953f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
1954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
1955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
1956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
1957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
1958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
1959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
1960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
1962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
1963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
1965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
1968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
1969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
1973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1974f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
1975349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
1976349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
1977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1979f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
1980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
1981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
1982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1984f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::submitOutputBuffers() {
1985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
1986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
1987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
1989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
1990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
1991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
1993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
1994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            status_t err = mCodec->mNativeWindow->lockBuffer(
1997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
1998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mGraphicBuffer.get());
1999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(err, (status_t)OK);
2000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
2001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
2002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
2005349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
2006349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
2008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
2009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
2011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2014f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
2015349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
20163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
2017349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
2018349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2019349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
2020349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
2021349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
2023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
2025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
2026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
2027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
2029349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2030349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
2031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2033f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
20343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
2035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
2037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2039f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
2040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
2041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
2044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2045349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
2046349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
2048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
2049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
2050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
2052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
2054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
2058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
20597a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
2060d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
2061d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
2062d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
2063d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
2064d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
2065d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
2066d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2067349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
2068349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
2070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
2071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
2072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
2074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
2076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
2080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
2082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
2084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
2089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
2093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2095f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
2096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
2098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
2099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
2101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
210231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
2103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
2104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
2105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
2106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
2107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2108349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
2109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
211131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
211231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
2113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
21143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
2115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
2116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
2119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
2122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
2124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
2128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2133f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
2134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
2135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
2136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2138f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
2139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
2141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
2142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
2145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
2147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2149f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
2150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
2151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
2152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
2155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
2156349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
2157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2158349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
21593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
2160349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
2161349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
2163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
2164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
2169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
2173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2175f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
21763856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
2177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
2178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2180f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
2181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
2183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
2184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
2186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
2187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
2189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
2190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
2192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
2193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
2195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
2196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
2197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2198cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
2199cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
2200cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
2201cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                    LOGE("Failed to allocate output port buffers after "
2202cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
2203cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
2204cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
2205cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber                    mCodec->signalError();
2206d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2207d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    // This is technically not correct, since we were unable
2208d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    // to allocate output buffers and therefore the output port
2209d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    // remains disabled. It is necessary however to allow us
2210d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    // to shutdown the codec properly.
2211d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->changeState(mCodec->mExecutingState);
2212cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
2213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
2215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
2216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
2217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
221831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
221931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
22203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
2221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
2222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2223349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
2224349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
2225349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
2226349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
2228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
2230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2242f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
2243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
2244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2246f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
2247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
2248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
2251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
2253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
2254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
2255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
2259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
2261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
2263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
2268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
2272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2274f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
22753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
227631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
227731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
2278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2280f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
2281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
2283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
2284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
2286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
2287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
2289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
2291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2293349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
2294349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
2295349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
2296349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
2297349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
2298349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
2299349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
2302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
23040af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
2305f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
2306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->allYourBuffersAreBelongToUs()) {
2307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
2308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
2309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
2310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
2312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
2313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
2315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2318f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
2319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
2320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
2321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
2323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2325f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
2326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
2327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
2328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
2330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2334f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
2335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
2336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2338f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
2339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
2340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
2343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
2345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
2347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
2351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
2353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
2354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
2355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
2360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
2364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2366f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
23673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
2368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2370f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
2371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
2373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
2374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
2376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
2377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
2379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
2381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mNativeWindow.clear();
2383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mNode = NULL;
2384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mOMX.clear();
2385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mComponentName.clear();
2386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mUninitializedState);
2388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
2390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
2391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
2392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
2394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
2398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2403f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
2404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
2405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2407f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
24083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
2409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
2411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2413f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
2414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
2415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
2418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
2420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
2424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
2426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
2427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
2432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
2436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2438f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
2439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
24407a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
2441d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
2442d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
2444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
2445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
2447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
2449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
2450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
2451e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
2452e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
2453e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
2454e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
2455e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
2456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
2457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
2458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
2459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
2460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
2462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
2465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2467349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
2468349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
2469349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
2470349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
2471349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
2472349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
2473349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
2474349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
2475349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
24763856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
2477349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
2478349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2479349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
2480349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2481349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
2482349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
2483349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
2486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2491f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
2492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
2493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
2495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2497f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
2498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
2499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
2501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2503f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
2504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
2505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
2506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
2507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
2508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
2509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
2510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
2512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
2513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2514dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
2515dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
2516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
2517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
2521