ACodec.cpp revision 496238cc7551d414067dcbbb4fe3bd801f205f95
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "ACodec"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
311173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/NativeWindowWrapper.h>
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
331065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
38496238cc7551d414067dcbbb4fe3bd801f205f95Andreas 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);
171c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
173f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
175c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
182c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
183c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
184c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
185c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
186c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
187c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
188c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
189c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
190c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
191c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
192c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
193c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
194c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
195c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
196c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
197c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
198c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
199c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
200c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
217f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
220f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
240349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
241349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
242349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
251349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
252349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
268f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
2905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
333f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
334afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
335afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber      mNode(NULL),
3365778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
337c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
3389806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
3399806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
3409806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
3419806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
3429806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMask(0) {
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
344c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
357dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
362f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
365f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
369f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3755778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
3765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
3775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
3785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
3795778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3815778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
3825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
3835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
3845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
3855778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3875778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
3885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
3895778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
391f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
3927a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
396f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
400c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
401c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
402c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
403c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
406496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
407496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
408496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
409496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = allocateOutputBuffersFromNativeWindow();
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
4385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
440ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
441ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
443afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
444afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
445afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
446afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
4471065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
448ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) {
449ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
450ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
451ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
452ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
453ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
454ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
455ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
456ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(ptr, def.nBufferSize);
457ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
4585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
459ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
4605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
461ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
462ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
463ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
464ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
465ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4671065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
4691065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
4701065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
481eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
482eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
483eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
485eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
487eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
490eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
4915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
4925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
496f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
51529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
5213c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
5223c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
5233c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
5245ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
5253c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
5263c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
5273c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
5283c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
529bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
530bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
531bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
532bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
533bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
534bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
535bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
536bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
537bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
538bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
539bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
540bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
541bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
542bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
543bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
544bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
545bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
546bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
547bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
548bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
549bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
550bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
551bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
5543c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
55729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
561258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    int minUndequeuedBufs = 0;
562258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
563258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
564258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            &minUndequeuedBufs);
565258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
566258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
56729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
568258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
569258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
570258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
571258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
572258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
573258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // buffer counts refer to - how do they account for the renderer holding on
574258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // to buffers?
575258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (def.nBufferCountActual < def.nBufferCountMin + minUndequeuedBufs) {
576258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs;
577258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
578258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
579258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
580258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
581258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (err != OK) {
58229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
583258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    mComponentName.c_str(), newBufferCount, err);
584258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
585258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
586258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
587258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
59229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), def.nBufferCountActual, def.nBufferSize);
600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
60274006804065941841883c4b46ee785070164023fJamie Gennis    for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
6038ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
6041e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
60629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
61174006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
61274006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
61374006804065941841883c4b46ee785070164023fJamie Gennis        info.mData = new ABuffer(0);
61474006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
61574006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
61674006804065941841883c4b46ee785070164023fJamie Gennis
617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
62129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
62274006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62674006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
62774006804065941841883c4b46ee785070164023fJamie Gennis
6283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
64074006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // Return the last two buffers to the native window.
643258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        cancelStart = def.nBufferCountActual - minUndequeuedBufs;
644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelEnd = def.nBufferCountActual;
645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
655f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
6621e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
671f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
6728ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
6731e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
6741e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
67529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
676c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
677c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mGraphicBuffer->handle == buf->handle) {
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
708349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
713349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        if (info->mStatus !=
714349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                BufferInfo::OWNED_BY_COMPONENT) {
715349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We shouldn't have sent out any buffers to the client at this
716349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // point.
717349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            CHECK_NE((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
718349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
726f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
746f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7655778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
7762944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
7772944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
7782944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
7792944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
786729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
787729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
788c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
789c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
790c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
791c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
7985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        { MEDIA_MIMETYPE_VIDEO_VPX,
7995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            "video_decoder.vpx", "video_encoder.vpx" },
800ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
801ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
8022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
8032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
8175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
8385ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
8405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
8445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8485778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
8505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
8515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
8525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
8535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
8585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
8605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
8615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
8625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
8642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
8652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
8662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
8675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
8685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
8695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
870d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
871d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
872d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
873d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
874d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
875d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
876d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
877d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
878d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                  mComponentName.c_str(), err);
879d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
880d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            return err;
881d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
882d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
883d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
8845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!strncasecmp(mime, "video/", 6)) {
8855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
8865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
8875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
8885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
8895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
8905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
8915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
8925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
8935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
8945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
8955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
8985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
8995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
9005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
9015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
902aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
903ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
904ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
905ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
906aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
907aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
908aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
909ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
910ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
911aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                    encoder, numChannels, sampleRate, bitRate, aacProfile, isADTS != 0);
9125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
913729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
9145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
915729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
9165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
917729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
918729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
919729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
920729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
921729de186450f78c099637e1fce743fe531862c52Andreas Huber
922729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
9235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
9245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
9255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
9265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
9275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
9292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
9302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
9312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
9322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
9332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
9342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
9352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
9362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
9372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                if (!msg->findInt32("flac-compression-level", &compressionLevel)) {
9382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
9392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
9402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    ALOGW("compression level %d outside [0..8] range, using 0", compressionLevel);
9412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
9422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
9432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    ALOGW("compression level %d outside [0..8] range, using 8", compressionLevel);
9442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
9452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
9462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
9472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = setupFlacCodec(encoder, numChannels, sampleRate, compressionLevel);
9482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
949ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
950ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
951ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
952ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
953ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
954ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
955ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
956ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
957ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
9585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
959729de186450f78c099637e1fce743fe531862c52Andreas Huber
9608b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
9618b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
9628b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
9639806555d3930be43e11106281dee354820ac1c88Andreas Huber
9648b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
9658b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
9668b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
9678b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
9689806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
9699806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
9709806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
9719806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
9729806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
9739806555d3930be43e11106281dee354820ac1c88Andreas Huber
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
9765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
9785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
9805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
984f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
10285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
10315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
10325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
10365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
10395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
10455778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10475778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1048aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1049aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1050ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1051ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1052ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1053ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
10545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
10555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
10565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
10575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
10585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
10645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
10655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
10675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
10685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
10715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
10725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
10735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
10755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
10765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
10785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
10795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
10825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
10835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
10855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
10865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
10885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
10895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
10925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
10935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
10945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
10965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
10975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
10995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
11005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
11035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
11055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
11065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
11075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
11095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
11105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
11115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
11125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
11135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1114aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
11155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
11165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
11185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
11195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
11215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
11225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
11255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1140ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1141ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1142ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1143ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1144ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
11485778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11505778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
11515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
11525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
11535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
11545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
11555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
11565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
11575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
11585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
11595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
11605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
11625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
11645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
11665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
11725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
11735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
11745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
11755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
11765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
11775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
11785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
11795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
11805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
11815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
11825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
11835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
11845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
11855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
11865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
11875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
11885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
11915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11955778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1196729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1197729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
11985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1199729de186450f78c099637e1fce743fe531862c52Andreas Huber
1200729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1201729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1202729de186450f78c099637e1fce743fe531862c52Andreas Huber
1203729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1204729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1205729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1206729de186450f78c099637e1fce743fe531862c52Andreas Huber
1207729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
12085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
12095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
12115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1212729de186450f78c099637e1fce743fe531862c52Andreas Huber
12135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
12145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
12155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1216729de186450f78c099637e1fce743fe531862c52Andreas Huber
12175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
12185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
12195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
12205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1221729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1222729de186450f78c099637e1fce743fe531862c52Andreas Huber
12235778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
12245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
12255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1226729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1227729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1228729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1229729de186450f78c099637e1fce743fe531862c52Andreas Huber
12302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
12312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
12322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
12332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
12342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
12352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
12362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
12372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
12382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
12392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
12402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
12412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
12422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
12432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
12442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
12452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
12462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
12472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
12482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
12492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
12502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
12512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
12522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
12532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
12542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
12552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
12562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
12572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1258729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1259729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1260729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1261729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1262729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1263729de186450f78c099637e1fce743fe531862c52Andreas Huber
1264729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1265729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1266729de186450f78c099637e1fce743fe531862c52Andreas Huber
1267729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1268729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1269729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1270729de186450f78c099637e1fce743fe531862c52Andreas Huber
1271729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1272729de186450f78c099637e1fce743fe531862c52Andreas Huber
1273729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1274729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1275729de186450f78c099637e1fce743fe531862c52Andreas Huber
1276729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1277729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1278729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1279729de186450f78c099637e1fce743fe531862c52Andreas Huber
1280729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1281729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1282729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1283729de186450f78c099637e1fce743fe531862c52Andreas Huber
1284729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1285729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1286729de186450f78c099637e1fce743fe531862c52Andreas Huber
1287729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1288729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1289729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1290729de186450f78c099637e1fce743fe531862c52Andreas Huber
1291729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1292729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1293729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1294729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1295729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1296729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1297729de186450f78c099637e1fce743fe531862c52Andreas Huber
1298c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1299c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1300729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1301729de186450f78c099637e1fce743fe531862c52Andreas Huber
1302729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1303729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1304729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1305729de186450f78c099637e1fce743fe531862c52Andreas Huber
1306f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1365f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
1378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber           || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
1379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber           || format.eColorFormat == OMX_COLOR_FormatCbYCrY
13801065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber           || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar
138118faac2af4e3b27deec0a707757883e5e569c591Haynes Mathew George           || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar
138218faac2af4e3b27deec0a707757883e5e569c591Haynes Mathew George           || format.eColorFormat == OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka);
1383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingAVC;
1393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingMPEG4;
1395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
13965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingH263;
1397386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG2, mime)) {
13985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingMPEG2;
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VPX, mime)) {
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingVPX;
1401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingUnused;
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
14505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
14525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
14595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
14735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
14755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
14775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
14945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
15035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
15065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
15085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
15105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
15125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
15615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
15635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
15645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
15655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
15665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
15695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
15725778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
15735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
16245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
16385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
16395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
16455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
16495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
16505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
16515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
16525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
16535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
16545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
16555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
16575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
16585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
16595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
16605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
16615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
16645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
16665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
16675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
16705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
16745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = configureBitrate(bitrate);
16815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
16875778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
16885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16895778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
16905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
16915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
16925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
16935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
16945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
17015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
17035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
17065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
17075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
17085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
17105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
17115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
17175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
17185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
17205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
17215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
17225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
17245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
17265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
17275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
17285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
17295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
17305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
17335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
17365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
17405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
17435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
17445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
17455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
17465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
17495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = configureBitrate(bitrate);
17555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
17615778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17635778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
17725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
17965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
17975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
18117c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
18127c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
18137c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return configureBitrate(bitrate);
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureBitrate(int32_t bitrate) {
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.eControlRate = OMX_Video_ControlRateVariable;
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1929f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
1930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
1932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
1937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
1944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
1945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
1946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
1947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
1948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
1952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
1954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
1955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
1957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
1958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
1959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1967f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
1968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
1969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
1973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1976d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
1977d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
1978d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
1979d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1980d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
1981d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
1982d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
1983d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
1984d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
1985d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
1986d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
1987d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
1988d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
1989d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
1990f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
1991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
1992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
1996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
19973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
1998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
1999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2007f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2012f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2017f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
202731e2508c75018145a8238925ff1a08cbde4e799aAndreas Hubervoid ACodec::sendFormatChange() {
202831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    sp<AMessage> notify = mNotify->dup();
202931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->setInt32("what", kWhatOutputFormatChanged);
203031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
203131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
203231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
203331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    def.nPortIndex = kPortIndexOutput;
203431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
203531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
203631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
203731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
203831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
203931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
204031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
204131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
204231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
204331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
204431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
204531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
204631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
204731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("width", videoDef->nFrameWidth);
204831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("height", videoDef->nFrameHeight);
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("stride", videoDef->nStride);
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("slice-height", videoDef->nSliceHeight);
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("color-format", videoDef->eColorFormat);
205231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
205331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_CONFIG_RECTTYPE rect;
205431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            InitOMXParams(&rect);
205531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            rect.nPortIndex = kPortIndexOutput;
205631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
205731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (mOMX->getConfig(
205831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        mNode, OMX_IndexConfigCommonOutputCrop,
205931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        &rect, sizeof(rect)) != OK) {
206031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nLeft = 0;
206131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nTop = 0;
206231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nWidth = videoDef->nFrameWidth;
206331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nHeight = videoDef->nFrameHeight;
206431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
206531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
206631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nLeft, 0);
206731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nTop, 0);
206831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nWidth, 0u);
206931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nHeight, 0u);
207031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
207131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
207231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
207331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setRect(
207431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    "crop",
207531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nLeft,
207631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nTop,
207731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nLeft + rect.nWidth - 1,
207831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nTop + rect.nHeight - 1);
207931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
208031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (mNativeWindow != NULL) {
208131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                android_native_rect_t crop;
208231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                crop.left = rect.nLeft;
208331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                crop.top = rect.nTop;
208489c120e7adbe09c6283591789594c5e591aa5032Andreas Huber                crop.right = rect.nLeft + rect.nWidth;
208589c120e7adbe09c6283591789594c5e591aa5032Andreas Huber                crop.bottom = rect.nTop + rect.nHeight;
208631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
208731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                CHECK_EQ(0, native_window_set_crop(
208831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                            mNativeWindow.get(), &crop));
208931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
209031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
209131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
209231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
209331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
209431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
209531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
209631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ((int)audioDef->eEncoding, (int)OMX_AUDIO_CodingPCM);
209731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
209831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PARAM_PCMMODETYPE params;
209931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            InitOMXParams(&params);
210031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            params.nPortIndex = kPortIndexOutput;
210131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
210231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ(mOMX->getParameter(
210331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        mNode, OMX_IndexParamAudioPcm,
210431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        &params, sizeof(params)),
210531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                     (status_t)OK);
210631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
210731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK(params.nChannels == 1 || params.bInterleaved);
210831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ(params.nBitPerSample, 16u);
210931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned);
211031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear);
211131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
211231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
211331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("channel-count", params.nChannels);
211431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("sample-rate", params.nSamplingRate);
21158b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mEncoderDelay + mEncoderPadding) {
21168b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                size_t frameSize = params.nChannels * sizeof(int16_t);
21178b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                if (mSkipCutBuffer != NULL) {
21188b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    size_t prevbufsize = mSkipCutBuffer->size();
21198b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    if (prevbufsize != 0) {
21208b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                        ALOGW("Replacing SkipCutBuffer holding %d bytes", prevbufsize);
21218b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
21228b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
21238b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay * frameSize,
21248b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                                                   mEncoderPadding * frameSize);
21258b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
21269806555d3930be43e11106281dee354820ac1c88Andreas Huber
21279806555d3930be43e11106281dee354820ac1c88Andreas Huber            if (mChannelMaskPresent) {
21289806555d3930be43e11106281dee354820ac1c88Andreas Huber                notify->setInt32("channel-mask", mChannelMask);
21299806555d3930be43e11106281dee354820ac1c88Andreas Huber            }
21309806555d3930be43e11106281dee354820ac1c88Andreas Huber
213131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
213231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
213331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
213431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
213531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
213631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
213731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
213831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
213931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
214031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
214131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
214231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
21435778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2144cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
2145cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
2146cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
2148cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
2149cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
2150cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
2151bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2152bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
2153bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
2154bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
2155bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
2156bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2157bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2158bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
2159bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
2160bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
2161bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
2162bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2163bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2164bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2165bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2166bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2167bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2168bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
2169bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
2170bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2171bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2172bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2173bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2174bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2175bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2176bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2177bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
2178bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2179bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2180bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2181bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2182bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2183bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2184bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
2185bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
2186bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2187bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2188bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2189bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2190bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2191bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2192bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
2193bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2194bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2195bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2196bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
2197bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2198bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2199bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2200bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
2201bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2202bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2203bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2204bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2205bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2206bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2207bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2208bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2209bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
2210bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
2211bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
2212bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
22131e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
22141e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2215bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2216bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2217bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2218bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2219bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2220bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2221bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2222bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2223bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2224bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
2225bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2226bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2227bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2228bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2229bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2230bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2231bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2232bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
2233bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2234bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
2235bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2236bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2237bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2238bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2239bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2240bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2241bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
22421e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
2243bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2244bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2245bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2246bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2247bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2248bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2249bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
2250bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2251bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2252bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
2253bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2254bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2255bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
2256bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
22571e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2258bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2259bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2260bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
2261bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2262bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
2263bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2264bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2265bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2266bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
2267bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
2268bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
2269bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2270bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2271bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2272bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2273bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2274bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2275bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2276bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
2277bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2278bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2279bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2280bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2281bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2282bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2283bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2284bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
2285bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2286bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
2287bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2290eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
2291eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2292eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2293496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
2294496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
2295496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
2296496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
2297496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2298496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
2299496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
2300496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2301496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
2302496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
2303496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2304496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
2305496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
2306496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
2307496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
2308496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
2309496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
2310496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2311eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
2312eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
2313eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
2314eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
2315eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2316eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2317eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
2318eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
2319eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2320eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2321eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
2322eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
2323eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2324eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2325eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
2326eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
2327eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2328eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2329eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
2330eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2331f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
2332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
2333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
2334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2336f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
2337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
2338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2340f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
2341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
2343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
2345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
2349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
2351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
2355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
2357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2366f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
2367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
2368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
2369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
2371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
2372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
2373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
2375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
2376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
2378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
2379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
2380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
2381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23820af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
23830af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
23840af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
23850af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
23860af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
23870af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
23880af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
23890af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
23900af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
23910af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
23920af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
2393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
2394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
2395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
2396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
2397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
2400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
2405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
2408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
2413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
2414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
2415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
2416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
2418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
2419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
2420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
2421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
2422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
2423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
2425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
2426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
2427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
2428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
2429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
2430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
2431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
2435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2439f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
2440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
24423856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
2443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
2444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
2446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
244829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
2449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2450cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
2451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2455f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
24563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
2457349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
2458349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
2460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
2461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
2463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
2464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2465d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
2466d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
2467d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
2468d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
2469d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
2470d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
2471d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
2472d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
2473d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
2474d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
2475d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
2476d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2477d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
2478d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
2479d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
2481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
2488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
2494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2501f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
2502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
2503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
2504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
2507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
2509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
2510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
2511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
25132d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
2514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
2516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
2517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
2519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
2521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
2523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2525f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
2526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
2527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
2528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25292d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
2530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
25315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
25325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25332d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
2534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
2535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] saw error %d instead of an input buffer",
25373831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber             mCodec->mComponentName.c_str(), err);
25383831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
25392d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
25405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
2542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
25455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
25465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
25475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
25485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
2551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
2552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
2554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
2556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
25605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
2561dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
2562dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
2563dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
2564dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
2565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
25715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
2572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
2573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
2576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
2578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
2579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
2580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
2581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
25835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
25845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
25855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
2587d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
2588d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
2589d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
2590d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
2591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
2593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
2594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
2595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2596078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
25973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
2598078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
25995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
26005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
26015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
2602078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
2603d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
2604d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
2605d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
2606d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
26073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
2608078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
2609d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
2610078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
2611349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2612d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
2613d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
2614d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
2615d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
2616d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
2617d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
2618d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
2620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
2621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
2622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
2623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
2624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
2625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
2626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
2627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
2629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
26315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
26325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
26335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
26345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
26355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
26375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
26385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
2639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
2640dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
26413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
2642dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
2643dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
2644dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
26453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
2646dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
2647dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
2648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26493856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
2650349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
2651349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
2653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
2654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
2655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
2656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
2657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
2658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
2659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
2660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
2662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
2664dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
2665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
2669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2675f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
2676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
2677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
2678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
2681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
2683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
2684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
2686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
2687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
2688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
2689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
2691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
2693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
2694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
2698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
2699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
2702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2704f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
2705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
2706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
2707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
2708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
2709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *platformPrivate,
2710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *dataPtr) {
27115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
27125778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
2713349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
2715d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2716d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
2717d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
2718d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
2719d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
2720d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
2721d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2722d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
2723d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
2724d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
2725d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2726d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
2727d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
2728d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
2729d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
2730d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
2732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
2733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
2735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
2737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
2739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
27465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
27475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
27485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
2749349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
27505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
27515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
27525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
2753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
27555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
27565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
275731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
27585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!mCodec->mIsEncoder && !mCodec->mSentFormat) {
27595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->sendFormatChange();
27605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
2761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mCodec->mNativeWindow == NULL) {
27635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mData->setRange(rangeOffset, rangeLength);
2764496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2765496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
2766496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
2767496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
2768496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
2769496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#endif
27705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
2771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27728b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
27738b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
27748b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
27755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
2776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
27785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
27795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
27802d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
27815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
2782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> reply =
27845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                new AMessage(kWhatOutputBufferDrained, mCodec->id());
2785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
2787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
2789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
27915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
2793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
27955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
27965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
2798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
2799dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
2800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
2801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
2803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
2812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
2813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2820f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
2821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
2822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
2823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
2825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
2826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
2827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
2828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
2830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
2831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && msg->findInt32("render", &render) && render != 0) {
2832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
2833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
28355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
2836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
28371e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
2838cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
2839cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
28405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
2841cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
2842cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
2843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
2844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
2845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
2848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
2853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
2856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
2857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
2859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
2866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
2868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
2869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
2871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
2872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2873c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
28743856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
2875c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
2876349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2877c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
2878c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
2879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2880c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
2881c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
2882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
2891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
2892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2899f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
2900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
2901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2903c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
2904c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
2905c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
2906c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
2907f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
2908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
2909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
2912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
2914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
2916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
29205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
29215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
29225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
29235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
29245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
2927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2928c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
2929c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
2930c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
2931c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(!keepComponentAllocated);
2932c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
2933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
2934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
2935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
2936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
2938c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
2939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
2942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
2944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
2945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
2946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
2948c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
2949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
2953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2958f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
2959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
2960c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
2961c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
2962c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
2963c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
29645778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
29655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2966c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
29675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
29685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2969c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
29705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
2972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
2973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
2975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2976e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
29775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
2979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
2981d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
29825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
2983e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
2984e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
2985e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
2986afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
2987e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
2988e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
2989e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
2990afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
29915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
29925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
29935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
29955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
29965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
29975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
30005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
30015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
30025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
30035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
3004e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
30055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30061065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
30071065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
30081065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
30091065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
30101065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
30111065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
3012e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3013e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3015078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
3016078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
3017078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
30181065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3019078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
3020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30211065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
30221065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
30231065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
30241065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
30251065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
30261065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
30271065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3028c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
30295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
30305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
30315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
30325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
30335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
30345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3035c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
3036cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
3037c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
3038c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
3039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXMessage, mCodec->id());
3041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
3042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
3044ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
3045ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3046ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
3047ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
3048ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
3049ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3050afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
3051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
3052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
3053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3054349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
3055349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
3056349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3057dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mCodec->mInputEOSResult = OK;
3058dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
30595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
30605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
30615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
30625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
30635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
30645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3065c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3066c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
3067c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3068c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
30695778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
30705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3071c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
3072c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3073c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
3074c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
3075c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3076c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3077c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
3078c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3079c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3080c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
3081c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3082c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3083c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
3084c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
3085c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3086c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
3087c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3088c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3089c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3090c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3091c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
3092c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3093c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3094c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mNativeWindow.clear();
3095c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mNode = NULL;
3096c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mOMX.clear();
3097afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        mCodec->mQuirks = 0;
3098ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags = 0;
3099c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mComponentName.clear();
3100c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3101c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
3102c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3103c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3104c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3105c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3106c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->post();
3107c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3108c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3109c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3110c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
3111c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3112c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
3113c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
3114c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3115c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
3116c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3117c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3118c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3119c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3120c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
3121c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3122c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
3123c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3124c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3125c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3126c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3127c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
3128c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3129c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3130c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3131c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3132c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3133c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
3134c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3135c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3136c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3137c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3138c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3139c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
3140c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3141c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3142c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3143c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
3144c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3145c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3146c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3147c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3148c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3149c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
3150c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
3151c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3152c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3153c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
3154c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3155c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3156c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
31575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
31585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
31595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
31615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
31635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
31645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
31665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3168c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
3169c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
3170c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
31715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
3172c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
31735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
3176386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
31775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
31781173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
31791173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
31801173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
31811173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
31821ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
31831ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
31841ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
31851ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
31905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
31915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
31925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
31935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3194c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3195c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
31965778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
31975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3198c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
31995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
32005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
32025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
3204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
3206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3210f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
3211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3214f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
32153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
3216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3217cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
3218cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
321929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
3220cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
3221cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
3222cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
32235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
322491bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
322591bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
3226cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
3227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3229f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
3230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
3231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
3237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3239f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3252f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
3253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
3259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
3262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
3265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3276f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
3277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3280f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
32813856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
3282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3284f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3297f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
3298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
3304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
3306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
3307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3318f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
3319349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
3320349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
3321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3323f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
3324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
3326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3328f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::submitOutputBuffers() {
3329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
3330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
3331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
3333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
3334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
3335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
3338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
3340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
3344349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
3345349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
3348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3353f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
3354349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
33553856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
3356349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
3357349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3358349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
3359349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
3360349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
3362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
3364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
3365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
3366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
3368349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3369349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
3370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3372f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
33733856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
3374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
3376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3378f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3384c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3385c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3386c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3387c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3388c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
3389c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
3390c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3391349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
3392349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
3398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
34057a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
3406d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
3407d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
3408d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
3409d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
3410d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
3411d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
3412d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3413349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
3414349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
3417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
3420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
3426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
3428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3433496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
3434496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
3435496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
3436496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
3437496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
3438496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
3439496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3440496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
3441496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
3442496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
3443496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3452f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
3453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
3456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
3458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
345931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
3460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
3461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
3463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3465349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
3466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
346831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
346931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
3470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
34713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
3472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
3473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
3479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3490f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
3491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
3492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3495f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
3496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
3498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
3499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
3502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
3504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3506f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
3507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3513349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
3514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3515349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
35163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
3517349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
3518349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3532f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
35333856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
3534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
3535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3537f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
3538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
3543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
3544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
3546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
3547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
3549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
3550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
3552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
3553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3555cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
3556cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
3557cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
355829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
3559cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
3560cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
3561cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
35625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
3563d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3564755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
3565755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
3566755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
3567755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
3568755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
3569755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
3570755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
3571755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
3572cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
3573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
3575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
3576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
3577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
357931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
35803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
3581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
3582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3583349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
3584349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
3585349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
3586349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
3588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
3590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3602f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
36035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
36045778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
3605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3607f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
3614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
3615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
3622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3635f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
36363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
363731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
36385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
363931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
3640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3642f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
3643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
3649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
36515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
3653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3657349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
3658349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
3659349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
3660349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
3661349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
3662349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
3663349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
36680af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3669f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
36705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
3671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
3672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
3673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
3674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
3676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
3677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3678bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (mCodec->mFlags & kFlagIsSecure && mCodec->mNativeWindow != NULL) {
3679bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
3680bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
3681bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
3682bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
3683bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
3684bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3685bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
3687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3690f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
3691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
3693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
3695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3697f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
3698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
3700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
3702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3706f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
3707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3710f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
3711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
3717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
3725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
3726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3738f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
37393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
3740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3742f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
3743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
3749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3750c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
3751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3762f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
3763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3766f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
37673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
3768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
3770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3772f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
3773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
3785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3797f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
3798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
37997a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
3800d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
3801d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
3806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
3808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
3809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
3810e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
3811e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
3812e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
3813e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
3814e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
3815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
3816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
3817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
3818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
3819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
3821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3826349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
3827349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
3828349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
3829349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
3830349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
3831349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
3832349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
3833349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
3834349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
38353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
3836349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
3837349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3838349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
3839349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3840349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
3841349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
3842349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3850f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
3851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
3852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
3854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3856f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
3857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
3858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
3860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3862f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
3863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
3864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
3865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
3866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
3867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
3868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
3869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
3871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
3872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3873dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
3874dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
3875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
3876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
3880